| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
net: openvswitch: fix flow mask use-after-free on flow deletion
The commit in the Fixes tag below made so flow->mask free is scheduled
via RCU right after it is removed from the flow table. The pointer
stays in the flow structure and it can be accessible while in the same
RCU critical section. This is done to avoid requiring ovs_mutex for
the ovs_flow_free().
However, while removing the flow during processing of CMD_DEL, we do
not take RCU read lock before the removal, and ovs_flow_cmd_fill_info()
uses the flow->mask pointer afterwards. The RCU read lock is taken,
but it's already late at that point. The comment on that line
acknowledges that the lock is cosmetic and doesn't serve a real purpose.
This leads to use-after-free if the RCU grace period passes between
removal and the filling. It is a short race window, but it is there
and can lead to a real crash in case memory allocation for the info
takes a bit longer:
BUG: KASAN: slab-use-after-free in __ovs_nla_put_key
net/openvswitch/flow_netlink.c:1996
BUG: KASAN: slab-use-after-free in ovs_nla_put_key+0x2463/0x2e30
net/openvswitch/flow_netlink.c:2250
Read of size 4 at addr ffff88801ee89970 by task ovs_flow_del_ec/9487
Call Trace:
<TASK>
__ovs_nla_put_key net/openvswitch/flow_netlink.c:1996
ovs_nla_put_key+0x2463/0x2e30 net/openvswitch/flow_netlink.c:2250
ovs_flow_cmd_fill_info+0x420/0x9c0 net/openvswitch/datapath.c:930
ovs_flow_cmd_del+0x53a/0x970 net/openvswitch/datapath.c:1467
...
netlink_rcv_skb+0x156/0x420 net/netlink/af_netlink.c:2556
</TASK>
Allocated by task 9487:
mask_alloc net/openvswitch/flow_table.c:967
flow_mask_insert net/openvswitch/flow_table.c:1012
ovs_flow_tbl_insert+0xea2/0x1a90 net/openvswitch/flow_table.c:1084
ovs_flow_cmd_new+0x7e3/0xd90 net/openvswitch/datapath.c:1086
...
netlink_rcv_skb+0x156/0x420 net/netlink/af_netlink.c:2556
Freed by task 9485:
rcu_free_sheaf+0x1e/0x100 mm/slub.c:5978
rcu_do_batch kernel/rcu/tree.c:2645
rcu_core+0x59c/0x10c0 kernel/rcu/tree.c:2897
handle_softirqs+0x1e4/0x9a0 kernel/softirq.c:622
...
instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1062
ovs_flow_tbl_remove() must be called after the ovs_flow_cmd_fill_info()
to avoid this race. This also helps with cleaning up the forced cast
and the cosmetic RCU read lock. Before the commit in the Fixes tag the
order did not matter as long as the flow object itself was not freed.
A wider RCU critical section could be another option, but we have a
GFP_KERNEL allocation in the way.
Reported by Trend Micro's Zero Day Initiative as ZDI-CAN-32042. |
| In the Linux kernel, the following vulnerability has been resolved:
net: phylink: correctly validate returned PCS in phylink_inband_caps
In phylink_inband_caps(), the PCS returned by mac_select_pcs is only
checked if NULL but mac_select_pcs can also return an error pointer.
This can cause a kernel panic as phylink_pcs_inband_caps() only checks
if passed PCS is not NULL and directly dereference ops from the phylink_pcs
struct.
Use the IS_ERR_OR_NULL macro to address both case where the returned
PCS can be NULL or an error pointer and prevent a kernel panic. |
| In the Linux kernel, the following vulnerability has been resolved:
net: ravb: avoid dereferencing an invalid PTP clock
The PTP clock is unavailable before the first open, so querying its
index can dereference a NULL pointer. Registration failures can also
leave an error pointer in priv->ptp.clock.
Cache the PHC index separately and report -1 while no clock is
registered. Normalize registration errors to NULL and preserve the
static timestamping capabilities. |
| In the Linux kernel, the following vulnerability has been resolved:
net: ravb: serialize PTP clock teardown
ravb_ptp_interrupt() can race with ravb_ptp_stop() and pass the clock to
ptp_clock_event() while ptp_clock_unregister() is freeing it. This can
lead to a use-after-free.
Use READ_ONCE() and WRITE_ONCE() for lockless access to the clock pointer.
Atomically detach it with xchg() before disabling PTP interrupts, then
synchronize all IRQs which can invoke ravb_ptp_interrupt() before
unregistering the detached clock.
A handler which read the old pointer completes before the clock is
unregistered, while later handlers read NULL and skip the event. |
| In the Linux kernel, the following vulnerability has been resolved:
net: thunderbolt: Release the Rx HopID that was handed out on mismatch
tb_xdomain_alloc_in_hopid() passes the wanted HopID to ida_alloc_range()
as the lower bound, so a taken id is not an error there: the allocator
returns the next free one above it. tbnet_connected_work() asks for the
peer's transmit path, treats any other id as a failure and returns
without releasing what it got, so that allocation stays live for the rest
of the XDomain connection with nothing left holding a reference to it.
Release the id when it is not the one we asked for, the same way the
error unwind at the end of the function releases the expected one. |
| In the Linux kernel, the following vulnerability has been resolved:
net: thunderbolt: Mark the connection down when bringing it up fails
Every failure path in tbnet_connected_work() undoes its own work and
returns without clearing login_sent, so the connection still looks
established. The next tbnet_tear_down() therefore takes its main branch
and repeats a teardown that already happened: it stops rings that are
already stopped, which is a dev_WARN() and fatal under panic_on_warn,
and it releases net->remote_transmit_path even on the HopID mismatch
path, where this connection never owned that id, silently freeing one
that someone else is still using.
Clear login_sent on those paths. That is enough for tbnet_tear_down() to
leave the unwound state alone, and login_received has to stay set: it
records that the peer has logged in and carries the transmit path it gave
us, which nothing on this side can make the peer send again. Two things
change beyond keeping the teardown out of the way: the logout request in
that block is no longer sent, and the peer's next login request now
re-queues our login work rather than connected_work, giving the
connection a fresh login instead of a retry on stale state. |
| In the Linux kernel, the following vulnerability has been resolved:
NTB: ntb_transport: Fail TX enqueue when the QP link is down
Commit f195a1a6fe41 ("ntb: Drop packets when qp link is down") meant to
make ntb_transport_tx_enqueue() drop packets submitted while the QP link
is down, but it only returns 0 without consuming the packet. Zero means
success by this function's contract, so ntb_netdev reports NETDEV_TX_OK
and forgets the skb: nothing queued it, nothing frees it, and it leaks,
one skb for every transmit racing a link-down.
Return -ENOLINK instead, restoring the contract that a non-zero return
leaves the buffer owned by the caller. With the preceding patch,
ntb_netdev frees the skb on non-retryable enqueue failures and returns
NETDEV_TX_OK, so a packet racing with link-down is dropped without leaking
or entering a busy retry loop. |
| In the Linux kernel, the following vulnerability has been resolved:
NTB: ntb_transport: Reject oversized TX buffers
ntb_process_tx() handles an oversized buffer by calling tx_handler()
with a NULL data pointer and returning success. ntb_netdev therefore
neither frees the skb in its completion callback nor takes its enqueue
error path, leaking it.
Reject oversized buffers in ntb_transport_tx_enqueue() before acquiring
a queue entry and return -EMSGSIZE. The caller retains ownership of the
buffer, and the preceding netdev patch frees the skb when enqueue
returns this permanent error. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: bound the peer rkey counts in SMC-Rv2 LLC messages
On a link whose device has max_recv_sge == 1 there is no shared v2 receive
buffer, and smc_llc_save_add_link_rkeys() takes the v2 extension from 44
bytes past the start of the queue entry's inline message:
ext = (struct smc_llc_msg_add_link_v2_ext *)(llc_msg + SMC_WR_TX_SIZE);
The entry is a 72-byte allocation and the extension starts at offset 68, so
ext->num_rkeys at offset 94 is already past it. This happens on every
SMC-Rv2 link addition, whatever the peer sends:
[ 2.490065] BUG: KASAN: slab-out-of-bounds in smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.490431] Read of size 2 at addr ffff8880056406de by task smctest/106
[ 2.490709]
[ 2.490792] CPU: 0 UID: 0 PID: 106 Comm: smctest Not tainted 7.2.0-rc5-p1-g77a5d9d9c99f #32 PREEMPT(lazy)
[ 2.490795] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 2.490798] Call Trace:
[ 2.490803] <TASK>
[ 2.490805] dump_stack_lvl+0x53/0x70
[ 2.490810] print_report+0xd0/0x630
[ 2.490828] ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[ 2.490832] ? smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.490834] kasan_report+0xce/0x100
[ 2.490836] ? smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.490837] smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.490839] ? smcr_buf_map_lgr+0x1bf/0x2b0
[ 2.490844] smc_llc_cli_add_link+0xca7/0x1e80
[ 2.490848] ? smc_llc_wait+0x355/0x810
[ 2.490850] ? __pfx_smc_llc_wait+0x10/0x10
[ 2.490851] ? __pfx_smc_llc_cli_add_link+0x10/0x10
[ 2.490853] ? __pfx_autoremove_wake_function+0x10/0x10
[ 2.490863] __smc_connect+0x3f5c/0x4980
[ 2.490873] ? __pfx_kernel_connect+0x10/0x10
[ 2.490888] ? __pfx___smc_connect+0x10/0x10
[ 2.490891] ? release_sock+0x148/0x1d0
[ 2.490894] smc_connect+0x42c/0x580
[ 2.490896] __sys_connect+0xfc/0x130
[ 2.490898] ? __pfx___sys_connect+0x10/0x10
[ 2.490900] ? handle_mm_fault+0x1a1/0x430
[ 2.490908] __x64_sys_connect+0x6d/0xb0
[ 2.490909] ? fpregs_assert_state_consistent+0x56/0xe0
[ 2.490917] do_syscall_64+0xf9/0x540
[ 2.490921] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 2.490924] RIP: 0033:0x421bb4
[ 2.490927] Code: ff f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 80 3d ad 34 09 00 00 74 13 b8 2a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 4c c3 0f 1f 00 55 48 89 e5 48 83 ec 10 89 55
[ 2.490929] RSP: 002b:00007ffd473b01a8 EFLAGS: 00000202 ORIG_RAX: 000000000000002a
[ 2.490935] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 0000000000421bb4
[ 2.490936] RDX: 0000000000000010 RSI: 00007ffd473b01d0 RDI: 0000000000000003
[ 2.490937] RBP: 0000000000003930 R08: 0000000000000004 R09: 0000000000000000
[ 2.490938] R10: 00007ffd473b0f98 R11: 0000000000000202 R12: 0000000000000006
[ 2.490939] R13: 00007ffd473b0f87 R14: 0000000000000003 R15: 00007ffd473b0f90
[ 2.490940] </TASK>
[ 2.490941]
[ 2.499545] Allocated by task 44:
[ 2.499693] kasan_save_stack+0x33/0x60
[ 2.499860] kasan_save_track+0x14/0x30
[ 2.500026] __kasan_kmalloc+0x8f/0xa0
[ 2.500190] __kmalloc_cache_noprof+0x158/0x370
[ 2.500393] smc_llc_enqueue+0x72/0x560
[ 2.500559] smc_wr_rx_tasklet_fn+0x474/0xa80
[ 2.500747] tasklet_action_common+0x20f/0x8a0
[ 2.500945] handle_softirqs+0x18e/0x590
[ 2.501115] do_softirq+0x3b/0x60
[ 2.501266] __local_bh_enable_ip+0x61/0x70
[ 2.501446] __alloc_skb+0x732/0x890
[ 2.501604] rxe_init_packet+0x16b/0x4f0
[ 2.501783] prepare_ack_packet+0xb8/0x830
[ 2.501962] rxe_receiver+0x495/0x96e0
[ 2.502125] do_work+0x144/0x470
[ 2.502269] process_one_work+0x633/0x1030
[ 2.502450] worker_thread+0x45b/0xd10
[ 2.50261
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: carry oversized SMC-Rv2 LLC messages in the queue entry
smc_llc_rmt_delete_rkey() and smc_llc_save_add_link_rkeys() read the part
of a v2 message that does not fit into the 44-byte union smc_llc_msg, and
both bound themselves by the size of the buffer it landed in, not by what
arrived. On a link with a shared v2 receive buffer a 44-byte
DELETE_RKEY_V2 declaring 255 rkeys reaches rkey[9..254] in whatever an
earlier message left in lgr->wr_rx_buf_v2, and passes each of them to
smc_rtoken_delete(). One of those 255 matched a registered rtoken and
deleted it. An ADD_LINK on such a link installs up to 255 rtokens from
the same bytes.
Copy the tail into the queue entry, so its length is the length of the
message that arrived, and declare the rkeys that fit inline as a member of
the union instead of reaching them through a cast. The same
DELETE_RKEY_V2 now processes the 9 rkeys it carries. The copy is limited
to the longest tail the two functions can read, so the peer does not pick
the size of the entry.
The bound the previous patch placed on links without a shared v2 receive
buffer is no longer needed. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: do not dereference an unset send buffer on the SMC-D teardown path
smc_close_stream_wait() calls smc_tx_prepared_sends() from inside its
sk_wait_event() condition, and sk_wait_event() evaluates that condition
once with the socket lock released. smcd_buf_detach() clears
conn->sndbuf_desc from smc_conn_kill() under lock_sock(), so a link group
terminating while a socket waits there leaves the helper dereferencing
NULL, faulting out of close(). SIOCOUTQ reads the field by hand, and
smc_close_cancel_work() drops the lock across two cancel_*_sync() calls.
Sample the pointer once in the helper, report nothing prepared while it is
unset, and bound the ioctl the same way. The receive tasklet dereferences
the field directly in smc_cdc_msg_recv_action(), not through this helper;
1/2 is what keeps it from running that late. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: fix socket refcount leak in smc_switch_conns()
smc_switch_conns() takes a reference on the SMC socket before dropping
lgr->conns_lock, so the connection stays alive while the CDC slot is
fetched:
sock_hold(&smc->sk);
read_unlock_bh(&lgr->conns_lock);
/* pre-fetch buffer outside of send_lock, might sleep */
rc = smc_cdc_get_free_slot(conn, to_lnk, &wr_buf, NULL, &pend);
if (rc)
goto err_out;
The err_out label only drops the wr_tx link reference, so this early exit
returns without the matching sock_put(). The second error exit is not
affected, because sock_put() has already run by then.
A leaked sk_refcnt means the smc_sock is never destroyed. Its send and
receive buffers stay allocated, and for a user socket the reference held
on the network namespace is never released, so the netns can no longer be
torn down.
smc_cdc_get_free_slot() fails when the target link goes down or when the
connection has been killed while the switch is in progress. Both are
reachable during the link failover this function implements, so the leak
is triggered by the same hardware events that make smc_switch_conns() run
in the first place.
Restructure so there is a single sock_put() covering both outcomes,
instead of adding a second one to the error path. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: fix use-after-free in smc_rx_pipe_buf_release()
smc_rx_splice() hands RMB pages to a pipe and takes a socket reference
per entry so the smc_sock stays alive until the reader finishes. The
connection does not: a concurrent close runs smc_conn_free(), which
releases the receive buffer back to the link group pool.
smc_rx_pipe_buf_release() tests sk_state before taking the socket lock.
The state can change between the test and the lock, and
smc_rx_update_cons() then dereferences conn->rmb_desc and walks
conn->lgr, which smc_conn_free() has already released. On the
is_reg_err path smcr_buf_unuse() frees the descriptor outright, so
this is a use-after-free.
Take the socket lock first and test conn->freed instead.
smc_conn_free() sets that flag before releasing anything, and every
caller holds the socket lock. The two paths exclude each other: either
the pipe release runs first with everything valid, or it sees the flag
and skips the update. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: fix use-after-free of the LLC qentry in smc_llc_srv_add_link()
smc_llc_srv_add_link() keeps add_llc pointing into the queue entry:
add_llc = &qentry->msg.add_link; smc_llc.c:1482
...
smc_llc_save_add_link_info(link_new, add_llc); smc_llc.c:1494
smc_llc_flow_qentry_del(&lgr->llc_flow_lcl); smc_llc.c:1495
...
u8 *llc_msg = smc_link_shared_v2_rxbuf(link) ?
(u8 *)lgr->wr_rx_buf_v2 : (u8 *)add_llc; smc_llc.c:1504
smc_llc_save_add_link_rkeys(link, link_new, llc_msg); smc_llc.c:1506
smc_llc_flow_qentry_del() kfree()s the entry, so on a link without a shared
v2 receive buffer the pointer handed to smc_llc_save_add_link_rkeys() is
already freed. Before the Fixes: commit that branch always used
lgr->wr_rx_buf_v2 and add_llc was not used after the free.
Reproduced on an unpatched tree over rxe, with KASAN, kasan_multi_shot
and a link forced to max_recv_sge == 1: the entry is freed and read by
the same call, and the freeing frame is smc_llc_srv_add_link() itself.
[ 2.523161] BUG: KASAN: slab-use-after-free in smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.523499] Read of size 2 at addr ffff8880052194de by task kworker/0:1/11
[ 2.523789]
[ 2.523862] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 7.2.0-rc5-p0-g2c9dd296545d #35 PREEMPT(lazy)
[ 2.523865] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 2.523866] Workqueue: smc_hs_wq smc_listen_work
[ 2.523869] Call Trace:
[ 2.523870] <TASK>
[ 2.523871] dump_stack_lvl+0x53/0x70
[ 2.523872] print_report+0xd0/0x630
[ 2.523874] ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[ 2.523876] ? smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.523878] kasan_report+0xce/0x100
[ 2.523879] ? smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.523881] smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.523883] ? smcr_buf_reg_lgr+0x2a4/0x660
[ 2.523885] smc_llc_srv_add_link+0xaa2/0x1e50
[ 2.523888] ? _printk+0xba/0xf0
[ 2.523897] ? __pfx_smc_llc_srv_add_link+0x10/0x10
[ 2.523899] ? down_write+0xb0/0x130
[ 2.523903] ? __pfx_down_write+0x10/0x10
[ 2.523905] smc_listen_work+0x489e/0x4d00
[ 2.523907] ? kmem_cache_free+0x1c6/0x3a0
[ 2.523911] ? __pfx_smc_listen_work+0x10/0x10
[ 2.523913] ? release_sock+0x148/0x1d0
[ 2.523915] ? smc_tcp_listen_work+0xb4f/0xfc0
[ 2.523917] ? _raw_spin_lock_irq+0x80/0xe0
[ 2.523918] ? __pfx__raw_spin_lock_irq+0x10/0x10
[ 2.523920] process_one_work+0x633/0x1030
[ 2.523922] ? assign_work+0x11d/0x370
[ 2.523924] worker_thread+0x45b/0xd10
[ 2.523926] ? __pfx_worker_thread+0x10/0x10
[ 2.523928] ? __pfx_worker_thread+0x10/0x10
[ 2.523929] kthread+0x2c6/0x3b0
[ 2.523931] ? recalc_sigpending+0x15c/0x1e0
[ 2.523934] ? __pfx_kthread+0x10/0x10
[ 2.523935] ret_from_fork+0x36e/0x5a0
[ 2.523937] ? __pfx_ret_from_fork+0x10/0x10
[ 2.523938] ? __switch_to+0x572/0xdd0
[ 2.523943] ? __pfx_kthread+0x10/0x10
[ 2.523944] ret_from_fork_asm+0x1a/0x30
[ 2.523947] </TASK>
[ 2.523948]
[ 2.531253] Allocated by task 48:
[ 2.531399] kasan_save_stack+0x33/0x60
[ 2.531570] kasan_save_track+0x14/0x30
[ 2.531737] __kasan_kmalloc+0x8f/0xa0
[ 2.531905] __kmalloc_cache_noprof+0x158/0x370
[ 2.532100] smc_llc_enqueue+0x72/0x560
[ 2.532268] smc_wr_rx_tasklet_fn+0x474/0xa80
[ 2.532491] tasklet_action_common+0x20f/0x8a0
[ 2.532714] handle_softirqs+0x18e/0x590
[ 2.532886] do_softirq+0x3b/0x60
[ 2.533036] __local_bh_enable_ip+0x61/0x70
[ 2.533221] __alloc_skb+0x732/0x890
[ 2.533384] rxe_init_packet+0x16b/0x4f0
[ 2.533567] prepare_ack_packet+0xb8/0x830
[ 2.533760] rxe_receiver+0x495/0x96e0
[ 2.533933] do_work+0x144/0x470
[ 2
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: stop killed, freed and out_of_sync sharing a byte
The three connection state flags are single-bit bitfields, so they occupy
one byte of struct smc_connection and every store to one is a
read-modify-write of the other two:
u8 killed : 1;
u8 freed : 1;
u8 out_of_sync : 1;
They are not written under a common lock. smc_cdc_msg_validate() sets
out_of_sync from the receive tasklet, while smc_conn_kill() sets killed
from process context under lock_sock(), and the receive path does not defer
to the backlog when the socket is owned -- smc_cdc_msg_recv() takes only
bh_lock_sock().
Give each flag its own byte so a store no longer touches its neighbours.
All readers test them as booleans and are unchanged. struct smc_connection
grows by two bytes. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: unregister the connection before draining the rx tasklet
smc_conn_free() calls smc_ism_unset_conn() only while the link group is
still on its device list, and never sets conn->killed.
smc_lgr_terminate_sched() unlinks the group immediately and defers killing
its connections to a work item, so a connection freed in that window keeps
its smcd->conn[] slot with both gates in smcd_handle_irq() open, and the
device can re-arm the receive tasklet after tasklet_kill() has returned. On
the DMB-nocopy path the ghost send buffer is freed right after that drain,
so the re-armed tasklet dereferences it.
Unregister unconditionally and drain before the detach at both teardown
sites, mirroring rmb_desc, which smc_buf_unuse() releases after the drain.
Clear conn->sndbuf_desc before freeing it as well, so a reader that samples
the pointer cannot get one that is already freed. |
| In the Linux kernel, the following vulnerability has been resolved:
net: cap advertised IP tunnel headroom
IP tunnel devices derive their advertised needed_headroom from lower
output devices. A stack of user-created devices can make the derived
value larger than the 16-bit skb header offsets can represent. Once IP
output reserves it, skb head expansion can wrap those offsets.
The runtime transmit path already caps a growing needed_headroom at 512.
Apply the same cap when tunnel configuration publishes needed_headroom
derived from a lower output device.
Capping the advertised value is safe: IP tunnel transmit still expands
the skb when a packet needs more headroom. A nonsensical stacked
configuration can therefore incur an extra reallocation, but it cannot
publish an unbounded reservation to upper layers. |
| In the Linux kernel, the following vulnerability has been resolved:
net: skbuff: don't touch shared zerocopy state in skb_tx_error()
skb_tx_error() completes the zerocopy uarg and clears
SKBFL_ALL_ZEROCOPY, and skb_zcopy_downgrade_managed() clears
SKBFL_MANAGED_FRAG_REFS. Both live in skb_shinfo(), which every clone
shares, while the caller only owns the reference it is about to drop.
Through a clone it tells the producer its pages are free and drops
SKBFL_SHARED_FRAG for an skb that is still in flight.
Open vSwitch reaches this with a non-last OVS_ACTION_ATTR_RECIRC:
clone_execute() sends a skb_clone() into ovs_dp_process_packet() while
do_execute_actions() keeps forwarding the original, and skb_clone()
does not privatise the frags here -- skb_orphan_frags() returns early
on SKBFL_DONT_ORPHAN. A flow miss on the clone then strips the marker
from the packet still being forwarded, and a later local ESP delivery
decrypts in place over frags it does not own privately.
Skip it for a cloned skb. Nothing is lost: skb_release_data() clears
the zerocopy state once the last reference to the shared data goes. |
| In the Linux kernel, the following vulnerability has been resolved:
seg6: reset IP6CB after IPv6 decapsulation
decap_and_validate() pulls the outer SRv6 headers and makes the inner
packet the skb network header. The IPv6 control block still contains
values collected while parsing the outer packet, including nhoff and
extension-header flags.
End.DX6 and End.DT6 route the inner IPv6 packet directly to the IPv6
input path. An unprivileged user can reach End.DT6 from a user and net
namespace by installing a local SID and injecting an outer packet with
Hop-by-Hop and Destination Options headers followed by an SRH and a
minimal inner IPv6 packet.
The outer extension headers leave a large nhoff in IP6CB. After
decapsulation, ip6_protocol_deliver_rcu() uses that stale offset on the
inner packet and reads beyond the skb head. KASAN reports:
BUG: KASAN: slab-out-of-bounds in ip6_protocol_deliver_rcu
ip6_protocol_deliver_rcu+0x1118/0x1450
ip6_input_finish+0x11b/0x240
seg6_local_input_core+0xed/0x2e0
lwtunnel_input+0x1e9/0x4e0
ipv6_rthdr_rcv+0x525f/0x6c50
ip6_protocol_deliver_rcu+0xcb7/0x1450
Before clearing IP6CB for an inner IPv6 packet, save its incoming
interface index and L3 slave state. Restore both after the clear and set
nhoff to the inner IPv6 base-header nexthdr field.
Use IP6CB(skb)->iif rather than skb->skb_iif because VRF processing can
replace skb_iif with the L3 master while IP6CB keeps the receiving
interface. Preserve IP6SKB_L3SLAVE for the same reason. |
| In the Linux kernel, the following vulnerability has been resolved:
mfd: qnap-mcu: keep the reply buffer alive past a command timeout
qnap_mcu_exec() publishes an on-stack buffer to the receive path:
unsigned char rx[QNAP_MCU_RX_BUFFER_SIZE];
...
reply->data = rx;
reply->length = length;
and qnap_mcu_receive_buf() writes into it from the serdev receive path,
which runs out of flush_to_ldisc() and is not serialized against
qnap_mcu_exec() at all. bus_lock cannot cover it, because qnap_mcu_exec()
holds that mutex across wait_for_completion_timeout().
On a timeout qnap_mcu_exec() returns with reply->data still pointing at
its own frame. A reply that arrives late, or an unsolicited message from
the MCU, is then written into a stack frame that has been left, corrupting
whatever runs next on that stack. The same applies when qnap_mcu_write()
fails, since that path returns without touching the reply state either.
Move the receive buffer into struct qnap_mcu. It is 37 bytes and the
structure is devm_kzalloc()ed, so it lives as long as the driver, and a
late write lands in memory that is still valid and is reinitialized by the
next command. bus_lock keeps commands from sharing it.
This deliberately does not clear reply->data or reply->length on the
timeout path. Doing so races with qnap_mcu_receive_buf(), which reads both
after its
if (!reply->length)
return size;
check: clearing reply->data gives a NULL dereference, and clearing
reply->length alone removes the reply->received == reply->length exit
condition, so the copy loop runs until the uart chunk is consumed and
overruns the buffer. Leaving both set keeps the write bounded by
reply->length, which qnap_mcu_exec() has already checked against
sizeof(mcu->rx). |