lkml.org 
[lkml]   [2023]   [Jan]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v6 10/13] riscv/kprobe: Add instruction boundary check for RVI/RVC hybrid kernel
Date
From: Liao Chang <liaochang1@huawei.com>

Add instruction boundary check to ensure kprobe doesn't truncate any RVI
instruction, which leads to kernel crash.

Signed-off-by: Liao Chang <liaochang1@huawei.com>
---
arch/riscv/kernel/probes/kprobes.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
index e1856b04db04..91a6b46909cc 100644
--- a/arch/riscv/kernel/probes/kprobes.c
+++ b/arch/riscv/kernel/probes/kprobes.c
@@ -49,11 +49,33 @@ static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs)
post_kprobe_handler(p, kcb, regs);
}

+bool __kprobes riscv_insn_boundary_check(unsigned long paddr)
+{
+#if defined(CONFIG_RISCV_ISA_C)
+ unsigned long size = 0, offs = 0, len = 0, entry = 0;
+
+ if (!kallsyms_lookup_size_offset(paddr, &size, &offs))
+ return false;
+
+ /*
+ * Scan instructions from function entry ensure the kprobe address
+ * is aligned with RVI or RVC boundary.
+ */
+ entry = paddr - offs;
+ while ((entry + len) < paddr)
+ len += GET_INSN_LENGTH(*(kprobe_opcode_t *)(entry + len));
+ return (entry + len) == paddr;
+#else
+ return true;
+#endif
+}
+
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
unsigned long probe_addr = (unsigned long)p->addr;

- if (probe_addr & 0x1)
+ /* for RVI/RCV hybrid kernel, it needs instruction boundary check */
+ if ((probe_addr & 0x1) || !riscv_insn_boundary_check(probe_addr))
return -EILSEQ;

/* copy instruction */
--
2.34.1
\
 
 \ /
  Last update: 2023-03-26 23:58    [W:0.202 / U:0.416 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site