Received: by 2002:a25:c205:0:0:0:0:0 with SMTP id s5csp6228076ybf; Thu, 5 Mar 2020 16:04:31 -0800 (PST) X-Google-Smtp-Source: ADFU+vtEBjMyQtfrMtOjX45QtsDDv46u2rn8AcIx6tzJJjRvwL3/RgEomdT4g+P9hH+TwKFUBzTd X-Received: by 2002:aca:c705:: with SMTP id x5mr756988oif.1.1583453071001; Thu, 05 Mar 2020 16:04:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1583453070; cv=none; d=google.com; s=arc-20160816; b=wV2u2U/p4VPY+EIJGPYogZNkq2OyqBVY7NgQfiYin+Iq7qMo+y0+2lBECPQnb3uQFB 5jOYtV0hqf0OmZaot8ZUKulrXjGzy8t54pG+V67oTlvyI+V3BZQo7uN5ZKt1QnS3Xc90 G1gkYOqTe0uGYfLFumvJHuMr0WtVf+xVVM0qhYEp+od3fKD1ZN0PODPHZK0IISsyen4C HFEfyzaRL5va2RhBvEIAubSVH6IKKN8fJ8lVfgh8f/3HlFYqnbFDICUUz7F0VbuHCo04 pgwBHcspq4y6Kcx4jTCsjO6K8tt7PgYqfwSimK0aZdLa5fRoL+5LB+IG3VBfSWnM81On GFPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=UgANqYbsGGPlfxgnPY19cqvlngm9uRL0rxGTl9wSa3M=; b=NTht6wXbwh0AoQixCMslBiQrJl59ByaUxrQu52EE6Kr11YUe+X8+C45vwixKIjoSbH Z7kEtMB5R6goFo77YfqJ6hVQb8/KPvh5vCIuIFBFAFbiveJQuF65hX7AGQZA5j2ggYYe qHXJGONMnBtqt7RamKilfgwzuPgvLTWK/w/a5fcXmzw1QUdY12YD+3YIy6dh0T3DCdEP Nmi/49mujqeoG3cOQr/gV7Klxv27DamhqYLxHJG2qWc1ivsYTBsgQ++VNjK7iEKHJl4X 0Q0fxzQwy9Zu7he1d9ud1Z7AeeehUhLXxZ0YJe+Iah8Kk7MeClTSjz2tRz3M0RqJSPuQ uXwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=VuT04Zcx; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j17si269349otl.278.2020.03.05.16.04.18; Thu, 05 Mar 2020 16:04:30 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=VuT04Zcx; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726413AbgCFADz (ORCPT + 99 others); Thu, 5 Mar 2020 19:03:55 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:34484 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726178AbgCFADz (ORCPT ); Thu, 5 Mar 2020 19:03:55 -0500 Received: by mail-wr1-f65.google.com with SMTP id z15so298763wrl.1 for ; Thu, 05 Mar 2020 16:03:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=UgANqYbsGGPlfxgnPY19cqvlngm9uRL0rxGTl9wSa3M=; b=VuT04ZcxYbJTxOo9c0uCxOSd/ZPzH3MFfT5wf8LjBL7qAdsd5VqtjqapYQFbytIFS3 8FLfKHw8xifjDWR+KMLhzi+4VNWcoiciGfvU24+eleH1KnXNnEgqJwtFKTaqZ4HOcf9B EeaSbrqz9uBVN6FAZakZf6jPhupLptJGajDVrjDZDgCYasmLJKBz5VAMAYGuOoLR4AY8 lqAcmKd8Sj07+k3sdRiOItoot14LqIBGCd+reJzWu9N4DNLaYhLsDE8JBxOhcPWHM/2u /zGf1ChbrZjey3ij83tzHgCHjXUCCVJ55qoR/zMd3bTXKLyE+w6Q4YWoDZ0KufNNiAE7 NV/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=UgANqYbsGGPlfxgnPY19cqvlngm9uRL0rxGTl9wSa3M=; b=Jp/z9qP6cvOc6Fxpoif2dmJ5A551QDcYrckCDofl3ik4f8YnPU5nbYRkz1/DkpO9nP Bhwvstggf79J+7Kv8MilMZ44cUhUWHwfBZ7tZrzz0k6/p5Ir6VMah3T2cGF3TwJ02wrs iPYUAF96NsdAcs3oIbd34CIV5tJv+WBk1i68kkyt8fT2cGrSgOFTBiemyNIIGqBPMsFO T55awHE6Pc+RMIMMKi+GBWQ/hzMf6YP4v0sg8m9B3fOMNS85Hd4mt2ljodZ9hRe9yyIO XojWCZg2kdUAl/D//obi2PZvR1NbTK3tYRJR29LMyb3UlIILLgzWawYMmF1khpTBrLI1 tF9Q== X-Gm-Message-State: ANhLgQ3OY2CDKIlOoUCya/gCQaV/v6y0TWA4FxJUI1KFoBHqaexKmbLV Z8zu7jFlXkdSI7DA8ivEgIECAbCeSBtbK1pKqt/WrA== X-Received: by 2002:adf:e38d:: with SMTP id e13mr416724wrm.133.1583453031144; Thu, 05 Mar 2020 16:03:51 -0800 (PST) MIME-Version: 1.0 References: <20200226004608.8128-1-trishalfonso@google.com> In-Reply-To: <20200226004608.8128-1-trishalfonso@google.com> From: Patricia Alfonso Date: Thu, 5 Mar 2020 16:03:39 -0800 Message-ID: Subject: Re: [PATCH] UML: add support for KASAN under x86_64 To: Jeff Dike , Richard Weinberger , anton.ivanov@cambridgegreys.com, Andrey Ryabinin , Dmitry Vyukov , Brendan Higgins , David Gow , Johannes Berg Cc: kasan-dev , LKML , linux-um@lists.infradead.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Feb 25, 2020 at 4:46 PM Patricia Alfonso wrote: > > Make KASAN run on User Mode Linux on x86_64. > > Depends on Constructor support in UML - "[RFC PATCH] um: > implement CONFIG_CONSTRUCTORS for modules" > (https://patchwork.ozlabs.org/patch/1234551/) by Johannes Berg. > > The location of the KASAN shadow memory, starting at > KASAN_SHADOW_OFFSET, can be configured using the > KASAN_SHADOW_OFFSET option. UML uses roughly 18TB of address > space, and KASAN requires 1/8th of this. The default location of > this offset is 0x7fff8000 as suggested by Dmitry Vyukov. There is > usually enough free space at this location; however, it is a config > option so that it can be easily changed if needed. > > The UML-specific KASAN initializer uses mmap to map > the roughly 2.25TB of shadow memory to the location defined by > KASAN_SHADOW_OFFSET. kasan_init() utilizes constructors to initialize > KASAN before main(). > > Disable stack instrumentation on UML via KASAN_STACK config option to > avoid false positive KASAN reports. > > Signed-off-by: Patricia Alfonso > --- Hi all, I just want to bump this so we can get all the comments while this is still fresh in everyone's minds. I would love if some UML maintainers could give their thoughts! Thanks, Patricia > arch/um/Kconfig | 13 +++++++++++++ > arch/um/Makefile | 6 ++++++ > arch/um/include/asm/common.lds.S | 1 + > arch/um/include/asm/kasan.h | 32 ++++++++++++++++++++++++++++++++ > arch/um/kernel/dyn.lds.S | 5 ++++- > arch/um/kernel/mem.c | 18 ++++++++++++++++++ > arch/um/os-Linux/mem.c | 22 ++++++++++++++++++++++ > arch/um/os-Linux/user_syms.c | 4 ++-- > arch/x86/um/Makefile | 3 ++- > arch/x86/um/vdso/Makefile | 3 +++ > lib/Kconfig.kasan | 2 +- > 11 files changed, 104 insertions(+), 5 deletions(-) > create mode 100644 arch/um/include/asm/kasan.h > > diff --git a/arch/um/Kconfig b/arch/um/Kconfig > index 0917f8443c28..fb2ad1fb05fd 100644 > --- a/arch/um/Kconfig > +++ b/arch/um/Kconfig > @@ -8,6 +8,7 @@ config UML > select ARCH_HAS_KCOV > select ARCH_NO_PREEMPT > select HAVE_ARCH_AUDITSYSCALL > + select HAVE_ARCH_KASAN if X86_64 > select HAVE_ARCH_SECCOMP_FILTER > select HAVE_ASM_MODVERSIONS > select HAVE_UID16 > @@ -200,6 +201,18 @@ config UML_TIME_TRAVEL_SUPPORT > > It is safe to say Y, but you probably don't need this. > > +config KASAN_SHADOW_OFFSET > + hex > + depends on KASAN > + default 0x7fff8000 > + help > + This is the offset at which the ~2.25TB of shadow memory is > + mapped and used by KASAN for memory debugging. This can be any > + address that has at least KASAN_SHADOW_SIZE(total address space divided > + by 8) amount of space so that the KASAN shadow memory does not conflict > + with anything. The default is 0x7fff8000, as it fits into immediate of > + most instructions. > + > endmenu > > source "arch/um/drivers/Kconfig" > diff --git a/arch/um/Makefile b/arch/um/Makefile > index d2daa206872d..28fe7a9a1858 100644 > --- a/arch/um/Makefile > +++ b/arch/um/Makefile > @@ -75,6 +75,12 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \ > -D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \ > -idirafter $(objtree)/include -D__KERNEL__ -D__UM_HOST__ > > +# Kernel config options are not included in USER_CFLAGS, but the option for KASAN > +# should be included if the KASAN config option was set. > +ifdef CONFIG_KASAN > + USER_CFLAGS+=-DCONFIG_KASAN=y > +endif > + > #This will adjust *FLAGS accordingly to the platform. > include $(ARCH_DIR)/Makefile-os-$(OS) > > diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S > index eca6c452a41b..731f8c8422a2 100644 > --- a/arch/um/include/asm/common.lds.S > +++ b/arch/um/include/asm/common.lds.S > @@ -83,6 +83,7 @@ > } > .init_array : { > __init_array_start = .; > + *(.kasan_init) > *(.init_array) > __init_array_end = .; > } > diff --git a/arch/um/include/asm/kasan.h b/arch/um/include/asm/kasan.h > new file mode 100644 > index 000000000000..2b81e7bcd4af > --- /dev/null > +++ b/arch/um/include/asm/kasan.h > @@ -0,0 +1,32 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef __ASM_UM_KASAN_H > +#define __ASM_UM_KASAN_H > + > +#include > +#include > + > +#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) > + > +/* used in kasan_mem_to_shadow to divide by 8 */ > +#define KASAN_SHADOW_SCALE_SHIFT 3 > + > +#ifdef CONFIG_X86_64 > +#define KASAN_HOST_USER_SPACE_END_ADDR 0x00007fffffffffffUL > +/* KASAN_SHADOW_SIZE is the size of total address space divided by 8 */ > +#define KASAN_SHADOW_SIZE ((KASAN_HOST_USER_SPACE_END_ADDR + 1) >> \ > + KASAN_SHADOW_SCALE_SHIFT) > +#else > +#error "KASAN_SHADOW_SIZE is not defined for this sub-architecture" > +#endif /* CONFIG_X86_64 */ > + > +#define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET) > +#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE) > + > +#ifdef CONFIG_KASAN > +void kasan_init(void); > +void kasan_map_memory(void *start, unsigned long len); > +#else > +static inline void kasan_init(void) { } > +#endif /* CONFIG_KASAN */ > + > +#endif /* __ASM_UM_KASAN_H */ > diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S > index f5001481010c..d91bdb2c3143 100644 > --- a/arch/um/kernel/dyn.lds.S > +++ b/arch/um/kernel/dyn.lds.S > @@ -103,7 +103,10 @@ SECTIONS > be empty, which isn't pretty. */ > . = ALIGN(32 / 8); > .preinit_array : { *(.preinit_array) } > - .init_array : { *(.init_array) } > + .init_array : { > + *(.kasan_init) > + *(.init_array) > + } > .fini_array : { *(.fini_array) } > .data : { > INIT_TASK_DATA(KERNEL_STACK_SIZE) > diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c > index 30885d0b94ac..7b0d028aa079 100644 > --- a/arch/um/kernel/mem.c > +++ b/arch/um/kernel/mem.c > @@ -18,6 +18,24 @@ > #include > #include > #include > +#include > + > +#ifdef CONFIG_KASAN > +void kasan_init(void) > +{ > + /* > + * kasan_map_memory will map all of the required address space and > + * the host machine will allocate physical memory as necessary. > + */ > + kasan_map_memory((void *)KASAN_SHADOW_START, KASAN_SHADOW_SIZE); > + init_task.kasan_depth = 0; > + os_info("KernelAddressSanitizer initialized\n"); > +} > + > +static void (*kasan_init_ptr)(void) > +__section(.kasan_init) __used > += kasan_init; > +#endif > > /* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */ > unsigned long *empty_zero_page = NULL; > diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c > index 3c1b77474d2d..8530b2e08604 100644 > --- a/arch/um/os-Linux/mem.c > +++ b/arch/um/os-Linux/mem.c > @@ -17,6 +17,28 @@ > #include > #include > > +/* > + * kasan_map_memory - maps memory from @start with a size of @len. > + * The allocated memory is filled with zeroes upon success. > + * @start: the start address of the memory to be mapped > + * @len: the length of the memory to be mapped > + * > + * This function is used to map shadow memory for KASAN in uml > + */ > +void kasan_map_memory(void *start, size_t len) > +{ > + if (mmap(start, > + len, > + PROT_READ|PROT_WRITE, > + MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, > + -1, > + 0) == MAP_FAILED) { > + os_info("Couldn't allocate shadow memory: %s\n.", > + strerror(errno)); > + exit(1); > + } > +} > + > /* Set by make_tempfile() during early boot. */ > static char *tempdir = NULL; > > diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c > index 715594fe5719..cb667c9225ab 100644 > --- a/arch/um/os-Linux/user_syms.c > +++ b/arch/um/os-Linux/user_syms.c > @@ -27,10 +27,10 @@ EXPORT_SYMBOL(strstr); > #ifndef __x86_64__ > extern void *memcpy(void *, const void *, size_t); > EXPORT_SYMBOL(memcpy); > -#endif > - > EXPORT_SYMBOL(memmove); > EXPORT_SYMBOL(memset); > +#endif > + > EXPORT_SYMBOL(printf); > > /* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms. > diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile > index 33c51c064c77..7dbd76c546fe 100644 > --- a/arch/x86/um/Makefile > +++ b/arch/x86/um/Makefile > @@ -26,7 +26,8 @@ else > > obj-y += syscalls_64.o vdso/ > > -subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o ../entry/thunk_64.o > +subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o ../entry/thunk_64.o \ > + ../lib/memmove_64.o ../lib/memset_64.o > > endif > > diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile > index 0caddd6acb22..450efa0fb694 100644 > --- a/arch/x86/um/vdso/Makefile > +++ b/arch/x86/um/vdso/Makefile > @@ -3,6 +3,9 @@ > # Building vDSO images for x86. > # > > +# do not instrument on vdso because KASAN is not compatible with user mode > +KASAN_SANITIZE := n > + > # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. > KCOV_INSTRUMENT := n > > diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan > index 81f5464ea9e1..5b54f3c9a741 100644 > --- a/lib/Kconfig.kasan > +++ b/lib/Kconfig.kasan > @@ -125,7 +125,7 @@ config KASAN_STACK_ENABLE > > config KASAN_STACK > int > - default 1 if KASAN_STACK_ENABLE || CC_IS_GCC > + default 1 if (KASAN_STACK_ENABLE || CC_IS_GCC) && !UML > default 0 > > config KASAN_S390_4_LEVEL_PAGING > -- > 2.25.0.265.gbab2e86ba0-goog >