From: glider@google.com
To: Alexander Potapenko <glider@google.com>
Cc: Jens Axboe <axboe@kernel.dk>, Andy Lutomirski <luto@kernel.org>,
Vegard Nossum <vegard.nossum@oracle.com>,
Dmitry Vyukov <dvyukov@google.com>,
linux-mm@kvack.org
Subject: [PATCH RFC v1 16/26] kmsan: Changing existing files to enable KMSAN builds
Date: Fri, 18 Oct 2019 11:42:54 +0200 [thread overview]
Message-ID: <20191018094304.37056-17-glider@google.com> (raw)
In-Reply-To: <20191018094304.37056-1-glider@google.com>
Do the following to make KMSAN usable:
- add KMSAN declarations to struct page and struct task_struct;
- add Makefile.kmsan to top-level Makefile;
- call KMSAN initialization from init/main.c
- add asm hooks to arch/x86/entry/entry_64.S;
- increase task stack size under KMSAN;
- disable page merging in block/blk.h;
- disable CONFIG_KMSAN in arch/x86/boot/compressed/misc.h to use
default string functions instead of KMSAN ones.
Signed-off-by: Alexander Potapenko <glider@google.com>
To: Alexander Potapenko <glider@google.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: linux-mm@kvack.org
---
Change-Id: I37e0b7f2d2f2b0aeac5753ff9d6b411485fc374e
---
Makefile | 3 ++-
arch/x86/boot/compressed/misc.h | 1 +
arch/x86/entry/entry_64.S | 18 ++++++++++++++++++
arch/x86/include/asm/page_64_types.h | 12 +++++++-----
block/blk.h | 7 +++++++
include/linux/mm_types.h | 9 +++++++++
include/linux/sched.h | 5 +++++
init/main.c | 3 +++
lib/stackdepot.c | 7 ++++---
mm/Makefile | 1 +
scripts/Makefile.lib | 6 ++++++
11 files changed, 63 insertions(+), 9 deletions(-)
diff --git a/Makefile b/Makefile
index ffd7a912fc46..5041e908f051 100644
--- a/Makefile
+++ b/Makefile
@@ -478,7 +478,7 @@ export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
-export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN
+export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN CFLAGS_KMSAN
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
@@ -898,6 +898,7 @@ KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
endif
include scripts/Makefile.kasan
+include scripts/Makefile.kmsan
include scripts/Makefile.extrawarn
include scripts/Makefile.ubsan
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index c8181392f70d..dd4bd8c5d97a 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -12,6 +12,7 @@
#undef CONFIG_PARAVIRT_XXL
#undef CONFIG_PARAVIRT_SPINLOCKS
#undef CONFIG_KASAN
+#undef CONFIG_KMSAN
/* cpu_feature_enabled() cannot be used this early */
#define USE_EARLY_PGTABLE_L5
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index b7c3ea4cb19d..1218672bad85 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -35,6 +35,7 @@
#include <asm/asm.h>
#include <asm/smap.h>
#include <asm/pgtable_types.h>
+#include <asm/kmsan.h>
#include <asm/export.h>
#include <asm/frame.h>
#include <asm/nospec-branch.h>
@@ -168,12 +169,14 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
PUSH_AND_CLEAR_REGS rax=$-ENOSYS
TRACE_IRQS_OFF
+ KMSAN_SYSCALL_ENTER
/* IRQs are off. */
movq %rax, %rdi
movq %rsp, %rsi
call do_syscall_64 /* returns with IRQs disabled */
+ KMSAN_SYSCALL_EXIT
TRACE_IRQS_IRETQ /* we're about to change IF */
/*
@@ -575,6 +578,7 @@ ENTRY(interrupt_entry)
1:
ENTER_IRQ_STACK old_rsp=%rdi save_ret=1
+ KMSAN_INTERRUPT_ENTER
/* We entered an interrupt context - irqs are off: */
TRACE_IRQS_OFF
@@ -604,12 +608,14 @@ common_interrupt:
addq $-0x80, (%rsp) /* Adjust vector to [-256, -1] range */
call interrupt_entry
UNWIND_HINT_REGS indirect=1
+ KMSAN_UNPOISON_PT_REGS
call do_IRQ /* rdi points to pt_regs */
/* 0(%rsp): old RSP */
ret_from_intr:
DISABLE_INTERRUPTS(CLBR_ANY)
TRACE_IRQS_OFF
+ KMSAN_INTERRUPT_EXIT
LEAVE_IRQ_STACK
testb $3, CS(%rsp)
@@ -802,6 +808,7 @@ ENTRY(\sym)
.Lcommon_\sym:
call interrupt_entry
UNWIND_HINT_REGS indirect=1
+ KMSAN_UNPOISON_PT_REGS
call \do_sym /* rdi points to pt_regs */
jmp ret_from_intr
END(\sym)
@@ -909,15 +916,18 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
.if \shift_ist != -1
subq $\ist_offset, CPU_TSS_IST(\shift_ist)
+ KMSAN_IST_ENTER(\shift_ist)
.endif
.if \read_cr2
movq %r12, %rdx /* Move CR2 into 3rd argument */
.endif
+ KMSAN_UNPOISON_PT_REGS
call \do_sym
.if \shift_ist != -1
+ KMSAN_IST_EXIT(\shift_ist)
addq $\ist_offset, CPU_TSS_IST(\shift_ist)
.endif
@@ -1079,7 +1089,9 @@ ENTRY(do_softirq_own_stack)
pushq %rbp
mov %rsp, %rbp
ENTER_IRQ_STACK regs=0 old_rsp=%r11
+ KMSAN_SOFTIRQ_ENTER
call __do_softirq
+ KMSAN_SOFTIRQ_EXIT
LEAVE_IRQ_STACK regs=0
leaveq
ret
@@ -1466,9 +1478,12 @@ ENTRY(nmi)
* done with the NMI stack.
*/
+ KMSAN_NMI_ENTER
movq %rsp, %rdi
movq $-1, %rsi
+ KMSAN_UNPOISON_PT_REGS
call do_nmi
+ KMSAN_NMI_EXIT
/*
* Return back to user mode. We must *not* do the normal exit
@@ -1678,10 +1693,13 @@ end_repeat_nmi:
call paranoid_entry
UNWIND_HINT_REGS
+ KMSAN_NMI_ENTER
/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
movq %rsp, %rdi
movq $-1, %rsi
+ KMSAN_UNPOISON_PT_REGS
call do_nmi
+ KMSAN_NMI_EXIT
/* Always restore stashed CR3 value (see paranoid_entry) */
RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
index 288b065955b7..ea9fbf09f43b 100644
--- a/arch/x86/include/asm/page_64_types.h
+++ b/arch/x86/include/asm/page_64_types.h
@@ -7,18 +7,20 @@
#endif
#ifdef CONFIG_KASAN
-#define KASAN_STACK_ORDER 1
+#define EXTRA_STACK_ORDER 1
+#elif defined(CONFIG_KMSAN)
+#define EXTRA_STACK_ORDER 2
#else
-#define KASAN_STACK_ORDER 0
+#define EXTRA_STACK_ORDER 0
#endif
-#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER)
+#define THREAD_SIZE_ORDER (2 + EXTRA_STACK_ORDER)
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
-#define EXCEPTION_STACK_ORDER (0 + KASAN_STACK_ORDER)
+#define EXCEPTION_STACK_ORDER (0 + EXTRA_STACK_ORDER)
#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
-#define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER)
+#define IRQ_STACK_ORDER (2 + EXTRA_STACK_ORDER)
#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
/*
diff --git a/block/blk.h b/block/blk.h
index 47fba9362e60..9ee271a22423 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -78,6 +78,13 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
phys_addr_t addr1 = page_to_phys(vec1->bv_page) + vec1->bv_offset;
phys_addr_t addr2 = page_to_phys(vec2->bv_page) + vec2->bv_offset;
+#ifdef CONFIG_KMSAN
+ /*
+ * Merging consequent physical pages may not work correctly under KMSAN
+ * if their metadata pages aren't consequent. Just disable merging.
+ */
+ return false;
+#endif
if (addr1 + vec1->bv_len != addr2)
return false;
if (xen_domain() && !xen_biovec_phys_mergeable(vec1, vec2->bv_page))
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 2222fa795284..c87c5416a802 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -216,6 +216,15 @@ struct page {
not kmapped, ie. highmem) */
#endif /* WANT_PAGE_VIRTUAL */
+#ifdef CONFIG_KMSAN
+ /*
+ * Bits in struct page are scarce, so the LSB in *shadow is used to
+ * indicate whether the page should be ignored by KMSAN or not.
+ */
+ struct page *shadow;
+ struct page *origin;
+#endif
+
#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
int _last_cpupid;
#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 7417e0207b48..e0f6e95c22ed 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -15,6 +15,7 @@
#include <linux/sem.h>
#include <linux/shm.h>
#include <linux/kcov.h>
+#include <linux/kmsan.h>
#include <linux/mutex.h>
#include <linux/plist.h>
#include <linux/hrtimer.h>
@@ -1172,6 +1173,10 @@ struct task_struct {
unsigned int kasan_depth;
#endif
+#ifdef CONFIG_KMSAN
+ struct kmsan_task_state kmsan;
+#endif
+
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
/* Index of current stored address in ret_stack: */
int curr_ret_stack;
diff --git a/init/main.c b/init/main.c
index 91f6ebb30ef0..afcca2a38348 100644
--- a/init/main.c
+++ b/init/main.c
@@ -32,6 +32,7 @@
#include <linux/nmi.h>
#include <linux/percpu.h>
#include <linux/kmod.h>
+#include <linux/kmsan.h>
#include <linux/vmalloc.h>
#include <linux/kernel_stat.h>
#include <linux/start_kernel.h>
@@ -554,6 +555,7 @@ static void __init mm_init(void)
*/
page_ext_init_flatmem();
report_meminit();
+ kmsan_initialize_shadow();
mem_init();
kmem_cache_init();
kmemleak_init();
@@ -625,6 +627,7 @@ asmlinkage __visible void __init start_kernel(void)
sort_main_extable();
trap_init();
mm_init();
+ kmsan_initialize();
ftrace_init();
diff --git a/lib/stackdepot.c b/lib/stackdepot.c
index 460efd3ef742..529a86eb1dd1 100644
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -233,8 +233,8 @@ unsigned int stack_depot_fetch(depot_stack_handle_t handle,
if (parts.slabindex > depot_index) {
WARN(1, "slab index %d out of bounds (%d) for stack id %08x\n",
parts.slabindex, depot_index, handle);
- __memset(trace, 0, sizeof(*trace));
- return;
+ *entries = NULL;
+ return 0;
}
slab = stack_slabs[parts.slabindex];
stack = slab + offset;
@@ -299,7 +299,8 @@ depot_stack_handle_t stack_depot_save(unsigned long *entries,
* contexts and I/O.
*/
alloc_flags &= ~GFP_ZONEMASK;
- alloc_flags &= (GFP_ATOMIC | GFP_KERNEL);
+ alloc_flags &= (GFP_ATOMIC | GFP_KERNEL |
+ __GFP_NO_KMSAN_SHADOW);
alloc_flags |= __GFP_NOWARN;
page = alloc_pages(alloc_flags, STACK_ALLOC_ORDER);
if (page)
diff --git a/mm/Makefile b/mm/Makefile
index d996846697ef..419e6e02dfaf 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_PAGE_POISONING) += page_poison.o
obj-$(CONFIG_SLAB) += slab.o
obj-$(CONFIG_SLUB) += slub.o
obj-$(CONFIG_KASAN) += kasan/
+obj-$(CONFIG_KMSAN) += kmsan/
obj-$(CONFIG_FAILSLAB) += failslab.o
obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
obj-$(CONFIG_MEMTEST) += memtest.o
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 179d55af5852..f9f38f7c1cd4 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -140,6 +140,12 @@ _c_flags += $(if $(patsubst n%,, \
$(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
endif
+ifeq ($(CONFIG_KMSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+ $(KMSAN_SANITIZE_$(basetarget).o)$(KMSAN_SANITIZE)y), \
+ $(CFLAGS_KMSAN))
+endif
+
ifeq ($(CONFIG_UBSAN),y)
_c_flags += $(if $(patsubst n%,, \
$(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \
--
2.23.0.866.gb869b98d4c-goog
next prev parent reply other threads:[~2019-10-18 9:44 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-18 9:42 [PATCH RFC v1 00/26] Add KernelMemorySanitizer infrastructure glider
2019-10-18 9:42 ` [PATCH RFC v1 01/26] stackdepot: check depot_index before accessing the stack slab glider
2019-10-18 9:42 ` [PATCH RFC v1 02/26] stackdepot: prevent Clang from optimizing away stackdepot_memcmp() glider
2019-10-18 9:42 ` [PATCH RFC v1 03/26] kasan: stackdepot: move filter_irq_stacks() to stackdepot.c glider
2019-10-18 9:42 ` [PATCH RFC v1 04/26] stackdepot: reserve 5 extra bits in depot_stack_handle_t glider
2019-10-18 9:42 ` [PATCH RFC v1 05/26] printk_safe: externalize printk_context glider
2019-10-21 9:09 ` Petr Mladek
2019-10-23 17:57 ` Alexander Potapenko
2019-10-23 18:00 ` Alexander Potapenko
2019-10-24 12:46 ` Petr Mladek
2019-10-28 13:09 ` Alexander Potapenko
2019-10-29 12:02 ` Petr Mladek
2019-10-29 12:45 ` Alexander Potapenko
2019-10-18 9:42 ` [PATCH RFC v1 06/26] kasan: compiler.h: rename __no_kasan_or_inline into __no_memory_tool_or_inline glider
2019-10-18 9:42 ` [PATCH RFC v1 07/26] kmsan: add ReST documentation glider
2019-10-18 9:42 ` [PATCH RFC v1 08/26] kmsan: gfp: introduce __GFP_NO_KMSAN_SHADOW glider
2019-10-18 9:42 ` [PATCH RFC v1 09/26] kmsan: introduce __no_sanitize_memory and __SANITIZE_MEMORY__ glider
2019-10-18 9:42 ` [PATCH RFC v1 10/26] kmsan: reduce vmalloc space glider
2019-10-18 9:42 ` [PATCH RFC v1 11/26] kmsan: add KMSAN runtime glider
2019-10-18 9:42 ` [PATCH RFC v1 12/26] kmsan: x86: sync metadata pages on page fault glider
2019-10-18 9:42 ` [PATCH RFC v1 13/26] kmsan: add tests for KMSAN glider
2019-10-18 9:42 ` [PATCH RFC v1 14/26] kmsan: make READ_ONCE_TASK_STACK() return initialized values glider
2019-10-18 9:42 ` [PATCH RFC v1 15/26] kmsan: Kconfig changes to disable options incompatible with KMSAN glider
2019-10-21 14:11 ` Harry Wentland
2019-10-18 9:42 ` glider [this message]
2019-10-18 9:42 ` [PATCH RFC v1 17/26] kmsan: disable KMSAN instrumentation for certain kernel parts glider
2019-10-18 9:42 ` [PATCH RFC v1 18/26] kmsan: mm: call KMSAN hooks from SLUB code glider
2019-10-18 13:22 ` Qian Cai
2019-10-18 13:33 ` Alexander Potapenko
2019-10-18 13:41 ` Qian Cai
2019-10-18 13:55 ` Alexander Potapenko
2019-10-18 14:42 ` Qian Cai
2019-10-18 14:54 ` Alexander Potapenko
2019-10-18 15:13 ` Qian Cai
2019-10-18 15:30 ` Alexander Potapenko
2019-10-18 16:08 ` Qian Cai
2019-10-18 9:42 ` [PATCH RFC v1 19/26] kmsan: call KMSAN hooks where needed glider
2019-10-18 15:02 ` Qian Cai
2019-10-29 14:09 ` Alexander Potapenko
2019-10-29 14:56 ` Qian Cai
2019-10-21 9:25 ` Petr Mladek
2019-10-29 13:59 ` Alexander Potapenko
2019-10-18 9:42 ` [PATCH RFC v1 20/26] kmsan: disable instrumentation of certain functions glider
2019-10-18 9:42 ` [PATCH RFC v1 21/26] kmsan: unpoison |tlb| in arch_tlb_gather_mmu() glider
2019-10-18 9:43 ` [PATCH RFC v1 22/26] kmsan: use __msan_memcpy() where possible glider
2019-10-18 9:43 ` [PATCH RFC v1 23/26] kmsan: unpoisoning buffers from devices etc glider
2019-10-18 15:27 ` Christoph Hellwig
2019-10-18 16:22 ` Matthew Wilcox
2019-10-29 14:45 ` Alexander Potapenko
2019-10-30 12:43 ` Alexander Potapenko
2019-10-18 9:43 ` [PATCH RFC v1 24/26] kmsan: hooks for copy_to_user() and friends glider
2019-10-18 9:43 ` [PATCH RFC v1 25/26] kmsan: disable strscpy() optimization under KMSAN glider
2019-10-18 9:43 ` [PATCH RFC v1 26/26] net: kasan: kmsan: support CONFIG_GENERIC_CSUM on x86, enable it for KASAN/KMSAN glider
2019-10-19 3:20 ` Randy Dunlap
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=20191018094304.37056-17-glider@google.com \
--to=glider@google.com \
--cc=axboe@kernel.dk \
--cc=dvyukov@google.com \
--cc=linux-mm@kvack.org \
--cc=luto@kernel.org \
--cc=vegard.nossum@oracle.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.