[BUG] kernel/nstree: listns stops at an inactive cursor entry
From: shaos
Date: Tue Oct 20 2026 - 07:17:04 EST
Hello,
The cursor-based listns() path can return ENOENT at an inactive namespace even when a later active namespace is still visible and listable. A caller continuing pagination can therefore stop early and miss later namespaces.
The PoC creates a user namespace and pins it in the namespace tree with a memfd passed to a surviving process. After the creator exits, the namespace becomes inactive but remains the first tree entry after the cursor. A later active user namespace is present. Plain listns(0) omits the inactive ID and includes the later ID, while listns(cursor=inactive_id-1) returns ENOENT; advancing the cursor to inactive_id returns the later namespace.
The normal list iteration skips inactive entries, but lookup_ns_id_at()/lookup_ns_owner_at() apply ns_get_unless_inactive() to only the first cursor match, and the syscall treats NULL as end-of-list.
HEAD commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
source version: Linux 7.3.0-rc7
architecture: x86-64
compiler: gcc 11.4.0, GNU ld 2.38
QEMU: 6.2.0
console output: https://gist.githubusercontent.com/shaos26/7832f4370119799cac6c493e6984e107/raw/41d7d989d2b28afa92d6a11989e218224e175647/console-output.txt
kernel config: https://gist.githubusercontent.com/shaos26/7832f4370119799cac6c493e6984e107/raw/3cd943ba8c6026b43ef016a37d07efd2533a317a/kernel-config.txt
reproducer: https://gist.githubusercontent.com/shaos26/7832f4370119799cac6c493e6984e107/raw/7cb61c70f803fcf46edb4ec185a5c526553b9c6b/poc.c
Build the kernel from the revision above with the attached config. Build poc.c as a static init program, place it at /init in an initramfs, and boot a fresh guest with:
timeout 120 qemu-system-x86_64 -m 2G -smp 2 -machine q35 \
-kernel artifacts/bzImage -initrd artifacts/probe-initramfs.cpio.gz \
-append "console=ttyS0 rdinit=/init panic=-1 oops=panic nokaslr loglevel=6 probe=listns" \
-nographic -no-reboot
Two fresh positive replays and an active-cursor control produced the expected results. This is an enumeration correctness issue; the PoC does not demonstrate a namespace permission bypass or escape. The affected lookup logic is unchanged in upstream master f47d223627f8; runtime validation was on v7.3-rc7.
Thanks,
shaos