summaryrefslogtreecommitdiff
path: root/kernel
AgeCommit message (Collapse)Author
3 daysprctl: fix PR_SET_MM_AUXV losing the forced AT_NULL terminatorBradley Morgan
[ Upstream commit 5146e0688d86f0654263e4b0e4ff1719b4072f16 ] prctl_set_auxv() copies the user vector into a stack buffer, forces AT_NULL on the last two entries there, and then copies only len bytes into mm->saved_auxv. Which is fine until the vector is shorter than the buffer, because then the forced terminator sits past the end of the copy and never lands in saved_auxv at all. The code even says /* Make sure the last entry is always AT_NULL */ and it does, just not in the part that gets copied. So mm->saved_auxv keeps the stale tail from exec. Reproducing it is easy: from a process with CAP_SYS_RESOURCE (just run it as root), call prctl(PR_SET_MM, PR_SET_MM_AUXV, ...) with a vector that has a couple of entries and no AT_NULL inside len (32 bytes on arm64), and then hexdump /proc/self/auxv, or gcore the process and look at the AUXV note with readelf -n. This is arm64, the new vector was just { AT_UID, 0x1111, AT_GID, 0x2222 }: idx before (from exec) after the prctl [0] AT_SYSINFO_EHDR 0x7ed1d6e000 AT_UID 0x1111 <- new [1] AT_MINSIGSTKSZ 0x1270 AT_GID 0x2222 <- new [2] AT_HWCAP 0x119fff AT_HWCAP 0x119fff <- stale [3] AT_PAGESZ 0x1000 AT_PAGESZ 0x1000 <- stale ... 16 more entries ... <- stale [20] AT_NULL 0x0 AT_NULL 0x0 21 entries before the prctl, still 21 after: the two new ones plus all 19 left over from exec. Every consumer walks the vector until AT_NULL, so what they get now is a vector that never existed at exec, the head from the prctl glued onto the tail of the old binary. gdb and crash pull the AUXV note out of coredumps to find AT_PHDR, AT_ENTRY, AT_SYSINFO_EHDR and friends, and a mixed vector points them at the wrong layout. /proc/<pid>/auxv and PR_GET_AUXV hand the same mess out to live processes too. Nothing crashes, everything just quietly reads a frankenstein auxv. And callers that terminate their own vector hide the whole thing, which is likely why nobody noticed since PR_SET_MM_AUXV landed in 2012. Nothing exciting security wise either, I mean it needs CAP_SYS_RESOURCE to begin with. prctl_set_mm_map() right above already copies the whole buffer for exactly this reason, so just do the same here. user_auxv is zero initialized and only partially filled from userspace, so the rest is zeros and nothing leaks. Link: https://lore.kernel.org/20260809002901.32591-1-include@grrlz.net Fixes: fe8c7f5cbf91 ("c/r: prctl: extend PR_SET_MM to set up more mm_struct entries") Signed-off-by: Bradley Morgan <include@grrlz.net> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: Cyrill Gorcuno <gorcunov@openvz.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Reject negative optlen in cgroup getsockopt hookJunseo Lim
[ Upstream commit 1b5aacd5b2419b0790e955e466d389a61c79b4b1 ] A cgroup getsockopt BPF program can shrink ctx->optlen after the kernel getsockopt handler has run. The kernel-buffer variant, used by TCP_ZEROCOPY_RECEIVE, only rejects values larger than the original length. If BPF writes a negative optlen, that value is accepted and propagated back to the TCP getsockopt code. It can then be passed to copy_to_sockptr() as a size_t and trigger the hardened usercopy bytes > INT_MAX warning. Reject negative ctx.optlen in __cgroup_bpf_run_filter_getsockopt_kern(), matching the lower-bound validation already present in the sockptr-based getsockopt hook. Fixes: 9cacf81f8161 ("bpf: Remove extra lock_sock for TCP_ZEROCOPY_RECEIVE") Reported-by: Sechang Lim <rhkrqnwk98@gmail.com> Signed-off-by: Junseo Lim <zirajs7@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/bpf/187a4d756275aaaee5d65eecb63c1477b3b66554.1786448307.git.zirajs7@gmail.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Check pointer type for all atomic RMW pathsYiyang Chen
[ Upstream commit 4bc49ae344d65cfcef738f281ac575cf73ca2fc5 ] Atomic RMW verification records an instruction pointer type only when the current destination is PTR_TO_ARENA. A second path can therefore reach the same instruction with an ordinary pointer without comparing it against the saved arena type. The post-verification fixup uses the saved type to rewrite the instruction to BPF_PROBE_ATOMIC for every path. Record the actual destination type for all atomic RMW paths so the existing mismatch check rejects incompatible uses of one instruction. Fixes: d503a04f8bc0 ("bpf: Add support for certain atomics in bpf_arena to x86 JIT") Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260816-bpf-next-038-mixed-atomic-v1-v2-1-4644c1886dbc@mails.tsinghua.edu.cn Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayssched_ext: Make SCHED_CLASS_EXT select GENERIC_ALLOCATORTejun Heo
[ Upstream commit 524ab50763af33d65e6e042cf7034cd8f82d437b ] kernel/sched/ext/arena.c uses the gen_pool allocator, which is built only when GENERIC_ALLOCATOR is set. SCHED_CLASS_EXT doesn't select it, so on configs where nothing else does, the build fails to link: build_policy.o: undefined reference to `gen_pool_create' build_policy.o: undefined reference to `gen_pool_for_each_chunk' build_policy.o: undefined reference to `gen_pool_destroy' Fixes: 9eca087deb0b ("sched_ext: Sub-allocator over kernel-claimed BPF arena pages") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202608151315.tvN3X0Oq-lkp@intel.com/ Closes: https://lore.kernel.org/oe-kbuild-all/202608151632.3p91bTQj-lkp@intel.com/ Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayssched_ext: Drop unlocked scx_rq_clock_invalidate() from scx_root_disable()Tejun Heo
[ Upstream commit d44093323131a42a85184315bb9b6da4813cc39b ] scx_root_disable() invalidates each rq's clock before taking the rq lock. scx_rq_clock_invalidate() is a plain read-modify-write of rq->scx.flags and every other writer of the word runs under the rq lock, so the unlocked update can race a concurrent flags update and lose one side's bits. The invalidation doesn't matter in the first place. The cached clock is read only by scx_bpf_now() from a loaded scheduler's BPF programs, nothing can re-validate the clock while sched_ext is disabled as scx_rq_clock_update() is gated on scx_enabled() too, and the usual rq lock cycles under the next scheduler refresh or invalidate it before it's practically observable. Drop the invalidation instead of fixing the locking. v2: Description and comment updated - the invalidation is unnecessary rather than subsumed by the rq lock cycle below. Fixes: 3a9910b5904d ("sched_ext: Implement scx_bpf_now()") Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Changwoo Min <changwoo@igalia.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix pending_pos walk on 32-bit ring position wrapIsrael Téllez García
[ Upstream commit 6ff5b56a50c5351aeeb180e34327736576c038fa ] The reservation path caches the position of the oldest not-yet-committed record in rb->pending_pos and advances it past already committed records on every reservation: while (pend_pos < prod_pos) { consumer_pos, producer_pos and pending_pos are unsigned long, i.e. 32-bit on 32-bit architectures, and Documentation/bpf/ringbuf.rst states that these counters may wrap around there. Every other comparison in the file is written as a difference, so modular arithmetic keeps them correct across the wrap. This one is an ordering comparison, and it is not wrap-safe. Once producer_pos wraps past 2^32, prod_pos is small while pend_pos still holds its pre-wrap value, so the loop condition is false and pending_pos is never advanced again. Reservations keep succeeding for a while, because bpf_ringbuf_has_space() uses differences, but new_prod_pos - pend_pos grows as the producer advances, and once it exceeds rb->mask every subsequent __bpf_ringbuf_reserve() call fails: the kernel believes a pending record spans the whole buffer. The ring never recovers, bpf_ringbuf_output() drops every event from then on, and nothing is logged. Observed on four armv7 devices (i.MX7 Dual, 6.6.52) running a tracepoint-based collector with a 512 KiB ring and 160-byte records. Every one of them stopped delivering after exactly 26846821 records and 4295491360 bytes had passed through the ring, at event rates between 441 and 862 records/s, that is after 8 h to 17 h of uptime: the trigger is the byte count, not time or load. That figure is 2^32 plus 524064 bytes, and the excess is one ring's worth of grace period, as expected while new_prod_pos - pend_pos is still below rb->mask. The last reservation that fits is the largest record boundary X with X + 160 <= 524287, and since 2^32 mod 160 = 96 the boundaries after the wrap sit at X = 64 (mod 160), giving X = 524064. Userspace kept consuming normally until the producer stopped, then read zero records for good. With this patch applied, one of the four devices took 10 GiB through the same ring with no stall, while the three unpatched ones kept wedging at the same byte count. 64-bit hosts are unaffected in practice: their counters would need 16 EiB to wrap. Compare the two positions as a difference instead. pending_pos never runs ahead of producer_pos, so the unsigned difference is the real distance between them and stays correct across the wrap. Fixes: cfa1a2329a69 ("bpf: Fix overrunning reservations in ringbuf") Signed-off-by: Israel Téllez García <i.tellez@btesa.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260814124843.22041-2-i.tellez@btesa.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysring-buffer: Remove trace_buffer::cpusVincent Donnefort
[ Upstream commit d9b5e22bf24d5c82522475306cd332b287ac43bc ] The 'cpus' field in struct trace_buffer became useless in commit 8e7b58c27b3c ("ring-buffer: Just update the subbuffers when changing their allocation order"). Remove it Link: https://patch.msgid.link/20260813131152.3589632-9-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: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix arm64 KASAN false positive after bpf_throwMykyta Yatsenko
[ Upstream commit b0e872a31e157d48479507c2821ba8bf6323b7ad ] arm64 passes zero as the stack pointer while walking BPF frames, so bpf_throw() leaves stale KASAN stack poison after jumping to the exception callback. Use the frame pointer as the fallback stack watermark. Fixes: e74cb1b42213 ("arm64: stacktrace: Implement arch_bpf_stack_walk() for the BPF JIT") Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Tested-by: Ihor Solodrai <ihor.solodrai@linux.dev> Link: https://lore.kernel.org/bpf/20260812-hello_world-v1-1-c3c2ddcb362d@meta.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daystracing: Have trace_event_update_all() only handle module that is loadingSteven Rostedt
[ Upstream commit ae70b04ab9c7f6162a8c0fdd18a62a945c133142 ] The function trace_event_update_all() does a scan of events looking to replace enums with their values in the strings that get exported to the event format files. It's run at boot up on all events and again when a module loads. The issue is that when a module loads, it still runs on *all* events. There's no reason to process every event when a module loads as the previous events have already been processed. Only execute on the events that are loaded with the module. Link: https://patch.msgid.link/20260813204226.29563591@gandalf.local.home Fixes: 3673b8e4ce723 ("tracing: Allow for modules to convert their enums to values") Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayssched/isolation: Defer freeing of cpumask memblock memory to initcallWaiman Long
[ Upstream commit 2b58c749b8c5244e259a0230bc57b10b010dc545 ] When testing a linux-next kernel with commit 59bd1d914bb5 ("memblock: warn when freeing reserved memory before memory map is initialized"), the following warning was hit when there was a "nohz_full" kernel boot parameter. Cannot free reserved memory because of deferred initialization of the memory map WARNING: mm/memblock.c:904 at __free_reserved_area+0xde/0xf0, CPU#0: swapper/0/0 : Call Trace: <TASK> memblock_phys_free+0xcb/0x100 housekeeping_init+0x14c/0x170 start_kernel+0x207/0x450 x86_64_start_reservations+0x24/0x30 x86_64_start_kernel+0xda/0xe0 common_startup_64+0x13e/0x141 </TASK> IOW, we shouldn't free memblock allocated memory so early in the boot process when memory map isn't fully initialized in deferred_init_memmap(). Fix it by saving the housekeeping cpumask memblock memory to be freed into a llist free list in housekeeping_init() and add a new housekeeping_late_init() helper to defer the actual freeing of memblock memory to when initcall's are being processed. The cpumask memblock memory is treated as a llist_node with the size of a "long" type which is also smallest cpumask size that can be allocated. The non-atomic version of the llist APIs are used as there is no contention. This commit depends on the presence of commit 7c2eee9c1367 ("memblock: don't touch memblock arrays when memblock_free() is called late") to prevent a KASAN UAF bug report [1]. [1] https://lore.kernel.org/lkml/20260505051821.1107133-1-longman@redhat.com/ Fixes: 27c3a5967f05 ("sched/isolation: Convert housekeeping cpumasks to rcu pointers") Signed-off-by: Waiman Long <longman@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Frederic Weisbecker <frederic@kernel.org> Reviewed-by: Phil Auld <pauld@redhat.com> Link: https://patch.msgid.link/20260701195810.477326-1-longman@redhat.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix UAF in bpf_trampoline_multi_attach_free on update failureHui Zhu
[ Upstream commit 0253073fb7d79a2dd2eae9581ea16db2aef395a6 ] When bpf_trampoline_update() fails before modify_fentry_multi()/ unregister_fentry_multi() is called, cur_image is unchanged (cur_image == old_image) and ftrace still calls into it. Freeing old_image in that case causes a UAF. Only free old_image when it differs from cur_image. Fixes: aef4dfa790b2 ("bpf: Add bpf_trampoline_multi_attach/detach functions") Signed-off-by: Hui Zhu <zhuhui@kylinos.cn> Acked-by: Leon Hwang <leon.hwang@linux.dev> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/bpf/aaa3829e11e2e26bcd3bda9ee6df7a0101a718ac.1786412280.git.zhuhui@kylinos.cn Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Derive the atomic load register in one placeDaniel Borkmann
[ Upstream commit 41c5dbb4be3c1ef4a5e2ce4c28de60b2be3cdccf ] check_atomic_rmw() open codes the mapping from a BPF_ATOMIC to the register it reads the old value into, the BPF_STX case of insn_def_regno() open codes the very same mapping a second time, the const folding and the liveness transfer functions a third and a fourth time, and BPF JITs need it as well to know which register a faulting BPF_PROBE_ATOMIC has to clear. Add a small helper so that all of them can share it. No functional change. The BPF_LOAD_ACQ case is there for the JITs, which do walk all instruction classes. const_reg_xfer() loses its explicit BPF_ATOMIC mode test since the helper checks class and mode itself; the BPF_PROBE_ATOMIC it additionally accepts cannot be seen there as it is only set from bpf_do_misc_fixups(), that is, after const folding has run. arg_track_xfer() keeps its mode test since that also guards the stack clearing next to it. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260811131600.506721-1-daniel@iogearbox.net Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Stable-dep-of: cf92a108601a ("bpf, x86: Clear fetch destination on faulting arena atomic") Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Compare iterator types during state pruningNing Ding
[ Upstream commit 83608e303b95d07afba1c15da0b5d9e513c2f15a ] An iterator stack slot can be MEM_RCU or PTR_UNTRUSTED. These states must not be equal, or the verifier can prune an unsafe path. Compare the pointer type for STACK_ITER slots. Fixes: dfab99df147b ("bpf: teach the verifier to enforce css_iter and task_iter in RCU CS") Signed-off-by: Ning Ding <dingning04@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260811035955.132989-2-dingning04@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayshrtimer: Account nr_retries on recovered interrupt retriesLiang Hao
[ Upstream commit 32a05ba399fc52661f59f38efd2e606f45eb2c8f ] Re-arranging hrtimer_interrupt() switched the retry path to a local counter and dropped the update of cpu_base->nr_retries, leaving the field exported via /proc/timer_list stuck at zero. Increment nr_retries only when another pass through the expiry loop is started; the third attempt that falls through to hang handling is still accounted by nr_hangs alone. Fixes: 288924384856 ("hrtimer: Re-arrange hrtimer_interrupt()") Signed-off-by: Liang Hao <haohlliang@gmail.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260731150408.19554-1-haohlliang@gmail.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayscgroup/cpuset: Use WRITE_ONCE() for shared prs_err updatesGuopeng Zhang
[ Upstream commit 26d3a59e0241c3ef9f66ae1ae990f9326acbc059 ] cpuset_partition_show() reads cs->prs_err without cpuset_mutex using READ_ONCE(). The field is documented as not lock protected, but several updates to live cpusets still use plain stores. Convert the remaining prs_err stores on live cpusets to WRITE_ONCE(). Fixes: 0c7f293efc87 ("cgroup/cpuset: Add cpuset.cpus.exclusive.effective for v2") Assisted-by: LLM Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn> Reviewed-by: Waiman Long <longman@redhat.com> Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix mmap_lock leak in irq_work pathSanghyun Park
[ Upstream commit fa9dcacdcdf487f0ffef64bf67622f1caed509f1 ] stack_map_get_build_id_offset() introduced a per-CPU irq_work to defer mmap_read_unlock() from NMI context, and bpf_find_vma() later reused the same mmap_unlock_work. Both callers only check whether the work is busy before taking mmap_lock, so a nested caller can reuse the slot before the first caller queues it. Two read locks may then be acquired while only one deferred unlock runs, leaking a read lock and blocking exit_mmap(). Reserve the per-CPU slot before mmap_read_trylock(). Use the same wrapper in stackmap and bpf_find_vma() so both callers release the reservation on trylock failure. Keep rejecting the slot while the irq_work remains busy. Release it after the irq_work callback unlocks the mm. Fixes: eac9153f2b58 ("bpf/stackmap: Fix deadlock with rq_lock in bpf_get_stack()") Reported-by: syzbot+cdd6c0925e12b0af60cc@syzkaller.appspotmail.com Reported-by: sashiko-bot@kernel.org Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Closes: https://syzkaller.appspot.com/bug?extid=cdd6c0925e12b0af60cc Closes: https://lore.kernel.org/r/20260630033745.B80201F000E9@smtp.kernel.org Link: https://lore.kernel.org/bpf/20260805031425.2157475-2-sanghyun.park.cnu@gmail.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf, cgroup: Fix storage null-ptr-deref after replacing progPu Lehui
[ Upstream commit 3f562c537e9ecf4bc5e206cfffc2cc047f1b7e94 ] Syzkaller reported a storage null-ptr-deref issue after replacing prog. This occurs in the following scenario: 1. prog A, an empty prog, is attached to a cgrp. 2. prog B uses BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE and calls the bpf_get_local_storage helper. 3. link_update is called to replace prog A with prog B. The reason is that __cgroup_bpf_replace fails to alloc and assign the required cgrp storage for the incoming replacement prog. Consequently, the new prog inherits an uninit storage, leading to null-ptr-deref panic when kick the new prog. Fix this by rejecting a link update if new_prog's cgroup storage is incompatible with link->prog. Fixes: 0c991ebc8c69 ("bpf: Implement bpf_prog replacement for an active bpf_cgroup_link") Signed-off-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Amery Hung <ameryhung@gmail.com> Acked-by: Leon Hwang <leon.hwang@linux.dev> Link: https://lore.kernel.org/bpf/20260728132336.2857800-1-pulehui@huaweicloud.com [0] Link: https://lore.kernel.org/bpf/f87b53c0-8f00-45a6-82db-8242fa9b143f@huaweicloud.com [1] Link: https://lore.kernel.org/bpf/20260807104403.1013064-1-pulehui@huaweicloud.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayssched/fair: Check CPU capacity before comparing group types during load balanceRicardo Neri
[ Upstream commit 50b101f6e586b4417d060a976fd831cd87e86e2b ] update_sd_pick_busiest() may incorrectly select a fully_busy group as the busiest group when its per-CPU capacity exceeds that of the destination CPU. This happens because the type of busiest group is initialized to group_has_spare and allows the fully_busy group to win the type comparison. update_sd_pick_busiest() should not choose a candidate scheduling group with at most one runnable task if its per-CPU capacity is greater than that of the destination CPU. Such a check already exists, but it is done too late: after the type comparison, preventing a subsequent fully_busy group of equal per-CPU capacity from being correctly selected. Move this check to occur before comparing group types. Fixes: 0b0695f2b34a ("sched/fair: Rework load_balance()") Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Christian Loehle <christian.loehle@arm.com> Reviewed-by: Chen Yu <yu.c.chen@intel.com> Reviewed-by: Tim Chen <tim.c.chen@linux.intel.com> Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org> Tested-by: Christian Loehle <christian.loehle@arm.com> Tested-by: Andrea Righi <arighi@nvidia.com> Link: https://patch.msgid.link/20260720-rneri-fix-cas-clusters-v6-3-bb500bf4afd4@linux.intel.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayssched/fair: Also gate overloaded status update for SD_ASYM_CPUCAPACITYRicardo Neri
[ Upstream commit 6060d61d13a10da8c90da4eadf4a421825149883 ] The argument sg_overloaded of update_sg_lb_stats() is only consumed when balancing at the root domain. It only makes sense to update it in such a case. Commit 3229adbe7875 ("sched/fair: Do not compute overloaded status unnecessarily during lb") updated the logic accordingly but missed the case in which the root domain has the SD_ASYM_CPUCAPACITY flag. Fix this. Fixes: 3229adbe7875 ("sched/fair: Do not compute overloaded status unnecessarily during lb") Reported-by: Chen Yu <yu.c.chen@intel.com> Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org> Tested-by: Christian Loehle <christian.loehle@arm.com> Tested-by: Andrea Righi <arighi@nvidia.com> Link: https://patch.msgid.link/20260720-rneri-fix-cas-clusters-v6-2-bb500bf4afd4@linux.intel.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Reject load-acquire from pointers requiring fault protectionDaniel Borkmann
[ Upstream commit 7db0a00445f1a40bacfe9b747405c11cb5f10fc9 ] A BPF_LOAD_ACQ is not rewritten to a BPF_PROBE_MEM load by the verifier, unlike a regular BPF_LDX, so the JIT emits a plain load with no exception table entry and a fault panics the kernel instead of being handled. Reject the source pointer types that a BPF_LDX would have had that fault protection applied to, i.e. the ones bpf_convert_ctx_accesses() turns into BPF_PROBE_MEM: a bare PTR_TO_BTF_ID, PTR_TO_BTF_ID | PTR_UNTRUSTED, PTR_TO_BTF_ID | MEM_ALLOC | PTR_UNTRUSTED and PTR_TO_MEM | MEM_RDONLY | PTR_UNTRUSTED. This is reachable e.g. by loading ->mm out of a trusted task_struct yields an untrusted pointer to mm_struct, and it is NULL for a kernel thread: [...] SEC("tp_btf/sched_switch") int BPF_PROG(demo, bool preempt, struct task_struct *prev, struct task_struct *next) { struct mm_struct *mm = next->mm; /* untrusted */ out_ldx = (__u64)mm->pgd; /* BPF_LDX */ out_acq = load_acquire(&mm->pgd); /* BPF_LOAD_ACQ */ return 0; } [...] Both dereference the same pointer, but only the BPF_LDX is protected (x86-64 JIT, jump targets shown prog-relative): [...] ; out_ldx = (__u64)mm->pgd; 17: movq $-10485760, %r10 1e: movq %rsi, %r11 21: addq $184, %r11 28: subq %r10, %r11 2b: movabsq $140737498841088, %r10 35: cmpq %r10, %r11 38: ja 0x3e <-- kernel addr? 3a: xorl %edi, %edi <-- no: dst = 0, skip the load 3c: jmp 0x45 3e: movq 184(%rsi), %rdi <-- yes: load + extable entry [...] ; load_acquire(&mm->pgd) 53: movq %rsi, %rdi 56: movq 184(%rdi), %rax <-- no check, no extable entry [...] Note that BPF_PROBE_MEM is not visible in a bpftool xlated dump, as bpf_insn_prepare_dump() rewrites it back to BPF_MEM. A PTR_TRUSTED pointer is deliberately not on the list. Such a load is not converted either, but it does not need to be, since the pointer is guaranteed live, so load-acquire from it stays allowed. The check is gated on BPF_LOAD_ACQ so that atomic RMW and store-release error messages are unchanged; writes (RMW / store-release) to such pointers are already rejected elsewhere, so only load-acquire needs this. Fixes: 880442305a39 ("bpf: Introduce load-acquire and store-release instructions") Reported-by: STAR Labs SG <info@starlabs.sg> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20260806201047.333389-1-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysmodule/dups: Fix use-after-free in kmod_dup_req lifetime handlingPetr Pavlu
[ Upstream commit 5eecb11b543f9f417bcf0dea239ff99c6af65dbd ] The kmod dups code uses RCU to ensure that a kmod_dup_req instance is freed only after it is no longer referenced. When releasing an instance, the kmod_dup_request_delete() function removes the kmod_dup_req from the dup_kmod_reqs list, waits via synchronize_rcu() and finally frees it. However, this doesn't work correctly because parallel users referencing the instance in kmod_dup_request_exists_wait() don't enter an RCU read-side critical section. This can result in a use-after-free. The kmod_dup_request_exists_wait() function may need to hold a valid reference to a kmod_dup_req instance across a blocking wait until the corresponding modprobe command completes. This makes it unsuitable for RCU. Fix the issue by changing the lifecycle management of kmod_dup_req to use reference counting. Fixes: 8660484ed1cf ("module: add debugging auto-load duplicate module support") Reviewed-by: Aaron Tomlin <atomlin@atomlin.com> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysmodule/dups: Inform duplicate requests about the result directlyPetr Pavlu
[ Upstream commit d258ed8a86bb46bbbbc84fb914478259a1e694a4 ] When kmod_dup_request_announce() announces the completion of a request_module() call to duplicate waiters, it queues a work item to invoke kmod_dup_request_complete(), and only that function calls complete_all(). This adds an arbitrary delay that is unnecessary and provides little benefit. Call complete_all() directly from kmod_dup_request_announce() instead. Signed-off-by: Petr Pavlu <petr.pavlu@suse.com> Stable-dep-of: 5eecb11b543f ("module/dups: Fix use-after-free in kmod_dup_req lifetime handling") Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysmodule: use strscpy() to copy module names in stats and dup trackingNaveen Kumar Chaudhary
[ Upstream commit 93c29ebd1622fb0670701e1c1b3a978a5cac08b7 ] Both try_add_failed_module() and kmod_dup_request_exists_wait() use memcpy() with strlen() to copy module names into fixed-size char[MODULE_NAME_LEN] buffers. Neither performs a bounds check on the copy. Current callers always pass names originating from mod->name (itself char[MODULE_NAME_LEN]), so this is not exploitable today. However both functions accept a plain const char * with no documented length contract, making them latent buffer overflows if a future caller passes a longer string. Replace memcpy() with strscpy() in both sites, which bounds the copy to MODULE_NAME_LEN and always NUL-terminates. Signed-off-by: Naveen Kumar Chaudhary <naveen.osdev@gmail.com> Reviewed-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com> Stable-dep-of: 5eecb11b543f ("module/dups: Fix use-after-free in kmod_dup_req lifetime handling") Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix sleepable check for tracing/lsm progLeon Hwang
[ Upstream commit 00244bdaa423d93f4571f3f6854378ce3365e524 ] When CONFIG_FUNCTION_ERROR_INJECTION is disabled, a sleepable tracing prog is allowed to attach to '__x64_'-alike prefix symbols. It is because the verifier does not verify whether the symbol is a kernel function or a bpf prog. That said, a sleepable tracing prog is allowed to attach to a bpf prog target whose name has '__x64_'-alike prefix. For example, a sleepable fentry prog attaches to a '__x64_sys_nop' XDP prog, and copies buffer from a user pointer with bpf_copy_from_user() helper. After attaching the XDP prog to lo interface, the kernel BUG could be triggered by 'ping -c 1 -W 1 127.0.0.1': [ 3.460756] BUG: sleeping function called from invalid context at kernel/bpf/trampoline.c:1324 Fix it by disallowing sleepable prog always when its target btf is not a kernel's btf. Fixes: 16d9c5660692 ("bpf: Always allow sleepable programs on syscalls") Signed-off-by: Leon Hwang <leon.hwang@linux.dev> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Viktor Malik <vmalik@redhat.com> Link: https://lore.kernel.org/bpf/20260805150810.34907-2-leon.hwang@linux.dev Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Clear buf on error in __bpf_get_task_stackJiri Olsa
[ Upstream commit f5d242825ca417bb6afe35fde6e8880f97ca43fb ] Both bpf_get_task_stack and bpf_get_task_stack_sleepable helpers that use __bpf_get_task_stack have buf defined as ARG_PTR_TO_UNINIT_MEM argument and we should initialize the buf on every return path. Adding missing buf memset for __bpf_get_task_stack fail paths. This provides deterministic buffer contents, which is useful when the buffer is used directly as a map key. Fixes: 06ab134ce8ec ("bpf: Refcount task stack in bpf_get_task_stack") Fixes: b992f01e6615 ("bpf: Guard against accessing NULL pt_regs in bpf_get_task_stack()") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260803210149.296496-10-jolsa@kernel.org Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Remove trace_in argument from __bpf_get_stackJiri Olsa
[ Upstream commit 58cfc2201d964163fe9c4a703136eb64db799f08 ] Now with the new callchain_* helper functions we can process trace_in case directly in bpf_get_stack_pe function and remove it from __bpf_get_stack which makes things easier for preemption fix in following change. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260803210149.296496-9-jolsa@kernel.org Stable-dep-of: f5d242825ca4 ("bpf: Clear buf on error in __bpf_get_task_stack") Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Factor callchain_finalize function from __bpf_get_stackJiri Olsa
[ Upstream commit 014fbe5902dccdaef69114abdcdb15e3dbe55e34 ] The new callchain_finalize function calls the build-id retrieval (if needed) and zeroes the buffer. This makes things easier for preemption fix in following change. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260803210149.296496-8-jolsa@kernel.org Stable-dep-of: f5d242825ca4 ("bpf: Clear buf on error in __bpf_get_task_stack") Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Factor callchain_store function from __bpf_get_stackJiri Olsa
[ Upstream commit cbb99938e7935c9f62c891573a4b09690e5e22de ] The new callchain_store function stores trace entries buffer into user supplied buffer. It covers both just-ip and buildid 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-7-jolsa@kernel.org Stable-dep-of: f5d242825ca4 ("bpf: Clear buf on error in __bpf_get_task_stack") Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Check load-acquire src ptr type before the loadDaniel Borkmann
[ Upstream commit b87803391baa7e0bef60549d8841f12e549ad057 ] check_atomic_load() calls check_load_mem() before atomic_ptr_type_ok(). For a load-acquire that fetches into its own source register (dst_reg == src_reg), check_load_mem() overwrites src_reg's type with the type of the loaded value, so the subsequent atomic_ptr_type_ok() no longer sees the source pointer and fails to reject the disallowed types (ctx, pkt, flow_keys, sock). Since bpf_convert_ctx_accesses() does not rewrite atomic loads, the raw access to the underlying kernel object is left in place. The destination type is taken from the ctx access itself, so a load-acquire of the sk field of struct __sk_buff for example leaves the register typed as PTR_TO_SOCK_COMMON_OR_NULL, which type_is_sk_pointer() does not match either, while it actually holds unconverted struct sk_buff bytes. Once the NULL check has passed this is a type confusion, not just a leak of kernel data. Validate src_reg with check_reg_arg() and check the source pointer type with atomic_ptr_type_ok() before the load again, mirroring check_atomic_rmw(). Out-of-range register numbers are already rejected earlier by check_and_resolve_insns() (commit 503d21ef8eac ("bpf: Do register range validation early")), and the only exemption there, is_stack_arg_ldx(), requires BPF_LDX | BPF_MEM | BPF_DW and thus never matches a BPF_ATOMIC insn. atomic_ptr_type_ok() can therefore not dereference register state out of bounds, that is, the out-of-bounds read addressed by the Fixes commit below does not reappear (as proven also via selftest). Fixes: c03bb2fa327e ("bpf: Fix out-of-bounds read in check_atomic_load/store()") Reported-by: STAR Labs SG <info@starlabs.sg> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/bpf/20260804201917.253491-1-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf, cgroup: Fix invalid storage access after __cgroup_bpf_attach failedPu Lehui
[ Upstream commit 6655c409707ec8ce9ce0850ffe4fe02331fd4d9c ] A potential invalid storage access issue can occur after replacing a cgroup bpf prog. This occurs in the following scenario: 1. prog1 with storage is attached to a cgroup in multi-attach mode. 2. prog1 is replaced with prog2 using BPF_F_REPLACE in multi-attach mode, but fails midway (e.g. in bpf_trampoline_link_cgroup_shim or update_effective_progs). 3. A new prog3 is attached to the cgroup in multi-attach mode. The reason is that __cgroup_bpf_attach overwrites pl->storage with the new storage prior to attachment completion. When attachment fails midway, the cleanup path calls bpf_cgroup_storages_free(new_storage) to free the newly allocated storage, but fails to restore pl->storage back to old_storage. Consequently, the still-active prog1 holds invalid or dangling storage pointers, leading to an invalid memory access when prog1 executes and calls bpf_get_local_storage. Additionally, original pl->flags and cgrp->bpf.flags[atype] are left unrestored. Fix this by saving old_pl_flags, old_storage, and old_flags prior to the update, and properly restoring all of them in the cleanup path on error. Fixes: 7d9c3427894f ("bpf: Make cgroup storages shared between programs on the same cgroup") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/bpf/20260803013934.4036646-1-pulehui@huaweicloud.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Invalidate RCU pointers after final spin unlockNing Ding
[ Upstream commit 180c7000712db77063b3a26f4c97e7dd9038f449 ] In a sleepable BPF program, a spin lock can provide the only RCU protection for a kptr. The final bpf_spin_unlock() ends that protection, but the verifier leaves the pointer valid. Another CPU can then free the object before the pointer is used. A capability-limited runtime PoC triggered a task_struct use-after-free in __bpf_get_task_stack(). Record whether the program is in an RCU-protected context before releasing the lock. Invalidate RCU-protected pointers only when the unlock leaves the final such context. This preserves valid pointers in non-sleepable programs and inside an explicit RCU read-side section. Fixes: 5861d1e8dbc4 ("bpf: Allow bpf_spin_{lock,unlock} in sleepable progs") Assisted-by: Codex:gpt-5.6-sol Assisted-by: ChatGPT:GPT-5.6-Pro Signed-off-by: Ning Ding <dingning04@gmail.com> Link: https://lore.kernel.org/bpf/20260803112615.3362122-2-dingning04@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix mmap_lock deadlock on arena lock failureJiayuan Chen
[ Upstream commit 0b10b945479c954393d62ee3229d2f224a4ca91c ] Reported by the Sashiko AI review. arena_vm_fault() returns VM_FAULT_RETRY when it can't take arena->spinlock, but it never took mmap_lock. The fault path assumes a VM_FAULT_RETRY handler already dropped mmap_lock and re-takes it on the retry, so mmap_lock gets taken twice and can deadlock: do_user_addr_fault() { fault = handle_mm_fault(...); // calls arena_vm_fault() if (fault & VM_FAULT_RETRY) goto retry; // re-locks mmap_lock mmap_read_unlock(mm); } Return VM_FAULT_SIGBUS instead, for two reasons: 1. We could keep VM_FAULT_RETRY, but then we'd have to drop the fault lock first and cap the retry ourselves, the way __folio_lock_or_retry() does. 2. A failed raw_res_spin_lock_irqsave() already means a possible deadlock was detected, so retrying just hits the same lock again. So returning VM_FAULT_RETRY here is overkill. Fixes: b8467290edab ("bpf: arena: make arena kfuncs any context safe") Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/bpf/20260728060517.95183-1-jiayuan.chen@linux.dev Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Reject >8 byte return values on return-reading trampoline pathsYonghong Song
[ Upstream commit c48796aa6c392cde93946e5d5a9a1f1b1cf72feb ] btf_distill_func_proto() builds the function model used for the fentry/fexit/fmod_ret/fsession trampolines and struct_ops. It has accepted a 16-byte __int128 return value since the trampoline was introduced: __get_type_size() returns the integer's type size, and the return-type check only rejected ret < 0. But the BPF trampoline preserves only 8 bytes of the return value (RAX on x86, i.e. R0). For an attach type that reads the target's return value the second half (RDX / R3) is neither saved nor restored, so a program attached to a function returning a 16-byte value corrupts the value seen by the real caller and itself observes only half of it. struct_ops trampolines have the same limitation. This affects the attach types that read the target's return value: fexit, fmod_ret and fsession (plus the _multi variants of fexit and fsession), and struct_ops. fentry/fentry_multi run before the target returns and are unaffected. Reject a >8 byte return value for these attach types in bpf_check_attach_target() and bpf_check_attach_btf_id_multi(), and for struct_ops in bpf_struct_ops_desc_init(). Fixes: fec56f5890d9 ("bpf: Introduce BPF trampoline") Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com> Acked-by: Leon Hwang <leon.hwang@linux.dev> Link: https://lore.kernel.org/bpf/20260729050159.2585809-1-yonghong.song@linux.dev Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayslocking/lockdep: Fix NULL pointer dereference in __lock_set_class()Naveen Kumar Chaudhary
[ Upstream commit 7577e00b9ab506202b9f1a33de3cc8cc6413a4db ] register_lock_class() can return NULL when the lock class pool is exhausted, graph_lock() fails, or key validation fails. However, __lock_set_class() uses the return value directly in pointer arithmetic without a NULL check: class = register_lock_class(lock, subclass, 0); hlock->class_idx = class - lock_classes; If class is NULL, this computes a wild offset that corrupts hlock->class_idx. The subsequent reacquire_held_locks() call will invoke hlock_class() with this corrupted index, leading to a NULL or out-of-bounds pointer dereference. Add the missing NULL check, consistent with how __lock_acquire() already handles this case at the same call site. Fixes: 64aa348edc61 ("lockdep: lock_set_subclass - reset a held lock's subclass") Signed-off-by: Naveen Kumar Chaudhary <naveen.osdev@gmail.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Waiman Long <longman@redhat.com> Reviewed-by: Dmitry Ilvokhin <d@ilvokhin.com> Link: https://patch.msgid.link/h2kfw43n4527x6mgi2lwpz2rieqnfzgictpv4wr5nyfjkc47co@2r5vz4uz44db Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysswiotlb: Preserve allocation virtual address for dynamic poolsAneesh Kumar K.V (Arm)
[ Upstream commit 57d29044d0f29a76c6ec0c112c8c7371d5608dc7 ] swiotlb_alloc_tlb() can allocate from the DMA atomic pool when a decrypted pool is needed from atomic context. With CONFIG_DMA_DIRECT_REMAP, the atomic pool is backed by remapped virtual addresses, which are not the same as the direct-map addresses returned by phys_to_virt(). swiotlb_init_io_tlb_pool() currently reconstructs the pool virtual address from the physical start address. For atomic-pool backed allocations this stores the wrong address in pool->vaddr. Later, swiotlb_free_tlb() passes that address to dma_free_from_pool(), which will fail to recognize the chunk Pass the virtual address returned by the allocation path into swiotlb_init_io_tlb_pool(), and store that address in pool->vaddr. This keeps the pool free path using the same virtual address as the allocator. Fixes: 79636caad361 ("swiotlb: if swiotlb is full, fall back to a transient memory pool") Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Tested-by: Michael Kelley <mhklinux@outlook.com> Tested-by: Mostafa Saleh <smostafa@google.com> Reviewed-by: Petr Tesarik <ptesarik@suse.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-6-aneesh.kumar@kernel.org Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix potential UAF when reading bpf link infoPu Lehui
[ Upstream commit 863f3ddd0b8ac65abfb50d3be0869268ac0e277b ] In bpf_link_show_fdinfo and bpf_link_get_info_by_fd, link->prog is accessed without holding any locks. If the prog is concurrently replaced via bpf_link_update, the old prog can be freed, leading to a potential UAF issue. Fix this by accessing link->prog under RCU protection to safely fetch the pointer and guarantee its lifetime while reading its fields. Fixes: 0c991ebc8c69 ("bpf: Implement bpf_prog replacement for an active bpf_cgroup_link") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Reviewed-by: Amery Hung <ameryhung@gmail.com> Acked-by: Leon Hwang <leon.hwang@linux.dev> Link: https://lore.kernel.org/bpf/f87b53c0-8f00-45a6-82db-8242fa9b143f@huaweicloud.com [0] Link: https://lore.kernel.org/bpf/20260728025457.2814876-1-pulehui@huaweicloud.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix potential UAF in bpf_netns_link_update_progPu Lehui
[ Upstream commit 5c5997836381010fc5907b36bc17d3b19407e933 ] In bpf_netns_link_update_prog, the checks for old_prog and prog type are currently performed locklessly before acquiring netns_bpf_mutex. This creates a race condition that can lead to a UAF issue. If two threads concurrently execute BPF_LINK_UPDATE on the same netns link, the following execution path can trigger a UAF: CPU0 CPU1 bpf_netns_link_update_prog if (old_prog && old_prog != link->prog) return -EPERM; bpf_netns_link_update_prog if (old_prog && old_prog != link->prog) ... old_prog = xchg(&link->prog, new_prog); bpf_prog_put(old_prog); if (new_prog->type != link->prog->type) <-- trigger UAF Fix this by moving the old_prog and prog->type checks inside the netns_bpf_mutex critical section. Meanwhile, use guard() to simplify lock management and avoid all the goto jumping. Fixes: 7f045a49fee0 ("bpf: Add link-based BPF program attachment to network namespace") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Amery Hung <ameryhung@gmail.com> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/bpf/f87b53c0-8f00-45a6-82db-8242fa9b143f@huaweicloud.com [0] Link: https://lore.kernel.org/bpf/20260728023259.2813482-1-pulehui@huaweicloud.com Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysrcu: Mark accesses to ->rcu_urgent_qs and ->rcu_need_heavy_qsItai Handler
[ Upstream commit 27d73e81195b395270117ff77c47be2ed9b09b12 ] rcu_all_qs() and rcu_note_context_switch() read/clear the per-CPU ->rcu_urgent_qs and ->rcu_need_heavy_qs flags with plain raw_cpu_read() and this_cpu_write(), while the RCU core clears them with WRITE_ONCE() in rcu_disable_urgency_upon_qs(). KCSAN flags the resulting same-CPU race: BUG: KCSAN: data-race in rcu_all_qs / rcu_disable_urgency_upon_qs It is benign -- the flags are advisory and rcu_all_qs() re-reads ->rcu_urgent_qs with smp_load_acquire() before acting on it -- but these are the last unmarked accesses to the two flags; every other access already uses READ_ONCE()/WRITE_ONCE()/smp_*. Mark them to match. No functional change. Reproduced on a PREEMPT_NONE, CONFIG_KCSAN_INTERRUPT_WATCHER=y kernel with a pthreads program whose threads (two per CPU) loop reading a large file: for (;;) { int fd = open("/proc/kallsyms", O_RDONLY); while (read(fd, buf, sizeof(buf)) > 0) ; close(fd); } The read()s drive cond_resched() -> rcu_all_qs() while the busy CPUs keep the grace period urgent, so the RCU core clears the flags concurrently. Fixes: 2dba13f0b6c2 ("rcu: Switch urgent quiescent-state requests to rcu_data structure") Signed-off-by: Itai Handler <itai.handler@gmail.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayssched_ext: Abort directly from the hardlockup handlerTejun Heo
[ Upstream commit 3c4b38064937a761ebbf85b1649e812db85eb59e ] scx_hardlockup() defers the abort to an irq_work because exit claiming used to take scx_sched_lock and couldn't run from NMI. The deferral is now unnecessary - claiming is NMI-safe and asserting ->aborting is exactly what breaks the live-locks that hard-lock CPUs. Call handle_lockup() directly and drop the irq_work. This also makes the self-detected case recoverable: the perf watchdog fires on the hard-locked CPU itself, where a queued irq_work never runs with IRQs off. Also fix the return value: %true used to be returned whenever sched_ext was loaded, suppressing the kernel's hardlockup report even when the abort was refused. Return %true only when this call initiated the abort. Fixes: bd2d76455b65 ("sched_ext: Defer scx_hardlockup() out of NMI") Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 dayssched_ext: Fix exit_cpu accuracy for lockup pathsCheng-Yang Chou
[ Upstream commit da428d572e07bb9dd2d076297ef5700f6483aafd ] handle_lockup() uses raw_smp_processor_id() for exit_cpu, which is wrong for two paths: - scx_hardlockup_irq_workfn() has the hung CPU in a local variable but irq_work may run elsewhere. Pass the local cpu explicitly. - scx_rcu_cpu_stall() records the detector CPU rather than the stalled one. Pass -1 for now. The next patch fixes this properly. Signed-off-by: Cheng-Yang Chou <yphbchou0911@gmail.com> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org> Stable-dep-of: 3c4b38064937 ("sched_ext: Abort directly from the hardlockup handler") Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysliveupdate: Remember FLB retrieve() statusDavid Matlack
[ Upstream commit 5c4a03afcb21783987ffc64562b76ddd5a21b12b ] LUO keeps track of successful retrieve attempts on an FLB. It does so to avoid multiple retrievals of the same FLB. Multiple retrievals cause problems because once the FLB is retrieved, the serialized data structures are likely freed and the FLB is likely in a very different state from what the code expects. All this works well when retrieve succeeds. When it fails, luo_flb_retrieve_one() returns the error immediately, without ever storing anywhere that a retrieve was attempted or what its error code was. If the user attempts to retrieve another file registered with the same FLB, LUO will attempt to call the FLB's retrieve() callback again. The retry is problematic for much of the same reasons listed above. The FLB is likely in a very different state than what the retrieve logic normally expects (e.g. some KHO pages may have already been restored and freed). There is no sane way of attempting the retrieve again. Remember the error retrieve returned and directly return it on a retry. This is done by changing the retrieved bool to a retrieve_status integer. A value of 0 means retrieve was never attempted, a positive value means it succeeded, and a negative value means it failed and the error code is the value. This is similar to commit f85b1c6af5bc ("liveupdate: luo_file: remember retrieve() status") which did the same for LUO files. Fixes: cab056f2aae7 ("liveupdate: luo_flb: introduce File-Lifecycle-Bound global state") Assisted-by: Gemini:gemini-3-pro-preview Signed-off-by: David Matlack <dmatlack@google.com> Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com> Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org> Link: https://patch.msgid.link/20260528174140.1921129-3-dmatlack@google.com Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysliveupdate: Reference count outgoing FLB dataDavid Matlack
[ Upstream commit 36882f3392395704c8a3fe7fac831fb6f5737e7d ] Increment the outgoing FLB refcount in liveupdate_flb_get_outgoing() so that the FLB structure cannot be freed while the caller is actively using it. Add an additional liveupdate_flb_put_outgoing() function so the caller can explicitly indicate when it is done using the outgoing FLB. During a Live Update, the kernel may need to fetch the outgoing FLB outside of the scope of a file handler's preserve() and unpreserve() callbacks. In that situation there is no way for the caller to protect itself against the outgoing FLB from being freed while it is using it. Incrementing the reference count in liveupdate_flb_get_outgoing() ensures it cannot be freed. This change also aligns the outgoing FLB lifecycle management with the incoming FLB, since the latter uses the same get/put semantics. Fixes: cab056f2aae7 ("liveupdate: luo_flb: introduce File-Lifecycle-Bound global state") Assisted-by: Gemini:gemini-3-pro-preview Signed-off-by: David Matlack <dmatlack@google.com> Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com> Link: https://patch.msgid.link/20260528174140.1921129-2-dmatlack@google.com Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysliveupdate: reject nonzero reserved value for SESSION_FINISHJackie Liu
[ Upstream commit 05cf3d87a0bf23e328a7f7db488860fe14acc335 ] The UAPI documents liveupdate_session_finish::reserved as requiring zero, but luo_session_finish() currently ignores it and finishes the session. Accepting nonzero values prevents the field from being safely repurposed by a future extension. Reject nonzero reserved values before changing session state, matching LIVEUPDATE_SESSION_GET_NAME. Fixes: 16cec0d26521 ("liveupdate: luo_session: add ioctls for file preservation") Assisted-by: Codex:gpt-5.6-sol Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn> Link: https://patch.msgid.link/20260716012607.22020-2-liu.yun@linux.dev Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix WARNING in bpf_tracing_link_releaseLeon Hwang
[ Upstream commit 61aaa8782bec59ecffd22e030f54ef9351bcabf9 ] The trampoline could be corrupted by the blindly 'tr->flags = BPF_TRAMP_F_TAIL_CALL_CTX' in verifier. 1. A fexit attached to a tail_call_reachable prog. 'tr->flags' became 'BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_TAIL_CALL_CTX'. And, the trampoline would poke the target prog's nop insn using jmp insn instead of call insn. 2. Another fexit loaded with the same tail_call_reachable prog target. 'tr->flags' became 'BPF_TRAMP_F_TAIL_CALL_CTX'. 3. Close the first fexit link. Due to no BPF_TRAMP_F_CALL_ORIG in 'tr->flags', the trampoline will fail to restore the prog's nop insn using call insn. [ 3.410719] WARNING: kernel/bpf/syscall.c:3551 at bpf_tracing_link_release+0x53/0x60, CPU#1: test_progs/98 ... [ 3.428793] bpf_link_free+0x58/0x130 [ 3.429293] bpf_link_release+0x23/0x30 Fix the warning by updating 'tr->flags' with '|=' and lock. Fixes: 2b5dcb31a19a ("bpf, x64: Fix tailcall infinite loop") Signed-off-by: Leon Hwang <leon.hwang@linux.dev> Reviewed-by: Pu Lehui <pulehui@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/bpf/20260722151909.69142-2-leon.hwang@linux.dev Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix CFI mismatch in task work callbackMykyta Yatsenko
[ Upstream commit 2805abd089576799b15092949420e3f8ba97fabd ] BPF subprograms use the bpf_callback_t ABI, but task work invokes the callback through a three-argument function pointer. This trips kCFI. Store and invoke the callback as bpf_callback_t. Fixes: 38aa7003e369 ("bpf: task work scheduling kfuncs") Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com> Link: https://lore.kernel.org/bpf/20260724-task_work_cfi-v1-1-2616691781ed@meta.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysPM: hibernate: Fix memory leak in snapshot_write_next() error pathMalaya Kumar Rout
[ Upstream commit 21d5c4cee31c5ce78f6decc7fafc7e7759af391f ] When memory_bm_create() succeeds for copy_bm but fails for zero_bm, the function returns without freeing the resources allocated for copy_bm. This results in a memory leak that includes radix tree nodes, zone structures, and page lists. Fix this by calling memory_bm_free() to release copy_bm's resources before returning the error code when zero_bm allocation fails. Fixes: 005e8dddd497 ("PM: hibernate: don't store zero pages in the image file") Signed-off-by: Malaya Kumar Rout <malayarout91@gmail.com> Acked-by: Brian Geffon <bgeffon@google.com> Link: https://patch.msgid.link/20260711145246.8625-1-malayarout91@gmail.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Mark bpf_refcount field as uniqueKumar Kartikeya Dwivedi
[ Upstream commit 61e655391cb19c31f94ecd4354f624c81ce4cf75 ] BPF_REFCOUNT is not marked as a unique field, while it should be. Fix this oversight. Fixes: d54730b50bae ("bpf: Introduce opaque bpf_refcount struct and add btf_record plumbing") Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://patch.msgid.link/20260719153634.2908692-4-memxor@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Preserve unique-field state across nested structsKumar Kartikeya Dwivedi
[ Upstream commit f08619f060468076e4acbdc10e0713af20d60e65 ] btf_find_struct_field() initializes a fresh seen mask for every recursive descent. Unique special fields in different levels of the same aggregate therefore do not see one another. The duplicate fields can reach btf_parse_fields(), where they trigger an invariant WARN_ON_ONCE(). A crafted user BTF can consequently trigger the warning before map creation checks capabilities. Initialize the seen mask once in btf_find_field() and pass the same pointer through struct, datasec, and nested-struct walks. This gives the entire field traversal one shared uniqueness state. Fixes: 64e8ee814819 ("bpf: look into the types of the fields of a struct type recursively.") Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://patch.msgid.link/20260719153634.2908692-3-memxor@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Fix offset warn check for bpf_res_spin_lockKumar Kartikeya Dwivedi
[ Upstream commit 04e19012efaec2bfd8c3b37fd8a6c3f1fe731ffc ] Sashiko pointed out correctly that the case statement for BPF_RES_SPIN_LOCK incorrectly checks offset for BPF_SPIN_LOCK. Fix it by checking res_spin_lock_off instead. Fixes: 0de2046137f9 ("bpf: Implement verifier support for rqspinlock") Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://patch.msgid.link/20260719153634.2908692-2-memxor@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
3 daysbpf: Zero queue and stack outputs on lock failureKumar Kartikeya Dwivedi
[ Upstream commit 7ac6e1ae41a09f1dd4baeeff1d028ae49ee01232 ] Queue and stack pop/peek helpers accept an uninitialized output buffer because the verifier expects the helper to initialize it. The empty-map error path clears the buffer, but a failed lock acquisition returns -EBUSY without writing it. Clear the output before returning -EBUSY so BPF programs cannot observe uninitialized stack contents after a failed helper call. Fixes: a34a9f1a19af ("bpf: Avoid deadlock when using queue and stack maps from NMI") Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/bpf/20260719125419.1782196-1-memxor@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>