1. It doesn't make sense to continue if handle_trampoline() fails,
   change handle_swbp() to always return after this call.

2. Turn pr_warn() into uprobe_warn(), and change handle_trampoline()
   to send SIGILL on failure. It is pointless to return to user mode
   with the corrupted instruction_pointer() which we can't restore.

Signed-off-by: Oleg Nesterov <o...@redhat.com>
Acked-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com>
Acked-by: Anton Arapov <ara...@gmail.com>
Tested-by: Pratyush Anand <pan...@redhat.com>
---
 kernel/events/uprobes.c |   21 ++++++++++-----------
 1 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index d8c702f..eabdc21 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1770,7 +1770,7 @@ handle_uretprobe_chain(struct return_instance *ri, struct 
pt_regs *regs)
        up_read(&uprobe->register_rwsem);
 }
 
-static bool handle_trampoline(struct pt_regs *regs)
+static void handle_trampoline(struct pt_regs *regs)
 {
        struct uprobe_task *utask;
        struct return_instance *ri;
@@ -1778,11 +1778,11 @@ static bool handle_trampoline(struct pt_regs *regs)
 
        utask = current->utask;
        if (!utask)
-               return false;
+               goto sigill;
 
        ri = utask->return_instances;
        if (!ri)
-               return false;
+               goto sigill;
 
        /*
         * TODO: we should throw out return_instance's invalidated by
@@ -1804,8 +1804,12 @@ static bool handle_trampoline(struct pt_regs *regs)
        }
 
        utask->return_instances = ri;
+       return;
+
+ sigill:
+       uprobe_warn(current, "handle uretprobe, sending SIGILL.");
+       force_sig_info(SIGILL, SEND_SIG_FORCED, current);
 
-       return true;
 }
 
 bool __weak arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs)
@@ -1824,13 +1828,8 @@ static void handle_swbp(struct pt_regs *regs)
        int uninitialized_var(is_swbp);
 
        bp_vaddr = uprobe_get_swbp_addr(regs);
-       if (bp_vaddr == get_trampoline_vaddr()) {
-               if (handle_trampoline(regs))
-                       return;
-
-               pr_warn("uprobe: unable to handle uretprobe pid/tgid=%d/%d\n",
-                                               current->pid, current->tgid);
-       }
+       if (bp_vaddr == get_trampoline_vaddr())
+               return handle_trampoline(regs);
 
        uprobe = find_active_uprobe(bp_vaddr, &is_swbp);
        if (!uprobe) {
-- 
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to