diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-27 12:08:22 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-27 12:08:22 -1000 |
| commit | 7d1f84f1b94e79cb95d974ab3ec54cb3a4d64f5b (patch) | |
| tree | 1055fc0d54d44122acbff64e0752747a03722bf3 /tools/testing | |
| parent | 83f32c773255720a661aa45d83e36278135f23f5 (diff) | |
| parent | b6232ca8d194c60ee603586e42b5ea584d4b7be9 (diff) | |
Merge tag 'mm-nonmm-stable-2026-10-25-14-57' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull non-MM updates from Andrew Morton:
- "ocfs2: exit recovery thread on mount error path" (Joseph Qi):
Stop OCFS2 recovery before freeing failed-mount state and replay
slots, closing use-after-free and double-free races. Defer
suballocator reclaim to break a transaction-lock deadlock with
dismount.
- "ocfs2: validate suballoc slot and bit of metadata blocks" (Joseph
Qi):
Validate OCFS2 metadata suballocator slots, bits and directory index
block locations. Reject corrupt metadata with filesystem errors
instead of BUGs or out-of-bounds accesses.
- "ocfs2: deal with legacy signed name hash values" (Joseph Qi):
Restore OCFS2 lookups for non-ASCII names stored with legacy signed
hashes. Use stored xattr hashes during bucket splits to avoid
duplicate entries and spurious ENOSPC failures.
- "ocfs2: stabilize dentry names in file and setattr traces" (Cen
Zhang):
Snapshot OCFS2 names during file and setattr tracing to prevent
rename races using freed storage or mismatched names and lengths.
Preserve trace formats and the locked release open-count sample.
- "panic: fix panic_force_cpu= redirect races and NMI bypass" (Bradley
Morgan):
Fix panic_force_cpu races and NMI redirection so crash-kernel CPU
selection is honored. Preserve variable arguments on failed redirects
and use a static message buffer.
- "fat: allocate multiple clusters in fallocate" (Matheus Alves de
Almeida):
Allocate FAT clusters in batches for FALLOC_FL_KEEP_SIZE and batch
FAT updates. This removes repeated single-cluster allocation
overhead, particularly on synchronous mounts.
- "scripts/gdb: fix radix tree lookup and stack depot diagnostic"
(Ting-Han Hou):
Fix GDB radix-tree lookup and its handling of XArray sibling, retry
and zero entries. Also repair the stack-depot diagnostic for an
out-of-range pool index.
- "hung_task: Improve warning budget handling and task reporting"
(Aaron Tomlin):
Reset the hung-task warning budget after recovery so later hangs
remain visible. Keep the configured limit intact and emit one summary
per scan when detailed reports exhaust the budget.
- "bootconfig: Reject unexpected data after null character and
cleanups" (Masami Hiramatsu):
Reject bootconfig data after an embedded null while accepting
trailing padding. Validate the full input in the userspace tool, and
retain internal tree sanity checks there rather than in the kernel.
- "kbuild: GCOV cleanups following the prefer-atomic fix" (Konstantin
Khorenko):
Use the actual GCOV build flags in the prefer-atomic compiler probe.
Move flag setup into scripts/Makefile.gcov and skip the probe when
GCOV is disabled.
- "ocfs2: xattr bucket validation fixes" (Joseph Qi):
Accept valid OCFS2 xattr buckets spanning 512-byte blocks, avoiding
false read-only remounts. Reject misaligned buckets and return errors
instead of panicking on corrupt defrag metadata.
- "ocfs2: fix metadata reservation for xattr value trees" (Joseph Qi):
Reserve enough OCFS2 metadata for new and relocated xattr value
trees. Fix shortfalls which could cause ENOSPC, dropped entries and
leaked clusters on fragmented filesystems; remove duplicate
reservations.
- "Introduce arch_do_panic" (Mete Durlu):
Add arch_do_panic() and move s390 and sparc handling out of generic
panic code. The architecture-specific actions now follow the
end-of-panic marker.
- "checkpatch: userspace improvements" (Petr Vorel):
Improve checkpatch's userspace detection and suppress kernel-only
checks. Recognize standard inttypes macros and add explicit
--userspace and --no-userspace overrides.
- "ocfs2: validate dr_fs_generation of dir index root blocks" (Joseph
Qi):
Check OCFS2 directory index generations and leaf block numbers.
Reject stale or misplaced blocks instead of using metadata left by a
previously formatted filesystem.
- "selftests/membarrier: Skip an unregistered memory barrier test on
Musl" (Chris Gellermann):
Skip the unregistered membarrier test when libc has already
registered the command. Musl does this during thread creation,
causing false failures in the multithreaded test.
- "init: fix array boundary bugs in boot parameter parsing"
(Wilson Felipe Pereira):
Fix boot argument boundary cases which leave stale arguments in
init's command line or panic when replacing the final environment
variable. Clear the last slot and check duplicates before the limit.
Summary of the 87 singletons in this merge:
The OCFS2 singletons fix deadlocks between xattr updates and inline
truncation, and during inode reclaim. Corrupt quota and extent
metadata could also crash the kernel or corrupt memory; these paths
now check the layout before using it. Other fixes close use-after-free
and publication races around cluster reconfiguration, node failure,
quota remount errors and shared refcount trees. New files now retain
security labels from all stacked LSMs instead of silently dropping all
but one. Valid xattr insertions also stop tripping FORTIFY on builds
with counted arrays.
Elsewhere, a lost wakeup could leave hardware-monitoring reads stuck
in unkillable sleep and block further I2C traffic. That is fixed, as
are kernel memory leaks in POSIX message-queue notifications and tmpfs
casefold setup which could grow until memory is exhausted. A driver
removal race which could crash the kernel is fixed too. The
hibernation command through reboot() also stops taking the same mutex
twice, avoiding a deadlock before suspension.
On the boot side, bzip2 decoding now accepts valid full blocks emitted
by lbzip2, fixing failures to boot those compressed kernels. Malformed
bzip2 streams can no longer overflow the decode buffer, and LZ4
initrds are checked before the decoder can read past their end. FAT
rejects geometry which overflows the data-area calculation on 32-bit
systems, and rolls back entries when inode setup fails, preventing
failed creations from reappearing after remount. The x86 XOR and RAID6
AVX paths also avoid imposing a slowdown on subsequent SSE code.
* tag 'mm-nonmm-stable-2026-10-25-14-57' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (134 commits)
scripts/gdb: fix stack depot out-of-bounds diagnostic
scripts/gdb: fix radix tree lookup pointer handling
ocfs2/cluster: remove zero-address nodes from IP tree on teardown
ocfs2: snapshot the dentry name while tracing file release
ocfs2: snapshot dentry names in file and setattr traces
ocfs2/dlm: drain join handlers before releasing module text
MAINTAINERS: update Markus's e-mail address
mailmap: add entries for Andrew Jones
stackdepot: stop preallocating after the final pool
ocfs2: drain quorum work before removing the cluster
watchdog: force console verbose when reporting lockups
profiling: fix sampling step on 64-bit big-endian systems
kernel/reboot: avoid potential deadlocks during suspension
compat: avoid double rounding in times()
ocfs2: pin owning modules for open debugfs files
ocfs2/cluster: initialize heartbeat regions before publishing them
selftests/proc: proc-pid-vm: fix unused variable warning on non-x86
ocfs2: pin refcount trees before dropping the lookup lock
ocfs2: validate the xattr tree root of an indexed xattr block
ocfs2/dlm: hold the lookup reference across convert AST enqueue
...
Diffstat (limited to 'tools/testing')
| -rw-r--r-- | tools/testing/selftests/core/unshare_test.c | 19 | ||||
| -rw-r--r-- | tools/testing/selftests/filelock/ofdlocks.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c | 32 | ||||
| -rw-r--r-- | tools/testing/selftests/membarrier/membarrier_test_impl.h | 17 | ||||
| -rw-r--r-- | tools/testing/selftests/proc/proc-pid-vm.c | 14 |
5 files changed, 60 insertions, 24 deletions
diff --git a/tools/testing/selftests/core/unshare_test.c b/tools/testing/selftests/core/unshare_test.c index ffce75a6c228..d40e963dd520 100644 --- a/tools/testing/selftests/core/unshare_test.c +++ b/tools/testing/selftests/core/unshare_test.c @@ -40,6 +40,14 @@ TEST(unshare_EMFILE) ASSERT_EQ(sscanf(buf, "%d", &nr_open), 1); + /* + * Cap nr_open for the duration of the test to avoid ENOMEM from a + * huge fd table allocation; buf/n keep the real original value so + * fs.nr_open can be restored to it once the test is done. + */ + if (nr_open > 1024 * 1024) + nr_open = 1024 * 1024; + ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &rlimit)); /* bump fs.nr_open */ @@ -73,10 +81,13 @@ TEST(unshare_EMFILE) if (pid == 0) { int err; + char buf3[32]; + ssize_t n3; - /* restore fs.nr_open */ + /* restore fs.nr_open to the (possibly capped) test baseline */ + n3 = sprintf(buf3, "%d\n", nr_open); lseek(fd, 0, SEEK_SET); - write(fd, buf, n); + write(fd, buf3, n3); /* ... and now unshare(CLONE_FILES) must fail with EMFILE */ err = unshare(CLONE_FILES); EXPECT_EQ(err, -1) @@ -89,6 +100,10 @@ TEST(unshare_EMFILE) EXPECT_EQ(waitpid(pid, &status, 0), pid); EXPECT_EQ(true, WIFEXITED(status)); EXPECT_EQ(0, WEXITSTATUS(status)); + + /* restore the real fs.nr_open value */ + lseek(fd, 0, SEEK_SET); + write(fd, buf, n); } TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/filelock/ofdlocks.c b/tools/testing/selftests/filelock/ofdlocks.c index 68bac28b234b..0ab484cb075b 100644 --- a/tools/testing/selftests/filelock/ofdlocks.c +++ b/tools/testing/selftests/filelock/ofdlocks.c @@ -40,7 +40,7 @@ int main(void) int fd2 = open("/tmp/aa", O_RDONLY); ksft_print_header(); - ksft_set_plan(4); + ksft_set_plan(5); unlink("/tmp/aa"); assert(fd != -1); diff --git a/tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c b/tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c index 81a994943e12..b4dcbcd79773 100644 --- a/tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c +++ b/tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c @@ -74,6 +74,24 @@ static void *waiter_entry1ap(void *data) return NULL; } +static void *waiter_entry1ap_loop(void *data) +{ + struct pollfd pfd; + struct epoll_event e; + struct epoll_mtcontext *ctx = data; + + pfd.fd = ctx->efd[0]; + pfd.events = POLLIN; + while (poll(&pfd, 1, 2000) > 0) { + if (epoll_wait(ctx->efd[0], &e, 1, 0) > 0) { + __sync_fetch_and_add(&ctx->count, 1); + break; + } + } + + return NULL; +} + static void *waiter_entry1o(void *data) { struct epoll_event e; @@ -809,7 +827,7 @@ TEST(epoll16) ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0); ctx.main = pthread_self(); - ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0); + ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap_loop, &ctx), 0); ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0); if (epoll_wait(ctx.efd[0], events, 1, -1) > 0) @@ -2925,7 +2943,7 @@ TEST(epoll56) ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0); ctx.main = pthread_self(); - ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0); + ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap_loop, &ctx), 0); ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0); if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0) @@ -3030,7 +3048,6 @@ TEST(epoll57) TEST(epoll58) { pthread_t emitter; - struct pollfd pfd; struct epoll_event e; struct epoll_mtcontext ctx = { 0 }; @@ -3061,15 +3078,10 @@ TEST(epoll58) ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0); ctx.main = pthread_self(); - ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0); + ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap_loop, &ctx), 0); ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0); - pfd.fd = ctx.efd[0]; - pfd.events = POLLIN; - if (poll(&pfd, 1, -1) > 0) { - if (epoll_wait(ctx.efd[0], &e, 1, 0) > 0) - __sync_fetch_and_add(&ctx.count, 1); - } + waiter_entry1ap_loop(&ctx); ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0); EXPECT_EQ(ctx.count, 2); diff --git a/tools/testing/selftests/membarrier/membarrier_test_impl.h b/tools/testing/selftests/membarrier/membarrier_test_impl.h index f6d7c44b2288..b4dcbb32538d 100644 --- a/tools/testing/selftests/membarrier/membarrier_test_impl.h +++ b/tools/testing/selftests/membarrier/membarrier_test_impl.h @@ -16,6 +16,11 @@ static int sys_membarrier(int cmd, int flags) return syscall(__NR_membarrier, cmd, flags); } +static int membarrier_get_registrations(void) +{ + return sys_membarrier(MEMBARRIER_CMD_GET_REGISTRATIONS, 0); +} + static int test_membarrier_get_registrations(int cmd) { int ret, flags = 0; @@ -24,7 +29,7 @@ static int test_membarrier_get_registrations(int cmd) registrations |= cmd; - ret = sys_membarrier(MEMBARRIER_CMD_GET_REGISTRATIONS, 0); + ret = membarrier_get_registrations(); if (ret < 0) { ksft_exit_fail_msg( "%s test: flags = %d, errno = %d\n", @@ -108,6 +113,16 @@ static int test_membarrier_private_expedited_fail(void) int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0; const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure"; + /* + * Some C libraries, like Musl, register the private expedited barrier + * command when creating a thread. Expecting an EPERM on an unregistered + * command will therefore no longer work. Skip the test in this case. + */ + if (MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED & membarrier_get_registrations()) { + ksft_test_result_skip("%s test: Command already registered\n", test_name); + return 0; + } + if (sys_membarrier(cmd, flags) != -1) { ksft_exit_fail_msg( "%s test: flags = %d. Should fail, but passed\n", diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index 4e6a3e53f975..98e882e56815 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c @@ -47,10 +47,6 @@ #include <sys/resource.h> #include <linux/fs.h> -#ifndef __maybe_unused -#define __maybe_unused __attribute__((__unused__)) -#endif - #include "kselftest.h" static inline long sys_execveat(int dirfd, const char *pathname, char **argv, char **envp, int flags) @@ -214,7 +210,6 @@ static int make_exe(const uint8_t *payload, size_t len) return fd1; } -#endif /* * 0: vsyscall VMA doesn't exist vsyscall=none @@ -222,15 +217,14 @@ static int make_exe(const uint8_t *payload, size_t len) * 2: vsyscall VMA is r-xp vsyscall=emulate */ static volatile int g_vsyscall; -static const char *str_vsyscall __maybe_unused; +static const char *str_vsyscall; -static const char str_vsyscall_0[] __maybe_unused = ""; -static const char str_vsyscall_1[] __maybe_unused = +static const char str_vsyscall_0[] = ""; +static const char str_vsyscall_1[] = "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]\n"; -static const char str_vsyscall_2[] __maybe_unused = +static const char str_vsyscall_2[] = "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; -#ifdef __x86_64__ static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___) { _exit(g_vsyscall); |
