Commit 79b7e67b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML updates from Richard Weinberger:

 - KASAN support for x86_64

 - noreboot command line option, just like qemu's -no-reboot

 - Various fixes and cleanups

* tag 'for-linus-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
  um: include sys/types.h for size_t
  um: Replace to_phys() and to_virt() with less generic function names
  um: Add missing apply_returns()
  um: add "noreboot" command line option for PANIC_TIMEOUT=-1 setups
  um: include linux/stddef.h for __always_inline
  UML: add support for KASAN under x86_64
  mm: Add PAGE_ALIGN_DOWN macro
  um: random: Don't initialise hwrng struct with zero
  um: remove unused mm_copy_segments
  um: remove unused variable
  um: Remove straying parenthesis
  um: x86: print RIP with symbol
  arch: um: Fix build for statically linked UML w/ constructors
  x86/um: Kconfig: Fix indentation
  um/drivers: Kconfig: Fix indentation
  um: Kconfig: Fix indentation
parents 4d5398a3 af3e1610
...@@ -12,6 +12,8 @@ config UML ...@@ -12,6 +12,8 @@ config UML
select ARCH_HAS_STRNLEN_USER select ARCH_HAS_STRNLEN_USER
select ARCH_NO_PREEMPT select ARCH_NO_PREEMPT
select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_KASAN if X86_64
select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ASM_MODVERSIONS select HAVE_ASM_MODVERSIONS
select HAVE_UID16 select HAVE_UID16
...@@ -82,7 +84,7 @@ config ARCH_HAS_CACHE_LINE_SIZE ...@@ -82,7 +84,7 @@ config ARCH_HAS_CACHE_LINE_SIZE
source "arch/$(HEADER_ARCH)/um/Kconfig" source "arch/$(HEADER_ARCH)/um/Kconfig"
config MAY_HAVE_RUNTIME_DEPS config MAY_HAVE_RUNTIME_DEPS
bool bool
config STATIC_LINK config STATIC_LINK
bool "Force a static link" bool "Force a static link"
...@@ -219,6 +221,19 @@ config UML_TIME_TRAVEL_SUPPORT ...@@ -219,6 +221,19 @@ config UML_TIME_TRAVEL_SUPPORT
It is safe to say Y, but you probably don't need this. It is safe to say Y, but you probably don't need this.
config KASAN_SHADOW_OFFSET
hex
depends on KASAN
default 0x100000000000
help
This is the offset at which the ~16TB 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 0x100000000000, which works even if mem is
set to a large value. On low-memory systems, try 0x7fff8000, as it fits
into the immediate of most instructions, improving performance.
endmenu endmenu
source "arch/um/drivers/Kconfig" source "arch/um/drivers/Kconfig"
......
...@@ -251,37 +251,37 @@ config UML_NET_VECTOR ...@@ -251,37 +251,37 @@ config UML_NET_VECTOR
depends on UML_NET depends on UML_NET
select MAY_HAVE_RUNTIME_DEPS select MAY_HAVE_RUNTIME_DEPS
help help
This User-Mode Linux network driver uses multi-message send This User-Mode Linux network driver uses multi-message send
and receive functions. The host running the UML guest must have and receive functions. The host running the UML guest must have
a linux kernel version above 3.0 and a libc version > 2.13. a linux kernel version above 3.0 and a libc version > 2.13.
This driver provides tap, raw, gre and l2tpv3 network transports This driver provides tap, raw, gre and l2tpv3 network transports
with up to 4 times higher network throughput than the UML network with up to 4 times higher network throughput than the UML network
drivers. drivers.
config UML_NET_VDE config UML_NET_VDE
bool "VDE transport (obsolete)" bool "VDE transport (obsolete)"
depends on UML_NET depends on UML_NET
select MAY_HAVE_RUNTIME_DEPS select MAY_HAVE_RUNTIME_DEPS
help help
This User-Mode Linux network transport allows one or more running This User-Mode Linux network transport allows one or more running
UMLs on a single host to communicate with each other and also UMLs on a single host to communicate with each other and also
with the rest of the world using Virtual Distributed Ethernet, with the rest of the world using Virtual Distributed Ethernet,
an improved fork of uml_switch. an improved fork of uml_switch.
You must have libvdeplug installed in order to build the vde You must have libvdeplug installed in order to build the vde
transport into UML. transport into UML.
To use this form of networking, you will need to run vde_switch To use this form of networking, you will need to run vde_switch
on the host. on the host.
For more information, see <http://wiki.virtualsquare.org/> For more information, see <http://wiki.virtualsquare.org/>
That site has a good overview of what VDE is and also examples That site has a good overview of what VDE is and also examples
of the UML command line to use to enable VDE networking. of the UML command line to use to enable VDE networking.
NOTE: THIS TRANSPORT IS DEPRECATED AND WILL BE REMOVED SOON!!! Please NOTE: THIS TRANSPORT IS DEPRECATED AND WILL BE REMOVED SOON!!! Please
migrate to UML_NET_VECTOR. migrate to UML_NET_VECTOR.
If unsure, say N. If unsure, say N.
config UML_NET_MCAST config UML_NET_MCAST
bool "Multicast transport (obsolete)" bool "Multicast transport (obsolete)"
...@@ -311,19 +311,19 @@ config UML_NET_PCAP ...@@ -311,19 +311,19 @@ config UML_NET_PCAP
depends on UML_NET depends on UML_NET
select MAY_HAVE_RUNTIME_DEPS select MAY_HAVE_RUNTIME_DEPS
help help
The pcap transport makes a pcap packet stream on the host look The pcap transport makes a pcap packet stream on the host look
like an ethernet device inside UML. This is useful for making like an ethernet device inside UML. This is useful for making
UML act as a network monitor for the host. You must have libcap UML act as a network monitor for the host. You must have libcap
installed in order to build the pcap transport into UML. installed in order to build the pcap transport into UML.
For more information, see For more information, see
<http://user-mode-linux.sourceforge.net/old/networking.html> That site <http://user-mode-linux.sourceforge.net/old/networking.html> That site
has examples of the UML command line to use to enable this option. has examples of the UML command line to use to enable this option.
NOTE: THIS TRANSPORT IS DEPRECATED AND WILL BE REMOVED SOON!!! Please NOTE: THIS TRANSPORT IS DEPRECATED AND WILL BE REMOVED SOON!!! Please
migrate to UML_NET_VECTOR. migrate to UML_NET_VECTOR.
If unsure, say N. If unsure, say N.
config UML_NET_SLIRP config UML_NET_SLIRP
bool "SLiRP transport (obsolete)" bool "SLiRP transport (obsolete)"
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
* protects against a module being loaded twice at the same time. * protects against a module being loaded twice at the same time.
*/ */
static int random_fd = -1; static int random_fd = -1;
static struct hwrng hwrng = { 0, }; static struct hwrng hwrng;
static DECLARE_COMPLETION(have_data); static DECLARE_COMPLETION(have_data);
static int rng_dev_read(struct hwrng *rng, void *buf, size_t max, bool block) static int rng_dev_read(struct hwrng *rng, void *buf, size_t max, bool block)
......
...@@ -83,6 +83,8 @@ ...@@ -83,6 +83,8 @@
} }
.init_array : { .init_array : {
__init_array_start = .; __init_array_start = .;
*(.kasan_init)
*(.init_array.*)
*(.init_array) *(.init_array)
__init_array_end = .; __init_array_end = .;
} }
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_UM_KASAN_H
#define __ASM_UM_KASAN_H
#include <linux/init.h>
#include <linux/const.h>
#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);
extern int kasan_um_is_ready;
#ifdef CONFIG_STATIC_LINK
#define kasan_arch_is_ready() (kasan_um_is_ready)
#endif
#else
static inline void kasan_init(void) { }
#endif /* CONFIG_KASAN */
#endif /* __ASM_UM_KASAN_H */
...@@ -59,11 +59,6 @@ static inline void release_thread(struct task_struct *task) ...@@ -59,11 +59,6 @@ static inline void release_thread(struct task_struct *task)
{ {
} }
static inline void mm_copy_segments(struct mm_struct *from_mm,
struct mm_struct *new_mm)
{
}
/* /*
* User space process size: 3GB (default). * User space process size: 3GB (default).
*/ */
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#undef XOR_SELECT_TEMPLATE #undef XOR_SELECT_TEMPLATE
/* pick an arbitrary one - measuring isn't possible with inf-cpu */ /* pick an arbitrary one - measuring isn't possible with inf-cpu */
#define XOR_SELECT_TEMPLATE(x) \ #define XOR_SELECT_TEMPLATE(x) \
(time_travel_mode == TT_MODE_INFCPU ? TT_CPU_INF_XOR_DEFAULT : x)) (time_travel_mode == TT_MODE_INFCPU ? TT_CPU_INF_XOR_DEFAULT : x)
#endif #endif
#endif #endif
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
*/ */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/* This is to get size_t */ /* This is to get size_t and NULL */
#ifndef __UM_HOST__ #ifndef __UM_HOST__
#include <linux/types.h> #include <linux/types.h>
#else #else
#include <stddef.h> #include <stddef.h>
#include <sys/types.h>
#endif #endif
extern void panic(const char *fmt, ...) extern void panic(const char *fmt, ...)
......
...@@ -109,7 +109,11 @@ SECTIONS ...@@ -109,7 +109,11 @@ SECTIONS
be empty, which isn't pretty. */ be empty, which isn't pretty. */
. = ALIGN(32 / 8); . = ALIGN(32 / 8);
.preinit_array : { *(.preinit_array) } .preinit_array : { *(.preinit_array) }
.init_array : { *(.init_array) } .init_array : {
*(.kasan_init)
*(.init_array.*)
*(.init_array)
}
.fini_array : { *(.fini_array) } .fini_array : { *(.fini_array) }
.data : { .data : {
INIT_TASK_DATA(KERNEL_STACK_SIZE) INIT_TASK_DATA(KERNEL_STACK_SIZE)
......
...@@ -18,6 +18,25 @@ ...@@ -18,6 +18,25 @@
#include <kern_util.h> #include <kern_util.h>
#include <mem_user.h> #include <mem_user.h>
#include <os.h> #include <os.h>
#include <linux/sched/task.h>
#ifdef CONFIG_KASAN
int kasan_um_is_ready;
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;
kasan_um_is_ready = true;
}
static void (*kasan_init_ptr)(void)
__section(".kasan_init") __used
= kasan_init;
#endif
/* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */ /* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */
unsigned long *empty_zero_page = NULL; unsigned long *empty_zero_page = NULL;
......
...@@ -27,7 +27,7 @@ void dump_trace(struct task_struct *tsk, ...@@ -27,7 +27,7 @@ void dump_trace(struct task_struct *tsk,
frame = (struct stack_frame *)bp; frame = (struct stack_frame *)bp;
while (((long) sp & (THREAD_SIZE-1)) != 0) { while (((long) sp & (THREAD_SIZE-1)) != 0) {
addr = *sp; addr = READ_ONCE_NOCHECK(*sp);
if (__kernel_text_address(addr)) { if (__kernel_text_address(addr)) {
reliable = 0; reliable = 0;
if ((unsigned long) sp == bp + sizeof(long)) { if ((unsigned long) sp == bp + sizeof(long)) {
......
...@@ -95,6 +95,7 @@ SECTIONS ...@@ -95,6 +95,7 @@ SECTIONS
} }
.got : { *(.got.plt) *(.got) } .got : { *(.got.plt) *(.got) }
.eh_frame : { KEEP (*(.eh_frame)) }
.dynamic : { *(.dynamic) } .dynamic : { *(.dynamic) }
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
......
...@@ -17,6 +17,28 @@ ...@@ -17,6 +17,28 @@
#include <init.h> #include <init.h>
#include <os.h> #include <os.h>
/*
* 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. */ /* Set by make_tempfile() during early boot. */
static char *tempdir = NULL; static char *tempdir = NULL;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <unistd.h> #include <unistd.h>
#include <sched.h> #include <sched.h>
#include <errno.h> #include <errno.h>
...@@ -707,10 +708,24 @@ void halt_skas(void) ...@@ -707,10 +708,24 @@ void halt_skas(void)
UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT); UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT);
} }
static bool noreboot;
static int __init noreboot_cmd_param(char *str, int *add)
{
noreboot = true;
return 0;
}
__uml_setup("noreboot", noreboot_cmd_param,
"noreboot\n"
" Rather than rebooting, exit always, akin to QEMU's -no-reboot option.\n"
" This is useful if you're using CONFIG_PANIC_TIMEOUT in order to catch\n"
" crashes in CI\n");
void reboot_skas(void) void reboot_skas(void)
{ {
block_signals_trace(); block_signals_trace();
UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); UML_LONGJMP(&initial_jmpbuf, noreboot ? INIT_JMP_HALT : INIT_JMP_REBOOT);
} }
void __switch_mm(struct mm_id *mm_idp) void __switch_mm(struct mm_id *mm_idp)
......
...@@ -136,7 +136,7 @@ static int remove_files_and_dir(char *dir) ...@@ -136,7 +136,7 @@ static int remove_files_and_dir(char *dir)
static inline int is_umdir_used(char *dir) static inline int is_umdir_used(char *dir)
{ {
char pid[sizeof("nnnnnnnnn")], *end, *file; char pid[sizeof("nnnnnnnnn")], *end, *file;
int dead, fd, p, n, err; int fd, p, n, err;
size_t filelen = strlen(dir) + sizeof("/pid") + 1; size_t filelen = strlen(dir) + sizeof("/pid") + 1;
file = malloc(filelen); file = malloc(filelen);
...@@ -145,7 +145,6 @@ static inline int is_umdir_used(char *dir) ...@@ -145,7 +145,6 @@ static inline int is_umdir_used(char *dir)
snprintf(file, filelen, "%s/pid", dir); snprintf(file, filelen, "%s/pid", dir);
dead = 0;
fd = open(file, O_RDONLY); fd = open(file, O_RDONLY);
if (fd < 0) { if (fd < 0) {
fd = -errno; fd = -errno;
......
...@@ -27,10 +27,10 @@ EXPORT_SYMBOL(strstr); ...@@ -27,10 +27,10 @@ EXPORT_SYMBOL(strstr);
#ifndef __x86_64__ #ifndef __x86_64__
extern void *memcpy(void *, const void *, size_t); extern void *memcpy(void *, const void *, size_t);
EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memcpy);
#endif
EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memset);
#endif
EXPORT_SYMBOL(printf); EXPORT_SYMBOL(printf);
/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms. /* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
......
...@@ -32,12 +32,12 @@ config 3_LEVEL_PGTABLES ...@@ -32,12 +32,12 @@ config 3_LEVEL_PGTABLES
bool "Three-level pagetables" if !64BIT bool "Three-level pagetables" if !64BIT
default 64BIT default 64BIT
help help
Three-level pagetables will let UML have more than 4G of physical Three-level pagetables will let UML have more than 4G of physical
memory. All the memory that can't be mapped directly will be treated memory. All the memory that can't be mapped directly will be treated
as high memory. as high memory.
However, this it experimental on 32-bit architectures, so if unsure say However, this it experimental on 32-bit architectures, so if unsure say
N (on x86-64 it's automatically enabled, instead, as it's safe there). N (on x86-64 it's automatically enabled, instead, as it's safe there).
config ARCH_HAS_SC_SIGNALS config ARCH_HAS_SC_SIGNALS
def_bool !64BIT def_bool !64BIT
......
...@@ -28,7 +28,8 @@ else ...@@ -28,7 +28,8 @@ else
obj-y += syscalls_64.o vdso/ 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 endif
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <sysdep/ptrace_user.h> #include <sysdep/ptrace_user.h>
#include <generated/asm-offsets.h> #include <generated/asm-offsets.h>
#include <linux/stddef.h>
#define STUB_MMAP_NR __NR_mmap #define STUB_MMAP_NR __NR_mmap
#define MMAP_OFFSET(o) (o) #define MMAP_OFFSET(o) (o)
......
...@@ -19,8 +19,8 @@ void show_regs(struct pt_regs *regs) ...@@ -19,8 +19,8 @@ void show_regs(struct pt_regs *regs)
print_modules(); print_modules();
printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current),
current->comm, print_tainted(), init_utsname()->release); current->comm, print_tainted(), init_utsname()->release);
printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, printk(KERN_INFO "RIP: %04lx:%pS\n", PT_REGS_CS(regs) & 0xffff,
PT_REGS_IP(regs)); (void *)PT_REGS_IP(regs));
printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs), printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs),
PT_REGS_EFLAGS(regs)); PT_REGS_EFLAGS(regs));
printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n",
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# Building vDSO images for x86. # 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. # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
KCOV_INSTRUMENT := n KCOV_INSTRUMENT := n
......
...@@ -221,6 +221,9 @@ int overcommit_policy_handler(struct ctl_table *, int, void *, size_t *, ...@@ -221,6 +221,9 @@ int overcommit_policy_handler(struct ctl_table *, int, void *, size_t *,
/* to align the pointer to the (next) page boundary */ /* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) #define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
/* to align the pointer to the (prev) page boundary */
#define PAGE_ALIGN_DOWN(addr) ALIGN_DOWN(addr, PAGE_SIZE)
/* test whether an address (unsigned long or pointer) is aligned to PAGE_SIZE */ /* test whether an address (unsigned long or pointer) is aligned to PAGE_SIZE */
#define PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)(addr), PAGE_SIZE) #define PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)(addr), PAGE_SIZE)
......
...@@ -295,9 +295,22 @@ int kasan_populate_vmalloc(unsigned long addr, unsigned long size) ...@@ -295,9 +295,22 @@ int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
return 0; return 0;
shadow_start = (unsigned long)kasan_mem_to_shadow((void *)addr); shadow_start = (unsigned long)kasan_mem_to_shadow((void *)addr);
shadow_start = ALIGN_DOWN(shadow_start, PAGE_SIZE);
shadow_end = (unsigned long)kasan_mem_to_shadow((void *)addr + size); shadow_end = (unsigned long)kasan_mem_to_shadow((void *)addr + size);
shadow_end = ALIGN(shadow_end, PAGE_SIZE);
/*
* User Mode Linux maps enough shadow memory for all of virtual memory
* at boot, so doesn't need to allocate more on vmalloc, just clear it.
*
* The remaining CONFIG_UML checks in this file exist for the same
* reason.
*/
if (IS_ENABLED(CONFIG_UML)) {
__memset((void *)shadow_start, KASAN_VMALLOC_INVALID, shadow_end - shadow_start);
return 0;
}
shadow_start = PAGE_ALIGN_DOWN(shadow_start);
shadow_end = PAGE_ALIGN(shadow_end);
ret = apply_to_page_range(&init_mm, shadow_start, ret = apply_to_page_range(&init_mm, shadow_start,
shadow_end - shadow_start, shadow_end - shadow_start,
...@@ -466,6 +479,10 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end, ...@@ -466,6 +479,10 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
if (shadow_end > shadow_start) { if (shadow_end > shadow_start) {
size = shadow_end - shadow_start; size = shadow_end - shadow_start;
if (IS_ENABLED(CONFIG_UML)) {
__memset(shadow_start, KASAN_SHADOW_INIT, shadow_end - shadow_start);
return;
}
apply_to_existing_page_range(&init_mm, apply_to_existing_page_range(&init_mm,
(unsigned long)shadow_start, (unsigned long)shadow_start,
size, kasan_depopulate_vmalloc_pte, size, kasan_depopulate_vmalloc_pte,
...@@ -531,6 +548,11 @@ int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask) ...@@ -531,6 +548,11 @@ int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask)
if (WARN_ON(!PAGE_ALIGNED(shadow_start))) if (WARN_ON(!PAGE_ALIGNED(shadow_start)))
return -EINVAL; return -EINVAL;
if (IS_ENABLED(CONFIG_UML)) {
__memset((void *)shadow_start, KASAN_SHADOW_INIT, shadow_size);
return 0;
}
ret = __vmalloc_node_range(shadow_size, 1, shadow_start, ret = __vmalloc_node_range(shadow_size, 1, shadow_start,
shadow_start + shadow_size, shadow_start + shadow_size,
GFP_KERNEL, GFP_KERNEL,
...@@ -554,6 +576,9 @@ int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask) ...@@ -554,6 +576,9 @@ int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask)
void kasan_free_module_shadow(const struct vm_struct *vm) void kasan_free_module_shadow(const struct vm_struct *vm)
{ {
if (IS_ENABLED(CONFIG_UML))
return;
if (vm->flags & VM_KASAN) if (vm->flags & VM_KASAN)
vfree(kasan_mem_to_shadow(vm->addr)); vfree(kasan_mem_to_shadow(vm->addr));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment