lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230127130541.1250865-11-chenguokai17@mails.ucas.ac.cn>
Date:   Fri, 27 Jan 2023 21:05:38 +0800
From:   Chen Guokai <chenguokai17@...ls.ucas.ac.cn>
To:     paul.walmsley@...ive.com, palmer@...belt.com,
        aou@...s.berkeley.edu, rostedt@...dmis.org, mingo@...hat.com,
        sfr@...b.auug.org.au
Cc:     linux-riscv@...ts.infradead.org, linux-kernel@...r.kernel.org,
        liaochang1@...wei.com
Subject: [PATCH v6 10/13] riscv/kprobe: Add instruction boundary check for RVI/RVC hybrid kernel

From: Liao Chang <liaochang1@...wei.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@...wei.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ