summaryrefslogtreecommitdiff
path: root/fs/exec.c
AgeCommit message (Collapse)Author
11 daysMerge tag 'vfs-7.4-rc1.sync_close' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull file closing updates from Christian Brauner: "This makes closing files synchronous for close_range(), exec and exit. Since fput() was switched to task work every final __fput() of an exiting task is queued on task work and run from exit_task_work(). exec and close_range() do the same. For a task with a large descriptor table that is a cmpxchg() and a TIF_NOTIFY_RESUME test-and-set per file plus a list entry for any later task_work_cancel() to search under pi_lock, and then a second pass over every struct file that isn't cache hot anymore by then. Oleg and Neil have pointed this out over the years. close_files(), close_range() and close-on-exec now flush and put each file inline the way close(2) does. Kernel threads aren't affected. They share init_files which init_task pins forever so their exit_files() never drops the last reference, and their fput() keeps punting to a workqueue. The one place that could put a table from a kthread context, a failing copy_process(), can't hold the last reference while the source table is alive. On a 64 vCPU KVM guest tearing down 4096, 65536 and 1M descriptors scattered at random positions in the table: 4096 fds 65536 fds 1M fds exit 1045 -> 895 us 18.9 -> 14.9 ms 429 -> 306 ms execve, close-on-exec 1393 -> 1190 us 21.4 -> 16.9 ms 471 -> 325 ms close_range() 1179 -> 988 us 21.9 -> 17.4 ms 484 -> 337 ms So that is 16-21% or 40-150 ns per closed file, largest at 1M descriptors. With eight processes tearing down 65536 descriptors each at once it stays at 16-21% because the second pass over 16 MB of struct file is what gets expensive when CPUs compete for the cache. With 32 or 64 processes both kernels are bound by pushing millions of files through slab and rcu and the difference shrinks to 4-8%. Files whose own release dominates gain less, 13% for eventfds, 11% for pipes, 6% for AF_UNIX sockets. close(2) is untouched and will-it-scale is within 2%. The spufs coredump support is removed. It was the only reason do_coredump() unshared the descriptor table. gdb dropped Cell debugging in 9.1 and binutils in 2.34, the Cell blades are gone and nothing on the PlayStation 3 produces or reads these notes. With that unshare_files() goes away, exec installs its private table through the new switch_files_struct() and the coredump startup completion becomes a plain thread count waited on with the new wait_var_event_state(). Three fixes for the synchronous close are included. A failed fork released its files under scx_fork_rwsem and deadlocked against the bpf link's release. A session leader's exit released its tty before disassociate_ctty() ran and the foreground job lost its SIGHUP, so the tty is hung up before the files are closed now. And descriptor tables are walked from the highest descriptor down which restores the order the deferred puts had and keeps a few long-standing release ordering bugs from deadlocking exit" * tag 'vfs-7.4-rc1.sync_close' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fs: close files from the highest descriptor down coredump: factor out coredump_wait_inactive() exit: hang up the tty before closing the files fork: release the files of a failed fork after sched_cancel_fork() coredump: replace the startup completion with a thread count sched: add wait_var_event_state() coredump: drop core_state->dumper fs: make close_cloexec_files() synchronous fs: rename do_close_on_exec() to close_cloexec_files() fs: make close_range() synchronous fs: make close_files() synchronous fs: add filp_close_sync() fs: remove unshare_files() fs: move unshare_fd() to fs/file.c fs: add switch_files_struct() coredump: stop unsharing the file descriptor table fs: don't open-code file_close_fd() in close_fd() powerpc: remove coredump support
12 daysMerge tag 'vfs-7.4-rc1.idmap' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs idmap constification from Christian Brauner: "This makes struct mnt_idmap const throughout the tree. A mount's idmapping is immutable. The only thing modified after alloc_mnt_idmap() is the reference count and that is hidden behind mnt_idmap_get() and mnt_idmap_put(). Everything else only reads from it. That is the same model struct cred uses and the idmapping is sensitive enough to deserve it. The conversion goes bottom up through the vfs{g,u}id and fs{g,u}id helpers, the privilege checks, acl, xattr and quota and then every inode operation that takes an idmap, so ->permission(), ->getattr(), ->setattr(), ->create(), ->mkdir(), ->mknod(), ->symlink(), ->rename(), ->tmpfile(), ->get_acl(), ->set_acl() and ->fileattr_set() with their implementations in every filesystem, plus the LSM hooks. struct vfsmount, struct mount_kattr and struct kstatmount store a const pointer and nop_mnt_idmap and invalid_mnt_idmap live in rodata, so anything that tries to modify them faults instead of silently corrupting the initial idmapping" * tag 'vfs-7.4-rc1.idmap' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (27 commits) fs: make nop_mnt_idmap and invalid_mnt_idmap const fs: port mnt_idmap() and file_mnt_idmap() to const mnt_idmap fs: port vfs_*() helpers to const mnt_idmap fs: port ->setattr() to pass const mnt_idmap fs: port ->getattr() to pass const mnt_idmap fs: port ->create() to pass const mnt_idmap fs: port ->symlink() to pass const mnt_idmap fs: port ->mkdir() to pass const mnt_idmap fs: port ->rename() to pass const mnt_idmap fs: port ->mknod() to pass const mnt_idmap fs: port ->tmpfile() to pass const mnt_idmap fs: port ->get_acl() to pass const mnt_idmap fs: port ->set_acl() to pass const mnt_idmap fs: port ->fileattr_set() to pass const mnt_idmap fs: port xattr to const mnt_idmap fs: port ->permission() to pass const mnt_idmap fs: port acl to const mnt_idmap fs: port inode_init_owner() to const mnt_idmap fs: port inode_owner_or_capable() to const mnt_idmap fs: port privilege checking helpers to const mnt_idmap ...
12 daysMerge tag 'kernel-7.4-rc1.signal' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull signal handling updates from Christian Brauner: "This stops TIF_NOTIFY_SIGNAL from interrupting work that can't be restarted and fixes a bunch of coredump and signal bugs. TIF_NOTIFY_SIGNAL kicks a task out of an uninterruptible sleep so it returns to userspace, runs its task work and goes back to sleep. That breaks coredumps: dump_interrupted() only lets fatal signals interrupt a dump and writes to a regular file ignore TIF_NOTIFY_SIGNAL. But the pipe and the socket paths check signal_pending() Adeep down in code that is shared with regular syscalls and bail. So a crashing process with io_uring requests in flight loses most of its coredump. In the selftest an unfixed kernel delivers 357324 of at least 5111808 bytes. And io_uring isn't the only source. klp_send_signals(), bpf_task_work_schedule_signal(), landlock's tsync, kthread_stop() and the printk kunit test raise the bit as well, some of them from irq context against any task. So this can't be fixed per subsystem and the state has to be per-task and ambient. Add PF_NO_NOTIFY_SIGNAL and no_notify_signal_save()/restore() helpers modelled on memalloc_nofs_save(). Inside such a section signal_pending() ignores TIF_NOTIFY_SIGNAL. Coredumps, the smb send path, which hand-rolled its own version of this, and the pid namespace reaper, which busy-looped when the bit kept getting raised, are converted. The second part is a set of fixes that fell out of looking at the coredump code with kres and modelling it in TLA+: - coredump_finish() woke the parked threads without holding rcu. A parked thread can exit on a spurious wakeup and be freed before wake_up_process() takes its pi_lock. - Only SIGKILL and the freezers interrupt a dump now and the three freezers agree. Power management and cgroup v1 freezing aborted a dump while a cgroup v2 freeze either waited for the dump or cut it short depending on where the core went. - io-wq set its exit bit without a barrier against the task work that creates workers. On weakly ordered architectures exit could hang on worker_done. - retarget_shared_pending() slingshotted a shared signal to the dumper when a zapped sibling restored its signal mask. That set TIF_SIGPENDING on the dumper and truncated the core. - A tracer could clear the signal mask of a user worker with PTRACE_SETSIGMASK and inject a coredump signal. An io-wq worker of an SQPOLL ring dumping core deadlocks the whole group. PTRACE_SETSIGMASK is refused for user workers now and __set_task_blocked() enforces the fork-time mask. - exec cancels io_uring requests before de_thread() so a worker creation queued as task work can't add a thread to a thread group that de_thread() just took down. - No io threads are created from a PF_SIGNALED or PF_POSTCOREDUMP creator anymore. Such a worker was invisible to zap_process() but still decremented threads_remaining on exit so the dumper could leave coredump_wait_inactive() early. Also included are a comment that do_each_pid_task() needs tasklist_lock, a READ_ONCE() in pid_alive() and a regression test for fork() into a pid namespace whose ancestor lost its init" * tag 'kernel-7.4-rc1.signal' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (21 commits) pid: use READ_ONCE() in pid_alive() selftests: pid_namespace: test fork with dead ancestor pid: document that do_each_pid_task() needs tasklist_lock signal: enforce the user worker signal mask in __set_task_blocked() fork: use SIG_KERNEL_ONLY_MASK for the user worker signal mask fork: don't create io threads once PF_POSTCOREDUMP is set fork: move the coredump and exec checks into create_io_thread() exec: cancel io_uring requests before de_thread() selftests/coredump: expect PTRACE_SETSIGMASK to be refused on a user worker selftests/coredump: test a user worker as the coredumping thread ptrace: refuse to change the signal mask of a user worker selftests/coredump: test shared signal retargeting during a dump signal: only SIGKILL and the freezers interrupt a coredumping task signal: don't retarget shared signals in a dying thread group io-wq: order the exit bit against worker creation task work coredump: hold RCU while releasing parked threads pid_namespace: prevent TIF_NOTIFY_SIGNAL from interrupting the reaper smb: prevent TIF_NOTIFY_SIGNAL from interrupting selftests/coredump: test that TIF_NOTIFY_SIGNAL doesn't truncate a coredump coredump: prevent TIF_NOTIFY_SIGNAL from interrupting coredumps ...
2026-10-05fs: make close_cloexec_files() synchronousChristian Brauner
Punting file closing to task work during exec slows down exec significantly when its done with a bunch of file descriptors. We can do this in-band instead. Flush already runs synchronous. Jann moved close-on-exec in e780259b54e6 ("exec: do_close_on_exec() before taking exec_update_lock") outside of exec_update_lock. The only lock that's still held now is cred_guard_mutex. It's deprecated and has five takers (1) exec (2) ptrace_attach() (3) seccomp() with SECCOMP_FILTER_FLAG_TSYNC (4) writes to /proc/<pid>/attr/* (5) lsm_set_self_attr() Four of them take the task's own cred_guard_mutex. When close_cloexec_files() runs, de_thread() ensured that the calling task is the only one alive in its thread-group. That leaves ptrace() waiting on cred_guard_mutex of the tracee going through exec. exec already sleeps under cred_guard_mutex in de_thread() when it reads binary and interpreter. So while we add wait-time to an attaching ptracer no new lock dependency is added. vfork() als waits but that's a dup_fd() copy of the fdtable and rarely holds the last reference. If that's an issue we can always change that later. Link: https://lore.kernel.org/CAGudoHEsGP1P+sAWaw_tbh1NesJhSeww8869uzmaqtgk8F43=Q@mail.gmail.com Link: https://patch.msgid.link/20260910-work-coredump-unlock-self-v4-9-a5c1800dc930@kernel.org Reviewed-by: NeilBrown <neil@brown.name> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-05fs: rename do_close_on_exec() to close_cloexec_files()Christian Brauner
Rename the helper and align it with close_files(). No functional changes. Link: https://patch.msgid.link/20260910-work-coredump-unlock-self-v4-8-a5c1800dc930@kernel.org Reviewed-by: NeilBrown <neil@brown.name> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-05fs: remove unshare_files()Christian Brauner
exec is the only caller left since commit 433967cab51e ("coredump: stop unsharing the file descriptor table"). All it does is call unshare_fd() with CLONE_FILES and install the copy. Kill the pointless helper and open-code it. No functional changes. Link: https://patch.msgid.link/20260910-work-coredump-unlock-self-v4-4-a5c1800dc930@kernel.org Reviewed-by: NeilBrown <neil@brown.name> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-23fs: port mnt_idmap() and file_mnt_idmap() to const mnt_idmapChristian Brauner
Now that everything takes a mnt_idmap as const store a const pointer in struct vfsmount, struct mount_kattr and struct kstatmount and return one from mnt_idmap(), file_mnt_idmap() and ovl_upper_mnt_idmap(). Finally, also make mnt_idmap_get() return a const pointer. Also convert the remaining local variables that are initialized from the accessors. alloc_mnt_idmap() keeps returning a non-const pointer. It is the only place where an idmapping is actually written to. Link: https://patch.msgid.link/20260901-work-idmap-const-v1-26-54ccd48e100b@kernel.org Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Seth Forshee <sforshee@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-22exec: cancel io_uring requests before de_thread()Christian Brauner
begin_new_exec() cancels the exec'ing thread's io_uring requests after de_thread() made it the only thread in the thread-group. Now io_uring_task_cancel() runs task work after. If it runs a create_worker_cb() item then a io-wq queued on the thread before the exec creates a new io-wq worker thread. Said thread joins the thread-group which de_thread() just took down. The io-iwq sticks around until it notices that its workqueue is dying. But code after de_thread() relies on being single-threaded. Move io_uring_task_cancel() before de_thread() but behind the point of no return. Any worker created during task work run from io_uring_task_cancel() is just a sibling thread that de_thread() will take down and reap. Once io_uring_task_cancel() returned the thread has neither a task context nor a workqueue left so nothing can add a thread behind de_thread()'s back anymore. Suggested-by: Oleg Nesterov <oleg@redhat.com> Link: https://lore.kernel.org/r/aq0_lvHDViIpX_Mu@redhat.com Fixes: 3bfe6106693b ("io-wq: fork worker threads from original task") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260921-work-coredump-fixes-v3-12-8e4adb1619e6@kernel.org Acked-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-22sched/cache: Introduce task_struct->sched_cache_grp to fix UAFTim Chen
Add a sched_cache_grp pointer to task_struct so that scheduler code can access the cache group directly via the task, without going through mm->sched_cache_grp. This decouples the scheduler's hot-path accesses from the mm_struct. Each task holds its own refcount on the sched_cache_group, separate from the reference held by its mm_struct. The reference is acquired in copy_mm() (fork) and exec_mmap() (exec), and released in exit_mm(). This fixes the use-after-free when account_mm_sched() reaches the group through a task whose mm is being switched, as reported by Hyunwoo: https://lore.kernel.org/lkml/apPb-Dr4nPYuHQOK@v4bel/ Convert all scheduler code in fair.c and exit.c to use p->sched_cache_grp instead of p->mm->sched_cache_grp. Keep the fork/exec/exit reference management out of the generic mm paths: add sched_cache_fork(), sched_cache_fork_cleanup(), sched_cache_exec_mmap() and sched_cache_exit_mm() in kernel/sched/cache_sched.c (with empty stubs for !CONFIG_SCHED_CACHE), so fs/exec.c, kernel/fork.c and kernel/exit.c each call one helper instead of open-coding the refcounting under #ifdef. Also add sched_cache_group_get() and task_cache_group_get(). Fixes: df0d98475954 ("sched/cache: Introduce infrastructure for cache-aware load balancing") Closes: https://lore.kernel.org/lkml/apPb-Dr4nPYuHQOK@v4bel/ Closes: https://lore.kernel.org/all/343a7e07-7fad-4979-9c9b-82ec038c293c@linux.dev/ Reported-by: Hyunwoo Kim <imv4bel@gmail.com> Reported-by: Zenghui Yu (Huawei) <zenghui.yu@linux.dev> Co-developed-by: Chen Yu <yu.c.chen@intel.com> Signed-off-by: Chen Yu <yu.c.chen@intel.com> Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: <stable@kernel.org> #7.2.x Link: https://patch.msgid.link/ae7081dc54736bf115215f9867abb2711a7403fb.1790035273.git.tim.c.chen@linux.intel.com
2026-09-16exec: Cleanup POSIX timers right after de_thread()Hyunwoo Kim
A per-thread CPU timer holds a reference to the PID of the thread it is attached to and, while it is armed, its node is queued in that thread's posix_cputimers. The task is looked up by that PID. When a non-leader thread exec()s, de_thread() changes which task owns that PID. pid_task(timer->it.cpu.pid, PIDTYPE_PID) then returns NULL, but the node is still queued on tsk, which is alive. timer_lock_sighand() takes a failed lookup to mean that the node is already dequeued, so it has nothing to undo. begin_new_exec() calls posix_cpu_timers_exit(me) right after exec_task_namespaces() and that removes the leftover node, so the state normally stays invisible. But bprm->point_of_no_return is set before de_thread(), so if unshare_files(), set_mm_exe_file(), exec_mmap() or exec_task_namespaces() fails, the task dies before it gets there. exit_itimers() then frees the k_itimer while its node is still queued, and reaping tsk later erases that freed node from the rbtree. In short: the non-leader thread B the parent timer_create(CLOCK_THREAD_CPUTIME_ID) timer_settime() arm_timer() // the node is queued on B execve() de_thread(B) exchange_tids(B, leader) // B's PID now belongs to the leader release_task(leader) __exit_signal(leader) posix_cpu_timers_exit(leader) // cleans leader's queue, not B's __unhash_process(leader) // that PID has no task anymore exec_mmap() mmap_read_lock_killable(old_mm) kill(B, SIGKILL) // -EINTR get_signal() do_exit() exit_itimers() posix_timer_delete() posix_cpu_timer_del() posix_timer_unhash_and_free() // freed while still queued wait4() release_task(B) posix_cpu_timers_exit(B) cleanup_timerqueue() timerqueue_del() // use-after-free Move the POSIX timer cleanup right after de_thread() before any of the later failure conditions brings the task into do_exit(). [ tglx: Move the cleanup right after de_thread() ] Fixes: 55e8c8eb2c7b ("posix-cpu-timers: Store a reference to a pid not a task") Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Tested-by: Kijo Park <red993688@gmail.com> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Frederic Weisbecker <frederic@kernel.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/ao7Q8miiuLAPVnWv@v4bel Link: https://patch.msgid.link/20260911090541.627712075@kernel.org
2026-09-09Merge tag 'vfs-7.3-rc3.fixes' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs fixes from Christian Brauner: - netfs: - Fix an uninitialized return value in netfs_unbuffered_write() when preparing the first subrequest fails - For partial unbuffered/DIO writes return the amount transferred rather than an error - Update i_size with the amount actually written when a partial transfer ends in an error - Fix a subrequest reference leak when the io_iter ends up empty - Handle netfs_alloc_subrequest() failure during unbuffered writes - Load all readahead folios into the rolling buffer upfront and drop the readahead references once the first subrequest is dispatched - Mark folios for copy-to-cache while issuing subrequests - Fix read progress reporting - afs: - Add the missing kunmap in the error path of afs_dir_search_bucket() - Fix a double kunmap in afs_edit_dir_remove() - Don't free an existing server's endpoint state when cleaning up a candidate server in afs_lookup_server() - Unbind peers removed from a server's address list - ufs: - Load the cylinder group metadata before creating the root dentry - Validate the cylinder group index and rotor positions before caching them - Treat an unreadable directory block as not empty - exec: - Close the close-on-exec files before taking exec_update_lock Closing a file can block on the filesystem, so a hung filesystem blocked everything that takes exec_update_lock and a FUSE server inspecting the calling process could deadlock - Drop the bprm loader before closing bprm->file in free_bprm() - exit: Hold a reference to thread_pid across proc_flush_pid() - reboot: Fix a use-after-free on cad_pid - nsfs: Keep the namespace tree fields out of the rcu_head used by kfree_rcu() - nstree: Check listing permission before taking a namespace reference in listns() - super: Return 0 when a nested thaw drops its hold while other freezers remain - ext4: Don't set I_METADATA_WRITEBACK during fastcommit replay - adfs: Free s_fs_info in ->kill_sb() - autofs: Free the inode info allocated in autofs_fill_super() when the root inode allocation fails - ovl: Return EINVAL instead of EIO on a user namespace mismatch now that it's a plain refusal and not an internal error - cachefiles: Don't cast the variable-length coherency data to a __be64 in the coherency tracepoint * tag 'vfs-7.3-rc3.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (28 commits) nstree: check listing permission before taking a namespace reference exec: do_close_on_exec() before taking exec_update_lock exit: hold a reference to thread_pid across proc_flush_pid fs: autofs: fix memory leak in autofs_fill_super() exec: Drop bprm loader before closing bprm->file afs: Clear stale peer app data after address list changes afs: Fix incorrect free in candidate cleanup in afs_lookup_server() afs: Fix double-unmap of directory block afs: Fix missing kunmap in afs_dir_search_bucket() ovl: return EINVAL instead of EIO in case of mismatched user_ns reboot: fix cad_pid use-after-free race cachefiles: Fix potential UAF/KASAN warning netfs: Fix read progress reporting netfs: Mark folios with COPY_TO_CACHE whilst issuing subreqs netfs: Fix readahead synchronisation issues by loading all folios upfront netfs: break unbuffered write when netfs_alloc_subrequest() fails netfs: Fix subreq ref leak netfs: Fix i_size update for partial transfer netfs: Fix error vs transferred passed to ->ki_complete() netfs: Fix unbuffered/DIO write partial transfer error return ...
2026-09-09exec: do_close_on_exec() before taking exec_update_lockJann Horn
do_close_on_exec() currently happens while holding the exec_update_lock, which is used in a lot of places that access process state to synchronize access checks. I recently added another such use of exec_update_lock, causing a regression. do_close_on_exec() can block waiting for a reply from a filesystem. That means a hung filesystem can block codepaths that use exec_update_lock; and it also means that a FUSE filesystem which attempts to inspect the calling process can deadlock. To avoid such problems, move do_close_on_exec() before the exec_update_lock is taken, but after the FD table has been copied if necessary. I have looked through all the calls between the old and new position of the do_close_on_exec() call; there seems to be no file descriptor table access in between. Reported-by: Benjamin Peterson <benjamin@locrian.net> Closes: https://lore.kernel.org/r/f5e8166a-88be-46c5-8939-1e5227ffe4c2@app.fastmail.com Fixes: 6650527444da ("proc: protect ptrace_may_access() with exec_update_lock (part 1)") Cc: stable@vger.kernel.org Signed-off-by: Jann Horn <jannh@google.com> Link: https://patch.msgid.link/20260907-cloexec-before-exec-update-lock-v1-1-8018c201a7df@google.com Tested-by: Benjamin Peterson <benjamin@locrian.net> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-03exec: Drop bprm loader before closing bprm->fileSun Jian
free_bprm() currently drops what may be the final reference to bprm->file before calling bprm_drop_loader(). Since bprm_drop_loader() is attachable via BPF fentry and bprm->file is exposed as a BTF_TYPE_SAFE_TRUSTED pointer, the file can be observed after its reference has been released. Move bprm_drop_loader() before do_close_execat(bprm->file), keeping the file reference held while the hook runs. This preserves the existing trusted BTF contract without changing verifier behavior. The loader file and bprm->file have independent references, so this reordering does not change their required teardown ordering. Link: https://sashiko.dev/#/patchset/20260831092305.42062-1-tasos.papagiannnis@gmail.com?part=3 Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com> Link: https://patch.msgid.link/20260901114011.112375-1-sun.jian.kdev@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-22Merge tag 'locking-urgent-2026-08-22' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull futex fixes from Ingo Molnar: - Enforce that the private futex owner shares the mm when attaching (Kyle Zeng, Thomas Gleixner) - Fix race on the initial mm->futex.phash.ref allocation (Hyunwoo Kim) - Fix might_sleep() warning in futex_pivot_pending() (Peter Zijlstra) * tag 'locking-urgent-2026-08-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: futex: Fix might_sleep() warning in futex_pivot_pending() futex: Fix race on the initial mm->futex.phash.ref allocation futex: Clean up the redundant exit/exec functions futex/pi: Plug private futex exec() race futex: Sanitize and document task_struct::futex::state transitions futex/pi: Reject cross-mm private futex owners
2026-08-16futex: Clean up the redundant exit/exec functionsThomas Gleixner
futex_exit_release() and futex_exec_release() are identical now. That means also exit_mm_release() and exec_mm_release() are identical. Consolidate the whole lot and remove the redundant copies. Signed-off-by: Thomas Gleixner <tglx@kernel.org> Reviewed-by: Kyle Zeng <kylebot@openai.com> Acked-by: Peter Zijlstra <peterz@infradead.org>
2026-08-16futex/pi: Plug private futex exec() raceThomas Gleixner
The check for private futexes whether the waiter's mm, which is stored in the futex_key and copied into the pi_state, is the same as the owner's mm is not sufficient for exec(). exec() has a gap where the mm check fails to give the correct answer: exec() ... exec_release_mm() futex_exec_release() tsk::futex::exit_state = EXITING; cleanup_robust_list(); 1) tsk::futex::exit_state = OK; ... old_mm = tsk::mm; 2) tsk::mm = ->mm; Between #1 and #2 the check for the mm is wrong as that mm is about to be swapped out and eventually freed. Plug this gap by: 1) Setting tsk::futex::exit_state to FUTEX_STATE_DEAD in futex_exec_release() 2) Setting tsk::futex::exit_state to FUTEX_STATE_OK after the mm has been switched. From a futex point of view the task is dead after it finished the robust list cleanup up to the point where it sets the state to OK again. Fixes: 80367ad01d93 ("futex: Add basic infrastructure for local task local hash") Signed-off-by: Thomas Gleixner <tglx@kernel.org> Reviewed-by: Kyle Zeng <kylebot@openai.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Cc: stable@vger.kernel.org
2026-08-03binfmt_misc: let a 'B' entry bind its interpretersChristian Brauner
A 'B' entry's load program selects its interpreter by absolute path, which open_exec() resolves at exec time in the mount namespace of whoever runs the binary. The handler names an interpreter but does not get to say which file that is. Whoever controls the filesystem view of the exec decides that instead. Static entries settled this long ago with 'F'. The interpreter is opened at registration in the registrant's context and every exec runs a clone of that file. Give a 'B' entry the same, for as many interpreters as it needs. An entry registered with 'D' cannot be matched yet, so it still belongs to whoever is configuring it and can be given interpreters one write at a time: echo ':qemu:B::::qemu_user:D' > register echo '+aarch64 /usr/bin/qemu-aarch64' > qemu echo '+arm /usr/bin/qemu-arm' > qemu echo 1 > qemu Each path is opened by its write, with the credentials the entry file was opened with, by the same helper that opens an 'F' interpreter. The load program picks one per exec with bpf_binprm_select_interp() and the entry hands out a clone of it. Nothing is resolved again, in any namespace. The path is everything past the first space, so no interpreter has to fit in a register string. An entry binds at most a hundred interpreters (BINFMT_MISC_INTERP_MAX). Every binding pins a struct file that no file descriptor accounts for, so RLIMIT_NOFILE does not apply and some cap is needed. A hundred is plenty and raising it later is cheap, lowering it is not. Selection is by name so the register string and the program need not agree on an order, and so the handler is not tied to where a distribution puts its interpreters. A name is a single word of printable ASCII so the entry file can report 'name path' lines. The interpreter runs under the path it was registered under. The entry file reads user memory once. bm_entry_write() copies the write in and dispatches on the first byte, and parse_command() takes the copied buffer. The status file has no binding to spell, so it keeps its own small copy in read_command(). That moves the length cap ahead of the dispatch. A write to an entry file longer than a binding can be is now refused with -E2BIG, and one from a bad address reports -EFAULT, where the command parser used to report -EINVAL for anything past three bytes. Configurations of one instance are kept apart by the lock removal already takes. Reading the set out of the entry file takes no lock. Bindings are rcu-published and the open entry file pins the entry together with everything it bound, so a reader either sees a whole node or misses it. The interpreter is opened before the configuration lock because resolving the path may walk this very filesystem, and only after the command has been parsed and the name validated from the copied buffer, so a write that can never bind opens nothing and the errno reflects the actual failure. Link: https://patch.msgid.link/20260730-work-binfmt_misc-preopen-v1-7-4a0b0da71f16@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-03exec: carry a PT_INTERP substitute in struct linux_binprmChristian Brauner
binfmt_misc currently supports an execution model where the registered interpreter becomes the executed program and the matched binary is handed to it as payload. The upcoming binfmt_misc loader mode inverts this. The matched binary remains the executed program and the registered interpreter is substituted into the role the binary's PT_INTERP would have played. Add the channel for that hand-over. bprm->loader carries an open_exec-style struct file reference from the binfmt_misc match to the binary format that consumes it. Unlike bprm->interpreter it does not request a restart of the format search. The stashing handler declines the exec with -ENOEXEC and the search continues to the real format in the same round. Both ELF loaders consume it, so give them the two helpers to do it with rather than a copy each. bprm_open_interpreter() hands out the substitute in place of what PT_INTERP names and bprm_drop_loader() releases one that turned out not to apply. Establish the complete lifecycle up front so a stashed loader can neither leak nor be silently ignored. - Chain restart: if another format wins the round by staging bprm->interpreter (binfmt_script) the stashed loader belonged to the file being replaced. Drop it at the top of the swap block in exec_binprm(). - Unclaimed or error: free_bprm() releases a still-stashed loader next to the other bprm file references. - Silent non-substitution: a final format that reaches begin_new_exec() with a pending loader would run the binary while ignoring the override. Refuse with -ENOEXEC before the point of no return. Formats that do not know about the override (binfmt_flat, out-of-tree) need no changes. Link: https://patch.msgid.link/20260721-work-bpf-binfmt_misc-ptinterp-v2-15-e57866e4ae0f@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-03exec: label mm->exe_file with the binary for a transparent dispatchChristian Brauner
When binfmt_misc dispatches a binary to an interpreter, the interpreter becomes bprm->file and begin_new_exec() labels mm->exe_file with it. For wine or qemu-user that is the point. For the transparent mode it defeats the point. The interpreter is an implementation detail and the process's identity is the binary. Relocatable programs that locate themselves via /proc/self/exe find the dynamic linker instead [1]. Userspace cannot get this right on its own. PR_SET_MM_MAP's exe_fd is gated on checkpoint_restore_ns_capable() in the caller's own user namespace - that is how CRIU restores an exe link - so the ability to retarget mm->exe_file is not what this adds. What userspace cannot do is have the link be right from the first instruction. Credentials are unaffected either way: they still derive from the interpreter unless 'C' says otherwise. bprm->executable is the file execve() access-checked and kept open for AT_EXECFD. It is already the file would_dump() bases the dumpability decision on and the file bprm->execfd_creds derives credentials from. Label mm->exe_file with it when the dispatch is transparent and the identity is correct from the start. The label names precisely the file the caller passed to execve(). Write-denial moves along with the label. Rather than tracking per mode who still owes a release, the denial do_open_execat() took stays on bprm->executable until the file is handed over. begin_new_exec() drops it right before installing the descriptor - set_mm_exe_file() has taken its own denial on the identity file by then - and free_bprm() releases an unconsumed executable with do_close_execat() like the other exec files. For a transparent dispatch the result is exact parity with a direct execution: a concurrently written binary fails execve() with -ETXTBSY at open and a running one cannot be opened for writing. The interpreter consequently is not exe-pinned and matches the role it has in a native PT_INTERP exec. A classic execfd dispatch now keeps the binary write-denied until the exec completes rather than only until the interpreter swap; the difference is confined to the exec itself. Nothing sets BINPRM_FLAGS_TRANSPARENT_INTERP yet; the transparent dispatch machinery in binfmt_misc follows and raises it from birth, so the label and the aux vector bit that announces it appear together. Link: https://inbox.sourceware.org/libc-alpha/87ik6fymha.fsf@oldenburg.str.redhat.com [1] Link: https://patch.msgid.link/20260721-work-bpf-binfmt_misc-ptinterp-v2-9-e57866e4ae0f@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-03exec: release the replaced file with do_close_execat()Christian Brauner
When the format search stages an interpreter exec_binprm() swaps it in and releases the file it replaces. Dropping the write denial the open took is done manually ahead of both release paths. The one path that keeps the file silently relies on it not being called. Let's just use do_close_execat() on the two paths that release the file and drop the denial explicitly on the one that does not. No functional change. Link: https://patch.msgid.link/20260721-work-bpf-binfmt_misc-ptinterp-v2-6-e57866e4ae0f@kernel.org Reviewed-by: Farid Zakaria <farid.m.zakaria@gmail.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-03exec: stash bpf-selected interpreter state in struct linux_binprmChristian Brauner
The upcoming bpf-backed binfmt_misc handlers decide how a binary is run programmatically at exec time: the interpreter itself, an optional single argument to pass to it, and the invocation flags that a static binfmt_misc entry fixes at registration time. The selection runs before load_misc_binary() has copied the binary path from bprm->interp into the argument vector, so the selecting program cannot go through bprm_change_interp() directly without clobbering argv[1]. Stage the selected state in the bprm instead, grouped in struct binfmt_misc_bpf and embedded anonymously in struct linux_binprm so the bprm->bpf_* accesses stay direct. The bprm is exclusively owned by the task doing the exec so no synchronization is needed. The consumers free and clear the fields once the exec attempt that set them is finished; free_bprm() covers all error paths. Link: https://patch.msgid.link/20260714-work-bpf-binfmt_misc-v2-1-57b7529c002c@kernel.org Reviewed-by: Farid Zakaria <farid.m.zakaria@gmail.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-21exec: fix unsigned loop counter wrap in transfer_args_to_stack()Christian Brauner
The stop value is derived from bprm->p >> PAGE_SHIFT. The index variable is an unsigned long. If bprm->p drops below PAGE_SIZE and stop becomes zero the loop condition index >= stop is always true. After the index == 0 iteration the decrement wraps to ULONG_MAX and bprm->page[ULONG_MAX] reads sizeof(void *) bytes in front of the array. The pointer has wrapped to -1. That garbage pointer is then passed to kmap_local_page() and PAGE_SIZE bytes are copied from wherever that lands into the stack of the process being created. And the loop doesn't terminate either... Getting there only requires bprm->p < PAGE_SIZE. On !MMU bprm_set_stack_limit() and bprm_hit_stack_limit() are empty. So the only constraint on how far bprm->p is pushed down is valid_arg_len(), i.e. that each individual string still fits in what is left. bprm->p starts at PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *) so a single argument or environment string of a little over 31 pages leaves it in the first page: Oops - load access fault [#1] CPU: 0 UID: 0 PID: 1 Comm: victim Not tainted 7.2.0-rc4 #1 epc : __memcpy+0xd4/0xf8 ra : transfer_args_to_stack+0xaa/0xae s4 : ffffffffffffffff s2 : 0000000000000000 a1 : ffffffdc98000000 a2 : 0000000000001000 status: 0000000a00001880 badaddr: ffffffdc98000000 cause: 0000000000000005 [<801a5324>] __memcpy+0xd4/0xf8 [<800d5f6a>] load_flat_binary+0x43a/0x65e [<800a2de4>] bprm_execve+0x1d4/0x316 [<800a351a>] do_execveat_common+0x12e/0x138 [<800a3d44>] __riscv_sys_execve+0x38/0x4e Kernel panic - not syncing: Fatal exception in interrupt This is an arcane bug but we should still fix it. Count down from MAX_ARG_PAGES so the loop ends when index reaches stop, stop == 0 included. The iterations performed are unchanged for every other value of stop. Only CONFIG_MMU=n builds are affected, transfer_args_to_stack() is used by binfmt_flat and binfmt_elf_fdpic on nommu only. The loop predates git history. commit 7e7ec6a93434 ("elf_fdpic_transfer_args_to_stack(): make it generic") only moved it from binfmt_elf_fdpic.c into fs/exec.c and narrowed the copy to the used part of the first page. The condition and the decrement are unchanged from 2.6.12-rc2. Link: https://patch.msgid.link/20260721-hochachtung-staumauer-pigmente-15d71f7d7d04@brauner Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-01exec: fix off-by-one in binfmt max rewrite depth commentAlan Urmancheev
The loop in exec_binprm() permits depth values 0 through 5, up to 5 successive binfmt rewrites (setting bprm->interpreter) until the 6th one would fail on depth > 5 and return -ELOOP. The comment claimed 4 levels, which was wrong. Adjusting the code to allow only 4 rewrites would be breaking userland, so fix the comment and not the code. Reproducer (a chain of shebanged scripts followed by an ELF binary): #!/bin/sh tmp=$(mktemp -d) echo $tmp cd $tmp mk () { echo $2 > $1; chmod +x $1; } for i in $(seq 4); do mk $i "#!$((i + 1))" done mk 5 '#!/bin/true' ./1 && echo '5 binfmt rewrites OK (1 -> 2 -> 3 -> 4 -> 5 -> /bin/true)' mk 5 '#!6' mk 6 '#!/bin/true' ./1 || echo '6 binfmt rewrites KO (1 -> 2 -> 3 -> 4 -> 5 -> 6 -> /bin/true)' Signed-off-by: Alan Urmancheev <alan.urman@gmail.com> Link: https://patch.msgid.link/20260623052322.74711-1-alan.urman@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-15Merge tag 'vfs-7.2-rc1.misc' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull misc vfs updates from Christian Brauner: "Features: - Reduce pipe->mutex contention by pre-allocating pages outside the lock in anon_pipe_write(). anon_pipe_write() called alloc_page() once per page while holding pipe->mutex. The allocation can sleep doing direct reclaim and runs memcg charging, which extends the critical section and stalls any concurrent reader on the same mutex. Now up to 8 pages are pre-allocated before the mutex is taken, leftovers are recycled into the per-pipe tmp_page[] cache before unlock, and any remainder is released after unlock, keeping the allocator out of the critical section on both sides. On a writers x readers sweep with 64KB writes against a 1 MB pipe throughput improves 6-28% and average write latency drops 5-22%; under memory pressure - when the cost of holding the mutex across reclaim is highest - throughput improves 21-48% and latency drops 17-33%. The microbenchmark is added to selftests. - uaccess/sockptr: fix the ignored_trailing logic in copy_struct_to_user() to behave as documented and the usize check in copy_struct_from_sockptr() for user pointers, and add copy_struct_{from,to}_bounce_buffer() and copy_struct_to_sockptr() helpers for upcoming users (IPPROTO_SMBDIRECT, IPPROTO_QUIC). - bpf: add a sleepable bpf_real_inode() kfunc that resolves the real inode backing a dentry via d_real_inode(). On overlayfs the inode attached to the dentry doesn't carry the underlying device information; this is used by the filesystem restriction BPF program that was merged into systemd. - docs: add guidelines for submitting new filesystems, motivated by the maintenance burden abandoned and untestable filesystems impose on VFS developers, blocking infrastructure work like folio conversions and iomap migration. Fixes: - libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo() and drop the now-redundant assignments in callers. This began as a one-line dma-buf fix for a path_noexec() warning; a pseudo filesystem has no reason not to set SB_I_NOEXEC. All init_pseudo() callers were audited: the only visible effect is on dma-buf where SB_I_NOEXEC silences the warning. - Handle set_blocksize() failures in legacy filesystems (bfs, hpfs, qnx4, jfs, befs, affs, isofs, minix, ntfs3, omfs). Mounting a device with a sector size > PAGE_SIZE crashed roughly half of them; the rest had the same missing error handling pattern. Plus a follow-up releasing the superblock buffer_head when setting the minix v3 block size fails. - mount: honour SB_NOUSER in the new mount API. - fs/fcntl: fix a SOFTIRQ-unsafe lock order in fasync signaling by switching the process-group paths of send_sigio() and send_sigurg() from read_lock(&tasklist_lock) to RCU, matching the single-PID path. - vfs: add an FS_USERNS_DELEGATABLE flag and set it for NFS, fixing delegated NFS mounts (fsopen() in a container with the mount performed by a privileged daemon) that broke when non-init s_user_ns was tied to FS_USERNS_MOUNT. - selftests/namespaces: fix a hang in nsid_test where an unreaped grandchild kept the TAP pipe write-end open, a waitpid(-1) race in listns_efault_test, and a false FAIL on kernels without listns() where the tests should SKIP. - filelock: fix the break_lease() stub signature for CONFIG_FILE_LOCKING=n. - init/initramfs_test: wait for the async initramfs unpacking before running; the test and do_populate_rootfs() share the parser state. - fs/coredump: reduce redundant log noise in validate_coredump_safety(). - iomap: pass the correct length to fserror_report_io() in __iomap_write_begin(). - backing-file: fix the backing_file_open() kerneldoc. Cleanups: - initramfs: refactor the cpio hex header parsing to use hex2bin() instead of the hand-rolled simple_strntoul() which is reverted, and extend the initramfs KUnit tests to cover header fields with 0x prefixes. - Replace __get_free_pages() and friends with kmalloc()/kzalloc() across quota, proc, ocfs2/dlm, nilfs2, nfs, nfsd, libfs, jfs, jbd2, isofs, fuse, select, namespace, configfs, binfmt_misc, bfs, and the do_mounts init code - part of the larger work of replacing page allocator calls with kmalloc(). - Use clear_and_wake_up_bit() in unlock_buffer() and journal_end_buffer_io_sync() instead of open-coding the sequence. - Drop unused VFS exports: unexport drop_super_exclusive(), remove start_removing_user_path_at(), and fold __start_removing_path() into start_removing_path(). - fs/read_write: narrow the __kernel_write() export with EXPORT_SYMBOL_FOR_MODULES(). - vfs: uapi: retire octal and hex constants in favor of (1 << n) for the O_ flags. Finding a free bit for a new flag across the architectures was needlessly hard with the mixed bases. - dcache: add extra sanity checks of dead dentries in dentry_free() via a new DENTRY_WARN_ONCE() that also prints d_flags. - iov_iter: use kmemdup_array() in dup_iter() to harden the allocation against multiplication overflow. - fs/pipe: write to ->poll_usage only once. - vfs: remove an always-taken if-branch in find_next_fd(). - dcache: use kmalloc_flex() for struct external_name in __d_alloc(). - namei: use QSTR() instead of QSTR_INIT() in path_pts(). - sync_file_range: delete dead S_ISLNK code. - Comment fixes: retire a stale comment in fget_task_next() and fix assorted spelling mistakes" * tag 'vfs-7.2-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (73 commits) backing-file: fix backing_file_open() kerneldoc parameter iomap: pass the correct len to fserror_report_io in __iomap_write_begin vfs: add FS_USERNS_DELEGATABLE flag and set it for NFS filelock: fix break_lease() stub signature for CONFIG_FILE_LOCKING=n vfs: uapi: retire octal and hex numbers in favor of (1 << n) for O_ flags bpf: add bpf_real_inode() kfunc fs/read_write: Do not export __kernel_write() to the entire world libfs: drop redundant SB_I_NOEXEC/SB_I_NODEV in init_pseudo() callers libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo() mount: honour SB_NOUSER in the new mount API fs/fcntl: fix SOFTIRQ-unsafe lock order in fasync signaling selftests/pipe: add pipe_bench microbenchmark fs/pipe: pre-allocate pages outside pipe->mutex in anon_pipe_write fs: retire stale comment in fget_task_next() fs: fix spelling mistakes in comment bfs: replace get_zeroed_page() with kzalloc() binfmt_misc: replace __get_free_page() with kmalloc() configfs: replace __get_free_pages() with kzalloc() fs/namespace: use __getname() to allocate mntpath buffer fs/select: replace __get_free_page() with kmalloc() ...
2026-05-26exec: free the old mm outside the exec locksChristian Brauner
exec_mmap() installs the new mm and then tears the old one down while still holding exec_update_lock for writing -- and with cred_guard_mutex held all the way to setup_new_exec(): setmax_mm_hiwater_rss(&tsk->signal->maxrss, old_mm); mm_update_next_owner(old_mm); mmput(old_mm); Neither lock is needed for this. exec_update_lock only exists to make the mm swap atomic with the later commit_creds(), so that permission-checking readers (proc, ptrace, the futex robust list, perf, kcmp, mm_access()) never observe the new mm together with the old credentials. Those readers all operate on task->mm, i.e. the new mm after the swap; none looks at the detached old mm, its ->owner or signal->maxrss. cred_guard_mutex guards credential calculation and is equally irrelevant here. The cost is real: __mmput() runs exit_mmap() over the entire old address space and can block in exit_aio() waiting for in-flight AIO, all while holding exec_update_lock for writing and cred_guard_mutex. For execve() of a large process this blocks ptrace_attach() and every exec_update_lock reader for the duration of the teardown. Stash the old mm in bprm->old_mm and release it from setup_new_exec() after both locks are dropped. setup_new_exec() still runs before setup_arg_pages() and the segment mappings, so the old address space is freed before the new one is populated and peak memory is unchanged. The ordering constraints are kept: old_mm's mmap_lock is still dropped in exec_mmap() before mm_update_next_owner() (required since commit 31a78f23bac0 ("mm owner: fix race between swapoff and exit")), and mm_update_next_owner() still precedes mmput(); both run in the execing task's context, as mm_update_next_owner() requires. If exec swaps the mm but fails before setup_new_exec() runs the old mm would leak, so add a backstop in free_bprm(). The lazy-tlb case (old_mm == NULL, e.g. kernel_execve()) has no address space to free and is left in exec_mmap(). Link: https://patch.msgid.link/20260522-work-exit_mm-v1-1-bd32d5a560bb@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-26exec_state: relocate dumpable informationChristian Brauner (Amutable)
The dumpable flag captured at execve() is consulted by __ptrace_may_access() and several /proc owner / visibility checks. It lives on mm_struct today, which exit_mm() clears from the task long before the task itself is reaped. exec_state is anchored to the execve() that established the current privilege domain. CLONE_VM siblings refcount-share the parent's exec_state via copy_exec_state(); non-CLONE_VM clones allocate a fresh exec_state inheriting the parent's dumpable mode and user_ns reference via task_exec_state_copy(). execve() allocates a fresh instance (via alloc_task_exec_state() in begin_new_exec()) and installs it under task_lock + exec_update_lock with task_exec_state_replace(). init_task uses a static instance. The dumpable mode now lives on task->exec_state->dumpable. task->mm->flags no longer carries dumpability; MMF_DUMPABLE_MASK is removed, but MMF_DUMPABLE_BITS is reserved so MMF_DUMP_FILTER_* bit positions remain stable for the /proc/<pid>/coredump_filter ABI. The task->user_dumpable cache bit and its assignment in exit_mm() are removed; readers go through get_dumpable(task) directly. coredump_params gains a snapshot field cprm.dumpable, populated from get_dumpable(current) at vfs_coredump() entry, replacing the previous __get_dumpable(cprm->mm_flags) consumers in fs/coredump.c and fs/pidfs.c. The user namespace recorded at execve() is consulted by __ptrace_may_access() and by /proc/PID/* owner derivation. Move the captured user_ns onto task_exec_state, which stays attached to the task past exit_mm() and across exit_files(). bprm grows a user_ns field staged in bprm_mm_init() with the caller's user_ns, narrowed by would_dump() to the closest privileged ancestor, and consumed by exec_mmap() via alloc_task_exec_state(bprm->user_ns). free_bprm() releases the staging reference. mm_struct loses ->user_ns entirely. Initializers in init-mm, efi_mm, and the implicit one in mm_init()/dup_mm()/mm_alloc() are removed; __mmdrop() drops the matching put_user_ns(). The kthread_use_mm() WARN_ON_ONCE(!mm->user_ns) is no longer meaningful and goes too. Reviewed-by: Jann Horn <jannh@google.com> Link: https://patch.msgid.link/20260520-work-task_exec_state-v3-4-69f895bc1385@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-26sched/coredump: introduce enum task_dumpableChristian Brauner (Amutable)
Replace the SUID_DUMP_DISABLE/USER/ROOT preprocessor constants with enum task_dumpable. Numeric values are preserved (kernel.suid_dumpable sysctl and prctl(PR_SET_DUMPABLE) ABI), so this is a pure rename with no behavioral change. Subsequent commits relocate dumpability onto a per-task structure where the enum type will allow stronger type-checking on the new API. Reviewed-by: Jann Horn <jannh@google.com> Reviewed-by: David Hildenbrand (arm) <david@kernel.org> Link: https://patch.msgid.link/20260520-work-task_exec_state-v3-1-69f895bc1385@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21fs/coredump: reduce redundant log noise in validate_coredump_safetyLi RongQing
Currently, writing to 'core_pattern' or 'suid_dumpable' sysctl nodes always triggers validate_coredump_safety(), even if the values have not changed. This results in redundant warning messages in dmesg: "Unsafe core_pattern used with fs.suid_dumpable=2..." This patch optimizes the procfs handlers to only invoke the safety validation when an actual change in the configuration is detected: 1. In proc_dostring_coredump(), compare the new core_pattern string with the existing one using strncmp(). 2. In proc_dointvec_minmax_coredump(), check if the new suid_dumpable value differs from the previous one. This keeps the kernel log clean from repetitive warnings when re-applying the same sysctl settings. Signed-off-by: Li RongQing <lirongqing@baidu.com> Link: https://patch.msgid.link/20260410080918.2319-1-lirongqing@baidu.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-04-01exec: use strnlen() in __set_task_commThorsten Blum
Use strnlen() to limit source string scanning to 'TASK_COMM_LEN - 1' bytes. Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260401152039.724811-3-thorsten.blum@linux.dev Signed-off-by: Kees Cook <kees@kernel.org>
2026-02-21Convert 'alloc_obj' family to use the new default GFP_KERNEL argumentLinus Torvalds
This was done entirely with mindless brute force, using git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' | xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/' to convert the new alloc_obj() users that had a simple GFP_KERNEL argument to just drop that argument. Note that due to the extreme simplicity of the scripting, any slightly more complex cases spread over multiple lines would not be triggered: they definitely exist, but this covers the vast bulk of the cases, and the resulting diff is also then easier to check automatically. For the same reason the 'flex' versions will be done as a separate conversion. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21treewide: Replace kmalloc with kmalloc_obj for non-scalar typesKees Cook
This is the result of running the Coccinelle script from scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to avoid scalar types (which need careful case-by-case checking), and instead replace kmalloc-family calls that allocate struct or union object instances: Single allocations: kmalloc(sizeof(TYPE), ...) are replaced with: kmalloc_obj(TYPE, ...) Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...) are replaced with: kmalloc_objs(TYPE, COUNT, ...) Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...) are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...) (where TYPE may also be *VAR) The resulting allocations no longer return "void *", instead returning "TYPE *". Signed-off-by: Kees Cook <kees@kernel.org>
2026-02-09Merge tag 'pull-filename' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull vfs 'struct filename' updates from Al Viro: "[Mostly] sanitize struct filename handling" * tag 'pull-filename' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (68 commits) sysfs(2): fs_index() argument is _not_ a pathname alpha: switch osf_mount() to strndup_user() ksmbd: use CLASS(filename_kernel) mqueue: switch to CLASS(filename) user_statfs(): switch to CLASS(filename) statx: switch to CLASS(filename_maybe_null) quotactl_block(): switch to CLASS(filename) chroot(2): switch to CLASS(filename) move_mount(2): switch to CLASS(filename_maybe_null) namei.c: switch user pathname imports to CLASS(filename{,_flags}) namei.c: convert getname_kernel() callers to CLASS(filename_kernel) do_f{chmod,chown,access}at(): use CLASS(filename_uflags) do_readlinkat(): switch to CLASS(filename_flags) do_sys_truncate(): switch to CLASS(filename) do_utimes_path(): switch to CLASS(filename_uflags) chdir(2): unspaghettify a bit... do_fchownat(): unspaghettify a bit... fspick(2): use CLASS(filename_flags) name_to_handle_at(): use CLASS(filename_uflags) vfs_open_tree(): use CLASS(filename_uflags) ...
2026-01-16do_open_execat(): don't care about LOOKUP_EMPTYAl Viro
do_file_open() doesn't. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-01-13switch {alloc,free}_bprm() to CLASS()Al Viro
All linux_binprm instances come from alloc_bprm() and are unconditionally destroyed by free_bprm() in the end of the same scope. IOW, CLASS() machinery is a decent fit for those. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-01-13do_execveat_common(): don't consume filename referenceAl Viro
... and convert its callers to CLASS(filename...) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-01-13execve: fold {compat_,}do_execve{,at}() into their sole callersAl Viro
All of them are wrappers for do_execveat_common() and each has exactly one caller. The only difference is in the way they are constructing argv/envp arguments for do_execveat_common() and that's easy to do with less boilerplate. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-01-13simplify the callers of alloc_bprm()Al Viro
alloc_bprm() starts with do_open_execat() and it will do the right thing if given ERR_PTR() for name. Allows to drop such checks in its callers... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-01-13simplify the callers of do_open_execat()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-01-13rename do_filp_open() to do_file_open()Al Viro
"filp" thing never made sense; seeing that there are exactly 4 callers in the entire tree (and it's neither exported nor even declared in linux/*/*.h), there's no point keeping that ugliness. FWIW, the 'filp' thing did originate in OSD&I; for some reason Tanenbaum decided to call the object representing an opened file 'struct filp', the last letter standing for 'position'. In all Unices, Linux included, the corresponding object had always been 'struct file'... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2025-12-15fs: use min() or umin() instead of min_t()David Laight
min_t(unsigned int, a, b) casts an 'unsigned long' to 'unsigned int'. Use min(a, b) instead as it promotes any 'unsigned int' to 'unsigned long' and so cannot discard significant bits. A couple of places need umin() because of loops like: nfolios = DIV_ROUND_UP(ret + start, PAGE_SIZE); for (i = 0; i < nfolios; i++) { struct folio *folio = page_folio(pages[i]); ... unsigned int len = umin(ret, PAGE_SIZE - start); ... ret -= len; ... } where the compiler doesn't track things well enough to know that 'ret' is never negative. The alternate loop: for (i = 0; ret > 0; i++) { struct folio *folio = page_folio(pages[i]); ... unsigned int len = min(ret, PAGE_SIZE - start); ... ret -= len; ... } would be equivalent and doesn't need 'nfolios'. Most of the 'unsigned long' actually come from PAGE_SIZE. Detected by an extra check added to min_t(). Signed-off-by: David Laight <david.laight.linux@gmail.com> Link: https://patch.msgid.link/20251119224140.8616-31-david.laight.linux@gmail.com Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-12-02Merge tag 'core-rseq-2025-11-30' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull rseq updates from Thomas Gleixner: "A large overhaul of the restartable sequences and CID management: The recent enablement of RSEQ in glibc resulted in regressions which are caused by the related overhead. It turned out that the decision to invoke the exit to user work was not really a decision. More or less each context switch caused that. There is a long list of small issues which sums up nicely and results in a 3-4% regression in I/O benchmarks. The other detail which caused issues due to extra work in context switch and task migration is the CID (memory context ID) management. It also requires to use a task work to consolidate the CID space, which is executed in the context of an arbitrary task and results in sporadic uncontrolled exit latencies. The rewrite addresses this by: - Removing deprecated and long unsupported functionality - Moving the related data into dedicated data structures which are optimized for fast path processing. - Caching values so actual decisions can be made - Replacing the current implementation with a optimized inlined variant. - Separating fast and slow path for architectures which use the generic entry code, so that only fault and error handling goes into the TIF_NOTIFY_RESUME handler. - Rewriting the CID management so that it becomes mostly invisible in the context switch path. That moves the work of switching modes into the fork/exit path, which is a reasonable tradeoff. That work is only required when a process creates more threads than the cpuset it is allowed to run on or when enough threads exit after that. An artificial thread pool benchmarks which triggers this did not degrade, it actually improved significantly. The main effect in migration heavy scenarios is that runqueue lock held time and therefore contention goes down significantly" * tag 'core-rseq-2025-11-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (54 commits) sched/mmcid: Switch over to the new mechanism sched/mmcid: Implement deferred mode change irqwork: Move data struct to a types header sched/mmcid: Provide CID ownership mode fixup functions sched/mmcid: Provide new scheduler CID mechanism sched/mmcid: Introduce per task/CPU ownership infrastructure sched/mmcid: Serialize sched_mm_cid_fork()/exit() with a mutex sched/mmcid: Provide precomputed maximal value sched/mmcid: Move initialization out of line signal: Move MMCID exit out of sighand lock sched/mmcid: Convert mm CID mask to a bitmap cpumask: Cache num_possible_cpus() sched/mmcid: Use cpumask_weighted_or() cpumask: Introduce cpumask_weighted_or() sched/mmcid: Prevent pointless work in mm_update_cpus_allowed() sched/mmcid: Move scheduler code out of global header sched: Fixup whitespace damage sched/mmcid: Cacheline align MM CID storage sched/mmcid: Use proper data structures sched/mmcid: Revert the complex CID management ...
2025-12-01Merge tag 'vfs-6.19-rc1.fd_prepare.fs' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull fd prepare updates from Christian Brauner: "This adds the FD_ADD() and FD_PREPARE() primitive. They simplify the common pattern of get_unused_fd_flags() + create file + fd_install() that is used extensively throughout the kernel and currently requires cumbersome cleanup paths. FD_ADD() - For simple cases where a file is installed immediately: fd = FD_ADD(O_CLOEXEC, vfio_device_open_file(device)); if (fd < 0) vfio_device_put_registration(device); return fd; FD_PREPARE() - For cases requiring access to the fd or file, or additional work before publishing: FD_PREPARE(fdf, O_CLOEXEC, sync_file->file); if (fdf.err) { fput(sync_file->file); return fdf.err; } data.fence = fd_prepare_fd(fdf); if (copy_to_user((void __user *)arg, &data, sizeof(data))) return -EFAULT; return fd_publish(fdf); The primitives are centered around struct fd_prepare. FD_PREPARE() encapsulates all allocation and cleanup logic and must be followed by a call to fd_publish() which associates the fd with the file and installs it into the caller's fdtable. If fd_publish() isn't called, both are deallocated automatically. FD_ADD() is a shorthand that does fd_publish() immediately and never exposes the struct to the caller. I've implemented this in a way that it's compatible with the cleanup infrastructure while also being usable separately. IOW, it's centered around struct fd_prepare which is aliased to class_fd_prepare_t and so we can make use of all the basica guard infrastructure" * tag 'vfs-6.19-rc1.fd_prepare.fs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (42 commits) io_uring: convert io_create_mock_file() to FD_PREPARE() file: convert replace_fd() to FD_PREPARE() vfio: convert vfio_group_ioctl_get_device_fd() to FD_ADD() tty: convert ptm_open_peer() to FD_ADD() ntsync: convert ntsync_obj_get_fd() to FD_PREPARE() media: convert media_request_alloc() to FD_PREPARE() hv: convert mshv_ioctl_create_partition() to FD_ADD() gpio: convert linehandle_create() to FD_PREPARE() pseries: port papr_rtas_setup_file_interface() to FD_ADD() pseries: convert papr_platform_dump_create_handle() to FD_ADD() spufs: convert spufs_gang_open() to FD_PREPARE() papr-hvpipe: convert papr_hvpipe_dev_create_handle() to FD_PREPARE() spufs: convert spufs_context_open() to FD_PREPARE() net/socket: convert __sys_accept4_file() to FD_ADD() net/socket: convert sock_map_fd() to FD_ADD() net/kcm: convert kcm_ioctl() to FD_PREPARE() net/handshake: convert handshake_nl_accept_doit() to FD_PREPARE() secretmem: convert memfd_secret() to FD_ADD() memfd: convert memfd_create() to FD_ADD() bpf: convert bpf_token_create() to FD_PREPARE() ...
2025-11-28exec: convert begin_new_exec() to FD_ADD()Christian Brauner
Link: https://patch.msgid.link/20251123-work-fd-prepare-v4-21-b6efa1706cfd@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-11-04rseq: Optimize event settingThomas Gleixner
After removing the various condition bits earlier it turns out that one extra information is needed to avoid setting event::sched_switch and TIF_NOTIFY_RESUME unconditionally on every context switch. The update of the RSEQ user space memory is only required, when either the task was interrupted in user space and schedules or the CPU or MM CID changes in schedule() independent of the entry mode Right now only the interrupt from user information is available. Add an event flag, which is set when the CPU or MM CID or both change. Evaluate this event in the scheduler to decide whether the sched_switch event and the TIF bit need to be set. It's an extra conditional in context_switch(), but the downside of unconditionally handling RSEQ after a context switch to user is way more significant. The utilized boolean logic minimizes this to a single conditional branch. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://patch.msgid.link/20251027084307.578058898@linutronix.de
2025-11-04rseq: Simplify the event notificationThomas Gleixner
Since commit 0190e4198e47 ("rseq: Deprecate RSEQ_CS_FLAG_NO_RESTART_ON_* flags") the bits in task::rseq_event_mask are meaningless and just extra work in terms of setting them individually. Aside of that the only relevant point where an event has to be raised is context switch. Neither the CPU nor MM CID can change without going through a context switch. Collapse them all into a single boolean which simplifies the code a lot and remove the pointless invocations which have been sprinkled all over the place for no value. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://patch.msgid.link/20251027084306.336978188@linutronix.de
2025-10-07coredump: fix core_pattern input validationChristian Brauner
In be1e0283021e ("coredump: don't pointlessly check and spew warnings") we tried to fix input validation so it only happens during a write to core_pattern. This would avoid needlessly logging a lot of warnings during a read operation. However the logic accidently got inverted in this commit. Fix it so the input validation only happens on write and is skipped on read. Fixes: be1e0283021e ("coredump: don't pointlessly check and spew warnings") Fixes: 16195d2c7dd2 ("coredump: validate socket name as it is written") Reviewed-by: Jan Kara <jack@suse.cz> Reported-by: Yu Watanabe <watanabe.yu@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-10-02Merge tag 'mm-stable-2025-10-01-19-00' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull MM updates from Andrew Morton: - "mm, swap: improve cluster scan strategy" from Kairui Song improves performance and reduces the failure rate of swap cluster allocation - "support large align and nid in Rust allocators" from Vitaly Wool permits Rust allocators to set NUMA node and large alignment when perforning slub and vmalloc reallocs - "mm/damon/vaddr: support stat-purpose DAMOS" from Yueyang Pan extend DAMOS_STAT's handling of the DAMON operations sets for virtual address spaces for ops-level DAMOS filters - "execute PROCMAP_QUERY ioctl under per-vma lock" from Suren Baghdasaryan reduces mmap_lock contention during reads of /proc/pid/maps - "mm/mincore: minor clean up for swap cache checking" from Kairui Song performs some cleanup in the swap code - "mm: vm_normal_page*() improvements" from David Hildenbrand provides code cleanup in the pagemap code - "add persistent huge zero folio support" from Pankaj Raghav provides a block layer speedup by optionalls making the huge_zero_pagepersistent, instead of releasing it when its refcount falls to zero - "kho: fixes and cleanups" from Mike Rapoport adds a few touchups to the recently added Kexec Handover feature - "mm: make mm->flags a bitmap and 64-bit on all arches" from Lorenzo Stoakes turns mm_struct.flags into a bitmap. To end the constant struggle with space shortage on 32-bit conflicting with 64-bit's needs - "mm/swapfile.c and swap.h cleanup" from Chris Li cleans up some swap code - "selftests/mm: Fix false positives and skip unsupported tests" from Donet Tom fixes a few things in our selftests code - "prctl: extend PR_SET_THP_DISABLE to only provide THPs when advised" from David Hildenbrand "allows individual processes to opt-out of THP=always into THP=madvise, without affecting other workloads on the system". It's a long story - the [1/N] changelog spells out the considerations - "Add and use memdesc_flags_t" from Matthew Wilcox gets us started on the memdesc project. Please see https://kernelnewbies.org/MatthewWilcox/Memdescs and https://blogs.oracle.com/linux/post/introducing-memdesc - "Tiny optimization for large read operations" from Chi Zhiling improves the efficiency of the pagecache read path - "Better split_huge_page_test result check" from Zi Yan improves our folio splitting selftest code - "test that rmap behaves as expected" from Wei Yang adds some rmap selftests - "remove write_cache_pages()" from Christoph Hellwig removes that function and converts its two remaining callers - "selftests/mm: uffd-stress fixes" from Dev Jain fixes some UFFD selftests issues - "introduce kernel file mapped folios" from Boris Burkov introduces the concept of "kernel file pages". Using these permits btrfs to account its metadata pages to the root cgroup, rather than to the cgroups of random inappropriate tasks - "mm/pageblock: improve readability of some pageblock handling" from Wei Yang provides some readability improvements to the page allocator code - "mm/damon: support ARM32 with LPAE" from SeongJae Park teaches DAMON to understand arm32 highmem - "tools: testing: Use existing atomic.h for vma/maple tests" from Brendan Jackman performs some code cleanups and deduplication under tools/testing/ - "maple_tree: Fix testing for 32bit compiles" from Liam Howlett fixes a couple of 32-bit issues in tools/testing/radix-tree.c - "kasan: unify kasan_enabled() and remove arch-specific implementations" from Sabyrzhan Tasbolatov moves KASAN arch-specific initialization code into a common arch-neutral implementation - "mm: remove zpool" from Johannes Weiner removes zspool - an indirection layer which now only redirects to a single thing (zsmalloc) - "mm: task_stack: Stack handling cleanups" from Pasha Tatashin makes a couple of cleanups in the fork code - "mm: remove nth_page()" from David Hildenbrand makes rather a lot of adjustments at various nth_page() callsites, eventually permitting the removal of that undesirable helper function - "introduce kasan.write_only option in hw-tags" from Yeoreum Yun creates a KASAN read-only mode for ARM, using that architecture's memory tagging feature. It is felt that a read-only mode KASAN is suitable for use in production systems rather than debug-only - "mm: hugetlb: cleanup hugetlb folio allocation" from Kefeng Wang does some tidying in the hugetlb folio allocation code - "mm: establish const-correctness for pointer parameters" from Max Kellermann makes quite a number of the MM API functions more accurate about the constness of their arguments. This was getting in the way of subsystems (in this case CEPH) when they attempt to improving their own const/non-const accuracy - "Cleanup free_pages() misuse" from Vishal Moola fixes a number of code sites which were confused over when to use free_pages() vs __free_pages() - "Add Rust abstraction for Maple Trees" from Alice Ryhl makes the mapletree code accessible to Rust. Required by nouveau and by its forthcoming successor: the new Rust Nova driver - "selftests/mm: split_huge_page_test: split_pte_mapped_thp improvements" from David Hildenbrand adds a fix and some cleanups to the thp selftesting code - "mm, swap: introduce swap table as swap cache (phase I)" from Chris Li and Kairui Song is the first step along the path to implementing "swap tables" - a new approach to swap allocation and state tracking which is expected to yield speed and space improvements. This patchset itself yields a 5-20% performance benefit in some situations - "Some ptdesc cleanups" from Matthew Wilcox utilizes the new memdesc layer to clean up the ptdesc code a little - "Fix va_high_addr_switch.sh test failure" from Chunyu Hu fixes some issues in our 5-level pagetable selftesting code - "Minor fixes for memory allocation profiling" from Suren Baghdasaryan addresses a couple of minor issues in relatively new memory allocation profiling feature - "Small cleanups" from Matthew Wilcox has a few cleanups in preparation for more memdesc work - "mm/damon: add addr_unit for DAMON_LRU_SORT and DAMON_RECLAIM" from Quanmin Yan makes some changes to DAMON in furtherance of supporting arm highmem - "selftests/mm: Add -Wunreachable-code and fix warnings" from Muhammad Anjum adds that compiler check to selftests code and fixes the fallout, by removing dead code - "Improvements to Victim Process Thawing and OOM Reaper Traversal Order" from zhongjinji makes a number of improvements in the OOM killer: mainly thawing a more appropriate group of victim threads so they can release resources - "mm/damon: misc fixups and improvements for 6.18" from SeongJae Park is a bunch of small and unrelated fixups for DAMON - "mm/damon: define and use DAMON initialization check function" from SeongJae Park implement reliability and maintainability improvements to a recently-added bug fix - "mm/damon/stat: expose auto-tuned intervals and non-idle ages" from SeongJae Park provides additional transparency to userspace clients of the DAMON_STAT information - "Expand scope of khugepaged anonymous collapse" from Dev Jain removes some constraints on khubepaged's collapsing of anon VMAs. It also increases the success rate of MADV_COLLAPSE against an anon vma - "mm: do not assume file == vma->vm_file in compat_vma_mmap_prepare()" from Lorenzo Stoakes moves us further towards removal of file_operations.mmap(). This patchset concentrates upon clearing up the treatment of stacked filesystems - "mm: Improve mlock tracking for large folios" from Kiryl Shutsemau provides some fixes and improvements to mlock's tracking of large folios. /proc/meminfo's "Mlocked" field became more accurate - "mm/ksm: Fix incorrect accounting of KSM counters during fork" from Donet Tom fixes several user-visible KSM stats inaccuracies across forks and adds selftest code to verify these counters - "mm_slot: fix the usage of mm_slot_entry" from Wei Yang addresses some potential but presently benign issues in KSM's mm_slot handling * tag 'mm-stable-2025-10-01-19-00' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (372 commits) mm: swap: check for stable address space before operating on the VMA mm: convert folio_page() back to a macro mm/khugepaged: use start_addr/addr for improved readability hugetlbfs: skip VMAs without shareable locks in hugetlb_vmdelete_list alloc_tag: fix boot failure due to NULL pointer dereference mm: silence data-race in update_hiwater_rss mm/memory-failure: don't select MEMORY_ISOLATION mm/khugepaged: remove definition of struct khugepaged_mm_slot mm/ksm: get mm_slot by mm_slot_entry() when slot is !NULL hugetlb: increase number of reserving hugepages via cmdline selftests/mm: add fork inheritance test for ksm_merging_pages counter mm/ksm: fix incorrect KSM counter handling in mm_struct during fork drivers/base/node: fix double free in register_one_node() mm: remove PMD alignment constraint in execmem_vmalloc() mm/memory_hotplug: fix typo 'esecially' -> 'especially' mm/rmap: improve mlock tracking for large folios mm/filemap: map entire large folio faultaround mm/fault: try to map the entire file folio in finish_fault() mm/rmap: mlock large folios in try_to_unmap_one() mm/rmap: fix a mlock race condition in folio_referenced_one() ...
2025-09-29Merge tag 'execve-v6.18-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull execve updates from Kees Cook: - binfmt_elf: preserve original ELF e_flags for core dumps (Svetlana Parfenova) - exec: Fix incorrect type for ret (Xichao Zhao) - binfmt_elf: Replace offsetof() with struct_size() in fill_note_info() (Xichao Zhao) * tag 'execve-v6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: binfmt_elf: preserve original ELF e_flags for core dumps binfmt_elf: Replace offsetof() with struct_size() in fill_note_info() exec: Fix incorrect type for ret
2025-09-13mm: update coredump logic to correctly use bitmap mm flagsLorenzo Stoakes
The coredump logic is slightly different from other users in that it both stores mm flags and additionally sets and gets using masks. Since the MMF_DUMPABLE_* flags must remain as they are for uABI reasons, and of course these are within the first 32-bits of the flags, it is reasonable to provide access to these in the same fashion so this logic can all still keep working as it has been. Therefore, introduce coredump-specific helpers __mm_flags_get_dumpable() and __mm_flags_set_mask_dumpable() for this purpose, and update all core dump users of mm flags to use these. [lorenzo.stoakes@oracle.com: abstract set_mask_bits() invocation to mm_types.h to satisfy ARC] Link: https://lkml.kernel.org/r/0e7ad263-1ff7-446d-81fe-97cff9c0e7ed@lucifer.local Link: https://lkml.kernel.org/r/2a5075f7e3c5b367d988178c79a3063d12ee53a9.1755012943.git.lorenzo.stoakes@oracle.com Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Christian Brauner <brauner@kernel.org> Acked-by: David Hildenbrand <david@redhat.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Andreas Larsson <andreas@gaisler.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Barry Song <baohua@kernel.org> Cc: Ben Segall <bsegall@google.com> Cc: Borislav Betkov <bp@alien8.de> Cc: Chengming Zhou <chengming.zhou@linux.dev> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: David Rientjes <rientjes@google.com> Cc: David S. Miller <davem@davemloft.net> Cc: Dev Jain <dev.jain@arm.com> Cc: Dietmar Eggemann <dietmar.eggemann@arm.com> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Jann Horn <jannh@google.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Juri Lelli <juri.lelli@redhat.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Kees Cook <kees@kernel.org> Cc: Marc Rutland <mark.rutland@arm.com> Cc: Mariano Pache <npache@redhat.com> Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org> Cc: Mateusz Guzik <mjguzik@gmail.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Mel Gorman <mgorman <mgorman@suse.de> Cc: Michal Hocko <mhocko@suse.com> Cc: Namhyung kim <namhyung@kernel.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Xu <peterx@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Sven Schnelle <svens@linux.ibm.com> Cc: Thomas Gleinxer <tglx@linutronix.de> Cc: Valentin Schneider <vschneid@redhat.com> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: xu xin <xu.xin16@zte.com.cn> Cc: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2025-08-25exec: Fix incorrect type for retXichao Zhao
In the setup_arg_pages(), ret is declared as an unsigned long. The ret might take a negative value. Therefore, its type should be changed to int. Signed-off-by: Xichao Zhao <zhao.xichao@vivo.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20250825073609.219855-1-zhao.xichao@vivo.com Signed-off-by: Kees Cook <kees@kernel.org>