ath11k_core_init() registers a PM notifier before the QMI server
becomes available. If the QMI server never arrives, the device remove()
path can take the early-exit path introduced for QMI initialization
failures, skipping ath11k_core_deinit().
As a result, the PM notifier remains registered after the ath11k base
object has been freed. A subsequent suspend or resume event may invoke
the stale notifier and trigger a use-after-free.
Fix this by explicitly unregistering the PM notifier in the QMI failure
cleanup path before releasing ath11k resources.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.2.0.c2-00204-QCAMSLSWPLZ-1
Fixes: 32d93b51bc ("wifi: ath11k: choose default PM policy for hibernation")
Signed-off-by: Miaoqing Pan <miaoqing.pan@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260806101331.484063-4-miaoqing.pan@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
On WCN6750, if QMI messages never arrive (for example when qrtr_smd
is not ready), WLAN initialization stops before the device is fully
registered. In this case ATH11K_FLAG_QMI_FAIL is not set because no
QMI event handler is executed.
When the driver is removed, ath11k_ahb_remove() still calls
ath11k_core_deinit(), which eventually triggers
ath11k_ce_cleanup_pipes() on uninitialized CE pipes and results in a
NULL pointer dereference in ath11k_hal_srng_access_begin():
ath11k_hal_srng_access_begin+0x14/0x68 [ath11k]
ath11k_ce_cleanup_pipes+0x184/0x190 [ath11k]
ath11k_pcic_stop+0x24/0x38 [ath11k]
ath11k_core_deinit+0xfc/0x1c0 [ath11k]
ath11k_ahb_remove+0x38/0xa0 [ath11k_ahb]
Fix this by invoking ath11k_ahb_remove_prepare() before the state
check and skipping ath11k_core_deinit() if ATH11K_FLAG_REGISTERED
is not set, core initialization did not complete and CE pipes may
remain uninitialized, making ath11k_core_deinit() unsafe.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.2.0.c2-00204-QCAMSLSWPLZ-1
Fixes: 00402f49d2 ("ath11k: Add support for WCN6750 device")
Signed-off-by: Miaoqing Pan <miaoqing.pan@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260806101331.484063-3-miaoqing.pan@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
On WCN6750 platforms, reboot stress testing occasionally results in WLAN
initialization failures after boot. The WPSS firmware reaches the running
state successfully, but no WLAN interface is created.
Analysis shows that ath11k_ahb depends on the QRTR SMD transport for QMI
communication with WPSS firmware. However, this dependency is not
currently expressed in Kconfig, allowing qrtr_smd and ath11k_ahb to load
in either order when built as modules.
If ath11k_ahb is loaded before qrtr_smd becomes available, WLAN
initialization may not complete successfully.
Make the QRTR and QRTR_SMD dependencies explicit and add a soft
dependency to ensure qrtr_smd is loaded before ath11k_ahb.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.2.0.c2-00204-QCAMSLSWPLZ-1
Fixes: 00402f49d2 ("ath11k: Add support for WCN6750 device")
Signed-off-by: Miaoqing Pan <miaoqing.pan@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260806101331.484063-2-miaoqing.pan@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
The ath12k-wsi binding documentation describes using the
generation-specific qcom,ath12k-calibration-variant binding as well as
the generation-agnostic qcom,calibration-variant binding to load
board-specific calibration data from the device tree. However, the
driver never implemented either of these.
Given that no devices currently supported use
qcom,ath12k-calibration-variant and the previous patch implements
qcom,calibration-variant, drop the generation-specific version from the
binding to prevent future confusion.
Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Link: https://patch.msgid.link/20260630133001.1426824-2-andrewjlamarche@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath10k and ath11k support reading calibration variants from the device
tree to locate the correct Board Description File (BDF). The ath12k-wsi
binding already describes using qcom,calibration-variant but it is not
implemented in the driver.
Many ath12k designs expose all the radios under a single phy, each of
which typically require a separate BDF. Without this, the radios may not
come up or will not be calibrated correctly.
Fix this by parsing the device tree for the generation-agnostic
qcom,calibration-variant. This allows the driver to properly select,
read and apply the correct BDF.
Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260630133001.1426824-1-andrewjlamarche@gmail.com
[fixed checkpatch issues]
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
On IPQ8074 a firmware assert reboots the SoC:
Unable to handle kernel read from unreadable memory at virtual address 0
pc : ath11k_hal_srng_access_begin+0xc/0x60 [ath11k]
lr : ath11k_dp_rx_process_mon_status+0x15c/0xd84 [ath11k]
Call trace:
ath11k_hal_srng_access_begin+0xc/0x60 [ath11k]
ath11k_dp_rx_process_mon_rings+0xa0/0x5d4 [ath11k]
ath11k_dp_service_srng+0x1f4/0x348 [ath11k]
ath11k_ahb_ext_grp_napi_poll+0x34/0xd4 [ath11k_ahb]
__napi_poll+0x38/0x188
net_rx_action+0x120/0x2c0
ath11k_core_reconfigure_on_crash() tears the data path down with
ath11k_dp_pdev_free(), ath11k_dp_free() and ath11k_hal_srng_clear(),
which memsets the ring list. The DP NAPI is still running while that
happens, so it services a ring whose address pointer has just been
cleared.
That function used to disable the interrupts first, until
commit d455e805de ("wifi: ath11k: rearrange IRQ enable/disable in reset path")
moved the disable into ath11k_core_reset(). reset_work is only queued
from mhi.c and from the debugfs hw-restart handler, so AHB parts never
run it on a real firmware crash. Their recovery goes QMI server exit ->
restart_work -> ath11k_core_reconfigure_on_crash() ->
ath11k_core_qmi_firmware_ready(), and nothing disables the interrupts
anywhere along it.
Disable them again on the crash path. The reset path has already done
so by the time it gets here, hence the ab->is_reset check.
This is also why the debugfs hw-restart trigger never showed the
problem: it goes through ath11k_core_reset(), the one path that still
had the disable.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.12-01460-QCAHKSWPL_SILICONZ-1
Fixes: d455e805de ("wifi: ath11k: rearrange IRQ enable/disable in reset path")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260726221908.104873-3-julius@bairaktaris.de
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ath11k_core_reset() calls ath11k_hif_ce_irq_disable() right before it
powers the target down, but ath11k_ahb_hif_ops_ipq8074 never set the
ce_irq_enable/ce_irq_disable pair, and ath11k_hif_ce_irq_disable() does
nothing when the op is NULL. On AHB the copy engine interrupts and their
tasklets therefore stay live across rproc_shutdown(), where the register
space they touch is no longer accessible.
Wire the ops up. The sequence is the one ath11k_ahb_stop() already runs,
factored into a helper and reused, so behaviour on the stop path is
unchanged. wcn6750 is not affected: it uses the pcic ops, which
implement the pair already.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260726221908.104873-2-julius@bairaktaris.de
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
In ath11k_dp_srng_setup(), the memory allocated for
ring->vaddr_unaligned is not freed in the error paths that follow.
Fix that by calling ath11k_dp_srng_cleanup() in those error paths.
Compile tested only. Issue found using a prototype static analysis tool
built on the LLVM compiler infrastructure.
Fixes: d5c65159f2 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260801114911.91483-1-nihaal@cse.iitm.ac.in
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Currently ath12k_mac_hw_register() unconditionally sets ab->new_alpha2 to
firmware. But when ab->new_alpha2 is the same as the country already
applied at boot time (stored in ab->default_regd), setting it again is
meaningless. So skip it in that case.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260729-ath12k-regd-wait-timeout-v1-4-504aa6e7e93c@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
ab->new_alpha2 is written under ab->base_lock by the 11d new country
code event handler ath12k_reg_11d_new_cc_event() and by the SMBIOS
BDF parser, and read under the same lock by ath12k_update_11d().
ath12k_mac_hw_register() however read ab->new_alpha2 without holding
base_lock, racing with those writers. Take base_lock and copy the
value into a local wmi_set_current_country_arg, mirroring what
ath12k_update_11d() already does, and use the local copy afterwards.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260729-ath12k-regd-wait-timeout-v1-3-504aa6e7e93c@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
In ath12k_mac_hw_register() the local 'ab' is fetched once from the first
radio, i.e. ath12k_ah_to_ar(ah, 0)->ab. When an ath12k_hw spans more than
one ath12k_base, the radios walked by for_each_ar() may belong to
different ath12k_base instances. Using the function-scope 'ab' inside
that loop then refers to the first radio's device, which is stale with
respect to the ar being processed.
This is not a functional problem currently: the loop only dereferences the
stale 'ab' under hw_params->current_cc_support, which is set only for
WCN7850 and QCC2072. Both devices expose a single radio per ath12k_hw, so
'ab' and ar->ab always point to the same ath12k_base.
Still, relying on that is fragile. Cache ar->ab into a per-iteration
'this_ab' and use it for the country code programming and the log messages
so that each radio is handled against its own ath12k_base regardless of how
many radios an ath12k_hw spans.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260729-ath12k-regd-wait-timeout-v1-2-504aa6e7e93c@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
During driver bring-up, ath12k_mac_hw_register() reinitializes
ar->regd_update_completed and sends a set current country command to
firmware. It then relies on the regulatory event from firmware to signal
that completion via ath12k_reg_chan_list_event().
However, when the country being set is identical to the one already
applied at boot time, ath12k_reg_validate_reg_info() returns
ATH12K_REG_STATUS_DROP through the "Avoid multiple overwrites to default
regd" path. In that case ath12k_reg_chan_list_event() jumps to mem_free
before assigning pdev_idx, so pdev_idx stays at its initial value of 255,
'ar' remains NULL and complete_all() is never called.
As a result the reinitialized completion is left unsignalled and the next
ath12k_regd_update() waits the full timeout, printing:
Timeout while waiting for regulatory update
Fix this by assigning pdev_idx from the event's phy_id right after it is
extracted, before validation, so that the drop and fallback paths still
reach complete_all(). Change the guard at the end to check the index
against ab->num_radios so that an out-of-range phy_id does not lead to an
invalid pdevs[] access.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Fixes: 906619a009 ("wifi: ath12k: handle regulatory hints during mac registration")
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260729-ath12k-regd-wait-timeout-v1-1-504aa6e7e93c@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Currently, ath12k_wmi_process_tpc_stats() has a !skb->data check. This
check is pointless since skb->data is accessed by ath12k_wmi_op_rx() in
order to dispatch the message to this function, therefore it is always
non-NULL.
Remove the pointless check and its associated warning message.
Compile tested only.
Assisted-by: Claude:claude-sonnet-4-6
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260728-ath12k_wmi_process_tpc_stats-skb-check-v1-1-01b7d09be20d@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
secretmem accounts folios by treating memory as if it were mlock()'d and
thus limited by the RLIMIT_MEMLOCK limit.
However the folios are unevictable and remain so until the inode is
evicted, eliminating usual mlock() semantics - mapping folios then
unmapping them does not clear their unevictable state, since it depends on
AS_UNEVICTABLE, not PG_mlocked.
A user can therefore easily work around the RLIMIT_MEMLOCK limit - simply
map then unmap and VmLck no longer counts the secretmem range. Worse,
folios are not accounted in the process's RSS, meaning the OOM killer
won't know to kill the process.
Repeatedly mapping/unmapping (or forking) can then result in the
consumption of all available system memory with unevictable folios and
cause system instability.
A secretmem fd can be passed between processes and over fork so a
per-process limit simply does not make sense, so follow the precedent set
by io_uring, perf, skbuff, iommufd and xdp by tracking the number of
locked pages in user_struct->locked_vm.
Since the scope tracked is actually inode lifetime, the RLIMIT_MEMLOCK
applies per-user not per-process, so it doesn't make sense to bypass for
users with CAP_IPC_LOCK, therefore remove this bypass.
There is simply no reason to carry on marking the mapping as mlock()'d
since it's misleading and the lifecycle is now correctly handled, so
remove this too.
Note that secretmem does not support any form of truncation (including
hole punching) and the folios are unreclaimable, so the folios need only
be accounted on fault and unaccounted on inode destruction.
__secretmem_account_pages() is more or less a duplicate of the code that
io_uring etc. use, but since this is a bug fix that needs backporting,
defer any de-duplication efforts to a follow-up.
test_mlock_limit() asserts mlock_future_ok() on mmap(), however this has
been removed, so remove the test altogether for the fix. A new test will
be sent separately for upstream.
Link: https://lore.kernel.org/20260826-secretmem-accounting-v3-1-94cb04399510@kernel.org
Fixes: 1507f51255 ("mm: introduce memfd_secret system call to create "secret" memory areas")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reported-by: Daehyeon Ko <4ncienth@gmail.com>
Closes: https://lore.kernel.org/linux-mm/20260813225328.2010303-1-4ncienth@gmail.com/
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Tested-by: Daehyeon Ko <4ncienth@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Hagen Paul Pfeifer <hagen@jauu.net>
Cc: Jakub Kacinski <kuba@kernel.org>
Cc: James Bottomley <james.bottomley@HansenPartnership.com>
Cc: Jesper Dangaard Brouer <hawk@kernel.org>
Cc: John Fastabend <john.fastabend@gmail.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Stanislav Fomichev <sdf@fomichev.me>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Uniquely an mremap() invocation using the MREMAP_DONTUNMAP flag can reset
a faulted VMA into an unfaulted one.
It does so after the page tables have been moved to the copied VMA with
MREMAP_DONTUNMAP leaving the old VMA in place which is naturally unfaulted
as the page tables it had are no longer present.
However, in doing so, it violates the invariant that the anonymous page
offset of an unfaulted VMA is vma->vm_start >> PAGE_SHIFT.
This is because a VMA may have been faulted in, mremap()'d (causing a
delta between its page offset and vma->vm_start >> PAGE_SHIFT), and then
mremap()'d again with MREMAP_DONTUNMAP resulting in the unfaulting.
This condition is a violation of a fundamental assumption in mm, but now
also triggers an assert in assert_sane_pgoff() which explicitly checks for
this condition.
Correct it by resetting the VMA's page offset at the point of completing
the MREMAP_DONTUNMAP operation.
Link: https://lore.kernel.org/20260825-fix-mremap-dontunmap-pgoff-v1-1-39a40b2c98b3@kernel.org
Fixes: 1583aa278f ("mm: mremap: unlink anon_vmas when mremap with MREMAP_DONTUNMAP success")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reported-by: syzbot+f12658786a4153df5113@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a87853b.ae6ddae5.3da009.0023.GAE@google.com/
Tested-by: syzbot+f12658786a4153df5113@syzkaller.appspotmail.com
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Reviewed-by: Kunwu Chan <kunwu.chan@gmail.com>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Cc: Jann Horn <jannh@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Li Xinhai <lixinhai.lxh@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
I have been working on transparent hugepages since 2012, starting with the
huge zero page and file-backed THP. A lot of the code that causes pain
now traces back to me. It is only fair if I share the review load for
THP.
Add myself to the reviewer list so get_maintainer.pl puts me on Cc: as
well. It is also my commitment to be more active in reviewing this code.
Link: https://lore.kernel.org/20260827103435.1371882-1-kas@kernel.org
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Barry Song <baohua@kernel.org>
Acked-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Acked-by: Usama Arif <usama.arif@linux.dev>
Acked-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: SJ Park <sj@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
When the root scheduler has sub-scheds attached, the COMPAT kfunc
wrappers scx_bpf_select_cpu_and() and scx_bpf_dsq_insert_vtime() refuse
the call and report to @p's scheduler:
scx_error(scx_task_sched(p), "... must be used");
The wrappers are reachable with tasks that have no scheduler.
scx_bpf_select_cpu_and() is in the select_cpu kfunc group, which
scx_kfunc_context_filter() opens to BPF_PROG_TYPE_SYSCALL programs;
scx_bpf_dsq_insert_vtime() is in the enqueue_dispatch group, which
ops.enqueue() and ops.dispatch() may call with any KF_RCU task -- the
group has no kf_tasks validation, and scx_dsq_insert_preamble() checks
task ownership with scx_task_on_sched() precisely because @p may be an
arbitrary task.
scx_task_sched(p) is p->scx.sched, which is NULL for tasks past
sched_ext_dead() -- which clears it via scx_disable_and_exit_task() on
exit -- and for idle tasks, which the enable paths skip as they are
never scheduled through SCX. It is also an rcu_dereference_protected()
that expects @p's pi_lock or rq lock, which neither wrapper holds.
Passing NULL to scx_error() reaches scx_vexit(), which dereferences
sch->exit_info, oopsing the kernel.
One concrete trigger exercised while developing the fix: a
BPF_PROG_TYPE_SYSCALL program calling the select_cpu_and wrapper on an
exited-but-not-reaped task while a sub-scheduler was attached (its pid
stays findable while the zombie is unreaped; faulting instruction is
the scx_vexit() prologue "mov r15,[rdi+0x398]" with RDI=NULL and 0x398
the offset of sch->exit_info):
sched_ext: BPF scheduler "kfunc_subsched_null" enabled
sched_ext: BPF sub-scheduler "kfunc_subsched_null" enabled
sched_ext: Unassociated program run_select_cpu_ (id 76)
BUG: kernel NULL pointer dereference, address: 0000000000000398
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
Oops: Oops: 0000 [#1] SMP NOPTI
CPU: 7 UID: 0 PID: 8201 Comm: kfunc_test_runn Tainted: G W
RIP: 0010:scx_vexit+0x25/0xa0
Code: ... <4c> 8b bf 98 03 00 00 ...
CR2: 0000000000000398
Call Trace:
<TASK>
__scx_exit+0x4f/0x70
scx_bpf_select_cpu_and+0xab/0xb0
bpf_prog_430ed61a7b66e03a_run_select_cpu_and+0x9c/0xe7
? __x64_sys_bpf+0x2c/0x40
bpf_prog_test_run_syscall+0x130/0x2f0
__sys_bpf+0x930/0x10d0
? __x64_sys_bpf+0x2c/0x40
__x64_sys_bpf+0x2c/0x40
do_syscall_64+0xbc/0x460
entry_SYSCALL_64_after_hwframe+0x76/0x7e
</TASK>
Read @p's scheduler under RCU instead, which the wrappers can do from
their guard(rcu)(): fault it when it can be determined, and when it
can't be determined -- @p is a task past sched_ext_dead() or an idle
task -- there is nothing obviously wrong to report, so just refuse the
call as before without faulting any scheduler.
These COMPAT wrappers are scheduled for eventual removal once the
deprecation grace period elapses, but until then -- and regardless of
their removal timeline -- they must not oops the kernel on a task they
are handed.
Cc: stable@vger.kernel.org # v7.1+
Fixes: a5fa0708cb ("sched_ext: Enforce scheduling authority in dispatch and select_cpu operations")
Suggested-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Wanwu Li <liwanwu@kylinos.cn>
Signed-off-by: Tejun Heo <tj@kernel.org>
- Use jiffies instead of jiffies_64 to address a data-race reported by
KCSAN
- Unpoison cpacf instruction results to address KMSAN reports
- Drop unused member from ap_device_id
- Fix potential NULL pointer dereferences in IPL code
- Add missing length check to SCLP error report handling
- Add missing length check to zcrypt CCA code
- Fix return code handling in diag324 code
- Handle multiple PMU stop callback invocations in perf pai code
correctly
- Reduce excessive debug feature size in perf pai code from 32 MiB to
4KiB
- Switch to common CPU capacity code in topology code to get rid of few
lines of code
- Address various bugs in corner cases in boot code
- Simplify/Rework crst_table_upgrade() to address a potential NULL
pointer dereference in case of an allocation failure
- Initialize padding bytes in CRT key structure in zcrypt code
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEECMNfWEw3SLnmiLkZIg7DeRspbsIFAmqZpREACgkQIg7DeRsp
bsImgxAAqulDVrRQjCWBEG3PkC9/JNyyOhVmWW688hGS3n6zGTqsw/8791u4RB3S
JepdWVPd9xs+xRKClSbdUHVAlr1A7zC8oczPPOji08DlXfbaQeUXXB9Dtt6ah5Eo
CvHKzCO6MWNh2XpQ1g+LTAUWuXrLuhWF8c7VDC4iijXniEL6SFpnsrTWCyW8erlZ
Tm6uP4K2xb6GQzMXmDcFH0SRao+EZD0n/CRp4dVOXOudO2v02BXMskTZEnzlnDNj
FiDGm6HGUKZJrjYdq/YWfWH0N2wIz/IiyX86lsSQft4rLvxvI494EqNtkyAJK8X+
UgjM7+p2iYfXDfSMUmvqi8u3p9aq65y6w9lS3W8rI2VJ8wJBSOrElBU0UlRyTxQX
bCAcYkdTW+/euaceqCgiMhevYMwJ2K1BA8f2Ob3ChI8MC1HkF9xnQ6cZOpJjaj4l
imAv8mthWvacyV/33aNv0V/pS2CeLhdNnGfIB8KaHZIQxnmv44wuFNEvbyuSMOx8
GnwFF0zG6c4x/6BSXDgfoWFOVVhdxkZf1PVywwREwNJcyuTslhQ4jyl/NrDl1cMQ
+vlKAqm0tuleNq4oIfWlEl2eocheFe97GjtV0Db66jkNCtnHVz1v21VIx3UgDcFB
lHOW/BwM9e7jDa6SheGfTHHcPgw+PLPZXyLlasucAma5xkPqY48=
=LHgC
-----END PGP SIGNATURE-----
Merge tag 's390-7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Heiko Carstens:
- Use jiffies instead of jiffies_64 to address a data-race reported by
KCSAN
- Unpoison cpacf instruction results to address KMSAN reports
- Drop unused member from ap_device_id
- Fix potential NULL pointer dereferences in IPL code
- Add missing length check to SCLP error report handling
- Add missing length check to zcrypt CCA code
- Fix return code handling in diag324 code
- Handle multiple PMU stop callback invocations in perf pai code
correctly
- Reduce excessive debug feature size in perf pai code from 32 MiB to
4KiB
- Switch to common CPU capacity code in topology code to get rid of few
lines of code
- Address various bugs in corner cases in boot code
- Simplify/Rework crst_table_upgrade() to address a potential NULL
pointer dereference in case of an allocation failure
- Initialize padding bytes in CRT key structure in zcrypt code
* tag 's390-7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/zcrypt: Fix uninitialized padding in CRT key structure
s390/mm: Simplify crst_table_upgrade()
s390/boot: Bound command line facility ranges
s390/boot: Avoid IPL parameter append past command line
s390/boot: Fix physical memory search range
s390/topology: Switch to common cpu capacity code
s390/pai: Reduce excessive debug feature size
s390/pai: Handle multiple PMU stop callback invocations
s390/diag324: Preserve -EBUSY return code
s390/zcrypt: Validate length in reply before using it
s390/pci: Fix leak of uninitialized kernel data in SCLP report
s390/ipl: Fix NULL deref in dump_reipl without re-IPL parm block
s390/ipl: Fix NULL deref in kdump without re-IPL parm block
s390/ap: Drop unused member from ap_device_id
s390/cpacf: Unpoison instruction results
s390/time: Use jiffies instead of jiffies_64
Previous releases - regressions:
- page_pool: keep frag_offset aligned for odd-sized requests
- sched: fix u32 duplicate handle when node ID pool is exhausted
- udp: create exceptions before socket matching
- igmp: convert struct ip_sf_list to RCU
- ip6_gre: check tunnel info before xmit in ip6gre_tunnel_xmit
- rds: acquire the fastpath locks in rds_conn_shutdown()
- tipc:
- protect node reset trace dump with node lock
- fix NULL deref in tipc_named_node_up() on empty publication list
- bluetooth:
L2CAP: fix out-of-bounds write in l2cap_ecred_connect
hci_core: fix race condition during device registration
- eth: mlx5e: prevent stale XSK buffer release on refill retries
- eth: bridge: don't truncate the port group walk on teardown
Previous releases - always broken:
- gro: fix nesting of TCP GSO SKBs in skb_gro_receive_list()
- sched: fix skb sizing and action leak on reoffload delete
- tcp: fix use-after-free in do_tcp_getsockopt()
- af_packet: don't cast tpacket_hdr.tp_len to int in tpacket_parse_header().
- sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration
- iptunnel: fix stale transport header during tunnel decapsulation
- eth: vxlan: fix use-after-free in vxlan_mdb_remote_src_del()
- eth: bonding: fix uninitialized transport header access in alb_determine_nd()
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-----BEGIN PGP SIGNATURE-----
iQJGBAABCgAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmqZp4kSHHBhYmVuaUBy
ZWRoYXQuY29tAAoJECkkeY3MjxOkEjkQALMGg903vZ4TfGlzKayFzyhcd5ZC8G4F
R4M+UgTGRfNuas/1YwjpyOpvOYyFgGZ9xBmYNFdsW0YCzZwu8PxpXgu6WTZ+F4gu
sDtWoAbN5V6CfY3fdC7IbXTp8t4CX+shQAsVvEp39Y8SJF4AZeMn8N0+Lnu4DlD3
DAPo/lYSSfvv7RK/5Jvr9FWo7vyoEylfG+LekzGASmWGwhC3h7kWGB4RB4PhJmyq
vRIj2ZjnzdDxu4N7ZGh+EEu5SBCcLP0e/dIMCDg++HAghDqPJ+7pzbWC1kFtQ0ss
qOSyws/xMW3D0Rb68tkiikYWRwgvXUsfEL7Jdf2lhC1xDI8ZpxrrnPYYSZS4rsjb
hjeBwtzRZhv5R0PnNlaZyNpFICIW3XwqP0bYqH/Z/CgwwkKYd+Rp6Tm7hkLpafNx
Py607x2Ff/L2Aydp8csJEyqFP33QOHAfeW+X/YCo4jTc0zBTMSsOblG/EsPPBdNX
fvhVkx4NdqAvIdLYm65cdvhe5dZtIhOAhwAMcrGiMIia4vCIsXq3fWbAe6Phtu8T
KHpQ7Esg/if6blNPpflBuVPsoU+5N6mL7a+zsurqvilJBC5DgYaxwbMlgRSUmJzg
2rR6IlrOsb0FFITNUv+xgPEGzMGV1rL4wnaMSmVN0tjmFQvcu24XQ17D+ug27+eG
rD+E2lrX5rNn
=0sv8
-----END PGP SIGNATURE-----
Merge tag 'net-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni:
"Including fixes from bluetooth.
Previous releases - regressions:
- page_pool: keep frag_offset aligned for odd-sized requests
- sched: fix u32 duplicate handle when node ID pool is exhausted
- udp: create exceptions before socket matching
- igmp: convert struct ip_sf_list to RCU
- ip6_gre: check tunnel info before xmit in ip6gre_tunnel_xmit
- rds: acquire the fastpath locks in rds_conn_shutdown()
- tipc:
- protect node reset trace dump with node lock
- fix NULL deref in tipc_named_node_up() on empty publication
list
- bluetooth:
- L2CAP: fix out-of-bounds write in l2cap_ecred_connect
- hci_core: fix race condition during device registration
- eth:
- mlx5e: prevent stale XSK buffer release on refill retries
- bridge: don't truncate the port group walk on teardown
Previous releases - always broken:
- gro: fix nesting of TCP GSO SKBs in skb_gro_receive_list()
- sched: fix skb sizing and action leak on reoffload delete
- tcp: fix use-after-free in do_tcp_getsockopt()
- af_packet: don't cast tpacket_hdr.tp_len to int in
tpacket_parse_header()
- sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration
- iptunnel: fix stale transport header during tunnel decapsulation
- eth:
- vxlan: fix use-after-free in vxlan_mdb_remote_src_del()
- bonding: fix uninitialized transport header access in
alb_determine_nd()"
* tag 'net-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (83 commits)
net: gro: Fix nesting of TCP GSO SKBs in skb_gro_receive_list()
net: stmmac: reconfigure RX packet parser table in stmmac_hw_setup() after reset
net: airoha: enable RX_DONE interrupt for RX queue 31
net/rds: don't let rds_conn_shutdown() consume a concurrent drop
net/rds: acquire the fastpath locks in rds_conn_shutdown()
net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks()
net/rds: tcp: don't force RDS_CONN_RESETTING over a concurrent shutdown
net/rds: clear cp_flags bits individually in rds_conn_path_reset()
net/rds: use clear_bit_unlock() in release_refill()
net/rds: use wq_has_sleeper() in release_in_xmit()
net: usb: qmi_wwan: add Compal EXM-G1x support
net: macb: exclude software FCS from TX byte statistics
net: Remove conflicting altnames for dying netns in __dev_change_net_namespace().
net: bridge: mcast: don't truncate the port group walk on teardown
bonding: do not clear curr_active_slave prematurely when releasing all slaves
net: qrtr: Send HELLO message on endpoint register
octeontx2-af: Fix limiting SRIOV VF count logic
bonding: alb: fix uninitialized transport header access in alb_determine_nd()
s390/ctcm: Prevent XID null dereference
net: psp: do not inherit the Rx association on clone
...
It is possible for userspace to set the job SRAM size to 0, but then still
have SRAM accesses in the command stream. When the job SRAM size is 0,
setting the region base register is skipped and a stale base address from
a prior job is used.
Check the region size against the job's SRAM size instead of just the size
of the SRAM. The job's SRAM size was already checked against the total SRAM
size.
Fixes: 9cff907748 ("accel: ethosu: Validate SRAM size on submit")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-5-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
On a mapping failure of the SRAM, the SRAM size is left as non-zero. The
probe will succeed as the error return is not checked since having SRAM is
not a hard requirement. The non-zero size allows jobs to access SRAM which
is left pointing to physical base address 0x0.
Fixes: 5a5e9c0228 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-4-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
While the QSIZE register setting should prevent an out of bounds access
of the command stream, it is not clear whether the h/w generates an
interrupt in this case as is required (to prevent a timeout). As a stop op
is expected end of the command stream, let's just ensure it is present. A
stop op in the middle of the command stream also makes no sense.
Fixes: 5a5e9c0228 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-3-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
The IRQF_SHARED flag doesn't work with runtime-pm as the IRQ handler
could run without resuming the device. This could also be fixed with
runtime-pm calls in the IRQ handler, but there is no known need for a
shared IRQ.
Fixes: 5a5e9c0228 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-2-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
A WARN_ON() returns a 0 or 1, not the original negative errno. Just drop
the WARN_ON() as the FD open will pass the return code to userspace and
there's only one possible source of the error (drm_sched_entity_init()).
Fixes: 5a5e9c0228 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-1-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Kumar Kartikeya Dwivedi says:
====================
Misc bug fixes - part 1
A set of miscellaneous fixes for bugs reported by Nicholas. These are
easy ones and should not require any major discussion, hence batched
together. See commit logs and selftests for details.
====================
Link: https://patch.msgid.link/20260903144433.1716731-1-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
A BPF_PROG_TYPE_SYSCALL program is sleepable, but its bpf_timer callbacks
run in a non-sleepable hrtimer softirq context.
Add verifier cases that call bpf_sys_bpf() and bpf_sys_close() from timer
callbacks. Without the syscall helper prototype annotations these programs
load, so their failure expectations expose the bug.
Also add successful controls that call each helper from the syscall program
main body, ensuring that the intended sleepable use remains accepted.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-11-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
bpf_sys_bpf() executes the bpf(2) syscall body, which can take mutexes,
allocate with GFP_KERNEL, and wait for an RCU grace period.
bpf_sys_close() reaches close_fd() and filp_close(), which can sleep as
well.
Both helpers are limited to BPF_PROG_TYPE_SYSCALL, whose main program is
sleepable. That does not make every callback sleepable: a syscall program
can register a bpf_timer callback, and the verifier checks that callback
in a non-sleepable context while retaining the syscall helper set.
Without .might_sleep on the prototypes, such a callback can invoke
bpf_sys_bpf() from hrtimer softirq context and trigger a
scheduling-while-atomic failure. bpf_sys_close() is exposed through the
same missing context check.
Set .might_sleep on both prototypes so the existing helper-context check
rejects them from timer callbacks and other atomic regions. Calls from the
sleepable main body remain valid.
Fixes: 79a7f8bdb1 ("bpf: Introduce bpf_sys_bpf() helper and program type.")
Fixes: 3abea08924 ("bpf: Add bpf_sys_close() helper.")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-10-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Add a load-time verifier test that dereferences argument 0 of the
sched_process_wait tp_btf program without checking it. The test expects the
nullable-pointer diagnostic, so it is accepted unexpectedly before the fix
and rejected as expected after it.
Add a successful control that checks the argument for NULL before the
dereference. This ensures the nullable marking preserves legitimate access
to the pid when the tracepoint supplies one.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-9-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
do_wait() passes wo->wo_pid to the sched_process_wait tracepoint.
kernel_wait4() leaves wo_pid NULL for wait4(-1), and
kernel_waitid_prepare() does likewise for waitid(P_ALL).
btf_ctx_access() currently types argument 0 as PTR_TO_BTF_ID |
PTR_TRUSTED. Without PTR_MAYBE_NULL, the verifier accepts an unchecked
dereference. Trusted pointer loads have no fault protection, so a wait for
any child can then cause a NULL pointer dereference in JITed BPF code.
Add sched_process_wait to raw_tp_null_args[] with argument 0 marked
nullable. The verifier rejects an unchecked dereference while preserving
access after the program checks the pointer for NULL.
Fixes: 838a10bd2e ("bpf: Augment raw_tp arguments with PTR_MAYBE_NULL")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-8-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Add a load-only verifier regression for a resilient lock operation in an
rbtree comparison callback. The program holds the rbtree's regular spin
lock and a separate resilient lock, then releases the resilient lock from
the callback. This isolates the missing kfunc policy check without running
a concurrent tree mutation.
Release the resilient lock before the regular lock on the outer
fall-through. The broken verifier therefore accepts the balanced program,
while the fixed verifier rejects the resilient unlock specifically while
verifying the callback.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-7-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
__bpf_rbtree_add() keeps parent and link pointers live across calls to the
program-supplied comparison callback. The verifier therefore requires the
root's lock to remain held throughout the callback.
The helper path enforces this rule for bpf_spin_lock() and
bpf_spin_unlock(), but the resilient lock kfunc argument path does not.
Since resilient locks may protect BPF rbtree roots, a callback can release
the root lock and let another CPU remove and free the node referenced by
the in-progress tree walk. The walk then resumes using freed pointers.
Reject resilient lock kfuncs in an rbtree comparison callback, matching
the existing policy for the spin lock helpers. Resilient-lock-protected
trees remain valid when their comparison callbacks leave lock state alone.
Fixes: 0de2046137 ("bpf: Implement verifier support for rqspinlock")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-6-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tailcall_callback tests a tail call one static subprogram below a callback.
That reaches the later stack-depth rejection, but it does not exercise the
tail-call helper while the current frame is itself a callback.
Add a callback that calls bpf_tail_call directly and expect the existing
"cannot tail call within callback" diagnostic. On an affected kernel, the
load instead reaches the "callback unexpected regs" verifier bug, so the
expected message is absent and the test fails. The existing ordinary
subprogram case remains a success control for legitimate tail calls.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-5-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
A tail call from a non-zero frame is modeled as a return from that frame.
The verifier makes R0 unknown and calls prepare_func_exit() for the taken
branch.
When the current frame is a synchronous callback, prepare_func_exit()
enforces the callback return-value contract and marks R0 precise. Since the
tail-call path synthesized R0 rather than deriving it from an instruction,
precision backtracking reaches the callback-calling instruction with R0
still requested and triggers the "callback unexpected regs" verifier bug.
A CAP_BPF task can therefore cause a WARN and an -EFAULT BPF_PROG_LOAD.
Tail calls reachable from callbacks are already rejected later by
check_max_stack_depth(). Reject a tail call made directly by a callback
before constructing the inconsistent return state, using the existing
diagnostic. Tail calls from ordinary subprograms keep their current
behavior.
Fixes: e3245f8990 ("bpf: properly verify tail call behavior")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-4-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Add load-only verifier coverage for the signal_generate and
signal_deliver info arguments. The signal_generate case performs a NULL
check before dereferencing info, ensuring that merely making it nullable
cannot satisfy the test when the nonzero SEND_SIG_PRIV sentinel is used.
Both programs load successfully without the verifier fix, contrary to
their expected-failure annotations. With the fix, info is a scalar and
the attempted dereferences are rejected.
Also add success cases showing that plain raw tracepoint and tp_btf
programs can continue to read and compare the context word as a scalar.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-3-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
The signal_generate and signal_deliver tracepoints declare their info
argument as a struct kernel_siginfo pointer. btf_ctx_access() therefore
treats it as a trusted pointer for tp_btf programs.
Signal delivery also uses SEND_SIG_NOINFO and SEND_SIG_PRIV as special
values for this argument. Those values are zero and one respectively,
and are not pointers. A tp_btf program can currently dereference either
value and fault the kernel. In particular, signal_generate can run from
timer interrupt context, turning the fault into a kernel panic.
Record both tracepoints in raw_tp_null_args[] and mark argument one as
a non-pointer. This preserves scalar access to the cookie while rejecting
direct and helper-mediated pointer use. Merely marking it nullable would
not suffice because SEND_SIG_PRIV is nonzero.
Fixes: 838a10bd2e ("bpf: Augment raw_tp arguments with PTR_MAYBE_NULL")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Jiayuan Chen says:
====================
bpf: Fix NULL-ptr-derefs when showing a void BTF type
This series fixes three NULL-ptr-derefs in BTF handling.
Patch 1 handles the syzbot report. A key-less BTF (btf_key_type_id == 0) used
to be rejected for hash maps, until htab and rhtab gained a ->map_check_btf
(to register a dtor) that does not look at the key, so a key-less hash map is
now accepted. Dumping it through bpffs feeds the key type_id 0 into
btf_type_seq_show() and NULL-derefs in btf_type_show(). Reject it again.
Patches 2 and 3 fix two related, pre-existing crashes reachable via
bpf_snprintf_btf(), which renders a type_id taken straight from the BPF
program against the vmlinux BTF. A "const void" (a modifier resolving to
void) NULL-derefs in btf_modifier_show() - void has no ->show op; a
BTF_KIND_VAR NULL-derefs in btf_var_show() - the vmlinux base BTF has no
resolved_ids. Patch 2 falls back to btf_df_show(), the "<unsupported kind:N>"
placeholder already used for FWD/FUNC/FLOAT/DECL_TAG; patch 3 resolves the
var's type directly, mirroring the existing guard in btf_modifier_show().
Patches 4 and 5 add selftests. Patch 4 checks a key-less hash and rhash map is
rejected at creation. Patch 5 extends the snprintf_btf test to render a
"const void" and a BTF_KIND_VAR from the vmlinux BTF and checks they resolve
without crashing.
v3 -> v4: Drop the pin-and-read reproducer from the key-less map test, fold
the void/VAR test into the existing snprintf_btf test, and simplify patch 2's
wording (review comments).
v2 -> v3: Fold in a third fix for the same class of bug, btf_var_show(),
reported while reviewing v2. Address review comments (Fixes attribution,
verbatim syzbot trace, skip instead of fail).
v1 -> v2: AI reported a pre-exist issue. Let's fold it in this series.
v3: https://lore.kernel.org/bpf/20260831110314.150870-1-jiayuan.chen@linux.dev/
v2: https://lore.kernel.org/bpf/20260830073242.148092-1-jiayuan.chen@linux.dev/
v1: https://lore.kernel.org/bpf/20260828093142.179856-1-jiayuan.chen@linux.dev/
====================
Link: https://patch.msgid.link/20260901104924.346187-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Extend the snprintf_btf test with type_ids from the vmlinux BTF that
used to NULL-deref in the BTF show path: a "const void", checked to
render the "<unsupported kind:0>" placeholder, and a BTF_KIND_VAR,
checked to resolve and render without error.
The program renders from its own buffer and the test picks a VAR whose
resolved type fits it, so the render stays in bounds.
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-6-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Create a hash and an rhash map with btf_key_type_id == 0 and expect
bpf_map_create() to fail with -EINVAL; a positive control with a real
key type confirms the rejection is about the key-less BTF and not some
unrelated failure.
Such a map used to be accepted and then NULL-deref in btf_type_show()
when dumped through bpffs.
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-5-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
btf_var_show() calls btf_type_id_resolve() unconditionally, which
dereferences btf->resolved_ids. That is NULL for a base BTF - e.g. the
vmlinux BTF that bpf_snprintf_btf() renders against - since base BTF is
not resolved during parsing. btf_modifier_show() guards this with
'if (btf->resolved_ids)', but btf_var_show() does not.
A BPF program that passes the type_id of a BTF_KIND_VAR from the vmlinux
BTF to bpf_snprintf_btf() thus NULL-derefs:
KASAN: probably user-memory-access in range [0x46638-0x4663f]
RIP: 0010:btf_var_show (kernel/bpf/btf.c:2929)
Call Trace:
<TASK>
btf_type_show (kernel/bpf/btf.c:8259)
btf_type_snprintf_show (kernel/bpf/btf.c:8329)
bpf_snprintf_btf (kernel/trace/bpf_trace.c:1047)
bpf_prog_test_run_raw_tp (net/bpf/test_run.c:829)
__sys_bpf (kernel/bpf/syscall.c:4804)
do_syscall_64 (arch/x86/entry/syscall_64.c:84)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
</TASK>
Resolve the var's type directly with btf_type_skip_modifiers() when
resolved_ids is NULL, mirroring btf_modifier_show().
Fixes: c4d0bfb450 ("bpf: Add bpf_snprintf_btf helper")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-4-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
btf_modifier_show() resolves the modifier and then calls
btf_type_ops(t)->show() unconditionally. For the void type (type_id 0,
BTF_KIND_UNKN) kind_ops[] has no entry, so ->show is NULL.
A "const void" (a modifier resolving to void) cannot be a map key or
value - map_check_btf() rejects it because void has no size - so the map
dump path does not reach it. But bpf_snprintf_btf() takes a type_id
straight from the BPF program, and passing such a "const void" from the
vmlinux BTF NULL-derefs:
KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]
RIP: 0010:btf_modifier_show (kernel/bpf/btf.c:2914)
Call Trace:
<TASK>
btf_type_show (kernel/bpf/btf.c:8251)
btf_type_snprintf_show (kernel/bpf/btf.c:8321)
bpf_snprintf_btf (kernel/trace/bpf_trace.c:1047)
bpf_prog_test_run_raw_tp (net/bpf/test_run.c:829)
__sys_bpf (kernel/bpf/syscall.c:4804)
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
</TASK>
Fall back to btf_df_show() when the resolved type has no show op; it
emits the "<unsupported kind:N>" placeholder already used for kinds like
FWD and FUNC. bpf_snprintf_btf() then returns the length as usual.
Fixes: c4d0bfb450 ("bpf: Add bpf_snprintf_btf helper")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-3-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
map_check_btf() allows a key-less BTF (btf_key_type_id == 0) only for
maps that have a ->map_check_btf callback, and leaves the actual
decision to that callback. Hash maps used to have no ->map_check_btf,
so a key-less BTF was rejected outright.
That changed when htab and rhtab gained a ->map_check_btf to register a
dtor - htab in commit 1df97a7453 ("bpf: Register dtor for freeing
special fields") and rhtab in commit 6905f86012 ("bpf: Allow special
fields in resizable hashtab"). Neither looks at the key, so a key-less
hash map now passes map_check_btf() and gets created. Reading it back
through bpffs feeds the key type_id 0 into btf_type_seq_show();
btf_type_by_id() returns the void type, kind_ops[BTF_KIND_UNKN] is NULL,
and btf_type_show() dereferences it:
RIP: 0010:btf_type_show+0x223/0x2e0 kernel/bpf/btf.c:8232
RSP: 0018:ffffc9000399f868 EFLAGS: 00010206
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000005 RSI: 0000000000000000 RDI: 0000000000000028
RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000
R10: ffffc9000399f970 R11: 0000000000000001 R12: ffffffff9b96b140
R13: ffffc9000399f8e0 R14: ffff88803d393c00 R15: 0000000000000003
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000000000 CR3: 000000003d213000 CR4: 0000000000352ef0
DR0: 0000000039ae8f55 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
btf_type_seq_show_flags+0xca/0x120 kernel/bpf/btf.c:8250
htab_map_seq_show_elem+0x12e/0x350 kernel/bpf/hashtab.c:1669
map_seq_show+0x13d/0x1e0 kernel/bpf/inode.c:293
traverse.part.0.constprop.0+0x107/0x650 fs/seq_file.c:112
traverse fs/seq_file.c:99 [inline]
seq_read_iter+0x93f/0x1270 fs/seq_file.c:196
seq_read+0x344/0x4d0 fs/seq_file.c:163
vfs_read+0x1e4/0xb40 fs/read_write.c:572
ksys_pread64 fs/read_write.c:764 [inline]
__do_sys_pread64 fs/read_write.c:772 [inline]
__se_sys_pread64 fs/read_write.c:769 [inline]
__x64_sys_pread64+0x1eb/0x250 fs/read_write.c:769
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Reject a key-less BTF in htab_map_check_btf() and rhtab_map_check_btf(),
restoring the previous behavior.
Fixes: 1df97a7453 ("bpf: Register dtor for freeing special fields")
Fixes: 6905f86012 ("bpf: Allow special fields in resizable hashtab")
Reported-by: syzbot+37b56485bbbf90ad8489@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a8f4e88.27659fcc.2ceef7.0008.GAE@google.com/T/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-2-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>