[tip:perf/urgent] uprobes: Fix handle_swbp() vs. unregister() + register() race once more

2018-11-22 Thread tip-bot for Andrea Parri
Commit-ID:  09d3f015d1e1b4fee7e9bbdcf54201d239393391
Gitweb: https://git.kernel.org/tip/09d3f015d1e1b4fee7e9bbdcf54201d239393391
Author: Andrea Parri 
AuthorDate: Thu, 22 Nov 2018 17:10:31 +0100
Committer:  Ingo Molnar 
CommitDate: Fri, 23 Nov 2018 08:31:19 +0100

uprobes: Fix handle_swbp() vs. unregister() + register() race once more

Commit:

  142b18ddc8143 ("uprobes: Fix handle_swbp() vs unregister() + register() race")

added the UPROBE_COPY_INSN flag, and corresponding smp_wmb() and smp_rmb()
memory barriers, to ensure that handle_swbp() uses fully-initialized
uprobes only.

However, the smp_rmb() is mis-placed: this barrier should be placed
after handle_swbp() has tested for the flag, thus guaranteeing that
(program-order) subsequent loads from the uprobe can see the initial
stores performed by prepare_uprobe().

Move the smp_rmb() accordingly.  Also amend the comments associated
to the two memory barriers to indicate their actual locations.

Signed-off-by: Andrea Parri 
Acked-by: Oleg Nesterov 
Cc: Alexander Shishkin 
Cc: Andrew Morton 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Linus Torvalds 
Cc: Namhyung Kim 
Cc: Paul E. McKenney 
Cc: Peter Zijlstra 
Cc: Stephane Eranian 
Cc: Thomas Gleixner 
Cc: Vince Weaver 
Cc: sta...@kernel.org
Fixes: 142b18ddc8143 ("uprobes: Fix handle_swbp() vs unregister() + register() 
race")
Link: 
http://lkml.kernel.org/r/20181122161031.15179-1-andrea.pa...@amarulasolutions.com
Signed-off-by: Ingo Molnar 
---
 kernel/events/uprobes.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 96d4bee83489..322e97bbb437 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -829,7 +829,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct 
file *file,
BUG_ON((uprobe->offset & ~PAGE_MASK) +
UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
 
-   smp_wmb(); /* pairs with rmb() in find_active_uprobe() */
+   smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
set_bit(UPROBE_COPY_INSN, >flags);
 
  out:
@@ -2178,10 +2178,18 @@ static void handle_swbp(struct pt_regs *regs)
 * After we hit the bp, _unregister + _register can install the
 * new and not-yet-analyzed uprobe at the same address, restart.
 */
-   smp_rmb(); /* pairs with wmb() in install_breakpoint() */
if (unlikely(!test_bit(UPROBE_COPY_INSN, >flags)))
goto out;
 
+   /*
+* Pairs with the smp_wmb() in prepare_uprobe().
+*
+* Guarantees that if we see the UPROBE_COPY_INSN bit set, then
+* we must also see the stores to >arch performed by the
+* prepare_uprobe() call.
+*/
+   smp_rmb();
+
/* Tracing handlers use ->utask to communicate with fetch methods */
if (!get_utask())
goto out;


[tip:perf/urgent] uprobes: Fix handle_swbp() vs. unregister() + register() race once more

2018-11-22 Thread tip-bot for Andrea Parri
Commit-ID:  09d3f015d1e1b4fee7e9bbdcf54201d239393391
Gitweb: https://git.kernel.org/tip/09d3f015d1e1b4fee7e9bbdcf54201d239393391
Author: Andrea Parri 
AuthorDate: Thu, 22 Nov 2018 17:10:31 +0100
Committer:  Ingo Molnar 
CommitDate: Fri, 23 Nov 2018 08:31:19 +0100

uprobes: Fix handle_swbp() vs. unregister() + register() race once more

Commit:

  142b18ddc8143 ("uprobes: Fix handle_swbp() vs unregister() + register() race")

added the UPROBE_COPY_INSN flag, and corresponding smp_wmb() and smp_rmb()
memory barriers, to ensure that handle_swbp() uses fully-initialized
uprobes only.

However, the smp_rmb() is mis-placed: this barrier should be placed
after handle_swbp() has tested for the flag, thus guaranteeing that
(program-order) subsequent loads from the uprobe can see the initial
stores performed by prepare_uprobe().

Move the smp_rmb() accordingly.  Also amend the comments associated
to the two memory barriers to indicate their actual locations.

Signed-off-by: Andrea Parri 
Acked-by: Oleg Nesterov 
Cc: Alexander Shishkin 
Cc: Andrew Morton 
Cc: Arnaldo Carvalho de Melo 
Cc: Jiri Olsa 
Cc: Linus Torvalds 
Cc: Namhyung Kim 
Cc: Paul E. McKenney 
Cc: Peter Zijlstra 
Cc: Stephane Eranian 
Cc: Thomas Gleixner 
Cc: Vince Weaver 
Cc: sta...@kernel.org
Fixes: 142b18ddc8143 ("uprobes: Fix handle_swbp() vs unregister() + register() 
race")
Link: 
http://lkml.kernel.org/r/20181122161031.15179-1-andrea.pa...@amarulasolutions.com
Signed-off-by: Ingo Molnar 
---
 kernel/events/uprobes.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 96d4bee83489..322e97bbb437 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -829,7 +829,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct 
file *file,
BUG_ON((uprobe->offset & ~PAGE_MASK) +
UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
 
-   smp_wmb(); /* pairs with rmb() in find_active_uprobe() */
+   smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
set_bit(UPROBE_COPY_INSN, >flags);
 
  out:
@@ -2178,10 +2178,18 @@ static void handle_swbp(struct pt_regs *regs)
 * After we hit the bp, _unregister + _register can install the
 * new and not-yet-analyzed uprobe at the same address, restart.
 */
-   smp_rmb(); /* pairs with wmb() in install_breakpoint() */
if (unlikely(!test_bit(UPROBE_COPY_INSN, >flags)))
goto out;
 
+   /*
+* Pairs with the smp_wmb() in prepare_uprobe().
+*
+* Guarantees that if we see the UPROBE_COPY_INSN bit set, then
+* we must also see the stores to >arch performed by the
+* prepare_uprobe() call.
+*/
+   smp_rmb();
+
/* Tracing handlers use ->utask to communicate with fetch methods */
if (!get_utask())
goto out;