Security Vulnerabilities
- CVEs Published In March 2025
In the Linux kernel, the following vulnerability has been resolved:
net/sched: cls_api: fix error handling causing NULL dereference
tcf_exts_miss_cookie_base_alloc() calls xa_alloc_cyclic() which can
return 1 if the allocation succeeded after wrapping. This was treated as
an error, with value 1 returned to caller tcf_exts_init_ex() which sets
exts->actions to NULL and returns 1 to caller fl_change().
fl_change() treats err == 1 as success, calling tcf_exts_validate_ex()
which calls tcf_action_init() with exts->actions as argument, where it
is dereferenced.
Example trace:
BUG: kernel NULL pointer dereference, address: 0000000000000000
CPU: 114 PID: 16151 Comm: handler114 Kdump: loaded Not tainted 5.14.0-503.16.1.el9_5.x86_64 #1
RIP: 0010:tcf_action_init+0x1f8/0x2c0
Call Trace:
tcf_action_init+0x1f8/0x2c0
tcf_exts_validate_ex+0x175/0x190
fl_change+0x537/0x1120 [cls_flower]
In the Linux kernel, the following vulnerability has been resolved:
geneve: Fix use-after-free in geneve_find_dev().
syzkaller reported a use-after-free in geneve_find_dev() [0]
without repro.
geneve_configure() links struct geneve_dev.next to
net_generic(net, geneve_net_id)->geneve_list.
The net here could differ from dev_net(dev) if IFLA_NET_NS_PID,
IFLA_NET_NS_FD, or IFLA_TARGET_NETNSID is set.
When dev_net(dev) is dismantled, geneve_exit_batch_rtnl() finally
calls unregister_netdevice_queue() for each dev in the netns,
and later the dev is freed.
However, its geneve_dev.next is still linked to the backend UDP
socket netns.
Then, use-after-free will occur when another geneve dev is created
in the netns.
Let's call geneve_dellink() instead in geneve_destroy_tunnels().
[0]:
BUG: KASAN: slab-use-after-free in geneve_find_dev drivers/net/geneve.c:1295 [inline]
BUG: KASAN: slab-use-after-free in geneve_configure+0x234/0x858 drivers/net/geneve.c:1343
Read of size 2 at addr ffff000054d6ee24 by task syz.1.4029/13441
CPU: 1 UID: 0 PID: 13441 Comm: syz.1.4029 Not tainted 6.13.0-g0ad9617c78ac #24 dc35ca22c79fb82e8e7bc5c9c9adafea898b1e3d
Hardware name: linux,dummy-virt (DT)
Call trace:
show_stack+0x38/0x50 arch/arm64/kernel/stacktrace.c:466 (C)
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0xbc/0x108 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0x16c/0x6f0 mm/kasan/report.c:489
kasan_report+0xc0/0x120 mm/kasan/report.c:602
__asan_report_load2_noabort+0x20/0x30 mm/kasan/report_generic.c:379
geneve_find_dev drivers/net/geneve.c:1295 [inline]
geneve_configure+0x234/0x858 drivers/net/geneve.c:1343
geneve_newlink+0xb8/0x128 drivers/net/geneve.c:1634
rtnl_newlink_create+0x23c/0x868 net/core/rtnetlink.c:3795
__rtnl_newlink net/core/rtnetlink.c:3906 [inline]
rtnl_newlink+0x1054/0x1630 net/core/rtnetlink.c:4021
rtnetlink_rcv_msg+0x61c/0x918 net/core/rtnetlink.c:6911
netlink_rcv_skb+0x1dc/0x398 net/netlink/af_netlink.c:2543
rtnetlink_rcv+0x34/0x50 net/core/rtnetlink.c:6938
netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline]
netlink_unicast+0x618/0x838 net/netlink/af_netlink.c:1348
netlink_sendmsg+0x5fc/0x8b0 net/netlink/af_netlink.c:1892
sock_sendmsg_nosec net/socket.c:713 [inline]
__sock_sendmsg net/socket.c:728 [inline]
____sys_sendmsg+0x410/0x6f8 net/socket.c:2568
___sys_sendmsg+0x178/0x1d8 net/socket.c:2622
__sys_sendmsg net/socket.c:2654 [inline]
__do_sys_sendmsg net/socket.c:2659 [inline]
__se_sys_sendmsg net/socket.c:2657 [inline]
__arm64_sys_sendmsg+0x12c/0x1c8 net/socket.c:2657
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x90/0x278 arch/arm64/kernel/syscall.c:49
el0_svc_common+0x13c/0x250 arch/arm64/kernel/syscall.c:132
do_el0_svc+0x54/0x70 arch/arm64/kernel/syscall.c:151
el0_svc+0x4c/0xa8 arch/arm64/kernel/entry-common.c:744
el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:762
el0t_64_sync+0x198/0x1a0 arch/arm64/kernel/entry.S:600
Allocated by task 13247:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x30/0x68 mm/kasan/common.c:68
kasan_save_alloc_info+0x44/0x58 mm/kasan/generic.c:568
poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
__kasan_kmalloc+0x84/0xa0 mm/kasan/common.c:394
kasan_kmalloc include/linux/kasan.h:260 [inline]
__do_kmalloc_node mm/slub.c:4298 [inline]
__kmalloc_node_noprof+0x2a0/0x560 mm/slub.c:4304
__kvmalloc_node_noprof+0x9c/0x230 mm/util.c:645
alloc_netdev_mqs+0xb8/0x11a0 net/core/dev.c:11470
rtnl_create_link+0x2b8/0xb50 net/core/rtnetlink.c:3604
rtnl_newlink_create+0x19c/0x868 net/core/rtnetlink.c:3780
__rtnl_newlink net/core/rtnetlink.c:3906 [inline]
rtnl_newlink+0x1054/0x1630 net/core/rtnetlink.c:4021
rtnetlink_rcv_msg+0x61c/0x918 net/core/rtnetlink.c:6911
netlink_rcv_skb+0x1dc/0x398 net/netlink/af_netlink.c:2543
rtnetlink_rcv+0x34/0x50 net/core/rtnetlink.c:6938
netlink_unicast_kernel net/netlink/af_n
---truncated---
In the Linux kernel, the following vulnerability has been resolved:
USB: gadget: f_midi: f_midi_complete to call queue_work
When using USB MIDI, a lock is attempted to be acquired twice through a
re-entrant call to f_midi_transmit, causing a deadlock.
Fix it by using queue_work() to schedule the inner f_midi_transmit() via
a high priority work queue from the completion handler.
In the Linux kernel, the following vulnerability has been resolved:
mm/zswap: fix inconsistency when zswap_store_page() fails
Commit b7c0ccdfbafd ("mm: zswap: support large folios in zswap_store()")
skips charging any zswap entries when it failed to zswap the entire folio.
However, when some base pages are zswapped but it failed to zswap the
entire folio, the zswap operation is rolled back. When freeing zswap
entries for those pages, zswap_entry_free() uncharges the zswap entries
that were not previously charged, causing zswap charging to become
inconsistent.
This inconsistency triggers two warnings with following steps:
# On a machine with 64GiB of RAM and 36GiB of zswap
$ stress-ng --bigheap 2 # wait until the OOM-killer kills stress-ng
$ sudo reboot
The two warnings are:
in mm/memcontrol.c:163, function obj_cgroup_release():
WARN_ON_ONCE(nr_bytes & (PAGE_SIZE - 1));
in mm/page_counter.c:60, function page_counter_cancel():
if (WARN_ONCE(new < 0, "page_counter underflow: %ld nr_pages=%lu\n",
new, nr_pages))
zswap_stored_pages also becomes inconsistent in the same way.
As suggested by Kanchana, increment zswap_stored_pages and charge zswap
entries within zswap_store_page() when it succeeds. This way,
zswap_entry_free() will decrement the counter and uncharge the entries
when it failed to zswap the entire folio.
While this could potentially be optimized by batching objcg charging and
incrementing the counter, let's focus on fixing the bug this time and
leave the optimization for later after some evaluation.
After resolving the inconsistency, the warnings disappear.
[42.hyeyoo@gmail.com: refactor zswap_store_page()]
In the Linux kernel, the following vulnerability has been resolved:
ASoC: SOF: stream-ipc: Check for cstream nullity in sof_ipc_msg_data()
The nullity of sps->cstream should be checked similarly as it is done in
sof_set_stream_data_offset() function.
Assuming that it is not NULL if sps->stream is NULL is incorrect and can
lead to NULL pointer dereference.
In the Linux kernel, the following vulnerability has been resolved:
nfp: bpf: Add check for nfp_app_ctrl_msg_alloc()
Add check for the return value of nfp_app_ctrl_msg_alloc() in
nfp_bpf_cmsg_alloc() to prevent null pointer dereference.
In the Linux kernel, the following vulnerability has been resolved:
drm/i915/gt: Use spin_lock_irqsave() in interruptible context
spin_lock/unlock() functions used in interrupt contexts could
result in a deadlock, as seen in GitLab issue #13399,
which occurs when interrupt comes in while holding a lock.
Try to remedy the problem by saving irq state before spin lock
acquisition.
v2: add irqs' state save/restore calls to all locks/unlocks in
signal_irq_work() execution (Maciej)
v3: use with spin_lock_irqsave() in guc_lrc_desc_unpin() instead
of other lock/unlock calls and add Fixes and Cc tags (Tvrtko);
change title and commit message
(cherry picked from commit c088387ddd6482b40f21ccf23db1125e8fa4af7e)
In the Linux kernel, the following vulnerability has been resolved:
nvmet: Fix crash when a namespace is disabled
The namespace percpu counter protects pending I/O, and we can
only safely diable the namespace once the counter drop to zero.
Otherwise we end up with a crash when running blktests/nvme/058
(eg for loop transport):
[ 2352.930426] [ T53909] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] PREEMPT SMP KASAN PTI
[ 2352.930431] [ T53909] KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]
[ 2352.930434] [ T53909] CPU: 3 UID: 0 PID: 53909 Comm: kworker/u16:5 Tainted: G W 6.13.0-rc6 #232
[ 2352.930438] [ T53909] Tainted: [W]=WARN
[ 2352.930440] [ T53909] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014
[ 2352.930443] [ T53909] Workqueue: nvmet-wq nvme_loop_execute_work [nvme_loop]
[ 2352.930449] [ T53909] RIP: 0010:blkcg_set_ioprio+0x44/0x180
as the queue is already torn down when calling submit_bio();
So we need to init the percpu counter in nvmet_ns_enable(), and
wait for it to drop to zero in nvmet_ns_disable() to avoid having
I/O pending after the namespace has been disabled.
In the Linux kernel, the following vulnerability has been resolved:
bpf: Fix softlockup in arena_map_free on 64k page kernel
On an aarch64 kernel with CONFIG_PAGE_SIZE_64KB=y,
arena_htab tests cause a segmentation fault and soft lockup.
The same failure is not observed with 4k pages on aarch64.
It turns out arena_map_free() is calling
apply_to_existing_page_range() with the address returned by
bpf_arena_get_kern_vm_start(). If this address is not page-aligned
the code ends up calling apply_to_pte_range() with that unaligned
address causing soft lockup.
Fix it by round up GUARD_SZ to PAGE_SIZE << 1 so that the
division by 2 in bpf_arena_get_kern_vm_start() returns
a page-aligned value.
In the Linux kernel, the following vulnerability has been resolved:
net: Add rx_skb of kfree_skb to raw_tp_null_args[].
Yan Zhai reported a BPF prog could trigger a null-ptr-deref [0]
in trace_kfree_skb if the prog does not check if rx_sk is NULL.
Commit c53795d48ee8 ("net: add rx_sk to trace_kfree_skb") added
rx_sk to trace_kfree_skb, but rx_sk is optional and could be NULL.
Let's add kfree_skb to raw_tp_null_args[] to let the BPF verifier
validate such a prog and prevent the issue.
Now we fail to load such a prog:
libbpf: prog 'drop': -- BEGIN PROG LOAD LOG --
0: R1=ctx() R10=fp0
; int BPF_PROG(drop, struct sk_buff *skb, void *location, @ kfree_skb_sk_null.bpf.c:21
0: (79) r3 = *(u64 *)(r1 +24)
func 'kfree_skb' arg3 has btf_id 5253 type STRUCT 'sock'
1: R1=ctx() R3_w=trusted_ptr_or_null_sock(id=1)
; bpf_printk("sk: %d, %d\n", sk, sk->__sk_common.skc_family); @ kfree_skb_sk_null.bpf.c:24
1: (69) r4 = *(u16 *)(r3 +16)
R3 invalid mem access 'trusted_ptr_or_null_'
processed 2 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
-- END PROG LOAD LOG --
Note this fix requires commit 838a10bd2ebf ("bpf: Augment raw_tp
arguments with PTR_MAYBE_NULL").
[0]:
BUG: kernel NULL pointer dereference, address: 0000000000000010
PF: supervisor read access in kernel mode
PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
PREEMPT SMP
RIP: 0010:bpf_prog_5e21a6db8fcff1aa_drop+0x10/0x2d
Call Trace:
<TASK>
? __die+0x1f/0x60
? page_fault_oops+0x148/0x420
? search_bpf_extables+0x5b/0x70
? fixup_exception+0x27/0x2c0
? exc_page_fault+0x75/0x170
? asm_exc_page_fault+0x22/0x30
? bpf_prog_5e21a6db8fcff1aa_drop+0x10/0x2d
bpf_trace_run4+0x68/0xd0
? unix_stream_connect+0x1f4/0x6f0
sk_skb_reason_drop+0x90/0x120
unix_stream_connect+0x1f4/0x6f0
__sys_connect+0x7f/0xb0
__x64_sys_connect+0x14/0x20
do_syscall_64+0x47/0xc30
entry_SYSCALL_64_after_hwframe+0x4b/0x53