Commit c9271209 authored by Andrea Parri's avatar Andrea Parri Committed by Greg Kroah-Hartman

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

commit 09d3f015d1e1b4fee7e9bbdcf54201d239393391 upstream.


  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: default avatarIngo Molnar <>
Signed-off-by: default avatarGreg Kroah-Hartman <>
parent def70991
......@@ -606,7 +606,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);
......@@ -1892,10 +1892,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
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment