Skip to content

Commit aa644c4

Browse files
olsajiriakpm00
authored andcommitted
uprobes: revert ref_ctr_offset in uprobe_unregister error path
There's error path that could lead to inactive uprobe: 1) uprobe_register succeeds - updates instruction to int3 and changes ref_ctr from 0 to 1 2) uprobe_unregister fails - int3 stays in place, but ref_ctr is changed to 0 (it's not restored to 1 in the fail path) uprobe is leaked 3) another uprobe_register comes and re-uses the leaked uprobe and succeds - but int3 is already in place, so ref_ctr update is skipped and it stays 0 - uprobe CAN NOT be triggered now 4) uprobe_unregister fails because ref_ctr value is unexpected Fix this by reverting the updated ref_ctr value back to 1 in step 2), which is the case when uprobe_unregister fails (int3 stays in place), but we have already updated refctr. The new scenario will go as follows: 1) uprobe_register succeeds - updates instruction to int3 and changes ref_ctr from 0 to 1 2) uprobe_unregister fails - int3 stays in place and ref_ctr is reverted to 1.. uprobe is leaked 3) another uprobe_register comes and re-uses the leaked uprobe and succeds - but int3 is already in place, so ref_ctr update is skipped and it stays 1 - uprobe CAN be triggered now 4) uprobe_unregister succeeds Link: https://lkml.kernel.org/r/[email protected] Fixes: 1cc3316 ("uprobes: Support SDT markers having reference count (semaphore)") Signed-off-by: Jiri Olsa <[email protected]> Acked-by: David Hildenbrand <[email protected]> Acked-by: Oleg Nesterov <[email protected]> Suggested-by: Oleg Nesterov <[email protected]> Cc: Andrii Nakryiko <[email protected]> Cc: "Masami Hiramatsu (Google)" <[email protected]> Cc: Peter Zijlstra <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 5eee4c2 commit aa644c4

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

kernel/events/uprobes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,8 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct vm_area_struct *vma,
581581

582582
out:
583583
/* Revert back reference counter if instruction update failed. */
584-
if (ret < 0 && is_register && ref_ctr_updated)
585-
update_ref_ctr(uprobe, mm, -1);
584+
if (ret < 0 && ref_ctr_updated)
585+
update_ref_ctr(uprobe, mm, is_register ? -1 : 1);
586586

587587
/* try collapse pmd for compound page */
588588
if (ret > 0)

0 commit comments

Comments
 (0)