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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sun, 17 Jul 2022 01:18:06 +0200 (CEST)
From:   Thomas Gleixner <tglx@...utronix.de>
To:     LKML <linux-kernel@...r.kernel.org>
Cc:     x86@...nel.org, Linus Torvalds <torvalds@...ux-foundation.org>,
        Tim Chen <tim.c.chen@...ux.intel.com>,
        Josh Poimboeuf <jpoimboe@...nel.org>,
        Andrew Cooper <Andrew.Cooper3@...rix.com>,
        Pawan Gupta <pawan.kumar.gupta@...ux.intel.com>,
        Johannes Wikner <kwikner@...z.ch>,
        Alyssa Milburn <alyssa.milburn@...ux.intel.com>,
        Jann Horn <jannh@...gle.com>, "H.J. Lu" <hjl.tools@...il.com>,
        Joao Moreira <joao.moreira@...el.com>,
        Joseph Nuzman <joseph.nuzman@...el.com>,
        Steven Rostedt <rostedt@...dmis.org>,
        "Peter Zijlstra (Intel)" <peterz@...radead.org>,
        Masami Hiramatsu <mhiramat@...nel.org>
Subject: [patch 35/38] kprobes: Add callthunk blacklisting

From: Peter Zijlstra <peterz@...radead.org>

Callthunks are not safe for probing. Add them to the kprobes black listed
areas.

Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
Cc: Masami Hiramatsu <mhiramat@...nel.org>
---
 arch/x86/kernel/callthunks.c |    5 ++++
 kernel/kprobes.c             |   52 +++++++++++++++++++++++++++----------------
 2 files changed, 38 insertions(+), 19 deletions(-)

--- a/arch/x86/kernel/callthunks.c
+++ b/arch/x86/kernel/callthunks.c
@@ -6,6 +6,7 @@
 #include <linux/debugfs.h>
 #include <linux/kallsyms.h>
 #include <linux/memory.h>
+#include <linux/kprobes.h>
 #include <linux/moduleloader.h>
 #include <linux/set_memory.h>
 #include <linux/static_call.h>
@@ -476,6 +477,7 @@ static __init_or_module int callthunks_s
 
 static __init noinline void callthunks_init(struct callthunk_sites *cs)
 {
+	unsigned long base, size;
 	int ret;
 
 	if (cpu_feature_enabled(X86_FEATURE_CALL_DEPTH)) {
@@ -494,6 +496,9 @@ static __init noinline void callthunks_i
 	if (WARN_ON_ONCE(ret))
 		return;
 
+	base = (unsigned long)builtin_layout.base;
+	size = builtin_layout.size;
+	kprobe_add_area_blacklist(base, base + size);
 	static_call_force_reinit();
 	thunks_initialized = true;
 }
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -2439,40 +2439,38 @@ void dump_kprobe(struct kprobe *kp)
 }
 NOKPROBE_SYMBOL(dump_kprobe);
 
-int kprobe_add_ksym_blacklist(unsigned long entry)
+static int __kprobe_add_ksym_blacklist(unsigned long start, unsigned long end)
 {
 	struct kprobe_blacklist_entry *ent;
-	unsigned long offset = 0, size = 0;
-
-	if (!kernel_text_address(entry) ||
-	    !kallsyms_lookup_size_offset(entry, &size, &offset))
-		return -EINVAL;
 
 	ent = kmalloc(sizeof(*ent), GFP_KERNEL);
 	if (!ent)
 		return -ENOMEM;
-	ent->start_addr = entry;
-	ent->end_addr = entry + size;
+	ent->start_addr = start;
+	ent->end_addr = end;
 	INIT_LIST_HEAD(&ent->list);
 	list_add_tail(&ent->list, &kprobe_blacklist);
 
-	return (int)size;
+	return (int)(end - start);
+}
+
+int kprobe_add_ksym_blacklist(unsigned long entry)
+{
+	unsigned long offset = 0, size = 0;
+
+	if (!kernel_text_address(entry) ||
+	    !kallsyms_lookup_size_offset(entry, &size, &offset))
+		return -EINVAL;
+
+	return __kprobe_add_ksym_blacklist(entry, entry + size);
 }
 
 /* Add all symbols in given area into kprobe blacklist */
 int kprobe_add_area_blacklist(unsigned long start, unsigned long end)
 {
-	unsigned long entry;
-	int ret = 0;
+	int ret = __kprobe_add_ksym_blacklist(start, end);
 
-	for (entry = start; entry < end; entry += ret) {
-		ret = kprobe_add_ksym_blacklist(entry);
-		if (ret < 0)
-			return ret;
-		if (ret == 0)	/* In case of alias symbol */
-			ret = 1;
-	}
-	return 0;
+	return ret < 0 ? ret : 0;
 }
 
 /* Remove all symbols in given area from kprobe blacklist */
@@ -2578,6 +2576,14 @@ static void add_module_kprobe_blacklist(
 		end = start + mod->noinstr_text_size;
 		kprobe_add_area_blacklist(start, end);
 	}
+
+#ifdef CONFIG_CALL_THUNKS
+	start = (unsigned long)mod->thunk_layout.base;
+	if (start) {
+		end = start + mod->thunk_layout.size;
+		kprobe_remove_area_blacklist(start, end);
+	}
+#endif
 }
 
 static void remove_module_kprobe_blacklist(struct module *mod)
@@ -2601,6 +2607,14 @@ static void remove_module_kprobe_blackli
 		end = start + mod->noinstr_text_size;
 		kprobe_remove_area_blacklist(start, end);
 	}
+
+#ifdef CONFIG_CALL_THUNKS
+	start = (unsigned long)mod->thunk_layout.base;
+	if (start) {
+		end = start + mod->thunk_layout.size;
+		kprobe_remove_area_blacklist(start, end);
+	}
+#endif
 }
 
 /* Module notifier call back, checking kprobes on the module */

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ