Commit 09d3f015 authored by Andrea Parri's avatar Andrea Parri Committed by Ingo Molnar

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


  142b18dd ("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: default avatarAndrea Parri <>
Acked-by: default avatarOleg 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 <>
Fixes: 142b18dd ("uprobes: Fix handle_swbp() vs unregister() + register() race")
Link: Ingo Molnar's avatarIngo Molnar <>
parent 472de49f
......@@ -829,7 +829,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
BUG_ON((uprobe->offset & ~PAGE_MASK) +
smp_wmb(); /* pairs with rmb() in find_active_uprobe() */
smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
set_bit(UPROBE_COPY_INSN, &uprobe->flags);
......@@ -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, &uprobe->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 &uprobe->arch performed by the
* prepare_uprobe() call.
/* Tracing handlers use ->utask to communicate with fetch methods */
if (!get_utask())
goto out;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment