| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
ksmbd: fix listener task lifetime on netdev events
The listener thread exits when its listening socket is shutdown. The
netdevice notifier shuts down the socket before calling kthread_stop(), so
the task_struct can be freed before kthread_stop() gets its reference.
Create the listener in a stopped state and hold an extra task_struct
reference until kthread_stop_put() completes. Also stop and release
listeners before freeing their interface records during TCP teardown. |
| In the Linux kernel, the following vulnerability has been resolved:
net/rds: acquire the fastpath locks in rds_conn_shutdown()
rds_conn_shutdown() quiesces the transmit and receive-refill paths by
waiting for RDS_IN_XMIT and RDS_RECV_REFILL to be sampled clear, and
then runs the transport shutdown and rds_conn_path_reset(). Sampling
the bits clear is not the same as owning them: the moment after the
wait_event() returns, rds_send_xmit() can re-acquire RDS_IN_XMIT (or
rds_ib_recv_refill() can re-acquire RDS_RECV_REFILL) and run
concurrently with the teardown.
The sender does recheck the connection state after taking the lock,
but that recheck is a classic store-buffering pattern: teardown writes
the state and reads the bit while the sender writes the bit and reads
the state. acquire_in_xmit() is only an acquire operation, so on
weakly ordered architectures both sides can miss each other's write,
and the transmit path then runs while the transport zeroes its rings
(e.g. rds_ib_ring_init()) and rds_send_path_reset() rewrites the
transmit state under it.
Oracle UEK fixed the same class of crashes - a 14-year tail of
BUG_ON()s in rds_ib_sub_signaled(), unexpected op-codes and NULL
dereferences in rds_ib_send_cqe_handler() during failover testing -
by making the teardown path *acquire* the fastpath bit locks instead
of testing them ("rds: Make sure transmit path and connection
tear-down does not run concurrently"). Ownership of a single word is
decided by RMW atomicity, so no cross-variable ordering is needed.
Do the same here: take both locks before calling the transport
shutdown, hold them across rds_conn_path_reset(), and release them
explicitly with a wake-up afterwards. Both are released with
clear_bit_unlock(), so that the ring re-initialization done by the
transport shutdown and the transmit state rewritten by
rds_send_path_reset() are ordered before either bit is seen clear by
the next acquire_in_xmit() or acquire_refill().
The fastpath users of these bits - rds_send_xmit() and
rds_ib_recv_refill() - are trylock style and back off while teardown
owns the locks, so no new lock dependency is introduced for them.
rds_tcp_reset_callbacks() is different: since the previous patch it
acquires RDS_IN_XMIT as well, and it blocks doing so, so its wait now
spans the teardown instead of at most one send batch. That waiter
runs from rds_tcp_accept_one() on the single-threaded krdsd workqueue
and holds rds_tcp_accept_lock and t_conn_path_lock while it waits, so
a duelling SYN accepted while its path is being torn down parks
accept processing for the duration of the teardown - for TCP bounded
by the (up to 5 s) drain loop in rds_tcp_conn_path_shutdown(). An IB
path's drain in rds_ib_conn_path_shutdown() has no round cap, but no
blocking waiter either: rds_tcp_reset_callbacks() is the only blocking
acquirer of these bits and waits only on its own TCP path, and the
fastpaths are trylock-and-back-off on both transports, so a long IB
drain lengthens only that path's own quiesce. The
window is narrow: the accept-side state check has to pass before the
teardown moves the path to RDS_CONN_DISCONNECTING.
Because krdsd is a single global workqueue, everything else queued
there - accept processing for other connections and network
namespaces, and the flush_workqueue(rds_wq) in rds_tcp_listen_stop()
during namespace teardown - waits behind the parked accept worker for
that time. It cannot deadlock, although the waits do point at each
other: the teardown blocks until the bit's holder releases it, and
the holder may be that krdsd accept worker. The holder finishes
without needing anything the teardown owns: the sync cancels
rds_tcp_reset_callbacks() issues target cp_send_w and cp_recv_w on
the path's ordered cp_wq, whose only execution slot is occupied by
the blocked cp_down_w itself, so they are pending at most and cancel
without flushing - a reliance on cp_wq being ordered that is now
noted next to those cancels (on
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
eth: nfp: bound the ntuple rule dump by the caller's buffer size
nfp_net_get_fs_loc() dumps every entry of nn->fs.list into rule_locs[]
without consulting cmd->rule_cnt, which is how many entries the caller
had room for. ETHTOOL_GRXCLSRLALL requires no CAP_NET_ADMIN and the
ioctl sizes the buffer from the rule_cnt userspace passes in, so once an
admin has installed flow steering rules any user can ask for fewer slots
than there are rules and run off the end of the allocation. A rule_cnt
of 0 leaves the buffer pointer NULL and the walk dereferences it.
Bail out with -EMSGSIZE when the buffer fills up, the way the other
ntuple capable drivers do, and report how many locations were filled so
a shrinking rule list does not leave the caller reading stale slots. |
| In the Linux kernel, the following vulnerability has been resolved:
vxlan: reject dynamic fdb entries that reference a nexthop id
The commit cited in the Fixes tag allowed VXLAN FDB entries to point to
FDB nexthops so that overlay traffic could be load balanced across
multiple VTEPs. Such entries can only be configured from user space,
cannot be learned and cannot roam. They only make sense with a user space
control plane such as E-VPN where data plane learning is disabled.
Despite that, the VXLAN driver does not currently prevent such entries
from being configured with the "dynamic" flag. The per-nexthop FDB list
is only protected by the per-device hash lock, which is not sufficient
when two VXLAN devices point to the same FDB nexthop and therefore share
the list. Aging runs in softirq context without RTNL, so an entry deleted
by one device can race with an addition or deletion from the other,
leading to list corruption:
list_del corruption. next->prev should be ffff8881069d9548, but was
dead000000000122. (next=ffff8881069d9448)
WARNING: CPU: 0 PID: 90 at lib/list_debug.c:65
__list_del_entry_valid_or_report+0x1aa/0x210
...
vxlan_fdb_destroy+0x5b8/0xad0
vxlan_cleanup+0x328/0x450
call_timer_fn+0x2a/0x1c0
run_timer_softirq+0x18c/0x210
BUG: KASAN: slab-use-after-free in vxlan_fdb_destroy
Fix this by rejecting the bogus configuration of dynamic FDB entries that
point to FDB nexthops, both when created and when an existing entry is
updated. As such, the per-nexthop FDB list is only ever mutated under the
RTNL lock. Add test cases to make sure that this does not regress in the
future. |
| In the Linux kernel, the following vulnerability has been resolved:
net/sched: defer qdisc freeing after failed creation
An RTM_NEWQDISC request can make clsact bind a populated shared ingress
block during ->init(), publishing an embedded mini_Qdisc to lockless
readers. If the same request has an invalid TCA_RATE, estimator setup
fails after ->init(); the unwind removes the pointer but synchronously
frees its containing qdisc while tc_run() may still hold it.
Retire failed qdiscs through the same RCU helper as normal destruction.
Inline the synchronous free into the callback now that no direct callers
remain. |
| In the Linux kernel, the following vulnerability has been resolved:
vdpa_sim_blk: reject out-of-range sector starts
vdpasim_blk_check_range() logs an invalid start sector but continues
validating the request. The subsequent unsigned capacity subtraction can
underflow and let an out-of-range buffer offset reach the data path.
The invalid offset is used by three request paths. VIRTIO_BLK_T_OUT
copies guest data to blk->buffer + offset through
vringh_iov_pull_iotlb(), causing an out-of-bounds write in
_copy_from_iter() or memcpy(). VIRTIO_BLK_T_IN copies from
blk->buffer + offset to the guest through vringh_iov_push_iotlb(),
causing an out-of-bounds read in _copy_to_iter().
VIRTIO_BLK_T_WRITE_ZEROES passes blk->buffer + offset to memset(),
causing an out-of-bounds write.
Reject starts at or beyond the capacity before the subtraction. Treat the
capacity boundary as invalid because the IN and OUT paths round byte counts
down to sectors for validation but later copy the original byte counts. A
sub-sector request at the capacity boundary would otherwise still access
past the end of the buffer.
I found this bug myself, though the patch was written with AI assistance. |
| In the Linux kernel, the following vulnerability has been resolved:
vdpa_sim_net: check TX pull result before RX copy
vringh_iov_pull_iotlb() returns a signed byte count. A failed TX pull is
currently added to the unsigned byte counter and then passed as a size_t
length to receive_filter() and vringh_iov_push_iotlb(). A negative error
can therefore become a large length in the RX path.
Handle non-positive pull results before every length use. Count the TX
error and complete the consumed TX descriptor with zero bytes.
I found this bug myself, though the patch was written with AI assistance. |
| In the Linux kernel, the following vulnerability has been resolved:
nstree: check listing permission before taking a namespace reference
legitimize_ns() takes a reference on the candidate namespace before
may_list_ns() has decided whether the caller may see it. The
__free(ns_put) cleanup on the denied path can drop the last reference to a
mount namespace while we still hold the rcu read lock, and put_mnt_ns()
may sleep there. This is the same problem commit 2ec2aff3c8e2 ("ns: make
sure reference are dropped outside of rcu lock") fixed for the put_user()
path. Neither ns_requested() nor may_list_ns() needs a reference, both
only look at the namespace type and at the caller's own namespaces, so do
the checks first and take the reference last.
Splat:
Voluntary context switch within RCU read-side critical section!
WARNING: kernel/rcu/tree_plugin.h:332 at rcu_note_context_switch+0x238/0x2a0, CPU#5: a/3442
CPU: 5 UID: 1000 PID: 3442 Comm: a Not tainted 7.0.0-30-generic #30-Ubuntu PREEMPT(lazy)
RIP: 0010:rcu_note_context_switch+0x238/0x2a0
Call Trace:
<TASK>
__schedule+0xcf/0x650
schedule+0x27/0x90
schedule_preempt_disabled+0x15/0x30
__mutex_lock.constprop.0+0x550/0xaf0
__mutex_lock_slowpath+0x13/0x20
mutex_lock+0x3b/0x50
exp_funnel_lock+0xb2/0x260
synchronize_rcu_expedited+0xe7/0x220
namespace_unlock+0x26a/0x320
put_mnt_ns+0xd3/0x120
mntns_put+0xe/0x20
do_listns+0x13e/0x560
__do_sys_listns+0x126/0x2d0
__x64_sys_listns+0x20/0x30
x64_sys_call+0x2366/0x2390
do_syscall_64+0x105/0x5a0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
</TASK> |
| In the Linux kernel, the following vulnerability has been resolved:
net: hinic: fix mailbox segment buffer overflow
check_mbox_seq_id_and_seg_len() validates that seq_id does not
exceed SEQ_ID_MAX_VAL (42) and seg_len does not exceed
MBOX_SEG_LEN (48). However, this allows the last segment
(seq_id=42) to carry a full 48-byte payload, writing to offset
42*48=2016 for 48 bytes (ending at byte 2064). The receive
buffer is only MBOX_MAX_BUF_SZ (2048) bytes, resulting in a
16-byte heap buffer overflow.
The hinic3 driver already handles this correctly by defining
MBOX_LAST_SEG_MAX_LEN and rejecting the last segment when it
exceeds the remaining buffer space. Apply the same fix to the
hinic driver. |
| In the Linux kernel, the following vulnerability has been resolved:
ipv6: fix fib6 walker UAF on seq stop
ipv6_route_iter_active() treats a walker in FWS_U at the table root as
already unlinked. fib6_del_route() can move a still-linked walker into
that same state when the current leaf is the last route at the root,
so ipv6_route_native_seq_stop() skips fib6_walker_unlink(). The seq
private object can then be freed while it remains on
net->ipv6.fib6_walkers. A later route deletion walks the dangling list
and uses the freed walker.
Use the list head as membership state and reinitialize it when
unlinking. Keep the existing w->node check so a never-started iterator
with a zeroed private object is not treated as linked.
The same stop helper is used by /proc/net/ipv6_route and by the BPF
ipv6_route iterator. The BPF show path only widens the race. |
| In the Linux kernel, the following vulnerability has been resolved:
ALSA: us122l: Prevent write upgrades for read mappings
The hwdep mmap callback rejects read-buffer mappings that are initially
writable, but leaves VM_MAYWRITE set on mappings created with PROT_READ.
A process that can open the hwdep node O_RDWR can later use mprotect() to
make the mapping writable.
The read allocation begins with struct usb_stream. Its read_size member is
used by the fault handler to decide which pages belong to the read buffer.
The read VMA intentionally remains expandable because pcm_usb_stream uses
mremap() after reading that size. Changing read_size first can therefore
map and access pages beyond the allocation. The same member is also
consumed by usb_stream_free(), where changing it can make
free_pages_exact() release pages outside the allocation.
Clear VM_MAYWRITE for read-buffer mappings after rejecting an initially
writable VMA. This keeps the separate output-buffer mapping writable while
preventing later permission upgrades. |
| In the Linux kernel, the following vulnerability has been resolved:
ufs: validate cylinder group metadata before caching it
ufs_read_cylinder() copies the cylinder group index and the rotor
positions straight from the on-disk group and caches them without any
check:
ucpi->c_cgx = fs32_to_cpu(sb, ucg->cg_cgx);
ucpi->c_rotor = fs32_to_cpu(sb, ucg->cg_rotor);
ucpi->c_frotor = fs32_to_cpu(sb, ucg->cg_frotor);
ucpi->c_irotor = fs32_to_cpu(sb, ucg->cg_irotor);
They are then used as indices during allocation and free:
- c_cgx indexes the cylinder summary array as
UFS_SB(sb)->fs_cs(ucpi->c_cgx), so a value past s_ncg writes a 32
bit count outside the s_csp allocation.
- c_frotor becomes a bitmap scan start, start = c_frotor >> 3, and
then length = ((s_fpg + 7) >> 3) - start. A start beyond the block
bitmap wraps the unsigned length to a huge value, so ubh_scanc()
walks far past the cylinder group buffers. c_irotor drives the
inode bitmap the same way.
A crafted image can set any of these freely, turning an ordinary
allocation into an out of bounds access.
Reject a cylinder group whose recorded index does not match the group
being read, or whose rotors fall outside the group, before the metadata
is cached. Valid filesystems keep cg_cgx equal to the group number and
the rotors within the group, so only malformed images are rejected. |
| In the Linux kernel, the following vulnerability has been resolved:
accel: ethosu: Ensure SRAM region size matches job
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. |
| In the Linux kernel, the following vulnerability has been resolved:
ASoC: sprd: validate compress buffer sizes against fixed allocations
sprd_platform_compr_open() allocates the stage 0 IRAM buffer (32K data
area) and the stage 1 DDR buffer (2M data area) with fixed sizes, but
sprd_platform_compr_copy() derives all copy lengths from the user
controlled runtime->fragment_size and the write() count, never
comparing them against the physical buffer sizes. The compress core
only checks fragment_size * fragments for an u32 overflow in
snd_compress_check_input(), so a local user can configure a logical
buffer of up to ~4GB via SNDRV_COMPRESS_SET_PARAMS, far exceeding the
fixed allocations.
A fragment_size larger than the 32K IRAM data area makes the stage 0
copy_from_user() overflow past the IRAM allocation, and a buffer_size
larger than the 2M DDR buffer makes the wrapping copy at the end of
sprd_platform_compr_copy() write fully user controlled data past the
buffer. No SNDRV_PCM_TRIGGER_START is needed, a write() in SETUP
state reaches the copy callback directly.
Reject parameters that do not fit into the fixed buffers in
set_params(), and fix the advertised max fragment size: 128K never
fitted into the 32K IRAM buffer. The caps values may have been carried over
from the qdsp6 driver, which allocates its buffers according to the
advertised maxima, unlike this driver. With 32K as max fragment size
the advertised limits are self-consistent: 32K * 64 = 2M equals the
DDR buffer size.
Discovered by Atuin - Automated Vulnerability Discovery Engine. |
| In the Linux kernel, the following vulnerability has been resolved:
exit: hold a reference to thread_pid across proc_flush_pid
Commit 0a36bad01731 ("release_task: kill the no longer needed
get/put_pid(thread_pid)") removed the reference around proc_flush_pid().
It assumed that free_pids(post.pids) at the end of release_task() would
keep thread_pid alive until then.
That assumption is wrong. __change_pid() only records a detached PID in
post.pids when pid_has_task() is false for every PIDTYPE. If another task
still uses the exiting task's PID as its process group or session ID,
__unhash_process() removes the exiting task's PIDTYPE_PID link but leaves
the PID out of post.pids. release_task() therefore holds no reference to
it after dropping tasklist_lock.
The other task can then remove the remaining PIDTYPE links. Its
free_pids() call schedules delayed_put_pid(), and the RCU callback can free
the PID before the first release_task() reaches proc_flush_pid().
An unprivileged reproducer races wait4(-1) against setsid() to trigger this
ordering. Three of three fresh v7.2 KASAN boots reported:
BUG: KASAN: slab-use-after-free in
proc_invalidate_siblings_dcache+0x3e2/0x3f0
Read of size 8 by task h7_pid_reaper/1921
Call Trace:
proc_invalidate_siblings_dcache
release_task
wait_consider_task
__do_wait
do_wait
kernel_wait4
Freed by task 0:
kmem_cache_free
put_pid
delayed_put_pid
rcu_core
Last potentially related work creation:
__call_rcu_common
free_pids
ksys_setsid
KASAN identified a 144-byte object from the pid cache and located the bad
read 80 bytes into the freed object, matching pid->inodes. With an
explicit reference, three of three fresh boots completed without a KASAN
report. The concurrent RCU callback dropped its reference while
proc_flush_pid() was protected, and the balancing put_pid() performed the
final free afterward.
Take a reference before __unhash_process() clears p->thread_pid and release
it after proc_flush_pid() completes.
A tested source reproducer is available privately on request. No
controlled read or write, information leak, or privilege escalation is
claimed. The mainline patch applies directly to v6.19.y and newer;
v6.16.y through v6.18.y need a context-adjusted backport. |
| In the Linux kernel, the following vulnerability has been resolved:
net: mpls: clear inner_protocol when the last label is popped
skb_mpls_push() records the pre-encapsulation network header once, gated
on !skb->inner_protocol. skb_mpls_pop() never clears that record, so it
outlives the encapsulation it describes.
Open vSwitch can then re-push MPLS onto a packet whose
inner_network_header still points at the older, deeper offset: push a
label, pop every label, recirculate (ovs_flow_key_update() re-derives
key->eth.type and resets network_header, but leaves inner_*), then push
again. ovs_fragment() trusts the record:
skb->network_header = skb->inner_network_header;
so skb_network_offset() goes negative. The bound check is signed:
if (skb_network_offset(skb) > MAX_L2_LEN)
a negative offset passes it, and prepare_frag() widens the value:
unsigned int hlen = skb_network_offset(skb);
memcpy(&data->l2_data, skb->data, hlen);
which is a ~4GiB memcpy out of a 30-byte per-CPU buffer.
Reproduced on v7.3-rc1. RDX is the truncated length, (unsigned int)(-8):
BUG: unable to handle page fault for address: ffffe8ffffc16000
#PF: supervisor write access in kernel mode
Oops: 0002 [#1] SMP KASAN NOPTI
RIP: 0010:memcpy+0x8/0x20
RDX: 00000000fffffff8 RSI: ffff888105d732db RDI: ffffe8ffffc16000
prepare_frag+0x3df/0x4e0
ovs_fragment+0x589/0x7e0
do_output+0x4ce/0x5e0
do_execute_actions+0x55d2/0x7b30
ovs_execute_actions+0xea/0x450
Same root-cause shape as commit 975b5b067f52 ("ipv6: sr: restore network
header before routing and forwarding"): a stale network header offset
reaching a consumer that widens it. Here it originates in the MPLS
push/pop path.
Clear inner_protocol once the packet is no longer MPLS, so a later push
re-records the current header. net/sched/act_mpls.c is the only other
skb_mpls_pop() caller and gets the same fix; sch_frag.c saves and
restores inner_protocol around fragmentation in the same way OVS does. |
| In the Linux kernel, the following vulnerability has been resolved:
net: openvswitch: fix use-after-free of the flow table mask array
tbl_mask_array_realloc() retires the old mask_array before it stops being
reachable:
old = ovsl_dereference(tbl->mask_array);
if (old) {
...
call_rcu(&old->rcu, mask_array_rcu_cb);
}
rcu_assign_pointer(tbl->mask_array, new);
call_rcu() only waits for read-side critical sections already in flight.
tbl->mask_array still points at old between the call_rcu() and the
rcu_assign_pointer(), so a reader entering ovs_flow_tbl_lookup_stats() in
that window picks up old in a fresh critical section that the pending
grace period does not cover.
tbl_mask_array_realloc() runs in process context under ovs_mutex, so the
window is preemptible and can outlast the grace period. Then
mask_array_rcu_cb() frees old before the swap runs:
BUG: KASAN: slab-use-after-free in flow_lookup.constprop.0+0x2bf/0x2f0
Read of size 8 at addr ffff888020b3e018 by task poc/741
flow_lookup.constprop.0+0x2bf/0x2f0
ovs_flow_tbl_lookup_stats+0x4a3/0x5c0
ovs_dp_process_packet+0x19c/0x710
ovs_vport_receive+0x243/0x390
internal_dev_xmit+0x81/0x170
Freed by task 728:
kfree+0x16a/0x4e0
rcu_core+0x853/0x1030
Publish the new array before retiring the old one. The kfree_rcu() that
call_rcu() replaced ran after the swap. |
| In the Linux kernel, the following vulnerability has been resolved:
netfilter: cttimeout: prevent UAF during module unload
nf_ct_set_timeout() protects the timeout hook dereference and policy lookup
with rcu_read_lock(). cttimeout_exit(), however, unregisters the per-net
operations before it clears the hook.
This allows the following interleaving:
CPU 0 CPU 1
cttimeout_exit() nf_ct_set_timeout()
unregister_pernet_subsys() rcu_read_lock()
kfree(pernet) h = nf_ct_timeout_hook
h->timeout_find_get()
nfct_timeout_pernet()
The hook still points to ctnl_timeout_find_get() when CPU 1 looks up the
already freed per-net timeout list. KASAN reported:
BUG: KASAN: slab-use-after-free in ctnl_timeout_find_get
Read of size 8 by task poc/90
Call Trace:
ctnl_timeout_find_get+0x271/0x2a0 [nfnetlink_cttimeout]
nf_ct_set_timeout+0x7b/0x3c0
xt_ct_tg_check+0x724/0xb20
xt_check_target+0x234/0xa90
do_ipt_set_ctl+0x570/0x1270
Allocated by task 89:
__kmalloc_noprof+0x16e/0x460
ops_init+0x6d/0x420
register_pernet_operations+0x2f6/0x670
Freed by task 91:
kfree+0x131/0x390
ops_undo_list+0x3d4/0x730
unregister_pernet_operations+0x232/0x490
unregister_pernet_subsys+0x1c/0x30
cttimeout_exit+0x52/0x970 [nfnetlink_cttimeout]
Clear the hook and wait for existing readers before unregistering the
per-net operations. This blocks new policy lookups and ensures readers that
observed the hook finish before the per-net storage is freed. |
| In the Linux kernel, the following vulnerability has been resolved:
netfilter: nf_log: unregister loggers before per-net teardown
nf_log_syslog and nfnetlink_log unregister their per-network namespace
operations before unregistering their global logger backends. This
leaves a window where a sysctl or netlink writer can rebind the still-
registered logger after the per-net pre-exit callback cleared the old
selection.
The race looks like this:
CPU 0 CPU 1
---- ----
unregister_pernet_subsys()
nf_log_unset(net, logger)
net->nf.nf_loggers[pf] = NULL
lock nf_log_mutex
find logger in loggers[][]
net->nf.nf_loggers[pf] = logger
unlock nf_log_mutex
nf_log_unregister(logger)
lock nf_log_mutex
loggers[pf][type] = NULL
unlock nf_log_mutex
synchronize_rcu()
module exit returns
module core frees backend memory
Later, a sysctl read or packet logging operation can dereference the
stale per-net logger pointer.
Fix this by unregistering the global logger backends before tearing down
per-net state. Once the global registrations are gone, later writers can
no longer rebind the logger. unregister_pernet_subsys() already waits
for an RCU grace period after the pre-exit callback clears the per-net
selection, while nf_log_unregister() continues to cover readers of the
global logger table.
Apply this ordering fix to both nf_log backends that combine per-net
teardown with global logger registration. |
| In the Linux kernel, the following vulnerability has been resolved:
inet: frags: invalidate queues before flushing them
fqdir_pre_exit() flushes the skbs from incomplete queues without
changing their completion state. A fragment which found a queue before
high_thresh was cleared can then acquire the queue lock and reuse stale
reassembly metadata. A queue concurrently killed after fqdir->dead is
set can instead become INET_FRAG_COMPLETE|INET_FRAG_HASH_DEAD while
still holding its old skbs; skipping it because it is complete leaves
those references behind until asynchronous fqdir teardown.
For IPv6, stale metadata can make ip6_frag_reasm() use the old
nhoffset with a new skb and access memory out of bounds. The resulting
heap corruption can be leveraged for local privilege escalation when
unprivileged network namespaces are available. Unflushed fragments can
also keep conntrack references alive after the conntrack per-net
cleanup point.
Kill each incomplete queue, then flush every queue still owned by the
dying rhashtable. HASH_DEAD identifies that ownership, while complete
queues without it are already owned by another destroy path and must be
left alone. Releasing a timer reference removed by inet_frag_kill() is
deferred to inet_frag_putn(), after the queue lock is dropped.
KASAN report:
BUG: KASAN: slab-out-of-bounds in ipv6_frag_rcv (net/ipv6/reassembly.c:289 (discriminator 2) net/ipv6/reassembly.c:229 (discriminator 2) net/ipv6/reassembly.c:391 (discriminator 2))
Write of size 1 at addr ff110001039c6e00 by task poc/771
Call Trace:
? ipv6_frag_rcv (net/ipv6/reassembly.c:289 (discriminator 2) net/ipv6/reassembly.c:229 (discriminator 2) net/ipv6/reassembly.c:391 (discriminator 2))
ipv6_frag_rcv (net/ipv6/reassembly.c:289 (discriminator 2) net/ipv6/reassembly.c:229 (discriminator 2) net/ipv6/reassembly.c:391 (discriminator 2))
ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:479 (discriminator 5))
ip6_input_finish (net/ipv6/ip6_input.c:534)
ipv6_rcv (include/net/dst.h:480 (discriminator 3) net/ipv6/ip6_input.c:119 (discriminator 3) net/ipv6/ip6_input.c:109 (discriminator 3) include/linux/netfilter.h:325 (discriminator 3) include/linux/netfilter.h:319 (discriminator 3) net/ipv6/ip6_input.c:351 (discriminator 3))
packet_sendmsg (net/packet/af_packet.c:3110 net/packet/af_packet.c:3142)
__x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880)
The buggy address belongs to the object at ff110001039c6b40
which belongs to the cache skbuff_small_head of size 704
The buggy address is located 0 bytes to the right of
allocated 704-byte region [ff110001039c6b40, ff110001039c6e00)
BUG: KASAN: slab-out-of-bounds in ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:423 (discriminator 1))
Read of size 1 at addr ff110001039c6e08 by task poc/771
Call Trace:
? ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:423 (discriminator 1))
ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:423 (discriminator 1))
ip6_input_finish (net/ipv6/ip6_input.c:534)
ipv6_rcv (include/net/dst.h:480 (discriminator 3) net/ipv6/ip6_input.c:119 (discriminator 3) net/ipv6/ip6_input.c:109 (discriminator 3) include/linux/netfilter.h:325 (discriminator 3) include/linux/netfilter.h:319 (discriminator 3) net/ipv6/ip6_input.c:351 (discriminator 3))
packet_sendmsg (net/packet/af_packet.c:3110 net/packet/af_packet.c:3142)
__x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880)
packet_sendmsg (net/packet/af_packet.c:2959 net/packet/af_packet.c:3053 net/packet/af_packet.c:3142)
__x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880)
The buggy address belongs to the object at ff110001039c6b40
which belongs to the cache skbuff_small_head of size 704
The buggy address is located 8 bytes to the right of
allocated 704-byte region [ff110001039c6b40, ff110001039c6e00) |