[PATCH 1/4] mm/kasan: Add CONFIG_KASAN_SOFTWARE

From: Christophe Leroy
Date: Wed Feb 02 2022 - 03:45:02 EST


Many many places check whether there is one of
CONFIG_KASAN_GENERIC or CONFIG_KASAN_SW_TAGS

In order to avoid adding more places with such a awful
check, add CONFIG_KASAN_SOFTWARE which is selected by
both CONFIG_KASAN_GENERIC and CONFIG_KASAN_SW_TAGS.

This patch only modifies core part. Arch specific parts
can be upgraded one by one in a second step.

Don't change mm/ptdump.c as those #ifdefs go away in
the patch after the next.

Signed-off-by: Christophe Leroy <christophe.leroy@xxxxxxxxxx>
---
include/linux/fortify-string.h | 2 +-
include/linux/kasan-checks.h | 2 +-
include/linux/kasan.h | 13 ++++++-------
include/linux/moduleloader.h | 3 +--
include/linux/sched.h | 2 +-
include/linux/vmalloc.h | 3 +--
init/init_task.c | 2 +-
lib/Kconfig.kasan | 9 +++++++--
mm/kasan/Makefile | 5 +++--
mm/kasan/common.c | 4 ++--
mm/kasan/kasan.h | 8 ++++----
mm/kasan/report.c | 2 +-
12 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
index a6cd6815f249..65c06e30fc6b 100644
--- a/include/linux/fortify-string.h
+++ b/include/linux/fortify-string.h
@@ -24,7 +24,7 @@ void __write_overflow(void) __compiletime_error("detected write beyond size of o
__ret; \
})

-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE
extern void *__underlying_memchr(const void *p, int c, __kernel_size_t size) __RENAME(memchr);
extern int __underlying_memcmp(const void *p, const void *q, __kernel_size_t size) __RENAME(memcmp);
extern void *__underlying_memcpy(void *p, const void *q, __kernel_size_t size) __RENAME(memcpy);
diff --git a/include/linux/kasan-checks.h b/include/linux/kasan-checks.h
index 3d6d22a25bdc..7ad385c4b2fc 100644
--- a/include/linux/kasan-checks.h
+++ b/include/linux/kasan-checks.h
@@ -15,7 +15,7 @@
* even in compilation units that selectively disable KASAN, but must use KASAN
* to validate access to an address. Never use these in header files!
*/
-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE
bool __kasan_check_read(const volatile void *p, unsigned int size);
bool __kasan_check_write(const volatile void *p, unsigned int size);
#else
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 4a45562d8893..c29778b25d8a 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -25,7 +25,7 @@ struct kunit_kasan_expectation {

#endif

-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE

#include <linux/pgtable.h>

@@ -66,7 +66,7 @@ extern void kasan_enable_current(void);
/* Disable reporting bugs for current task */
extern void kasan_disable_current(void);

-#else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+#else /* CONFIG_KASAN_SOFTWARE */

static inline int kasan_add_zero_shadow(void *start, unsigned long size)
{
@@ -79,7 +79,7 @@ static inline void kasan_remove_zero_shadow(void *start,
static inline void kasan_enable_current(void) {}
static inline void kasan_disable_current(void) {}

-#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+#endif /* CONFIG_KASAN_SOFTWARE */

#ifdef CONFIG_KASAN_HW_TAGS

@@ -467,8 +467,7 @@ static inline void kasan_populate_early_vm_area_shadow(void *start,

#endif /* CONFIG_KASAN_VMALLOC */

-#if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
- !defined(CONFIG_KASAN_VMALLOC)
+#if defined(CONFIG_KASAN_SOFTWARE) && !defined(CONFIG_KASAN_VMALLOC)

/*
* These functions provide a special case to support backing module
@@ -478,12 +477,12 @@ static inline void kasan_populate_early_vm_area_shadow(void *start,
int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask);
void kasan_free_shadow(const struct vm_struct *vm);

-#else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
+#else /* CONFIG_KASAN_SOFTWARE && !CONFIG_KASAN_VMALLOC */

static inline int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask) { return 0; }
static inline void kasan_free_shadow(const struct vm_struct *vm) {}

-#endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
+#endif /* CONFIG_KASAN_SOFTWARE && !CONFIG_KASAN_VMALLOC */

#ifdef CONFIG_KASAN_INLINE
void kasan_non_canonical_hook(unsigned long addr);
diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h
index 9e09d11ffe5b..232687e315b3 100644
--- a/include/linux/moduleloader.h
+++ b/include/linux/moduleloader.h
@@ -96,8 +96,7 @@ void module_arch_cleanup(struct module *mod);
/* Any cleanup before freeing mod->module_init */
void module_arch_freeing_init(struct module *mod);

-#if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
- !defined(CONFIG_KASAN_VMALLOC)
+#if defined(CONFIG_KASAN_SOFTWARE) && !defined(CONFIG_KASAN_VMALLOC)
#include <linux/kasan.h>
#define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
#else
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f5b2be39a78c..8d815aea1009 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1335,7 +1335,7 @@ struct task_struct {
u64 timer_slack_ns;
u64 default_timer_slack_ns;

-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE
unsigned int kasan_depth;
#endif

diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 880227b9f044..83d870b16a31 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -28,8 +28,7 @@ struct notifier_block; /* in notifier.h */
#define VM_MAP_PUT_PAGES 0x00000200 /* put pages and free array in vfree */
#define VM_NO_HUGE_VMAP 0x00000400 /* force PAGE_SIZE pte mapping */

-#if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
- !defined(CONFIG_KASAN_VMALLOC)
+#if defined(CONFIG_KASAN_SOFTWARE) && !defined(CONFIG_KASAN_VMALLOC)
#define VM_DEFER_KMEMLEAK 0x00000800 /* defer kmemleak object creation */
#else
#define VM_DEFER_KMEMLEAK 0
diff --git a/init/init_task.c b/init/init_task.c
index 73cc8f03511a..fa924e5ae173 100644
--- a/init/init_task.c
+++ b/init/init_task.c
@@ -177,7 +177,7 @@ struct task_struct init_task
.numa_group = NULL,
.numa_faults = NULL,
#endif
-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE
.kasan_depth = 1,
#endif
#ifdef CONFIG_KCSAN
diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan
index 879757b6dd14..4b2de3bd188a 100644
--- a/lib/Kconfig.kasan
+++ b/lib/Kconfig.kasan
@@ -46,6 +46,9 @@ menuconfig KASAN

if KASAN

+config KASAN_SOFTWARE
+ bool
+
choice
prompt "KASAN mode"
default KASAN_GENERIC
@@ -69,6 +72,7 @@ config KASAN_GENERIC
depends on CC_HAS_WORKING_NOSANITIZE_ADDRESS
select SLUB_DEBUG if SLUB
select CONSTRUCTORS
+ select KASAN_SOFTWARE
help
Enables generic KASAN mode.

@@ -90,6 +94,7 @@ config KASAN_SW_TAGS
depends on CC_HAS_WORKING_NOSANITIZE_ADDRESS
select SLUB_DEBUG if SLUB
select CONSTRUCTORS
+ select KASAN_SOFTWARE
help
Enables software tag-based KASAN mode.

@@ -125,7 +130,7 @@ endchoice

choice
prompt "Instrumentation type"
- depends on KASAN_GENERIC || KASAN_SW_TAGS
+ depends on KASAN_SOFTWARE
default KASAN_OUTLINE

config KASAN_OUTLINE
@@ -150,7 +155,7 @@ endchoice

config KASAN_STACK
bool "Enable stack instrumentation (unsafe)" if CC_IS_CLANG && !COMPILE_TEST
- depends on KASAN_GENERIC || KASAN_SW_TAGS
+ depends on KASAN_SOFTWARE
depends on !ARCH_DISABLE_KASAN_INLINE
default y if CC_IS_GCC
help
diff --git a/mm/kasan/Makefile b/mm/kasan/Makefile
index adcd9acaef61..5f22899b3b2b 100644
--- a/mm/kasan/Makefile
+++ b/mm/kasan/Makefile
@@ -36,6 +36,7 @@ CFLAGS_hw_tags.o := $(CC_FLAGS_KASAN_RUNTIME)
CFLAGS_sw_tags.o := $(CC_FLAGS_KASAN_RUNTIME)

obj-$(CONFIG_KASAN) := common.o report.o
-obj-$(CONFIG_KASAN_GENERIC) += init.o generic.o report_generic.o shadow.o quarantine.o
+obj-$(CONFIG_KASAN_SOFTWARE) += init.o shadow.o
+obj-$(CONFIG_KASAN_GENERIC) += generic.o report_generic.o quarantine.o
obj-$(CONFIG_KASAN_HW_TAGS) += hw_tags.o report_hw_tags.o tags.o report_tags.o
-obj-$(CONFIG_KASAN_SW_TAGS) += init.o report_sw_tags.o shadow.o sw_tags.o tags.o report_tags.o
+obj-$(CONFIG_KASAN_SW_TAGS) += sw_tags.o report_sw_tags.o tags.o report_tags.o
diff --git a/mm/kasan/common.c b/mm/kasan/common.c
index 92196562687b..5693fe2c176f 100644
--- a/mm/kasan/common.c
+++ b/mm/kasan/common.c
@@ -45,7 +45,7 @@ void kasan_set_track(struct kasan_track *track, gfp_t flags)
track->stack = kasan_save_stack(flags, true);
}

-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE
void kasan_enable_current(void)
{
current->kasan_depth++;
@@ -58,7 +58,7 @@ void kasan_disable_current(void)
}
EXPORT_SYMBOL(kasan_disable_current);

-#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+#endif /* CONFIG_KASAN_SOFTWARE */

void __kasan_unpoison_range(const void *address, size_t size)
{
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index c17fa8d26ffe..57d96714bc1b 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -55,7 +55,7 @@ static inline bool kasan_sync_fault_possible(void)

#endif

-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE
#define KASAN_GRANULE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT)
#else
#include <asm/mte-kasan.h>
@@ -211,7 +211,7 @@ struct kasan_free_meta *kasan_get_free_meta(struct kmem_cache *cache,
const void *object);
#endif

-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE

static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
{
@@ -235,14 +235,14 @@ static inline bool addr_has_metadata(const void *addr)
bool kasan_check_range(unsigned long addr, size_t size, bool write,
unsigned long ret_ip);

-#else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+#else /* CONFIG_KASAN_SOFTWARE */

static inline bool addr_has_metadata(const void *addr)
{
return (is_vmalloc_addr(addr) || virt_addr_valid(addr));
}

-#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+#endif /* CONFIG_KASAN_SOFTWARE */

#if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
void kasan_print_tags(u8 addr_tag, const void *addr);
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 3ad9624dcc56..bce57bbd1baa 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -334,7 +334,7 @@ static void print_memory_metadata(const void *addr)

static bool report_enabled(void)
{
-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+#ifdef CONFIG_KASAN_SOFTWARE
if (current->kasan_depth)
return false;
#endif
--
2.33.1