From fed4c72689805001108f86868e5856edb3d3808a Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Sat, 28 May 2016 18:39:03 +0530 Subject: [PATCH 1/8] um: Eliminate null test after alloc_bootmem alloc_bootmem function never returns NULL. Thus a NULL test after a call to this function is unnecessary. The Coccinelle semantic patch used to make this change is follows: @@ expression E; statement S; @@ E = alloc_bootmem(...) ... when != E - if (E == NULL) S Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Richard Weinberger --- arch/um/kernel/initrd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index 55cead809b18..48bae81f8dca 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -37,8 +37,6 @@ static int __init read_initrd(void) } area = alloc_bootmem(size); - if (area == NULL) - return 0; if (load_initrd(initrd, area, size) == -1) return 0; From b63236972e1344b247750451e2be0a06cd125f21 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 12 Jun 2016 21:56:42 +0200 Subject: [PATCH 2/8] um: Setup physical memory in setup_arch() Currently UML sets up physical memory very early, long before setup_arch() was called by the kernel main function. This can cause problems when code paths in UML's memory setup code assume that the kernel is already running. i.e. when kmemleak is enabled it will evaluate current() in free_bootmem(). That early current() is undefined and UML explodes. Solve the problem by setting up physical memory in setup_arch(), at this stage the kernel has materialized and basic infrastructure such as current() works. Signed-off-by: Richard Weinberger --- arch/um/kernel/um_arch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 16630e75f056..e8175a8aa22c 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -319,9 +319,6 @@ int __init linux_main(int argc, char **argv) start_vm = VMALLOC_START; - setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); - mem_total_pages(physmem_size, iomem_size, highmem); - virtmem_size = physmem_size; stack = (unsigned long) argv; stack &= ~(1024 * 1024 - 1); @@ -334,7 +331,6 @@ int __init linux_main(int argc, char **argv) printf("Kernel virtual memory size shrunk to %lu bytes\n", virtmem_size); - stack_protections((unsigned long) &init_thread_info); os_flush_stdout(); return start_uml(); @@ -342,6 +338,10 @@ int __init linux_main(int argc, char **argv) void __init setup_arch(char **cmdline_p) { + stack_protections((unsigned long) &init_thread_info); + setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); + mem_total_pages(physmem_size, iomem_size, highmem); + paging_init(); strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; From 5609a3d309836d047eb60275db69d82d47268283 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 12 Jun 2016 21:56:43 +0200 Subject: [PATCH 3/8] um: Select HAVE_DEBUG_KMEMLEAK Now we have the infrastructure to support kmemleak. Enable the HAVE flag. Signed-off-by: Richard Weinberger --- arch/um/Kconfig.common | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index cc0013475444..de562da1bbed 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -5,6 +5,7 @@ config UML select HAVE_ARCH_SECCOMP_FILTER select HAVE_UID16 select HAVE_FUTEX_CMPXCHG if FUTEX + select HAVE_DEBUG_KMEMLEAK select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select GENERIC_IO From 57a05d83b16710aff30510c33768df7ab17e0b4a Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 12 Jun 2016 22:03:16 +0200 Subject: [PATCH 4/8] um: Fix possible deadlock in sig_handler_common() We are in atomic context and must not sleep. Sleeping here is possible since malloc() maps to kmalloc() with GFP_KERNEL. Cc: stable@vger.kernel.org Fixes: b6024b21 ("um: extend fpstate to _xstate to support YMM registers") Signed-off-by: Richard Weinberger --- arch/um/os-Linux/signal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 8acaf4e384c0..a86d7cc2c2d8 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -15,6 +15,7 @@ #include #include #include +#include void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = { [SIGTRAP] = relay_signal, @@ -32,7 +33,7 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc) struct uml_pt_regs *r; int save_errno = errno; - r = malloc(sizeof(struct uml_pt_regs)); + r = uml_kmalloc(sizeof(struct uml_pt_regs), UM_GFP_ATOMIC); if (!r) panic("out of memory"); @@ -91,7 +92,7 @@ static void timer_real_alarm_handler(mcontext_t *mc) { struct uml_pt_regs *regs; - regs = malloc(sizeof(struct uml_pt_regs)); + regs = uml_kmalloc(sizeof(struct uml_pt_regs), UM_GFP_ATOMIC); if (!regs) panic("out of memory"); From 3e93895735745916756122d58941be89a17c42b4 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Sun, 12 Jun 2016 22:04:53 +0200 Subject: [PATCH 5/8] um: Use asm-generic/irqflags.h Instead proving its own arch_local_irq_save() and arch_irqs_disabled() version use the generic version from asm-generic/irqflags.h. A nice side effect is that um gets a few additional arch_ functions as well. Signed-off-by: Daniel Wagner [rw: Massaged commit message] Signed-off-by: Richard Weinberger --- arch/um/include/asm/irqflags.h | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h index c780d8a16773..3bb221e1d5a4 100644 --- a/arch/um/include/asm/irqflags.h +++ b/arch/um/include/asm/irqflags.h @@ -6,37 +6,33 @@ extern int set_signals(int enable); extern void block_signals(void); extern void unblock_signals(void); +#define arch_local_save_flags arch_local_save_flags static inline unsigned long arch_local_save_flags(void) { return get_signals(); } +#define arch_local_irq_restore arch_local_irq_restore static inline void arch_local_irq_restore(unsigned long flags) { set_signals(flags); } +#define arch_local_irq_enable arch_local_irq_enable static inline void arch_local_irq_enable(void) { unblock_signals(); } +#define arch_local_irq_disable arch_local_irq_disable static inline void arch_local_irq_disable(void) { block_signals(); } -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags; - flags = arch_local_save_flags(); - arch_local_irq_disable(); - return flags; -} +#define ARCH_IRQ_DISABLED 0 +#define ARCh_IRQ_ENABLED (SIGIO|SIGVTALRM) -static inline bool arch_irqs_disabled(void) -{ - return arch_local_save_flags() == 0; -} +#include #endif From 8e99bc70468dcc42a756ca4b100e2fb2c30c4c89 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 12 Jun 2016 22:04:54 +0200 Subject: [PATCH 6/8] um: Enable TRACE_IRQFLAGS_SUPPORT Now we have everything we need, so enable TRACE_IRQFLAGS_SUPPORT. Signed-off-by: Richard Weinberger --- arch/um/Kconfig.common | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index de562da1bbed..08d931c98621 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -31,10 +31,9 @@ config PCI config PCMCIA bool -# Yet to do! config TRACE_IRQFLAGS_SUPPORT bool - default n + default y config LOCKDEP_SUPPORT bool From 915eed20e40f4dcb142cb29a3de6f6ba67f4bb5a Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Sat, 21 May 2016 17:46:10 +0200 Subject: [PATCH 7/8] um: Support kcov This adds support for kcov to UML. There is a small problem where UML will randomly segfault during boot; this is because current_thread_info() occasionally returns an invalid (non-NULL) pointer and we try to dereference it in __sanitizer_cov_trace_pc(). I consider this a bug in UML itself and this patch merely exposes it. [v2: disable instrumentation in UML-specific code] Cc: Quentin Casasnovas Cc: Richard Weinberger Cc: Thomas Meyer Cc: user-mode-linux-devel Cc: Dmitry Vyukov Signed-off-by: Vegard Nossum Signed-off-by: Richard Weinberger --- arch/um/Kconfig.common | 1 + arch/um/kernel/Makefile | 5 +++++ arch/um/os-Linux/Makefile | 3 +++ arch/x86/um/vdso/Makefile | 3 +++ 4 files changed, 12 insertions(+) diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index 08d931c98621..f8530d866c9f 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -1,6 +1,7 @@ config UML bool default y + select ARCH_HAS_KCOV select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_SECCOMP_FILTER select HAVE_UID16 diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index a6a5e42caaef..2f36d515762e 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -3,6 +3,11 @@ # Licensed under the GPL # +# Don't instrument UML-specific code; without this, we may crash when +# accessing the instrumentation buffer for the first time from the +# kernel. +KCOV_INSTRUMENT := n + CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \ -DELF_ARCH=$(LDS_ELF_ARCH) \ -DELF_FORMAT=$(LDS_ELF_FORMAT) \ diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 08ff5094fcdd..ada473bf6f46 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -3,6 +3,9 @@ # Licensed under the GPL # +# Don't instrument UML-specific code +KCOV_INSTRUMENT := n + obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o \ umid.o user_syms.o util.o drivers/ skas/ diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile index 6c803ca49b5d..d72dec406ccb 100644 --- a/arch/x86/um/vdso/Makefile +++ b/arch/x86/um/vdso/Makefile @@ -2,6 +2,9 @@ # Building vDSO images for x86. # +# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. +KCOV_INSTRUMENT := n + VDSO64-y := y vdso-install-$(VDSO64-y) += vdso.so From 8a545f185145e3c09348cd74326268ecfc6715a3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Jul 2016 13:12:34 +0300 Subject: [PATCH 8/8] hostfs: Freeing an ERR_PTR in hostfs_fill_sb_common() We can't pass error pointers to kfree() or it causes an oops. Fixes: 52b209f7b848 ('get rid of hostfs_read_inode()') Signed-off-by: Dan Carpenter Signed-off-by: Richard Weinberger --- fs/hostfs/hostfs_kern.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 5c57654927a6..90e46cd752fe 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -959,10 +959,11 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) if (S_ISLNK(root_inode->i_mode)) { char *name = follow_link(host_root_path); - if (IS_ERR(name)) + if (IS_ERR(name)) { err = PTR_ERR(name); - else - err = read_name(root_inode, name); + goto out_put; + } + err = read_name(root_inode, name); kfree(name); if (err) goto out_put;