linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sami Tolvanen <samitolvanen@google.com>
To: linux-kernel@vger.kernel.org
Cc: Kees Cook <keescook@chromium.org>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	x86@kernel.org, Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Nathan Chancellor <nathan@kernel.org>,
	Nick Desaulniers <ndesaulniers@google.com>,
	Joao Moreira <joao@overdrivepizza.com>,
	Sedat Dilek <sedat.dilek@gmail.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	linux-hardening@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, llvm@lists.linux.dev,
	Sami Tolvanen <samitolvanen@google.com>
Subject: [RFC PATCH v2 04/21] cfi: Remove CONFIG_CFI_CLANG_SHADOW
Date: Fri, 13 May 2022 13:21:42 -0700	[thread overview]
Message-ID: <20220513202159.1550547-5-samitolvanen@google.com> (raw)
In-Reply-To: <20220513202159.1550547-1-samitolvanen@google.com>

In preparation to switching to -fsanitize=kcfi, remove support for the
CFI module shadow that will no longer be needed.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
---
 arch/Kconfig        |  10 --
 include/linux/cfi.h |  12 ---
 kernel/cfi.c        | 237 +-------------------------------------------
 kernel/module.c     |  15 ---
 4 files changed, 1 insertion(+), 273 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 31c4fdc4a4ba..625db6376726 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -739,16 +739,6 @@ config CFI_CLANG
 
 	    https://clang.llvm.org/docs/ControlFlowIntegrity.html
 
-config CFI_CLANG_SHADOW
-	bool "Use CFI shadow to speed up cross-module checks"
-	default y
-	depends on CFI_CLANG && MODULES
-	help
-	  If you select this option, the kernel builds a fast look-up table of
-	  CFI check functions in loaded modules to reduce performance overhead.
-
-	  If unsure, say Y.
-
 config CFI_PERMISSIVE
 	bool "Use CFI in permissive mode"
 	depends on CFI_CLANG
diff --git a/include/linux/cfi.h b/include/linux/cfi.h
index c6dfc1ed0626..4ab51c067007 100644
--- a/include/linux/cfi.h
+++ b/include/linux/cfi.h
@@ -20,18 +20,6 @@ extern void __cfi_check(uint64_t id, void *ptr, void *diag);
 #define __CFI_ADDRESSABLE(fn, __attr) \
 	const void *__cfi_jt_ ## fn __visible __attr = (void *)&fn
 
-#ifdef CONFIG_CFI_CLANG_SHADOW
-
-extern void cfi_module_add(struct module *mod, unsigned long base_addr);
-extern void cfi_module_remove(struct module *mod, unsigned long base_addr);
-
-#else
-
-static inline void cfi_module_add(struct module *mod, unsigned long base_addr) {}
-static inline void cfi_module_remove(struct module *mod, unsigned long base_addr) {}
-
-#endif /* CONFIG_CFI_CLANG_SHADOW */
-
 #else /* !CONFIG_CFI_CLANG */
 
 #ifdef CONFIG_X86_KERNEL_IBT
diff --git a/kernel/cfi.c b/kernel/cfi.c
index 9594cfd1cf2c..2cc0d01ea980 100644
--- a/kernel/cfi.c
+++ b/kernel/cfi.c
@@ -32,237 +32,6 @@ static inline void handle_cfi_failure(void *ptr)
 }
 
 #ifdef CONFIG_MODULES
-#ifdef CONFIG_CFI_CLANG_SHADOW
-/*
- * Index type. A 16-bit index can address at most (2^16)-2 pages (taking
- * into account SHADOW_INVALID), i.e. ~256M with 4k pages.
- */
-typedef u16 shadow_t;
-#define SHADOW_INVALID		((shadow_t)~0UL)
-
-struct cfi_shadow {
-	/* Page index for the beginning of the shadow */
-	unsigned long base;
-	/* An array of __cfi_check locations (as indices to the shadow) */
-	shadow_t shadow[1];
-} __packed;
-
-/*
- * The shadow covers ~128M from the beginning of the module region. If
- * the region is larger, we fall back to __module_address for the rest.
- */
-#define __SHADOW_RANGE		(_UL(SZ_128M) >> PAGE_SHIFT)
-
-/* The in-memory size of struct cfi_shadow, always at least one page */
-#define __SHADOW_PAGES		((__SHADOW_RANGE * sizeof(shadow_t)) >> PAGE_SHIFT)
-#define SHADOW_PAGES		max(1UL, __SHADOW_PAGES)
-#define SHADOW_SIZE		(SHADOW_PAGES << PAGE_SHIFT)
-
-/* The actual size of the shadow array, minus metadata */
-#define SHADOW_ARR_SIZE		(SHADOW_SIZE - offsetof(struct cfi_shadow, shadow))
-#define SHADOW_ARR_SLOTS	(SHADOW_ARR_SIZE / sizeof(shadow_t))
-
-static DEFINE_MUTEX(shadow_update_lock);
-static struct cfi_shadow __rcu *cfi_shadow __read_mostly;
-
-/* Returns the index in the shadow for the given address */
-static inline int ptr_to_shadow(const struct cfi_shadow *s, unsigned long ptr)
-{
-	unsigned long index;
-	unsigned long page = ptr >> PAGE_SHIFT;
-
-	if (unlikely(page < s->base))
-		return -1; /* Outside of module area */
-
-	index = page - s->base;
-
-	if (index >= SHADOW_ARR_SLOTS)
-		return -1; /* Cannot be addressed with shadow */
-
-	return (int)index;
-}
-
-/* Returns the page address for an index in the shadow */
-static inline unsigned long shadow_to_ptr(const struct cfi_shadow *s,
-	int index)
-{
-	if (unlikely(index < 0 || index >= SHADOW_ARR_SLOTS))
-		return 0;
-
-	return (s->base + index) << PAGE_SHIFT;
-}
-
-/* Returns the __cfi_check function address for the given shadow location */
-static inline unsigned long shadow_to_check_fn(const struct cfi_shadow *s,
-	int index)
-{
-	if (unlikely(index < 0 || index >= SHADOW_ARR_SLOTS))
-		return 0;
-
-	if (unlikely(s->shadow[index] == SHADOW_INVALID))
-		return 0;
-
-	/* __cfi_check is always page aligned */
-	return (s->base + s->shadow[index]) << PAGE_SHIFT;
-}
-
-static void prepare_next_shadow(const struct cfi_shadow __rcu *prev,
-		struct cfi_shadow *next)
-{
-	int i, index, check;
-
-	/* Mark everything invalid */
-	memset(next->shadow, 0xFF, SHADOW_ARR_SIZE);
-
-	if (!prev)
-		return; /* No previous shadow */
-
-	/* If the base address didn't change, an update is not needed */
-	if (prev->base == next->base) {
-		memcpy(next->shadow, prev->shadow, SHADOW_ARR_SIZE);
-		return;
-	}
-
-	/* Convert the previous shadow to the new address range */
-	for (i = 0; i < SHADOW_ARR_SLOTS; ++i) {
-		if (prev->shadow[i] == SHADOW_INVALID)
-			continue;
-
-		index = ptr_to_shadow(next, shadow_to_ptr(prev, i));
-		if (index < 0)
-			continue;
-
-		check = ptr_to_shadow(next,
-				shadow_to_check_fn(prev, prev->shadow[i]));
-		if (check < 0)
-			continue;
-
-		next->shadow[index] = (shadow_t)check;
-	}
-}
-
-static void add_module_to_shadow(struct cfi_shadow *s, struct module *mod,
-			unsigned long min_addr, unsigned long max_addr)
-{
-	int check_index;
-	unsigned long check = (unsigned long)mod->cfi_check;
-	unsigned long ptr;
-
-	if (unlikely(!PAGE_ALIGNED(check))) {
-		pr_warn("cfi: not using shadow for module %s\n", mod->name);
-		return;
-	}
-
-	check_index = ptr_to_shadow(s, check);
-	if (check_index < 0)
-		return; /* Module not addressable with shadow */
-
-	/* For each page, store the check function index in the shadow */
-	for (ptr = min_addr; ptr <= max_addr; ptr += PAGE_SIZE) {
-		int index = ptr_to_shadow(s, ptr);
-
-		if (index >= 0) {
-			/* Each page must only contain one module */
-			WARN_ON_ONCE(s->shadow[index] != SHADOW_INVALID);
-			s->shadow[index] = (shadow_t)check_index;
-		}
-	}
-}
-
-static void remove_module_from_shadow(struct cfi_shadow *s, struct module *mod,
-		unsigned long min_addr, unsigned long max_addr)
-{
-	unsigned long ptr;
-
-	for (ptr = min_addr; ptr <= max_addr; ptr += PAGE_SIZE) {
-		int index = ptr_to_shadow(s, ptr);
-
-		if (index >= 0)
-			s->shadow[index] = SHADOW_INVALID;
-	}
-}
-
-typedef void (*update_shadow_fn)(struct cfi_shadow *, struct module *,
-			unsigned long min_addr, unsigned long max_addr);
-
-static void update_shadow(struct module *mod, unsigned long base_addr,
-		update_shadow_fn fn)
-{
-	struct cfi_shadow *prev;
-	struct cfi_shadow *next;
-	unsigned long min_addr, max_addr;
-
-	next = vmalloc(SHADOW_SIZE);
-
-	mutex_lock(&shadow_update_lock);
-	prev = rcu_dereference_protected(cfi_shadow,
-					 mutex_is_locked(&shadow_update_lock));
-
-	if (next) {
-		next->base = base_addr >> PAGE_SHIFT;
-		prepare_next_shadow(prev, next);
-
-		min_addr = (unsigned long)mod->core_layout.base;
-		max_addr = min_addr + mod->core_layout.text_size;
-		fn(next, mod, min_addr & PAGE_MASK, max_addr & PAGE_MASK);
-
-		set_memory_ro((unsigned long)next, SHADOW_PAGES);
-	}
-
-	rcu_assign_pointer(cfi_shadow, next);
-	mutex_unlock(&shadow_update_lock);
-	synchronize_rcu();
-
-	if (prev) {
-		set_memory_rw((unsigned long)prev, SHADOW_PAGES);
-		vfree(prev);
-	}
-}
-
-void cfi_module_add(struct module *mod, unsigned long base_addr)
-{
-	update_shadow(mod, base_addr, add_module_to_shadow);
-}
-
-void cfi_module_remove(struct module *mod, unsigned long base_addr)
-{
-	update_shadow(mod, base_addr, remove_module_from_shadow);
-}
-
-static inline cfi_check_fn ptr_to_check_fn(const struct cfi_shadow __rcu *s,
-	unsigned long ptr)
-{
-	int index;
-
-	if (unlikely(!s))
-		return NULL; /* No shadow available */
-
-	index = ptr_to_shadow(s, ptr);
-	if (index < 0)
-		return NULL; /* Cannot be addressed with shadow */
-
-	return (cfi_check_fn)shadow_to_check_fn(s, index);
-}
-
-static inline cfi_check_fn find_shadow_check_fn(unsigned long ptr)
-{
-	cfi_check_fn fn;
-
-	rcu_read_lock_sched_notrace();
-	fn = ptr_to_check_fn(rcu_dereference_sched(cfi_shadow), ptr);
-	rcu_read_unlock_sched_notrace();
-
-	return fn;
-}
-
-#else /* !CONFIG_CFI_CLANG_SHADOW */
-
-static inline cfi_check_fn find_shadow_check_fn(unsigned long ptr)
-{
-	return NULL;
-}
-
-#endif /* CONFIG_CFI_CLANG_SHADOW */
 
 static inline cfi_check_fn find_module_check_fn(unsigned long ptr)
 {
@@ -291,11 +60,7 @@ static inline cfi_check_fn find_check_fn(unsigned long ptr)
 	 * up if necessary.
 	 */
 	RCU_NONIDLE({
-		if (IS_ENABLED(CONFIG_CFI_CLANG_SHADOW))
-			fn = find_shadow_check_fn(ptr);
-
-		if (!fn)
-			fn = find_module_check_fn(ptr);
+		fn = find_module_check_fn(ptr);
 	});
 
 	return fn;
diff --git a/kernel/module.c b/kernel/module.c
index 6cea788fd965..296fe02323e9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2151,8 +2151,6 @@ void __weak module_arch_freeing_init(struct module *mod)
 {
 }
 
-static void cfi_cleanup(struct module *mod);
-
 /* Free a module, remove from lists, etc. */
 static void free_module(struct module *mod)
 {
@@ -2194,9 +2192,6 @@ static void free_module(struct module *mod)
 	synchronize_rcu();
 	mutex_unlock(&module_mutex);
 
-	/* Clean up CFI for the module. */
-	cfi_cleanup(mod);
-
 	/* This may be empty, but that's OK */
 	module_arch_freeing_init(mod);
 	module_memfree(mod->init_layout.base);
@@ -4141,7 +4136,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	synchronize_rcu();
 	kfree(mod->args);
  free_arch_cleanup:
-	cfi_cleanup(mod);
 	module_arch_cleanup(mod);
  free_modinfo:
 	free_modinfo(mod);
@@ -4530,15 +4524,6 @@ static void cfi_init(struct module *mod)
 	if (exit)
 		mod->exit = *exit;
 #endif
-
-	cfi_module_add(mod, module_addr_min);
-#endif
-}
-
-static void cfi_cleanup(struct module *mod)
-{
-#ifdef CONFIG_CFI_CLANG
-	cfi_module_remove(mod, module_addr_min);
 #endif
 }
 
-- 
2.36.0.550.gb090851708-goog


  parent reply	other threads:[~2022-05-13 20:22 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-13 20:21 [RFC PATCH v2 00/21] KCFI support Sami Tolvanen
2022-05-13 20:21 ` [RFC PATCH v2 01/21] efi/libstub: Filter out CC_FLAGS_CFI Sami Tolvanen
2022-05-14 21:42   ` Kees Cook
2022-05-16 15:44     ` Sami Tolvanen
2022-05-13 20:21 ` [RFC PATCH v2 02/21] arm64/vdso: " Sami Tolvanen
2022-05-14 21:42   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 03/21] kallsyms: Ignore __kcfi_typeid_ Sami Tolvanen
2022-05-14 21:43   ` Kees Cook
2022-05-13 20:21 ` Sami Tolvanen [this message]
2022-05-14 21:43   ` [RFC PATCH v2 04/21] cfi: Remove CONFIG_CFI_CLANG_SHADOW Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 05/21] cfi: Drop __CFI_ADDRESSABLE Sami Tolvanen
2022-05-14 21:44   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 06/21] cfi: Switch to -fsanitize=kcfi Sami Tolvanen
2022-05-14 21:46   ` Kees Cook
2022-05-15  3:41   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 07/21] cfi: Add type helper macros Sami Tolvanen
2022-05-14 21:49   ` Kees Cook
2022-05-16 12:28     ` Rasmus Villemoes
2022-05-16 16:23       ` Sami Tolvanen
2022-05-16 16:04     ` Sami Tolvanen
2022-05-13 20:21 ` [RFC PATCH v2 08/21] psci: Fix the function type for psci_initcall_t Sami Tolvanen
2022-05-14 21:50   ` Kees Cook
2022-05-16 15:44     ` Sami Tolvanen
2022-05-17  8:47   ` Mark Rutland
2022-05-13 20:21 ` [RFC PATCH v2 09/21] arm64: Add types to indirect called assembly functions Sami Tolvanen
2022-05-14 21:50   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 10/21] arm64: Add CFI error handling Sami Tolvanen
2022-05-14 21:51   ` Kees Cook
2022-05-16 16:24     ` Sami Tolvanen
2022-05-13 20:21 ` [RFC PATCH v2 11/21] arm64: Drop unneeded __nocfi attributes Sami Tolvanen
2022-05-14 21:54   ` Kees Cook
2022-05-16 16:28     ` Sami Tolvanen
2022-05-13 20:21 ` [RFC PATCH v2 12/21] treewide: Drop function_nocfi Sami Tolvanen
2022-05-14 21:54   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 13/21] treewide: Drop WARN_ON_FUNCTION_MISMATCH Sami Tolvanen
2022-05-14 21:54   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 14/21] treewide: Drop __cficanonical Sami Tolvanen
2022-05-14 21:56   ` Kees Cook
2022-05-16 16:32     ` Sami Tolvanen
2022-05-13 20:21 ` [RFC PATCH v2 15/21] objtool: Don't warn about __cfi_ preambles falling through Sami Tolvanen
2022-05-14 21:56   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 16/21] x86/tools/relocs: Ignore __kcfi_typeid_ relocations Sami Tolvanen
2022-05-14 21:57   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 17/21] x86: Add types to indirectly called assembly functions Sami Tolvanen
2022-05-14 21:58   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 18/21] x86/purgatory: Disable CFI Sami Tolvanen
2022-05-14 21:58   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 19/21] x86/vdso: " Sami Tolvanen
2022-05-14 21:58   ` Kees Cook
2022-05-13 20:21 ` [RFC PATCH v2 20/21] x86: Add support for CONFIG_CFI_CLANG Sami Tolvanen
2022-05-14 22:02   ` Kees Cook
2022-05-16 18:57     ` Sami Tolvanen
2022-05-15  3:19   ` Kees Cook
2022-05-16  8:32   ` David Laight
2022-05-16 16:39     ` Sami Tolvanen
2022-05-16 21:32       ` David Laight
2022-05-16 21:44         ` Peter Zijlstra
2022-05-16 22:03           ` Sami Tolvanen
2022-05-17  6:44             ` Peter Zijlstra
2022-05-17 20:36               ` Sami Tolvanen
2022-05-17  7:56             ` David Laight
2022-05-16  9:54   ` Peter Zijlstra
2022-05-16 11:45     ` Peter Zijlstra
2022-05-16 12:58       ` Peter Zijlstra
2022-05-20 13:49         ` Matthew Wilcox
2022-05-16 17:15     ` Sami Tolvanen
2022-05-16 18:30       ` Peter Zijlstra
2022-05-16 19:39         ` Sami Tolvanen
2022-05-16 20:37           ` Peter Zijlstra
2022-05-25 20:02             ` Kees Cook
2022-05-16 22:59         ` Kees Cook
2022-05-17  8:05           ` Peter Zijlstra
2022-05-17  8:32             ` Joao Moreira
2022-05-17  8:40             ` Peter Zijlstra
2022-05-17  8:48               ` David Laight
2022-05-17  9:38                 ` Peter Zijlstra
2022-05-13 20:21 ` [RFC PATCH v2 21/21] init: Drop __nocfi from __init Sami Tolvanen
2022-05-14 22:03   ` Kees Cook
2022-05-16 17:16     ` Sami Tolvanen
     [not found] ` <CA+icZUWr+-HjMvY1VZf+nqjTadxSTDciux0Y5Y-+p_j4o7CmXg@mail.gmail.com>
2022-05-16 17:57   ` [RFC PATCH v2 00/21] KCFI support Sami Tolvanen
2022-05-17  7:33     ` Sedat Dilek
2022-05-17 18:49       ` Nathan Chancellor
2022-05-19  9:01         ` Sedat Dilek
2022-05-19 20:26           ` Nathan Chancellor
2022-05-19 20:41             ` Sami Tolvanen
2022-05-17  8:57 ` Peter Zijlstra
2022-05-17 20:25   ` Sami Tolvanen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220513202159.1550547-5-samitolvanen@google.com \
    --to=samitolvanen@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=joao@overdrivepizza.com \
    --cc=jpoimboe@redhat.com \
    --cc=keescook@chromium.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=mark.rutland@arm.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=sedat.dilek@gmail.com \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).