summaryrefslogtreecommitdiff
path: root/kernel
AgeCommit message (Collapse)Author
24 hoursbpf: Disable preemption in bpf_get_stackidJiri Olsa
[ Upstream commit 15f1bd8574662f1b7b26aaa2e23ebf4066f0117d ] The get_perf_callchain call needs disabled preemption plus we need it disabled as long as we access its returned trace entries buffer. Note the bpf_get_stackid_pe function is executed already with preemption disabled. Fixes: d5a3b1f69186 ("bpf: introduce BPF_MAP_TYPE_STACK_TRACE") Reported-by: Tao Chen <chen.dylane@linux.dev> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/bpf/20260803210149.296496-6-jolsa@kernel.org Closes: https://lore.kernel.org/bpf/20260206090653.1336687-2-chen.dylane@linux.dev/ Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursbpf: Use stack id functions instead of __bpf_get_stackidJiri Olsa
[ Upstream commit 09b3fd6caa0b57f8a39254ee5db3af30bdd53c18 ] Replacing __bpf_get_stackid calls with sequence of following functions: stackid_fastpath stackid_new_bucket stackid_install This makes code more structured and allows us to easily disable preemption only in bpf_get_stackid in following changes. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260803210149.296496-5-jolsa@kernel.org Stable-dep-of: 15f1bd857466 ("bpf: Disable preemption in bpf_get_stackid") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursbpf: Factor stackid_new_bucket from __bpf_get_stackidJiri Olsa
[ Upstream commit bb4e6f4e1b68fe60c04ca04c564c6624e837dbf4 ] The new stackid_new_bucket allocates the new bucket and initializes it with the trace data. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260803210149.296496-4-jolsa@kernel.org Stable-dep-of: 15f1bd857466 ("bpf: Disable preemption in bpf_get_stackid") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursbpf: Factor stackid_fastpath function from __bpf_get_stackidJiri Olsa
[ Upstream commit 0ca56befcffec3a6c9d1842eae06c74e1cf41f11 ] The new stackid_fastpath does the fast stack hash and trace check, that does not need new bucket allocation. It covers both just-ip and buildid code paths. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260803210149.296496-3-jolsa@kernel.org Stable-dep-of: 15f1bd857466 ("bpf: Disable preemption in bpf_get_stackid") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursbpf: Factor stackid_init function from __bpf_get_stackidJiri Olsa
[ Upstream commit 15b837759a97237d647962f9943afe0d55af615a ] The new stackid_init function stores all the necessary bits for stackid trace and it will be used by other functions in following changes. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260803210149.296496-2-jolsa@kernel.org Stable-dep-of: 15f1bd857466 ("bpf: Disable preemption in bpf_get_stackid") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursring-buffer: Allow splice reads on static buffersVincent Donnefort
commit 6365c44a824ff138e7926413932bb5c2e28a4c8c upstream. ring_buffer_read_page() rejects splice (full=1) reads on static buffers (that is user-mapped, persistent or remote) because !read check assumes unread pages must be swapped. However for those buffers we have no other choice than memcpy the data. For the memcpy case, only return an error when the writer is still on the reader page for the splice interface to wait. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260901155445.1475405-2-vdonnefort@google.com Fixes: 117c39200d9d ("ring-buffer: Introducing ring-buffer mapping functions") Signed-off-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursperf: Fix use-after-free when perf mmap() revival races with the last munmap()Yilin Zhang
commit 58a8108bc73de0740d5b88150465d6690ea5f85f upstream. perf_mmap_close() drops rb->mmap_count *without* holding event->mmap_mutex (the refcount_dec_and_test() right before the refcount_dec_and_mutex_lock() of event->mmap_count). A concurrent perf_mmap_rb() can slot its entire "revival" path into that window (perf_mmap holds event->mmap_mutex for its whole duration, including rb_alloc): munmap side (perf_mmap_close) mmap side (perf_mmap_rb) ----------------------------------- -------------------------------- rb->mmap_count 1 -> 0 (no lock) (holds event->mmap_mutex) inc_not_zero(rb->mmap_count) fails ring_buffer_attach(event, NULL) rb_alloc() + attach new rb refcount_set(&event->mmap_count, 1) lock; event->mmap_count 1 -> 0 ring_buffer_attach(event, NULL) ring_buffer_put() -> frees the *new* rb The revival's refcount_set(&event->mmap_count, 1) is an invisible 1 -> 1 write: the close frees the just-revived buffer although the other process still has it mapped -- a page-level use-after-free allowing local privilege escalation to root by any unprivileged user (default kernel.perf_event_paranoid=2). Swap the order of the two counter updates: event->mmap_count is dropped first via refcount_dec_and_mutex_lock(), so its 1 -> 0 transition and the ring_buffer_attach() stay serialized with perf_mmap(). rb->mmap_count == 0 then implies every event using the buffer is detached already, so the result of the rb->mmap_count drop can gate the remaining teardown directly and detach_rest is no longer needed. An earlier fix for this race from Kyle Zeng and David Lee takes event->mmap_mutex around both counter updates [0]; here the not-last close stays lockless. Fixes: 59741451b49c ("perf: Identify the 0->1 transition for event::mmap_count") Reported-by: Kimi Security Team <bug-report@moonshot.ai> Suggested-by: Peter Zijlstra <peterz@infradead.org> Co-developed-by: Weiming Shi <shiweiming@moonshot.ai> Signed-off-by: Weiming Shi <shiweiming@moonshot.ai> Signed-off-by: Yilin Zhang <yilinzhang@moonshot.ai> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/linux-perf-users/20260804060931.711308-1-david.lee@trailofbits.com/ [0] Cc: <stable@vger.kernel.org> Cc: stable@vger.kernel.org # 6.18+ Link: https://patch.msgid.link/20260831162155.1437652-1-yilinzhang@moonshot.ai Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hourskprobes: Protect kprobe_blacklist with RCUMasami Hiramatsu (Google)
commit 0c4256196b3a105307e2235fbfd85e768bbcdd0f upstream. __within_kprobe_blacklist() traverses kprobe_blacklist without holding kprobe_mutex. When a module is unloaded, kprobe_remove_area_blacklist() removes blacklist entries and immediately frees them with kfree(). A concurrent call to within_kprobe_blacklist() can therefore dereference freed memory. Furthermore, within_kprobe_blacklist() can be called in atomic or non-preemptible contexts where the sleeping kprobe_mutex cannot be taken. Protect kprobe_blacklist with RCU. Use guard(rcu)() and list_for_each_entry_rcu() for traversal, list_add_tail_rcu() for insertions, list_del_rcu() for deletions, and kfree_rcu() to reclaim entries safely after a grace period. Link: https://lore.kernel.org/all/178810004323.64882.16493230858653316962.stgit@devnote2/ Fixes: 376e242429bf ("kprobes: Introduce NOKPROBE_SYMBOL() macro to maintain kprobes blacklist") Cc: stable@vger.kernel.org Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/all/20260807155802.F06041F000E9@smtp.kernel.org/ Assisted-by: Antigravity:gemini-3.7-flash Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursbpf: Fix infinite loop in pcpu_freelist push with one possible CPUHui Su
commit efebf6496685c93150df5bb0794363ae70c5f58a upstream. __pcpu_freelist_push() can loop forever when only one CPU is possible and an NMI re-enters pcpu_freelist_push() while the interrupted context holds that CPU's freelist lock. After the current-CPU fast path fails, the fallback loop walks cpu_possible_mask while skipping the current CPU. With CONFIG_SMP=n, or when an SMP kernel is limited to one possible CPU with nr_cpus=1 or possible_cpus=1, there are no other possible CPUs to examine. The loop therefore makes no lock acquisition attempt and can never make progress. The following stack was observed on a UP system: NMI context: pcpu_freelist_push free_htab_elem htab_map_delete_elem [perf-event BPF program] __perf_event_overflow perf_event_nmi_handler exc_nmi Interrupted context: __pcpu_freelist_push pcpu_freelist_push free_htab_elem htab_map_delete_elem [raw_tp/sys_enter BPF program] __bpf_trace_sys_enter do_syscall_64 raw_res_spin_lock() detects the same-CPU recursive acquisition and returns -EDEADLK, but the subsequent fallback loop has no candidate head on a system with one possible CPU. Restore the extra fallback head that existed before the rqspinlock conversion. Keep the current-CPU fast path, then try the other possible CPUs and finally the extra head. The additional head lets a push, which cannot fail without losing a preallocated element, make progress when the only per-CPU head is held by the interrupted context. Also check the extra head from the pop path so that nodes placed there can be reused. Fixes: f2ac0e5d1c4d ("bpf: Convert percpu_freelist.c to rqspinlock") Signed-off-by: Hui Su <sh_def@163.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/bpf/20260806175600.1993595-1-sh_def@163.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursdma-direct: return struct page from dma_direct_alloc_from_pool()Aneesh Kumar K.V (Arm)
commit 94a04ad732c9f8b9554270fc4038a06737de5c22 upstream. Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper") changed dma_direct_alloc_from_pool() to return the CPU address from dma_alloc_from_pool(). That fits dma_direct_alloc(), but dma_direct_alloc_pages() also uses the helper and expects a struct page *. Fix this by making dma_direct_alloc_from_pool() return the struct page * again, and pass the CPU address back through an out-parameter for the dma_direct_alloc() caller. Fixes: 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper") Cc: stable@vger.kernel.org Tested-by: Michael Kelley <mhklinux@outlook.com> Tested-by: Mostafa Saleh <smostafa@google.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org> Reviewed-by: Mostafa Saleh <smostafa@google.com> Link: https://lore.kernel.org/r/20260717180442.110954-2-aneesh.kumar@kernel.org Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursftrace: Synchronize the initialization of ftrace_opsSteven Rostedt
commit 4617721c502b2ddaa4e324e86da4997edf738fa5 upstream. There's some internal state that ftrace_ops needs to have set, but since it can be declared outside of the ftrace.c code, it calls ftrace_ops_init() on the ops in every global function. The issue is that if two tasks call it on the same ops at the same time it is possible to have the initialization of one corrupt the initialization of the other call. Create a ops_mutex to use to synchronize every initialization of the ftrace_ops. The mutex is taken within checking the ftrace_ops flag that states it was initializied but the flag is checked again after the mutex has been taken. Checking first outside the mutex allows it to shortcut having to take the mutex. But then the check needs to be done again after the mute is taken in case of races. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock") Reported-by: sashiko-bot@kernel.org Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/ Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursftrace: Take trace_array reference before accessing its ftrace_opsSteven Rostedt
commit 9100191e5acb2e5ea2313f436667bb5fce129f47 upstream. The trace instance files set_ftrace_filter and set_ftrace_notrace was updated to work with specific trace instances (trace_arrays). The issue is that when these files are opened, there is a small race window where it will use the ftrace_ops from the inode->private pointer to get a reference to the trace_array and then take its reference. The problem is that the ftrace_ops itself could be freed. If the rmdir on the instance happens at the same time the set_ftrace_filter file is opened, the rmdir could have also freed the ftrace_ops and referencing it will cause a use-after-free bug and crash the kernel. Instead, pass in the trace_array as the file private data (NULL for the top level instance), and then pass both the trace_array and the ftrace_ops to the ftrace_regex_open() function. If the trace_array is NULL, then it just uses the ftrace_ops without the need to take its reference (like normal). If the ftrace_ops is NULL, that is only the case for the top level instance and the global_ops can be used. This allows the trace_array to have its reference incremented before touching the ftrace_ops that could also be freed when the instance is. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260828223901.29e26edb@robin Fixes: 591dffdade9f0 ("ftrace: Allow for function tracing instance to filter functions") Reported-by: Breno Leitao <leitao@debian.org> Tested-by: Breno Leitao <leitao@debian.org> Closes: https://lore.kernel.org/all/apGORjltZgAiAYHT@gmail.com/ Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursfutex: Provide rt_mutex_.*_schedule() equivalents for futex schedulingSebastian Andrzej Siewior
commit 912edebe8501a36c6bedcef03bd238ab90a7e060 upstream. There is rt_mutex_{pre|post}_schedule() around rt_mutex_wait_proxy_lock() to ensure that sched_submit_work()/ sched_update_worker() is invoked before we schedule out and block on rt_mutex while waiting for it become available. The reason is that blocking on rt_mutex assigns a pi_waiter for the PI chain and sched_submit_work() will also assign a pi_waiter if it blocks on lock but a this point we already have a waiter assigned. We can't skip sched_submit_work() entirely because I/O relies on the fact that I/O queue is flushed while it blocks on a sleeping lock. Therefore sched_submit_work() is moved before we block on the lock. Sleeping lock in this context means mutex or rw_semaphore not spinlock_t on PREEMPT_RT. Because the mutex abstraction on PREEMPT_RT uses the same abstraction as the futex proxy lock, the futex code ended up using rt_mutex_{pre|post}_schedule(), too. Using it is/ was just to keep the task_struct::sched_rt_mutex assertion happy. Futex proxy lock is used only in the syscall context of a task. At this point it never got any I/O that needs to be flushed and it can't be a workqueue that needs to notify that it will be scheduled out. Therefore sched_submit_work() does nothing here. By mistake futex_wait_requeue_pi() -> rt_mutex_wait_proxy_lock() did not get the rt_mutex_{pre|post}_schedule() annotation. This was not noticed because in this callchain the lock is (usually) not contended and so rt_mutex_slowlock_block() does not schedule, triggering the assert. Adding rt_mutex_pre_schedule() here looks wrong (as noted by PeterZ) because at this point there is a pi_waiter recorded and invoking sched_submit_work() with a possible lock contention would be wrong. Add rt_mutex_futex_{pre|post}_schedule() which toggles the sched_rt_mutex assert and does not involve sched_submit_work(). Add asserts here to ensure that sched_submit_work() would do nothing. Use it only in futex proxy lock case which is rt_mutex_wait_proxy_lock(). Remove it from futex_lock_pi(). Fixes: d14f9e930b90 ("locking/rtmutex: Use rt_mutex specific scheduler helpers") Reported-by: Yao Kai <yaokai34@huawei.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260901135453.3121948-2-bigeasy@linutronix.de Closes: https://lore.kernel.org/all/20260717084922.4153317-2-yaokai34@huawei.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hoursfutex: Prevent rcuwait use-after-free during requeue PIYao Kai
commit a3b8d46fe401cba3a5c46dea610e6eb3dc15370e upstream. On PREEMPT_RT, FUTEX_CMP_REQUEUE_PI can trigger a KASAN report (slab-out-of-bounds) in futex_requeue_pi_complete() invocation of rcuwait_wake_up(). The futex_q used by futex_wait_requeue_pi() is allocated on the waiter's stack. An early wakeup can race with a PI requeue as follows: waiter requeue task ------ ------------ futex_wait_requeue_pi() futex_do_wait() schedule() futex_requeue futex_proxy_trylock_atomic() futex_requeue_pi_prepare() Q_REQUEUE_PI_NONE -> Q_REQUEUE_PI_IN_PROGRESS * timeout/ signal wakes waiter * futex_requeue_pi_wakeup_sync() Q_REQUEUE_PI_IN_PROGRESS -> Q_REQUEUE_PI_WAIT requeue_pi_wake_futex futex_requeue_pi_complete() cmpxchg Q_REQUEUE_PI_WAIT -> Q_REQUEUE_PI_LOCKED rcuwait_wait_event() if (atomic_read(&q->requeue_state) != Q_REQUEUE_PI_WAIT) break /* no schedule() */ /* q.pi_state->owner == current */ futex_private_hash_put() /* return from syscall */ rcuwait_wake_up(&q->requeue_wait) /* q is gone */ futex_requeue_pi_complete() publishes Q_REQUEUE_PI_LOCKED before calling rcuwait_wake_up(). The waiter observes this state in rcuwait_wait_event() before invoking schedule() in rcuwait_wait_event(). Here, the waiter is free leave the syscall before requeue task can complete the wake. To address this race skip rcuwait_wake_up() in the Q_REQUEUE_PI_LOCKED case. This state is only published by requeue_pi_wake_futex(), which saves q->task before futex_requeue_pi_complete() and wakes the waiter via wake_up_state(). This wake is intended to wake the waiter from its futex_do_wait() sleep. If the waiter is still sleeping there, it can not get into the Q_REQUEUE_PI_WAIT state (and require this removed wake). Should the waiter be woken up from futex_do_wait() by other means (as in this example) and sleep in futex_requeue_pi_wakeup_sync() then the wake_up_state() from requeue_pi_wake_futex() will wake it, too. Should the waiter task terminate before wake_up_state() had a chance to wake the task then the task pointer does not become invalid because the futex_hash_bucket::lock is held and the task pointer is RCU protected. [bigeasy: Updated comment and commit message] Fixes: 07d91ef510fb1 ("futex: Prevent requeue_pi() lock nesting issue on RT") Signed-off-by: Yao Kai <yaokai34@huawei.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260901135453.3121948-3-bigeasy@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hourstracing: Take trace_array reference when opening options fileSteven Rostedt
commit f2951ebd15c36a1ea4820a7f0cbb0b5f1c028b73 upstream. The options files do not take the trace_array reference for the options they represent. This could cause a use-after-free kernel crash if one of these files is opened by one task and another task removes the instance that the option is for. Because it doesn't take a reference upon opening, it will not stop the removal which will free the options descriptor that is being used. As the options are somewhat dynamic in their creation at boot up, each file represents a flag in the trace_array. The trace_array has an array of indexes to represent each of these flags that is stored in the trace_flags_index array. The address of the index array element is used to pass to the inode->i_private pointer. Then that element is read which holds the index (which represents the flag) and then the index is used to calculate the trace_array descriptor from its trace_flags_index array. One issue is that the index element can not be referenced until the trace_array's reference is taken. To handle this, create a new helper function called: trace_array_options_get() that will iterate all the existing trace_arrays in the ftrace_trace_arrays list (under the trace_types_lock), and compare the passed in address of the index element with the entire array of the trace_array's trace_flags_index array. If it matches, then up the corresponding trace_array's reference and return. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260902121918.5a9e9d1b@gandalf.local.home Fixes: 577b785f55168 ("tracing: add tracer dependent options to options directory") Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/linux-trace-kernel/20260828135858.2AC501F000E9@smtp.kernel.org/ Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hourstracing: Have show_event_filters/triggers files take trace array refSteven Rostedt
commit f4a771cc684c7354b6200147f7252c58d17408ff upstream. The newly added files show_event_filters and show_event_triggers that show all filters or triggers that are set within the trace array do not take a reference for the trace array it is showing. Without taking a reference, the trace_array may be freed via "rmdir" while a task is reading one of theses files. Those files iterate all the events within an instance (trace_array) and nothing prevents that instance from being freed while its data is being read. This causes a use-after-free crash. Have the open of both those files take the trace_array reference via the trace_array_get() that prevents the trace_array from being freed while the files are opened. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260828094153.17b95037@gandalf.local.home Fixes: 729757b96a662 ("tracing: Add show_event_filters to expose active event filters") Fixes: 6a80838814eea ("tracing: Add show_event_triggers to expose active event triggers") Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu> Closes: https://lore.kernel.org/all/CA+0ovCjerKZJLwXScM9bF2ga2rLi4_XOpUfK41NDbENpeu98jA@mail.gmail.com/ Reviewed-by: Aaron Tomlin <atomlin@atomlin.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 hourstracing/probes: Fix anon_stack check for unnamed bitfields in ↵Masami Hiramatsu (Google)
btf_find_struct_member commit f36d94a20ca185bcadef3a10b980cd2cfd72d53a upstream. btf_find_struct_member() traverses into nested anonymous structures and unions by pushing members with !member->name_off onto anon_stack. However, it does not consider the unnamed bitfields (e.g. `int : 5` or `unsigned int : 0`) which also have member->name_off == 0. If such an unnamed bitfield is pushed to anon_stack, the btf_find_struct_member() return an error even if there are other valid entries in anon_stack. To fix this, only push unnamed struct/union members to anon_stack. Also move the btf_type_is_struct() check to the entry of this function because now it is sure only struct/union are pushed to anon_stack. Link: https://lore.kernel.org/all/178827249775.123716.7813217688423513612.stgit@devnote2/ Fixes: 302db0f5b3d8 ("tracing/probes: Add a function to search a member of a struct/union") Cc: stable@vger.kernel.org Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/all/20260830143859.D56991F00A3D@smtp.kernel.org/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Reviewed-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daystimer: Keep debugobjects state consistent in migrate_timer_list()Thomas Gleixner
commit c793bbfc4a0a9f5a66978fc91559e9681748dbeb upstream. When timers are migrated away from an offline CPU the debugobjects state gets corrupted. The timer is accounted as inactive on deletion, but the enqueue on the alive CPU lacks the activation call. That used to work, but got broken when the trace point and the debug objects call got separated. That change missed to fixup migrate_timer_list(). Add the missing debug_timer_activate() invocation to fix it. Fixes: dc1e7dc5ac62 ("timer: Move trace point to get proper index") Signed-off-by: Thomas Gleixner <tglx@kernel.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/87bjb0l7ha.ffs@fw13 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daystimekeeping: Check the return value of tk_get_aux_ts64 in __do_adjtimex()Thomas Weißschuh (Schneider Electric)
commit 4b61084b11bcecce86d03804ff30f8d7b465593c upstream. If the auxiliary clock is disabled during tk_get_aux_ts64() but is enabled before tks->clock_valid is checked, then uninitialized stackdata will be used in the calculations and indirectly leaked to userspace. The same race window also exists after this change and also for the core timekeeper. But in these cases the only effect would be incorrect adjustments and this is userspace's responsibility to avoid this. Fixes: 4eca49d0b621 ("timekeeping: Prepare do_adtimex() for auxiliary clocks") Signed-off-by: Thomas Weißschuh (Schneider Electric) <thomas.weissschuh@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260731-timekeeping-aux-adjtimex-return-v1-1-b7fea4692886@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daystaskstats: fix cpumask parsing cutting off the last characterBradley Morgan
commit 1f58a5335cdd14b3fb5f2a5d3763dee1f5cba1d3 upstream. parse() hands nla_strscpy() len as dstsize, and nla_strscpy() copies at most dstsize - 1 bytes. When the attr payload comes in without a trailing NUL, srclen == len >= dstsize and the last character of the cpumask string gets cut off. Register "0-15" and you are silently listening on "0-1", exit data for the rest never shows up. The bug only bites when the sender doesn't NUL terminate the payload; senders that include the NUL were always fine (srclen gets decremented for the trailing NUL, so srclen < dstsize). Thats probably why this survived 20 years. And the policy is NLA_STRING, not NLA_NUL_STRING, so a payload without the trailing NUL is legit input here. Skip the kmalloc/nla_strscpy dance entirely and use nla_strdup(), which already allocates srclen + 1 and terminates. The nla_len() bounds checks stay as they were. Link: https://lore.kernel.org/EC49FE41-7F5F-41E0-A07A-ABEB8ECA514D@grrlz.net Fixes: f9fd8914c1ac ("[PATCH] per-task delay accounting taskstats interface: control exit data through cpumasks") Signed-off-by: Bradley Morgan <include@grrlz.net> Reported-by: Oleg Deomi <oleg.deomi@gmail.com> Closes: https://lore.kernel.org/CAByWkfZ6b1=3H9pwkz-dDQOs9cZaF-HYQ6b9Yb0=Hq2r1Vv_Pw@mail.gmail.com Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Balbir Singh <bsingharora@gmail.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssignal: avoid shared siginfo namespace rewritesBradley Morgan
commit d19cdc167e696714509e87d3f7ae765b6e164589 upstream. send_signal_locked() rewrites sender ids for the target namespace. Group sends reuse the same siginfo, so one recipient can affect the next. Copy the siginfo before changing it. Link: https://lore.kernel.org/86a8857d58d43ee26a8b365b837fd24830343494.1782159692.git.include@grrlz.net Fixes: 7a0cf094944e ("signal: Correct namespace fixups of si_pid and si_uid") Signed-off-by: Bradley Morgan <include@grrlz.net> Acked-by: Oleg Nesterov <oleg@redhat.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Adrian Huang <adrianhuang0701@gmail.com> Cc: Aleksandr Nogikh <nogikh@google.com> Cc: Christian Brauner <brauner@kernel.org> Cc: Marco Elver <elver@google.com> Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[]Oleg Nesterov
commit 7170ca01623b399c97f2ae9d3e228badc1f25ea3 upstream. cad_pid is global, and kill_cad_pid() is only used in the root namespace. However, due to pid_table_root_permissions(), a non-root user can unshare pid/user namespaces and modify it from the child namespace. This makes no sense and is simply wrong. Move it to kern_reboot_table[] where it logically belongs; this ensures that only GLOBAL_ROOT_UID can read/modify this sysctl. Note that this patch doesn't preserve "#ifdef CONFIG_PROC_SYSCTL" around the "cad_pid"; CONFIG_PROC_SYSCTL selects CONFIG_SYSCTL, so it is always set when kern_reboot_table[] is compiled. Cc: stable@vger.kernel.org Fixes: e054bcbe7e7a ("sysctl: move cad_pid into kernel/pid.c") Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Alexey Gladkov <legion@kernel.org> Reviewed-by: Bradley Morgan <include@grrlz.net> Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Signed-off-by: Joel Granados <joel.granados@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysdma-contiguous: fix truncation of numa_cma / cma_pernuma sizes >= 2GAlexander Graf
commit 1476cca098f6d3a553fcec6fe9b7d86e15c00b59 upstream. numa_cma=0:4G reserves nothing at all. dma_numa_cma_reserve() copies the requested size into a local int before handing it to cma_declare_contiguous_nid(), so 0x100000000 truncates to zero and the loop skips the node silently. Both parameters are documented in kernel-parameters.txt as nn[MG], so that is the syntax the documentation invites. Which bits survive decides what a request turns into: 4G, 8G and 16G reserve nothing, 2G, 3G and 6G sign-extend into a size the allocator rejects with a warning, and 5G quietly reserves 1G. It reaches further than those parameters. On a CMA_SIZE_PERNUMA kernel with no per-node parameter, dma_numa_cma_reserve() takes the per-node size from the default area, so a plain cma=4G on a multi-node machine feeds that size through the same local and loses every per-node area. numa_cma_size[] and pernuma_size_bytes are both phys_addr_t, so use it for the local too, and give early_numa_cma() separate variables for the node id and the size while in there. Fixes: d5cae2261b86 ("dma-contiguous: simplify numa cma area handling") Cc: stable@vger.kernel.org Assisted-by: Kiro:claude-opus-5 Signed-off-by: Alexander Graf <graf@amazon.com> Reviewed-by: Feng Tang <feng.tang@linux.alibaba.com> Link: https://lore.kernel.org/r/20260821224252.70640-1-graf@amazon.com Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysring-buffer: Stop remote reader update when page swap failsIvan Immanuel Shaji
commit 5eab74874d11160725c42ab676ba97a797a362eb upstream. The remote swap_reader_page callback can return -EBUSY when the writer moves the head before the remote catches it, particularly during an event storm on a small buffer. __rb_get_reader_page_from_remote() currently warns about that failure but continues with the unchanged reader ID and rearranges the local page list as though the swap succeeded. Handle the callback failure as a recoverable error. Report it with pr_warn_ratelimited() and return NULL. Callers already handle a NULL reader page as a failed attempt. This avoids splicing the same page as both the previous and new reader without flooding the log under contention. Cc: stable@vger.kernel.org Fixes: 2e67fabd8b77 ("ring-buffer: Introduce ring-buffer remotes") Link: https://patch.msgid.link/20260825-kernel-patch-1-v2-2-bb3461807a32@gmail.com Assisted-by: LLM sparse Signed-off-by: Ivan Immanuel Shaji <ivanimmanuel1234@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysring-buffer: Make cpu_buffer::free_page a buffer_data_read_pageVincent Donnefort
commit 7a1fb95de5404134f8758c1295ce88986bdf117c upstream. Discarding a cached reader page after a concurrent ring buffer resize uses the new global subbuf_order for the free_pages() call. This mismatched order may crashes the kernel or leaks memory because the cached page was allocated under the old size. Save the actual free_page order alongside the page address to ensure we always refer to the correct value and do not rely on the potentially stalled cpu_buffer->subbuf_order value. The simplest is to make free_page a buffer_data_read_page which already covers exactly what we need: a page address and a page order. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260813131152.3589632-4-vdonnefort@google.com Fixes: 8e7b58c27b3c ("ring-buffer: Just update the subbuffers when changing their allocation order") Signed-off-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysring-buffer: Hold cpu_buffer::lock when resizing a subbufVincent Donnefort
commit 24974bd0da1b47fd56c975533ead50abf754e74d upstream. Because, ring_buffer_subbuf_order_set() can clear cpu_buffer->free_page, hold cpu_buffer->lock to prevent races with ring_buffer_alloc_read_page() and ring_buffer_free_read_page(). Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260813131152.3589632-3-vdonnefort@google.com Fixes: 8e7b58c27b3c ("ring-buffer: Just update the subbuffers when changing their allocation order") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260810125633.3344684-1-vdonnefort%40google.com # patch 3 Signed-off-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysring-buffer: Free cpu_buffer::free_page with subbuf_orderVincent Donnefort
commit 234b1a72e9706fe20c08c96f4374ec8e83b934cb upstream. When sub-buffers use an order greater than 0, cpu_buffer->free_page is allocated with subbuf_order. Use the correct order for cpu_buffer->free_page. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260813131152.3589632-2-vdonnefort@google.com Fixes: f9b94daa542a ("ring-buffer: Set new size of the ring buffer sub page") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260806211306.3704194-1-vdonnefort%40google.com # patch 3 Signed-off-by: Vincent Donnefort <vdonnefort@google.com> Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page()Vincent Donnefort
commit e743527c5bfdceda1095bc0a9e596e2aebb6a9c3 upstream. ring_buffer_alloc_read_page() is racy with ring_buffer_subbuf_order_set, it can allocate a reader page with an outdated order. This isn't a big issue, the user can still re-allocate a new reader page and try again. However, what is more problematic is if the value of subbuf_order changes in the middle of ring_buffer_alloc_read_page(). In that case, bpage->order might not match the actual allocated memory. Use bpage->order for the allocation to prevent this race. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260813131152.3589632-6-vdonnefort@google.com Fixes: bce761d75745 ("ring-buffer: Read and write to ring buffers with custom sub buffer size") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched_ext: Keep kick_sync waiting on the rq's own CPUTejun Heo
commit e0253dd04beb03e79477c5ef4768b11135687206 upstream. kick_sync_wait_bal_cb() assumes it runs on the rq's CPU from the __schedule() tail: the snapshots it compares against live in that CPU's percpu area and the busy-wait runs with the rq lock dropped and IRQs enabled. However, dispatch can now drop the rq lock while the callback sits queued, and rq lock takers in that window (the sched class change paths, the scx task iterator) flush pending balance callbacks on release, running the callback on a foreign CPU. Such a run compares against unrelated snapshots and can deadlock when the executing CPU is itself a wait target. Bail on a foreign CPU and leave the wait state alone. The wait only observes progress that the resched kicks already guarantee and the rq's next wait picks up the stale cpus_to_sync bits. Fixes: 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()") Cc: stable@vger.kernel.org # v6.19+ Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched_ext: Don't BUG_ON a destroyed DSQ in process_deferred_reenq_usersTao Cui
commit 8d8dd8ae89eaa78b37fc85528e926029f5facbdf upstream. scx_bpf_dsq_reenq() queues a deferred reenq (dru) that runs from run_deferred(), not ops.dispatch(). If the DSQ is destroyed before the dru runs, process_deferred_reenq_users() sees dsq->id == SCX_DSQ_INVALID and hits the BUG_ON. destroy_dsq() doesn't flush pending drus, so just skip. tj: Read dsq->id once with READ_ONCE(). Reading it separately in the INVALID check and the BUG_ON would leave a window where destroy_dsq() can invalidate the id between the two reads and still trigger the BUG_ON. Fixes: 84b1a0ea0b7c ("sched_ext: Implement scx_bpf_dsq_reenq() for user DSQs") Cc: stable@vger.kernel.org # v7.1+ Signed-off-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched_ext: Fix inverted ops.core_sched_before() invocationTejun Heo
commit f7b6d128dd49a6eec09066ecfd29095f12588786 upstream. scx_prio_less() implements prio_less() semantics - %true means that @a is the lower priority and should run after @b. ops.core_sched_before() is documented to return %true when @a should run before @b. scx_prio_less() returns the op's value as-is, inverting the documented semantics at runtime. Call the op with the arguments swapped. scx_qmap followed the wiring instead of the documentation and returned %true for the younger task, so the two inversions canceled out and it behaved as intended. Flip its comparison to match. scx_qmap is likely the only current user in or out of the kernel tree. Any scheduler written the same way needs the same flip, while schedulers following the documentation are fixed by this change. Fixes: 7b0888b7cc19 ("sched_ext: Implement core-sched support") Cc: stable@vger.kernel.org # v6.12+ Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched_ext: Fix exit_task leak on fork failure during enablefangqiurong
commit 03506edca637a8465dba9f635c50e9884fbcaf4e upstream. scx_fork() initializes tasks when scx_init_task_enabled is set, but scx_cancel_fork() only exits them when scx_enabled() is true. A fork that fails in the enable window (between releasing scx_fork_rwsem and setting __scx_enabled) runs ops.init_task() but never ops.exit_task(). Gate scx_cancel_fork() on scx_init_task_enabled. Fixes: 4269c603cc26 ("sched_ext: Enable scx_ops_init_task() separately") Cc: stable@vger.kernel.org # v6.12+ Signed-off-by: fangqiurong <fangqiurong@kylinos.cn> Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched_ext: Count rq lock releases in rq->scx.lock_drop_seqTejun Heo
commit f2da9587118d5da41a3f81a59642d5bb4782ddcc upstream. Under core scheduling, pick_next_task() selects for all SMT siblings under one continuous hold of the shared core-wide rq lock, and sched_ext's dispatch can release that lock from inside the pick. In preparation for making the core-sched pick detect the releases and retry, add rq->scx.lock_drop_seq and bump it at every site that can release an rq lock while a dispatch may be in flight. The counter is only maintained while core scheduling is enabled. No functional changes. Fixes: 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()") Cc: stable@vger.kernel.org # v6.19+ Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched_ext: Fix rq->core_pick corruption under core schedulingTejun Heo
commit d954004205c1a1d3f59ce8482b559266c15600fa upstream. Core scheduling's pick_next_task() picks what to run on every SMT sibling of the core in a single pass under the shared core-wide rq lock. The selection state is consistent only while the lock is held continuously, so ->pick_task() originally could not release it. However, since 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()"), sched_ext runs dispatch from inside the pick and dispatching can drop the rq lock. To support this, pick_next_task() has been updated to restart the whole selection when a pick returns RETRY_TASK after releasing the lock. When selections on the same core interleave through the dropped lock, they corrupt each other's state: one clears the other's rq->core_pick leading to a NULL deref, or invalidates its keep-the-previous-task decision leaving a dequeued task running, which deadlocks the next wakeup and matches the reported hard hangs. A cookied ping-pong load on an SMT machine makes the interleavings frequent and kills the kernel within seconds. Fix it by making the pick return RETRY_TASK whenever dispatch released the rq lock, so that a selection only ever commits picks made under a continuously held lock. The previous patch's rq->scx.lock_drop_seq counts the releases. A dispatch that touched nothing never releases the lock and its verdict, including "nothing to run", stands: retries are bounded, each following a dispatch that actually did something, and an idle CPU does not loop. If another dispatch is already in flight on the rq, skip dispatching and pick from what is already queued locally - the in-flight dispatch has released the lock, so its own selection will retry and re-pick this rq, while returning RETRY_TASK here would only spin on the lock that dispatch needs to finish. Balance callbacks must run in the context that queued them, so they can only be queued on the CPU's own rq. When dispatching for another rq, run the deferred work directly instead - that rq may consume all its picks through the core-sched fast path and never queue the callback itself. The put_prev_task_scx() warning about a runnable task being left behind assumed that dispatch ran as part of the very pick that is switching away. That now only holds on the non-core path, so gate it and drop the cookie-match test, which is always true without core scheduling, from its condition. Fixes: 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()") Cc: stable@vger.kernel.org # v6.19+ Reported-by: ElXreno <elxreno@gmail.com> Link: https://github.com/sched-ext/scx/issues/3715 Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched_ext: Fix this_rq() assumptions in dispatch kfuncsTejun Heo
commit 3dd52416e44a70bc993adb96d2e0d71b9ea21359 upstream. Under core scheduling, dispatch runs from within the core-wide pick and can target a sibling rq, so ops.dispatch() may execute on a CPU different from the dispatched rq's. Several kfunc paths assumed the two always coincide: - scx_dsq_move() decided whether an rq lock is held by testing this_rq()'s rq flags and lock-danced accordingly. A dispatch for a sibling took the unlocked-context branch and acquired the source rq lock on top of the already held dispatched rq lock which could deadlock. - scx_bpf_sub_dispatch() dispatched this_rq() with its stashed sub_dispatch_prev, which is NULL when dispatching for a sibling. - finish_dispatch(), scx_bpf_dsq_reenq() and scx_bpf_dsq_nr_queued() resolved SCX_DSQ_LOCAL to this CPU's local DSQ rather than the dispatched rq's. The latter two are callable from other rq-locked operations too, where SCX_DSQ_LOCAL now likewise resolves to the op's rq. This changes behavior also without core scheduling, e.g. for ops.enqueue() running a remote wakeup on the waking CPU, and is intended: which CPU happens to execute an operation is incidental, the op's rq is what it is operating on, and the resolution now matches the insert side where SCX_DSQ_LOCAL dispatches land on the task's rq. Use the rq tracked by scx_locked_rq(), which is set to the dispatched rq around ops invocations and NULL in unlocked contexts. Fixes: 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()") Cc: stable@vger.kernel.org # v6.19+ Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched_ext: Replace SCX_RQ_BAL_KEEP with a dispatch verdict returnTejun Heo
commit ffaab58d217581cb75353168f8812a16e10463fc upstream. SCX_RQ_BAL_KEEP tells the pick to keep running the previous task, a leftover from when balancing and picking were separate operations. An rq-level flag only works while dispatches and picks pair up one to one, which core scheduling breaks: selections interleave through dispatch's lock drops and a pick can consume a stale flag, keeping a task that has since been dequeued. Fixing core scheduling support requires the decision to travel with the dispatch that made it. Make scx_dispatch_sched() and balance_one() return an explicit verdict instead and drop the flag's plumbing from the tools autogen enum headers. Also factor the pick-side invocation, its follow-up queueing and the post-dispatch checks out of do_pick_task_scx() into dispatch_pick(). No functional changes intended. v2: Drop the SCX_RQ_BAL_KEEP plumbing from the tools autogen enum headers as well (Andrea). Fixes: 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()") Cc: stable@vger.kernel.org # v6.19+ Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched/core: Make core-sched flips wait for in-flight selectionsTejun Heo
commit f3629c63a4af3e491381780bc6c123cb498c4c40 upstream. Core scheduling's pick_next_task() operates on all sibling rqs under one acquisition of the shared core-wide lock. A ->pick_task() that releases the rq lock leaves every sibling __lock momentarily free, letting __sched_core_flip(false) complete mid-selection and rebind rq_lockp() under it. The selection resumes on the split locks, touching sibling state it no longer protects, and __schedule() finally releases a lock that was never taken while leaking the one that was. Count in-flight core-wide selections in the leader's rq->core_pick_in_flight and make __sched_core_flip() wait for the count to drain. The count only changes under the shared lock, which the flip holds while sampling, so no other ordering is needed. The wait can repeat while selections overlap, but the flip backs off between samples and flips are rare cookie-lifetime events. sched_core_cpu_deactivate() moves the count to the new leader - a stale copy left behind would bias it forever if that CPU later returns as its own leader. Fixes: 539f65125d20 ("sched: Add core wide task selection and scheduling") Cc: stable@vger.kernel.org # v5.14+ Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayssched/core: Handle pick_task() releasing the rq lockTejun Heo
commit c10b216a072ff5c57bc880a05f87eb519aecc529 upstream. Core scheduling's pick_next_task() breaks when a ->pick_task() implementation can release the rq lock. The selection state derived on entry is only valid while the lock is held continuously. Once a pick can drop the lock, an interleaving selection can invalidate all of it: the single-CPU fast path can commit an uncookied pick although the core went cookied during the release, and forceidle committed by the interleaving selection skews the restarted pass's accounting. Fix it by restarting the whole selection when a pick returns RETRY_TASK after releasing the lock: a single restart point above the state derivation replaces the per-loop restart labels, so a retry picks up state committed by interleaving selections and accounts and resets forceidle like a fresh selection would. need_sync and fi_before latch across retries. Clock validity can't be re-derived - there is no program-ordered way to tell whether the own and core rq clocks are still updated after the lock was released, as other lockers' pin cycles may or may not have invalidated them. When restarting, clear core_clock_updated so that the sibling loop re-updates the core rq, and update the own rq clock if invalidated. Fixes: 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()") Cc: stable@vger.kernel.org # v6.19+ Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysparams: fix charp corruption on allocation failureJiacheng Yu
commit 3dfaae04243cde460d82dfc2a7dd0bb6664d20ae upstream. param_set_charp() stores charp parameters in allocated memory after slab is available, and releases the previous value when the parameter is updated. The previous value is released before the replacement allocation succeeds. If kmalloc_parameter() fails, the setter returns -ENOMEM with the parameter left as NULL. Failing zswap's compressor update before zswap is initialized can later trigger: BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: 0010:strcmp+0x10/0x30 Call Trace: zswap_setup+0x3b1/0x490 zswap_enabled_param_set+0x5b/0xa0 param_attr_store+0x93/0xe0 module_attr_store+0x1c/0x30 kernfs_fop_write_iter+0x116/0x1f0 Allocate and copy the replacement first, then replace the parameter value only after allocation succeeds. Fixes: e180a6b7759a ("param: fix charp parameters set via sysfs") Cc: stable@vger.kernel.org Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com> Reviewed-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysmodule/kallsyms: fix nextval for data symbol lookupStanislaw Gruszka
commit 0e9f090a4e9bfae5a190ccf89eab3bf14f6b0f96 upstream. The symbol lookup code assumes the queried address resides in either MOD_TEXT or MOD_INIT_TEXT. This breaks for addresses in other module memory regions (e.g. rodata or data), resulting in incorrect upper bounds and wrong symbol size. Select the module memory region the address belongs to instead of hardcoding text sections. Also initialize the lower bound to the start of that region, as searching from address 0 is unnecessary. Cc: stable@vger.kernel.org Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl> Reviewed-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysmodule: validate string table section typesThiébaud Weksteen
commit 9a5ff45689329835f874cefe5174e577d141d423 upstream. In elf_validity_cache_sechdrs, section sizes and offsets are validated, unless the section type is SHT_NULL or SHT_NOBITS. Later, elf_validity_cache_secstrings and elf_validity_cache_index_str access the section name table (.shstrtab) and symbol string table (.strtab) headers without first ensuring that their types are SHT_STRTAB. If a section type is SHT_NULL or SHT_NOBITS, sh_offset has not been validated and may reference out-of-bounds memory when dereferenced in elf_validity_cache_secstrings or elf_validity_cache_strtab. Validate that both string section headers are of type SHT_STRTAB before caching them. Cc: stable@vger.kernel.org Signed-off-by: Thiébaud Weksteen <tweek@google.com> Reviewed-by: Aaron Tomlin <atomlin@atomlin.com> Reviewed-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayskho: fix size calculation in kho_preserved_memory_reserve()Pratyush Yadav (Google)
commit 3a0b8fa2eb36afc88b62a95f33f0c77c71fa5ded upstream. kho_preserved_memory_reserve() calculates the size of a preservation by doing 1 << (order + PAGE_SHIFT). Since the '1' is a 32-bit integer, it can only be shifted by 31. That is, it will only work for preservations up to 2 GiB. Larger preservations will trigger undefined behaviour. While preservations larger than 2 GiB can't be obtained via folios currently, they can be obtained via kho_preserve_pages(). For example, memblock reserve_mem uses kho_preserve_pages(). Reservations larger than 2 GiB are valid and will trigger this bug if properly aligned. Fix it by using 1UL for shifting. Fixes: fc33e4b44b27 ("kexec: enable KHO support for memory preservation") Reported-by: Sashiko <sashiko-bot@kernel.org> Cc: stable@vger.kernel.org Signed-off-by: Pratyush Yadav (Google) <pratyush@kernel.org> Link: https://patch.msgid.link/20260727150240.889555-1-pratyush@kernel.org Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 dayscpufreq: schedutil: Fix rate limit overflowHui Su
commit 3bff8f8e95fdc6ad19c8a1a8f87029094747e4bf upstream. rate_limit_us is an unsigned int, while NSEC_PER_USEC is defined as 1000L. On 32-bit systems, the multiplication is therefore performed using 32-bit unsigned arithmetic before the result is assigned to freq_update_delay_ns. For example, writing 4294968 to rate_limit_us wraps the delay from 4294968000 ns to 704 ns. This makes schedutil update far more often than configured. Add sugov_update_rate_limit_us() to widen rate_limit_us to s64 before converting it to nanoseconds. Use the helper when updating the tunable through sysfs and when starting the governor, so both paths perform the conversion without overflow. Fixes: 9bdcb44e391d ("cpufreq: schedutil: New governor based on scheduler utilization data") Signed-off-by: Hui Su <sh_def@163.com> Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com> Cc: All applicable <stable@vger.kernel.org> Link: https://patch.msgid.link/20260806142304.1761454-1-sh_def@163.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daysbpf: Harden bloom filter sizing and indexing on 32-bit kernelsJérémy Jean
commit 11c1e836710dcba03e50454a4eedfdbaf8d3050e upstream. bloom_map_alloc() has two 32-bit-specific problems when the computed bitmap reaches the U32_MAX fallback case. First, BITS_TO_BYTES(U32_MAX) is evaluated with 32-bit arithmetic. The addition performed by DIV_ROUND_UP wraps, so the map allocates only the fixed-size bloom filter object while keeping bitset_mask == U32_MAX. Subsequent updates can then write past the allocated object. Second, fixing only the allocation size is not sufficient. The bloom hash is a u32, but set_bit() takes a signed long bit number and x86 test_bit() eventually feeds the index to variable_test_bit(long, ...). On 32-bit kernels, hashes in [0x80000000, U32_MAX] therefore become negative bit offsets. x86 bt/bts with a memory operand interpret those offsets relative to the supplied base, so a map with bitset_mask == U32_MAX can read or write before bloom->bitset even after allocating the full 512 MiB bitmap. Keep the U32_MAX fallback, but split each hash into a word pointer and an in-word bit number before calling test_bit() or set_bit(). The bitops argument is then always in [0, BITS_PER_LONG - 1], while BIT_WORD(h) still selects the intended word in the full bitmap. Compute the bitset size from (u64)bitset_mask + 1 before passing the final size to bpf_map_area_alloc(). This fixes the original under-allocation and keeps the allocated storage consistent with the addressable bitset. Exploitation note: local privilege escalation is possible on a 32-bit x86 kernel using the under-allocation bug from a binary with CAP_BPF. Fixes: 9330986c0300 ("bpf: Add bloom filter map implementation") Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/bpf/20260805060228.2703051-1-Jeremy.Jean@oss.cyber.gouv.fr Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Assisted-by: Codex:gpt-5
5 daysbpf: Disable preemption in __bpf_get_stackDaniel Borkmann
commit b1a47b2708d4e95dbd23aee2ec83752190897b3f upstream. get_perf_callchain() returns a per-CPU perf_callchain_entry buffer and releases its recursion slot via put_callchain_entry() before returning, so nothing keeps the entry reserved while __bpf_get_stack() consumes it below. A preemptible BPF program (e.g. a non-sleepable raw tracepoint program on a PREEMPT kernel, which runs under migrate_disable() but not preempt_disable()) can be scheduled out between obtaining the entry and the copy. Another task scheduled on the same CPU then reuses the same per-CPU buffer and overwrites trace->nr with a larger value. copy_len is then computed from the inflated trace->nr and can exceed the caller's buffer, causing an out-of-bounds write in the memcpy() and in the build_id path. The rcu_read_lock() taken here alone does not prevent this. It is only taken on the may_fault path, and under CONFIG_PREEMPT_RCU it does not disable preemption; it merely keeps perf's callchain buffer array alive (freed via call_rcu()) and does nothing to stop another task from reusing the entry. Disable preemption around obtaining the callchain entry and copying it into the caller's buffer, so the entry cannot be reused underneath us and trace->nr stays bounded by max_depth. Build ID resolution may fault and is therefore deferred until after preemption is re-enabled; by then the instruction pointers have already been copied into buf, so it operates only on that private copy. Note, preempt_disable() also subsumes the buffer-lifetime guarantee the rcu_read_lock() provided, since a preempt-disabled section is an RCU read-side critical section for the callchain buffers' call_rcu() reclaim. Fixes: c195651e565a ("bpf: add bpf_get_stack helper") Reported-by: Tao Chen <chen.dylane@linux.dev> Reported-by: STAR Labs SG <info@starlabs.sg> Signed-off-by: Daniel Borkmann <borkmann@iogearbox.net> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/bpf/20260803210149.296496-11-jolsa@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Closes: https://lore.kernel.org/bpf/20260206090653.1336687-1-chen.dylane@linux.dev/ [ changed Fixes: commit ]
5 daysaudit: avoid dropping live tree ref on fsnotify rule autoremoveJérémy Jean
commit 783f0f0974c156aca630f4ffff248671082a098d upstream. audit_del_rule() is used for both netlink deletion templates and internal fsnotify autoremove. The former passes a parsed template which owns a temporary tree reference; the latter passes the installed entry itself. The unconditional audit_put_tree() at the end of audit_del_rule() assumes the template case. For mixed AUDIT_DIR plus AUDIT_EXE rules, an fsnotify autoremove event therefore drops the installed rule's live tree reference. Repeating this across rules sharing the same tree can free the tree while another rule still references it, and a later autoremove dereferences the freed pathname while comparing rules. Move the temporary-tree put to audit_rule_change(), the caller that owns deletion templates. Keep it in the AUDIT_DEL_RULE cleanup so both successful deletion and -ENOENT still release the parser-owned tree. Cc: stable@kernel.org Fixes: 34d99af52ad4 ("audit: implement audit by executable") Assisted-by: Codex:gpt-5 Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr> Reviewed-by: Ricardo Robaina <rrobaina@redhat.com> Tested-by: Ricardo Robaina <rrobaina@redhat.com> [PM: dropped unnecessary comment for line length reasons] Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daystracing: Fix use-after-free with same-name named triggersHui Su
commit a7318172aa332a161fb9618286e64454c827f8fd upstream. When two hist triggers on different events are registered with the same name=, the second one reuses the first as named_data. Both are added to tr->hist_vars by save_hist_vars() during event_hist_trigger_parse(), because save_hist_vars() is called before event_trigger_register() while the named reuse is only detected later, in hist_register_trigger(). In the named-data branch hist_register_trigger() then frees the second histogram's hist_data via destroy_hist_data(), but never removes its tr->hist_vars list entry, leaving a dangling pointer and leaking the trace_array reference it holds. A later hist trigger that references a variable makes find_var_file() walk tr->hist_vars and dereference the freed hist_data. The bug is reproducible from userspace by writing three hist triggers to tracefs: cd /sys/kernel/tracing echo 'hist:keys=common_pid:x=common_pid:name=mh' > events/sched/sched_switch/trigger echo 'hist:keys=common_pid:x=common_pid:name=mh' > events/sched/sched_process_fork/trigger echo 'hist:keys=common_pid:vals=$x' > events/sched/sched_process_exit/trigger The third write panics the kernel: BUG: KASAN: slab-use-after-free in find_var_file.part.0+0x272/0x290 Read of size 8 at addr ffff888001f8a0e0 by task sh/1 CPU: 1 UID: 0 PID: 1 Comm: sh Tainted: G D N Call Trace: find_var_file.part.0 find_event_var parse_atom parse_expr __create_val_field event_hist_trigger_parse trigger_process_regex event_trigger_write vfs_write ksys_write do_syscall_64 entry_SYSCALL_64_after_hwframe Allocated by task 1: event_hist_trigger_parse Freed by task 1: hist_register_trigger+0x618/0xa30 event_hist_trigger_parse The buggy address belongs to freed 2048-byte region Oops: general protection fault ... RIP: find_var_file.part.0 Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b Fix by removing the hist_data from tr->hist_vars and releasing the trace_array reference in the named-data branch of hist_register_trigger() before freeing the hist_data. Cc: stable@vger.kernel.org Fixes: 6f86bdeab633 ("tracing: Fix bad hist from corrupting named_triggers list") Link: https://patch.msgid.link/20260816100427.33642-3-sh_def@163.com Signed-off-by: Hui Su <sh_def@163.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daystracing: Fix use-after-free in trace_pipe read on sub-buffer order changeDeepanshu Kartikey
commit 372f8534244d632ad5118e8a87a11291b01712d3 upstream. Writing to buffer_subbuf_size_kb calls ring_buffer_subbuf_order_set(), which frees every sub-buffer of the ring buffer, including the reader page, and replaces them with newly allocated ones. Readers of trace_pipe hold pointers into those pages. ring_buffer_peek() looks up an event under cpu_buffer->reader_lock but returns the event pointer after dropping the lock, and peek_next_entry() then calls ring_buffer_event_length() and ring_buffer_event_data() on it. If the sub-buffer order is changed in that window, the reader dereferences freed memory: BUG: KASAN: use-after-free in ring_buffer_peek+0x3e0/0x430 Read of size 1 at addr ffff88802a4cf010 by task syz-executor989/6002 Freed by: free_buffer_page kernel/trace/ring_buffer.c:398 [inline] ring_buffer_subbuf_order_set+0x1325/0x18e0 kernel/trace/ring_buffer.c:7444 buffer_subbuf_size_write+0x182/0x280 kernel/trace/trace.c:8221 Take trace_access_lock(RING_BUFFER_ALL_CPUS) around the order change. This is the lock trace_pipe readers already hold across their entire peek-and-print loop, so the swap can no longer race with a reader that is dereferencing a peeked event. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260817140655.5694-1-kartikey406@gmail.com Fixes: f9b94daa542a ("ring-buffer: Set new size of the ring buffer sub page") Reported-by: syzbot+685955db58555575fdd2@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=685955db58555575fdd2 Tested-by: syzbot+685955db58555575fdd2@syzkaller.appspotmail.com Reviewed-by: Bradley Morgan <include@grrlz.net> Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daystracing: Fix retry exhaustion in simple ring buffer reader swapIvan Immanuel Shaji
commit e0d3aed7b12cf37b74c7cc5265073d0263b49cde upstream. simple_ring_buffer_swap_reader_page() starts with retry set to 8 and post-decrements it only after a failed link replacement. On the final attempt, a successful replacement leaves retry at zero, while a failed replacement leaves it at -1. The current !retry test reverses both outcomes. It returns an error after a successful final replacement, leaving the link update complete but the reader bookkeeping unfinished. After a failed final replacement, it falls through and updates the head and reader pointers as though the replacement succeeded, which can corrupt the ring. Treat only a negative counter as exhaustion and return the documented -EBUSY error. Cc: stable@vger.kernel.org Fixes: 34e5b958bdad ("tracing: Introduce simple_ring_buffer") Link: https://patch.msgid.link/20260825-kernel-patch-1-v2-1-bb3461807a32@gmail.com Assisted-by: LLM sparse Reviewed-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Ivan Immanuel Shaji <ivanimmanuel1234@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5 daystracing: Fix logged instance name on creation failureVincent Donnefort
commit a9a01be2834a529cbd490ccbab02643f0c1735f2 upstream. When boot instance creation fails, the kernel incorrectly logs "(null)" as the instance name because strsep() consumes curr_str entirely during parsing. Print the properly parsed name variable instead. And while at it log the error code. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260807085423.4175161-1-vdonnefort@google.com Fixes: cb1f98c5e574 ("tracing: Add creation of instances at boot command line") Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>