From 4076f7329832074196e050def49d22265fce2021 Mon Sep 17 00:00:00 2001 From: "Marcel W. Wysocki" Date: Sun, 15 Feb 2026 22:28:02 +0800 Subject: [PATCH 01/10] um: fix address-of CMSG_DATA() rvalue in stub The UML stub takes the address of CMSG_DATA(fd_msg): fd_map = (void *)&CMSG_DATA(fd_msg); CMSG_DATA() is specified by POSIX to return unsigned char *. Taking its address is semantically wrong -- the intent is to get a pointer to the control message data, which is exactly what CMSG_DATA() already returns. This happens to compile with glibc because glibc's primary CMSG_DATA definition accesses a flexible array member: #define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data) An array lvalue can have its address taken, and &array yields the same address as array. However, glibc also has an alternative definition that uses pointer arithmetic (returning an rvalue), and musl's definition always uses pointer arithmetic: /* musl */ #define CMSG_DATA(cmsg) \ ((unsigned char *)(((struct cmsghdr *)(cmsg)) + 1)) Taking the address of an rvalue is a hard error in C, so the current code fails to compile with musl libc. Remove the erroneous & operator. The resulting code is correct regardless of the CMSG_DATA implementation -- it simply assigns the data pointer, which is what the subsequent code (fd_map[--num_fds]) expects. No functional change with glibc; fixes the build with musl. Signed-off-by: Marcel W. Wysocki Link: https://patch.msgid.link/20260215142803.1455757-1-maci.stgn@gmail.com Signed-off-by: Johannes Berg --- arch/um/kernel/skas/stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/kernel/skas/stub.c b/arch/um/kernel/skas/stub.c index 67cab46a602c..e09216a20cb5 100644 --- a/arch/um/kernel/skas/stub.c +++ b/arch/um/kernel/skas/stub.c @@ -146,7 +146,7 @@ stub_signal_interrupt(int sig, siginfo_t *info, void *p) /* Receive the FDs */ num_fds = 0; fd_msg = msghdr.msg_control; - fd_map = (void *)&CMSG_DATA(fd_msg); + fd_map = (void *)CMSG_DATA(fd_msg); if (res == iov.iov_len && msghdr.msg_controllen > sizeof(struct cmsghdr)) num_fds = (fd_msg->cmsg_len - CMSG_LEN(0)) / sizeof(int); From d46dfb369a4627d90efc2c2ffbe29e38e3e74286 Mon Sep 17 00:00:00 2001 From: "Marcel W. Wysocki" Date: Sun, 15 Feb 2026 22:28:03 +0800 Subject: [PATCH 02/10] um: avoid struct sigcontext redefinition with musl mcontext.c includes both and . With musl libc, this causes a struct sigcontext redefinition error: pulls in musl's , which defines struct sigcontext directly. The kernel's then provides a second, conflicting definition of the same struct. With glibc this does not conflict because glibc's signal headers source their struct sigcontext from the kernel's own UAPI headers, so the include guard in makes the second inclusion a no-op. mcontext.c does not actually use struct sigcontext by name -- it only needs the FP-state types (_fpstate, _xstate, etc.) that are defined in independently of the sigcontext struct. Temporarily rename sigcontext to __kernel_sigcontext during the inclusion of so that the kernel's definition does not collide with musl's. The #undef restores normal name resolution immediately afterward. No functional change with glibc; fixes the build with musl. Signed-off-by: Marcel W. Wysocki Link: https://patch.msgid.link/20260215142803.1455757-2-maci.stgn@gmail.com Signed-off-by: Johannes Berg --- arch/x86/um/os-Linux/mcontext.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/um/os-Linux/mcontext.c b/arch/x86/um/os-Linux/mcontext.c index a21403df6663..b1580df80b3f 100644 --- a/arch/x86/um/os-Linux/mcontext.c +++ b/arch/x86/um/os-Linux/mcontext.c @@ -4,7 +4,13 @@ #include #include #include +/* + * musl defines struct sigcontext in . Rename the kernel's + * copy to avoid redefinition while keeping the FP-state types available. + */ +#define sigcontext __kernel_sigcontext #include +#undef sigcontext #include #include #include From 1ccc861dbbc1b4c6a896e95f815ef3310775c33f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 26 Feb 2026 14:11:12 -0800 Subject: [PATCH 03/10] um: time-travel: clean up kernel-doc warnings Repair all kernel-doc warnings in um_timetravel.h: - add one enum description - mark "reserve" as private - use a leading '@' on current_time Warning: include/uapi/linux/um_timetravel.h:59 Enum value 'UM_TIMETRAVEL_SHARED_MAX_FDS' not described in enum 'um_timetravel_shared_mem_fds' Warning: include/uapi/linux/um_timetravel.h:245 union member 'reserve' not described in 'um_timetravel_schedshm_client' Warning: include/uapi/linux/um_timetravel.h:288 struct member 'current_time' not described in 'um_timetravel_schedshm' Signed-off-by: Randy Dunlap Link: https://patch.msgid.link/20260226221112.1042008-1-rdunlap@infradead.org Signed-off-by: Johannes Berg --- include/uapi/linux/um_timetravel.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/um_timetravel.h b/include/uapi/linux/um_timetravel.h index 546a690b0346..fa7c75334f2e 100644 --- a/include/uapi/linux/um_timetravel.h +++ b/include/uapi/linux/um_timetravel.h @@ -56,6 +56,9 @@ enum um_timetravel_shared_mem_fds { * in the control message */ UM_TIMETRAVEL_SHARED_LOGFD, + /** + * @UM_TIMETRAVEL_SHARED_MAX_FDS: number of fds listed here + */ UM_TIMETRAVEL_SHARED_MAX_FDS, }; @@ -242,6 +245,7 @@ union um_timetravel_schedshm_client { __u64 req_time; __u64 name; }; + /* private: */ char reserve[128]; /* reserved for future usage */ }; @@ -264,7 +268,7 @@ union um_timetravel_schedshm_client { * is made by any client. Clients also must update this value when they * insert/update an own request into the shared memory while not running * themselves, and the new request is before than the current value. - * current_time: Current time, can only be set by the client in running state + * @current_time: Current time, can only be set by the client in running state * (indicated by @running_id), though that client may only run until @free_until, * so it must remain smaller than @free_until. * @running_id: The current client in state running, set before a client is From 102331b66bcaf1f41f50b9c4cd5c36e46bafa9f3 Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Tue, 3 Mar 2026 07:52:23 +0800 Subject: [PATCH 04/10] um: Fix potential race condition in TLB sync During the TLB sync, we need to traverse and modify the page table, so we should hold the page table lock. Since full SMP support for threads within the same process is still missing, let's disable the split page table lock for simplicity. Fixes: 1e4ee5135d81 ("um: Add initial SMP support") Signed-off-by: Tiwei Bie Link: https://patch.msgid.link/20260302235224.1915380-2-tiwei.btw@antgroup.com Signed-off-by: Johannes Berg --- arch/um/kernel/tlb.c | 1 + mm/Kconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 39608cccf2c6..5386ab2d0da5 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -165,6 +165,7 @@ int um_tlb_sync(struct mm_struct *mm) unsigned long addr, next; int ret = 0; + guard(spinlock_irqsave)(&mm->page_table_lock); guard(spinlock_irqsave)(&mm->context.sync_tlb_lock); if (mm->context.sync_tlb_range_to == 0) diff --git a/mm/Kconfig b/mm/Kconfig index ebd8ea353687..befa8909ae29 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -572,6 +572,7 @@ config SPLIT_PTE_PTLOCKS depends on !ARM || CPU_CACHE_VIPT depends on !PARISC || PA20 depends on !SPARC32 + depends on !UML config ARCH_ENABLE_SPLIT_PMD_PTLOCK bool From cd4126d48f7f61928c18498629ca19a0f846d0c4 Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Tue, 3 Mar 2026 07:52:24 +0800 Subject: [PATCH 05/10] um: Fix pte_read() and pte_exec() for kernel mappings The pte_read() and pte_exec() helpers are only used during the TLB sync to determine the read/exec permissions for mmap. However, for kernel mappings, they will always return 0. This leads to kern_map() having to unconditionally set the exec flag to 1 and the read flag unexpectedly always being 0. Remove the unnecessary check for the _PAGE_USER bit in these helpers to ensure that the kernel mapping permissions can be correctly determined. Signed-off-by: Tiwei Bie Link: https://patch.msgid.link/20260302235224.1915380-3-tiwei.btw@antgroup.com Signed-off-by: Johannes Berg --- arch/um/include/asm/pgtable.h | 9 ++++----- arch/um/kernel/tlb.c | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index 3b42b0f45bf6..e156ef6f4fdb 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -121,13 +121,12 @@ static inline int pte_none(pte_t pte) */ static inline int pte_read(pte_t pte) { - return((pte_get_bits(pte, _PAGE_USER)) && - !(pte_get_bits(pte, _PAGE_PROTNONE))); + return !pte_get_bits(pte, _PAGE_PROTNONE); } -static inline int pte_exec(pte_t pte){ - return((pte_get_bits(pte, _PAGE_USER)) && - !(pte_get_bits(pte, _PAGE_PROTNONE))); +static inline int pte_exec(pte_t pte) +{ + return !pte_get_bits(pte, _PAGE_PROTNONE); } static inline int pte_write(pte_t pte) diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 5386ab2d0da5..1f175716b474 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -29,10 +29,9 @@ static int kern_map(struct mm_id *mm_idp, unsigned long virt, unsigned long len, int prot, int phys_fd, unsigned long long offset) { - /* TODO: Why is executable needed to be always set in the kernel? */ return os_map_memory((void *)virt, phys_fd, offset, len, prot & UM_PROT_READ, prot & UM_PROT_WRITE, - 1); + prot & UM_PROT_EXEC); } static int kern_unmap(struct mm_id *mm_idp, From 92d5c5c04eaa61f01c5b99bea9d639f0bd008036 Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Sun, 8 Mar 2026 14:04:06 +0800 Subject: [PATCH 06/10] um: Remove CONFIG_FRAME_WARN from x86_64_defconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CONFIG_FRAME_WARN=1024 setting in x86_64_defconfig originates from arch/um/defconfig, which was split into i386_defconfig and x86_64_defconfig by commit e40f04d040c6 ("arch/um: make it work with defconfig and x86_64"). Currently, it's even smaller than the default on 32bit (i.e., 1280). It's no longer suitable for 64bit. Building with x86_64_defconfig triggers the following warning: lib/maple_tree.c: In function ‘mas_wr_bnode’: lib/maple_tree.c:3740:1: warning: the frame size of 1056 bytes is larger than 1024 bytes [-Wframe-larger-than=] 3740 | } | ^ Since we have a larger CONFIG_KERNEL_STACK_ORDER on 64bit (twice that of 32bit) by default, we could increase CONFIG_FRAME_WARN accordingly. Let's remove the CONFIG_FRAME_WARN=1024 setting from x86_64_defconfig and just use the default value (2048 for 64bit) defined in lib/Kconfig.debug, as we do for 32bit. Signed-off-by: Tiwei Bie Link: https://patch.msgid.link/20260308060406.2772832-1-tiwei.btw@antgroup.com Signed-off-by: Johannes Berg --- arch/um/configs/x86_64_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig index cf309c5406a2..af6ff784e2d3 100644 --- a/arch/um/configs/x86_64_defconfig +++ b/arch/um/configs/x86_64_defconfig @@ -60,5 +60,4 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_NLS=y CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y -CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_KERNEL=y From d1895c15fc7d90a615bc8c455feb02acaf08ef1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Wed, 18 Mar 2026 22:03:26 +0100 Subject: [PATCH 07/10] x86/um: fix vDSO installation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generic vDSO installation logic used by 'make vdso_install' requires that $(vdso-install-y) is defined by the top-level architecture Makefile and that it contains a path relative to the root of the tree. For UML neither of these is satisfied. Move the definition of $(vdso-install-y) to a place which is included by the arch/um/Makefile and use the full relative path. Fixes: f1c2bb8b9964 ("um: implement a x86_64 vDSO") Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20260318-um-vdso-install-v1-1-26a4ca5c4210@weissschuh.net Signed-off-by: Johannes Berg --- arch/x86/Makefile.um | 2 ++ arch/x86/um/vdso/Makefile | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/Makefile.um b/arch/x86/Makefile.um index c86cbd9cbba3..19c13afa474e 100644 --- a/arch/x86/Makefile.um +++ b/arch/x86/Makefile.um @@ -60,4 +60,6 @@ ELF_FORMAT := elf64-x86-64 LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib64 LINK-y += -m64 +vdso-install-y += arch/x86/um/vdso/vdso.so.dbg + endif diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile index 8a7c8b37cb6e..7664cbedbe30 100644 --- a/arch/x86/um/vdso/Makefile +++ b/arch/x86/um/vdso/Makefile @@ -3,8 +3,6 @@ # Building vDSO images for x86. # -vdso-install-y += vdso.so - # files to link into the vdso vobjs-y := vdso-note.o um_vdso.o From 8aae2da6104ab98799b203c10cb3e0bd719fe02b Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 23 Mar 2026 10:17:14 -0700 Subject: [PATCH 08/10] um: Replace strncpy() with strnlen()+memcpy_and_pad() in strncpy_chunk_from_user() Replace the deprecated[1] strncpy() with strnlen() on the source followed by memcpy_and_pad(). This function is a chunk callback for UML's strncpy_from_user() implementation, called by buffer_op() to process userspace memory one page at a time. The source is a kernel-mapped userspace address that is not guaranteed to be NUL-terminated; "len" bounds how many bytes to read from it. By measuring the source string length first with strnlen(), we avoid reading past the NUL terminator in the source. memcpy_and_pad() then copies the string content and zero-fills the remainder of the chunk, preserving the original strncpy() behavior exactly: copy up to the first NUL, then pad with zeros to the full length. strtomem_pad() would be the idiomatic helper for this strnlen() + memcpy_and_pad() pattern, but it requires a compile-time-determinable destination size (via ARRAY_SIZE()). Here the destination is a char * into a caller-provided buffer and the chunk length is a runtime value, so the explicit two-step is necessary. No behavioral change: the same bytes are written to the destination (string content followed by zero padding), the pointer advances by the same amount, and the NUL-found return condition is unchanged. Link: https://github.com/KSPP/linux/issues/90 [1] Signed-off-by: Kees Cook Link: https://patch.msgid.link/20260323171713.work.839-kees@kernel.org Signed-off-by: Johannes Berg --- arch/um/kernel/skas/uaccess.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 198269e384c4..caef1deef795 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -170,8 +170,8 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) char **to_ptr = arg, *to = *to_ptr; int n; - strncpy(to, (void *) from, len); - n = strnlen(to, len); + n = strnlen((void *) from, len); + memcpy_and_pad(to, len, (void *) from, n, 0); *to_ptr += n; if (n < len) From 91e901c65b4da02a6fd543e3f0049829ae9645b7 Mon Sep 17 00:00:00 2001 From: Michael Bommarito Date: Wed, 8 Apr 2026 03:01:02 -0400 Subject: [PATCH 09/10] um: drivers: call kernel_strrchr() explicitly in cow_user.c Building ARCH=um on glibc >= 2.43 fails: arch/um/drivers/cow_user.c: error: implicit declaration of function 'strrchr' [-Wimplicit-function-declaration] glibc 2.43's C23 const-preserving strrchr() macro does not survive UML's global -Dstrrchr=kernel_strrchr remap from arch/um/Makefile. Call kernel_strrchr() directly in cow_user.c so the source no longer depends on the -D rewrite. Fixes: 2c51a4bc0233 ("um: fix strrchr() problems") Suggested-by: Johannes Berg Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito Link: https://patch.msgid.link/20260408070102.2325572-1-michael.bommarito@gmail.com [remove unnecessary 'extern'] Signed-off-by: Johannes Berg --- arch/um/drivers/cow_user.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 29b46581ddd1..dc1d1bcd85ec 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c @@ -15,6 +15,12 @@ #include "cow.h" #include "cow_sys.h" +/* + * arch/um/Makefile remaps strrchr to kernel_strrchr; call the kernel + * name directly to avoid glibc >= 2.43's C23 strrchr macro. + */ +char *kernel_strrchr(const char *, int); + #define PATH_LEN_V1 256 /* unsigned time_t works until year 2106 */ @@ -153,7 +159,7 @@ static int absolutize(char *to, int size, char *from) errno); return -1; } - slash = strrchr(from, '/'); + slash = kernel_strrchr(from, '/'); if (slash != NULL) { *slash = '\0'; if (chdir(from)) { From 6522fe5c1b007c376fc5f2de1016c99a18b0af8e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 8 Apr 2026 22:20:42 -0700 Subject: [PATCH 10/10] um: Disable GCOV_PROFILE_ALL on 32-bit UML with Clang 20/21 Clang 20 and 21 miscompute __builtin_object_size() when -fprofile-arcs is active on 32-bit UML targets, which passes incorrect object size calculations for local variables through always_inline copy_to_user() and check_copy_size(), causing spurious compile-time errors: include/linux/ucopysize.h:52:4: error: call to '__bad_copy_from' declared with 'error' attribute: copy source size is too small The regression was introduced in LLVM commit 02b8ee281947 ("[llvm] Improve llvm.objectsize computation by computing GEP, alloca and malloc parameters bound"), which shipped in Clang 20. It was fixed in LLVM by commit 45b697e610fd ("[MemoryBuiltins] Consider index type size when aggregating gep offsets"), which was backported to the LLVM 22.x release branch. The bug requires 32-bit UML + GCOV_PROFILE_ALL (which uses -fprofile-arcs), though the exact trigger depends on optimizer decisions influenced by other enabled configs. Prevent the bad combination by disabling UML's ARCH_HAS_GCOV_PROFILE_ALL on 32-bit when using Clang 20.x or 21.x. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202604030531.O6FveVgn-lkp@intel.com/ Suggested-by: Nathan Chancellor Assisted-by: Claude:claude-opus-4-6[1m] Signed-off-by: Kees Cook Link: https://patch.msgid.link/20260409052038.make.995-kees@kernel.org Signed-off-by: Johannes Berg --- arch/um/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 098cda44db22..d9541d13d9eb 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -11,7 +11,9 @@ config UML select ARCH_HAS_CACHE_LINE_SIZE select ARCH_HAS_CPU_FINALIZE_INIT select ARCH_HAS_FORTIFY_SOURCE - select ARCH_HAS_GCOV_PROFILE_ALL + # Clang 20 & 21 miscompute __builtin_object_size() under -fprofile-arcs + # on 32-bit, causing spurious compile-time errors in check_copy_size(). + select ARCH_HAS_GCOV_PROFILE_ALL if !(!64BIT && CLANG_VERSION >= 200000 && CLANG_VERSION < 220100) select ARCH_HAS_KCOV select ARCH_HAS_STRNCPY_FROM_USER select ARCH_HAS_STRNLEN_USER