From: Mani Tofigh <[email protected]>

A new probe at the address of a force-unoptimized probe can stop
firing.  When unoptimize_kprobe() force-unoptimizes an unused probe it
disarms and unhashes it, but the next dispatch disarms it again.  If a
new probe was registered at the same address in the meantime, the
second disarm clears the new probe's int3.  For a module address the
same disarm would write to freed module text after rmmod.

Skip the disarm for unhashed probes since they're always disarmed before
they're unhashed.  With the fix, the new probe fires.

Fixes: 06e0d3b89da1 ("kprobes: Make optprobe optimizer multi-generational and 
asynchronous")
Signed-off-by: Mani Tofigh <[email protected]>
---
 kernel/kprobes.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 4c35cc24aadc..84a5f68476eb 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -631,8 +631,12 @@ static void do_unoptimize_kprobes(struct list_head 
*unopt_list,
        list_for_each_entry_safe(op, tmp, free_list, list) {
                /* Switching from detour code to origin */
                op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
-               /* Disarm probes if marked disabled and not gone */
-               if (kprobe_disabled(&op->kp) && !kprobe_gone(&op->kp))
+               /*
+                * Disarm probes if marked disabled and not gone. Unhashed 
probes
+                * were disarmed before they were unhashed.
+                */
+               if (kprobe_disabled(&op->kp) && !kprobe_gone(&op->kp) &&
+                   !hlist_unhashed(&op->kp.hlist))
                        arch_disarm_kprobe(&op->kp);
                if (kprobe_unused(&op->kp)) {
                        /*

-- 
2.53.0



Reply via email to