Patch "riscv: kprobe: Fixup kernel panic when probing an illegal position" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    riscv: kprobe: Fixup kernel panic when probing an illegal position

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     riscv-kprobe-fixup-kernel-panic-when-probing-an-ille.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 532e3184e5769cf28860d72a29059af86883051a
Author: Guo Ren <guoren@xxxxxxxxxx>
Date:   Tue Jan 31 23:06:04 2023 -0500

    riscv: kprobe: Fixup kernel panic when probing an illegal position
    
    [ Upstream commit 87f48c7ccc73afc78630530d9af51f458f58cab8 ]
    
    The kernel would panic when probed for an illegal position. eg:
    
    (CONFIG_RISCV_ISA_C=n)
    
    echo 'p:hello kernel_clone+0x16 a0=%a0' >> kprobe_events
    echo 1 > events/kprobes/hello/enable
    cat trace
    
    Kernel panic - not syncing: stack-protector: Kernel stack
    is corrupted in: __do_sys_newfstatat+0xb8/0xb8
    CPU: 0 PID: 111 Comm: sh Not tainted
    6.2.0-rc1-00027-g2d398fe49a4d #490
    Hardware name: riscv-virtio,qemu (DT)
    Call Trace:
    [<ffffffff80007268>] dump_backtrace+0x38/0x48
    [<ffffffff80c5e83c>] show_stack+0x50/0x68
    [<ffffffff80c6da28>] dump_stack_lvl+0x60/0x84
    [<ffffffff80c6da6c>] dump_stack+0x20/0x30
    [<ffffffff80c5ecf4>] panic+0x160/0x374
    [<ffffffff80c6db94>] generic_handle_arch_irq+0x0/0xa8
    [<ffffffff802deeb0>] sys_newstat+0x0/0x30
    [<ffffffff800158c0>] sys_clone+0x20/0x30
    [<ffffffff800039e8>] ret_from_syscall+0x0/0x4
    ---[ end Kernel panic - not syncing: stack-protector:
    Kernel stack is corrupted in: __do_sys_newfstatat+0xb8/0xb8 ]---
    
    That is because the kprobe's ebreak instruction broke the kernel's
    original code. The user should guarantee the correction of the probe
    position, but it couldn't make the kernel panic.
    
    This patch adds arch_check_kprobe in arch_prepare_kprobe to prevent an
    illegal position (Such as the middle of an instruction).
    
    Fixes: c22b0bcb1dd0 ("riscv: Add kprobes supported")
    Signed-off-by: Guo Ren <guoren@xxxxxxxxxxxxxxxxx>
    Signed-off-by: Guo Ren <guoren@xxxxxxxxxx>
    Reviewed-by: Björn Töpel <bjorn@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20230201040604.3390509-1-guoren@xxxxxxxxxx
    Signed-off-by: Palmer Dabbelt <palmer@xxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
index 00088dc6da4b..125241ce82d6 100644
--- a/arch/riscv/kernel/probes/kprobes.c
+++ b/arch/riscv/kernel/probes/kprobes.c
@@ -46,6 +46,21 @@ static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs)
 	post_kprobe_handler(p, kcb, regs);
 }
 
+static bool __kprobes arch_check_kprobe(struct kprobe *p)
+{
+	unsigned long tmp  = (unsigned long)p->addr - p->offset;
+	unsigned long addr = (unsigned long)p->addr;
+
+	while (tmp <= addr) {
+		if (tmp == addr)
+			return true;
+
+		tmp += GET_INSN_LENGTH(*(u16 *)tmp);
+	}
+
+	return false;
+}
+
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	unsigned long probe_addr = (unsigned long)p->addr;
@@ -56,6 +71,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 		return -EINVAL;
 	}
 
+	if (!arch_check_kprobe(p))
+		return -EILSEQ;
+
 	/* copy instruction */
 	p->opcode = *p->addr;
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux