6.6.152-rc1 review
Greg Kroah-Hartman
maintainerPATCH 139/156 eventfs: Use children field for rcu head and add memory barriers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit f0ece16ffca7384787b692431961ce202907acf5 upstream.
When an eventfs inode is freed, it sets ei->is_freed and then uses its ei->list to add it to the srcu link list as the list field is a union with the rcu list head. As the ei->list is used to iterate over an SRCU protected list without taking the eventfs_mutex, there's nothing stopping the iteration over that list to see the ei->rcu instead of the ei->list and it will read a corrupt target.
To fix this, change the union of the rcu list head with the children list. On freeing the eventfs inode, set the is_free and execute a smp_wmb() before adding the eventfs inode to the SRCU list.
On iteration of the ei->children list, at the start, execute a smp_rmb() and then read the is_freed of the ei to see if the children list is still valid. If is_freed is set, then the ei_child read is not valid and the loop should exit immediately.
--- fs/tracefs/event_inode.c | 24 ++++++++++++++++++++++++ fs/tracefs/internal.h | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-)
fs/tracefs/event_inode.c +24 -0
@@ -125,7 +125,17 @@ static inline void put_ei(struct eventfsstatic inline void free_ei (struct eventfs_inode *ei) {if (ei) { +/* The ei should have no children if it is being freed. */ +WARN_ON_ONCE (!list_empty (&ei->children)); ei->is_freed =1 ; +/* +* The SRCU iteration has a smp_rmb() to make sure it +* sees a child (that may have already been freed) +* before it reads is_free. If is_free is set, it must +* not use the child it acquired from ei->children, as +* the list may be used for SRCU. +*/ +smp_wmb ();put_ei (ei); } }
@@ -717,6 +727,20 @@ static int eventfs_iterate(struct file *list_for_each_entry_srcu (ei_child, &ei->children, list,srcu_read_lock_held (&eventfs_srcu)) { +/* +* If the ei is being freed, then the ei->children may be +* being used as the rcu list, which means the next element +* may be garbage. The ei->is_free is set before switching +* the ei->children over to ei->rcu. The read memory barrier +* here makes sure the ei_child is read before is_free is +* updated. +* +* Matches the smp_wmb() in free_ei() +*/ +smp_rmb (); +if (ei->is_freed) +return -EINVAL ; +if (c >0 ) { c--;continue ;
fs/tracefs/internal.h +2 -2
@@ -46,11 +46,11 @@ struct eventfs_attr {* @ino: The saved inode number */ struct eventfs_inode { +struct list_head list;union { -struct list_head list; +struct list_head children;struct rcu_head rcu; }; -struct list_head children;const struct eventfs_entry *entries;const char *name;struct eventfs_attr *entry_attrs;
Greg Kroah-Hartman
maintainerPATCH 140/156 Revert "thermal/drivers/hwmon: Cleanup coding style a bit"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit ff8da20b6f47c48d46e47f93f7a59e2d56ee9107 upstream.
Revert commit 030a48b0f6ce ("thermal/drivers/hwmon: Cleanup coding style a bit") that introduced a use-after-free into the error path of thermal_add_hwmon_sysfs() by removing a valid check from it.
--- drivers/thermal/thermal_hwmon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/thermal/thermal_hwmon.c +2 -1
@@ -218,7 +218,8 @@ int thermal_add_hwmon_sysfs(struct thermif (new_hwmon_device)hwmon_device_unregister (hwmon->device); free_mem: -kfree (hwmon); +if (new_hwmon_device) +kfree (hwmon);return result; }
Greg Kroah-Hartman
maintainerPATCH 141/156 ptp: ocp: Fix board ID over-read
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ahmad Byagowi <[email protected]>
commit 6b69f2ef10cdb018c0b127a7cab88e590bbddba4 upstream.
The EEPROM board ID is a fixed 13-byte field and is not guaranteed to contain a NUL terminator. Passing it directly to devlink_info_version_fixed_put() treats it as a C string and may read beyond the field.
Format at most OCP_BOARD_ID_LEN bytes into the existing local buffer before reporting the ID. Use a precision limit because the snprintf() output size alone does not bound the source string scan.
--- drivers/ptp/ptp_ocp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/ptp/ptp_ocp.c +3 -1
@@ -1671,9 +1671,11 @@ ptp_ocp_devlink_info_get(struct devlinkif (err)return err; +snprintf (buf,sizeof (buf),"%.*s" ,OCP_BOARD_ID_LEN , + (const char *)bp->board_id); err =devlink_info_version_fixed_put (req,DEVLINK_INFO_VERSION_GENERIC_BOARD_ID , - bp->board_id); + buf);if (err)return err;
Greg Kroah-Hartman
maintainerPATCH 142/156 ring-buffer: Use current_context for safe per-CPU buffer swap
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tengda Wu <[email protected]>
commit f27bdc43077e4fcb5557dfc315ee8d91e741f483 upstream.
The ring_buffer_swap_cpu() function currently checks the per-CPU committing counter to determine if a buffer is actively being written to before performing the swap. However, there exists a race window where this check can be bypassed:
ring_buffer_lock_reserve
cpu_buffer = buffer->buffers[cpu]; // cpu_buffer_a
rb_reserve_next_event
rb_start_commit // inc committing
if (unlikely(READ_ONCE(cpu_buffer->buffer) != buffer)) {...}
__rb_reserve_next
rb_move_tail
rb_end_commit(cpu_buffer); // dec committing => 0
/* interrupt hits here, successfully swaps! */
local_inc(&cpu_buffer->committing);
ring_buffer_unlock_commit
cpu_buffer = buffer->buffers[cpu]; // cpu_buffer_b
rb_commit
rb_end_commit
RB_WARN_ON(cpu_buffer, !local_read(&cpu_buffer->committing))
// triggers warningThe committing counter can temporarily drop to 0 during a single write operation (within rb_move_tail), creating a window where swap can succeed even though the write is still in progress. This leads to inconsistent buffer state and triggers the RB_WARN_ON in rb_commit().
Replace the committing counter check with current_context checks, which are set at the entry of ring_buffer_lock_reserve() and remain valid throughout the entire write operation, providing a reliable indicator of buffer busy state during swap.
--- kernel/trace/ring_buffer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
kernel/trace/ring_buffer.c +4 -4
@@ -5458,7 +5458,7 @@ int ring_buffer_swap_cpu(struct trace_bu {struct ring_buffer_per_cpu *cpu_buffer_a;struct ring_buffer_per_cpu *cpu_buffer_b; -int ret = -EINVAL ; +int ret = -EBUSY ;if (!cpumask_test_cpu (cpu, buffer_a->cpumask) || !cpumask_test_cpu (cpu, buffer_b->cpumask))
@@ -5494,10 +5494,10 @@ int ring_buffer_swap_cpu(struct trace_buatomic_inc (&cpu_buffer_a->record_disabled);atomic_inc (&cpu_buffer_b->record_disabled); - ret = -EBUSY ; -if (local_read (&cpu_buffer_a->committing)) +/* Do not swap if either buffer is in the process of writing */ +if (cpu_buffer_a->current_context) goto out_dec; -if (local_read (&cpu_buffer_b->committing)) +if (cpu_buffer_b->current_context) goto out_dec;/*
Greg Kroah-Hartman
maintainerPATCH 143/156 ipv6: fix Route Information option length validation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuejie Shi <[email protected]>
commit d1ad8fb2ac6a1afb71dc22d9ae8efb4dda96c824 upstream.
rt6_route_rcv() validates the Route Information option (RFC 4191) length against the prefix length, but both checks are off by one.
rinfo->length is the ND option length in units of 8 octets and it *includes* the 8-byte option header, so an option carrying N bytes of prefix has length == 1 + N/8. RFC 4191 section 2.3 requires length 3 when Prefix Length is greater than 64, and 2 or 3 when it is greater than 0. The code accepts length >= 2 and length >= 1 respectively.
ipv6_addr_prefix() then copies prefix_len/8 bytes out of rinfo->prefix, so a Router Advertisement with (prefix_len=128, length=2) or (prefix_len=64, length=1) makes the kernel read up to 8 bytes past the end of the option. Those bytes end up in the prefix of the route that gets installed, so they are visible to userspace:
# RA with a Route Information option (prefix_len=128, length=2)
# followed by a source link-layer address option, 01 01 de ad be ef ca fe
$ ip -6 route show
2001:db8:dead:beef:101:dead:beef:cafe via fe80::1234 dev veth0 proto ra
^^^^^^^^^^^^^^^^^^ the next option, read out of boundsWhen the Route Information option is the last one in the packet, those eight bytes come from the skb tail room instead.
Reject the option lengths RFC 4191 does not allow.
--- net/ipv6/route.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/ipv6/route.c +4 -4
@@ -989,13 +989,13 @@ int rt6_route_rcv(struct net_device *dev }else if (rinfo->prefix_len >128 ) {return -EINVAL ; }else if (rinfo->prefix_len >64 ) { -if (rinfo->length <2 ) { +/* RFC 4191: Length MUST be 3 when Prefix Length > 64 */ +if (rinfo->length <3 )return -EINVAL ; - } }else if (rinfo->prefix_len >0 ) { -if (rinfo->length <1 ) { +/* RFC 4191: Length MUST be 2 or 3 when Prefix Length > 0 */ +if (rinfo->length <2 )return -EINVAL ; - } } pref = rinfo->route_pref;
Greg Kroah-Hartman
maintainerPATCH 144/156 ip6_tunnel: clear skb2->cb[] in ip6ip6_err()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <[email protected]>
commit f803c086399da277b5d0ff36a107d0f162751800 upstream.
ip6ip6_err() clones an outer IPv6 ICMP error skb, pulls it to the quoted inner IPv6 packet, and then passes the clone to icmpv6_send(). The clone still carries the outer packet's inet6_skb_parm in skb->cb.
If the outer packet had a Home Address Option, IP6CB(skb2)->dsthao remains non-zero after skb_pull(). icmpv6_send() later calls mip6_addr_swap(), which uses that stale dsthao offset against the quoted inner packet. A malformed inner destination-options header can then make the HAO lookup and address swap run past the end of the quoted packet and corrupt skb_shared_info.
Clear skb2->cb[] before pulling the quoted inner IPv6 packet so the reply path does not reuse metadata left by the outer IPv6 stack.
--- net/ipv6/ip6_tunnel.c | 3 +++ 1 file changed, 3 insertions(+)
net/ipv6/ip6_tunnel.c +3 -0
@@ -675,6 +675,9 @@ ip6ip6_err(struct sk_buff *skb, struct iif (!skb2)return 0 ; +/* Remove debris left by outer IPv6 stack. */ +memset (IP6CB (skb2),0 ,sizeof (*IP6CB (skb2))); +skb_dst_drop (skb2);skb_pull (skb2, offset);skb_reset_network_header (skb2);
Greg Kroah-Hartman
maintainerPATCH 145/156 fscrypt: use the mount idmap for the owner check in fscrypt_ioctl_set_policy()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhan Xusheng <[email protected]>
commit cf6c993c0feca7984797e634deba3c80342e199a upstream.
fscrypt_ioctl_set_policy() calls inode_owner_or_capable() with &nop_mnt_idmap before allowing an encryption policy to be set, instead of the idmap of the mount the ioctl was issued on.
fscrypt is used by filesystems that support idmapped mounts (e.g. ext4, f2fs), so on such a mount this compares the caller's fsuid against the unmapped on-disk owner rather than the mapped owner: the actual owner can be wrongly denied with -EACCES and an unrelated caller wrongly allowed. Use file_mnt_idmap(filp) instead.
--- fs/crypto/policy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/crypto/policy.c +1 -1
@@ -505,7 +505,7 @@ int fscrypt_ioctl_set_policy(struct filereturn -EFAULT ; policy.version = version; -if (!inode_owner_or_capable (&nop_mnt_idmap, inode)) +if (!inode_owner_or_capable (file_mnt_idmap (filp), inode))return -EACCES ; ret =mnt_want_write_file (filp);
Greg Kroah-Hartman
maintainerPATCH 146/156 sched/psi: Shut down rtpoll_timer in psi_cgroup_free()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit 5457025fa8ca3c0d2732109513de839e3e797190 upstream.
psi_schedule_rtpoll_work() is called locklessly from the scheduler hotpath and can race psi_trigger_destroy() taking down the last rtpoll trigger under rtpoll_trigger_lock:
psi_schedule_rtpoll_work() psi_trigger_destroy()
rcu_read_lock();
task = rcu_dereference(rtpoll_task);
rcu_assign_pointer(rtpoll_task, NULL);
timer_delete(&rtpoll_timer);
mod_timer(&rtpoll_timer, ...);
rcu_read_unlock();
synchronize_rcu();
kthread_stop(task_to_destroy);The group can then be freed with the re-armed timer still pending, and poll_timer_fn() runs on freed memory.
461daba06bdc ("psi: eliminate kthread_worker from psi trigger scheduling mechanism") deleted the timer synchronously after the synchronize_rcu(), which prevented this but raced trigger creation instead: the deletion could cancel the timer that a new trigger set armed during the grace period and, as creation also reinitialized the timer at the time, corrupt it. 8f91efd870ea ("psi: Fix race between psi_trigger_create/destroy") moved the initialization into group_init() and the deletion into the locked section, trading the creation races for the window above.
Neither placement in the destruction path works. A pending timer firing while the group is alive is harmless though. poll_timer_fn() just wakes the rtpoll waitqueue and doesn't re-arm itself. Bind the timer to the group's lifetime instead and shut it down in psi_cgroup_free(). Nothing can arm it by then. timer_shutdown_sync() because the timer is never armed again.
--- kernel/sched/psi.c | 6 ++++++ 1 file changed, 6 insertions(+)
kernel/sched/psi.c +6 -0
@@ -1138,6 +1138,12 @@ void psi_cgroup_free(struct cgroup *cgroreturn ;cancel_delayed_work_sync (&cgroup->psi->avgs_work); +/* +* A psi_schedule_rtpoll_work() call racing the last trigger's +* destruction may have re-armed the timer after psi_trigger_destroy() +* deleted it. Spurious firing while the group is alive is harmless. +*/ +timer_shutdown_sync (&cgroup->psi->rtpoll_timer);free_percpu (cgroup->psi->pcpu);/* All triggers must be removed by now */ WARN_ONCE (cgroup->psi->rtpoll_states,"psi: trigger leak\n" );
Greg Kroah-Hartman
maintainerPATCH 147/156 bpf, sockmap: Fix sk_redir use-after-free in send verdict
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <[email protected]>
commit a76624733730e541e4955fdecf506af2f6b20558 upstream.
sk_psock_msg_verdict() takes a socket reference for psock->sk_redir. tcp_bpf_send_verdict() copies that pointer while holding the source socket lock, but does not take a reference for the local copy before dropping the lock around tcp_bpf_sendmsg_redir().
When apply_bytes keeps the cached verdict active, another sendmsg() on the same source socket can consume the remaining bytes and release the cached reference while the first thread still holds only the raw local pointer:
CPU 0 CPU 1
sk_redir = psock->sk_redir
apply_bytes remains nonzero
release_sock(sk)
lock_sock(sk) apply_bytes reaches zero psock->sk_redir = NULL release_sock(sk) tcp_bpf_sendmsg_redir(sk_redir) sock_put(sk_redir)
tcp_bpf_sendmsg_redir(sk_redir)
The final sock_put() can free sk_redir before CPU 0 dereferences it.
KASAN reported:
BUG: KASAN: slab-use-after-free in tcp_bpf_sendmsg_redir+0xf39/0x1020 Read of size 8 at addr ffff888108537090 by task poc/87 Call Trace: tcp_bpf_sendmsg_redir+0xf39/0x1020 tcp_bpf_sendmsg+0x977/0x1a50 __sys_sendto+0x32c/0x3a0 __x64_sys_sendto+0xdb/0x1b0 Allocated by task 85: sk_prot_alloc+0x56/0x210 sk_clone+0x6f/0x14b0 inet_csk_clone_lock+0x24/0x740 tcp_create_openreq_child+0x25/0x2710 tcp_v4_syn_recv_sock+0x10a/0xe00 Freed by task 0: __kasan_slab_free+0x43/0x70 slab_free_after_rcu_debug+0xa6/0x1e0 rcu_core+0x50a/0x1850 Last potentially related work creation: __sk_destruct+0x3da/0x540 sk_psock_destroy+0x81e/0xab0 process_one_work+0x63a/0x1070
Take a temporary socket reference while the source socket lock still protects psock->sk_redir, and drop it after tcp_bpf_sendmsg_redir() returns. This keeps each unlocked use independent of cached-verdict ownership.
--- net/ipv4/tcp_bpf.c | 2 ++ 1 file changed, 2 insertions(+)
net/ipv4/tcp_bpf.c +2 -0
@@ -455,6 +455,7 @@ more_data:case __SK_REDIRECT: redir_ingress = psock->redir_ingress; sk_redir = psock->sk_redir; +sock_hold (sk_redir);sk_msg_apply_bytes (psock, tosend);if (!psock->apply_bytes) {/* Clean up before releasing the sock lock. */
@@ -475,6 +476,7 @@ more_data:if (eval == __SK_REDIRECT)sock_put (sk_redir); +sock_put (sk_redir);lock_sock (sk);sk_mem_uncharge (sk, sent);
Greg Kroah-Hartman
maintainerPATCH 148/156 scsi: scsi_debug: Negate wrapped memcmp() result
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Rao <[email protected]>
commit c4f6916a99cf105c3ff340b6210fcbba3fa66b35 upstream.
comp_write_worker() returns true when the compared data matches. memcmp() returns zero for equal data and non-zero for different data, so its result must be negated before it is stored in a bool.
The first segment already uses !memcmp(), but the wrapped segment uses memcmp() directly, reversing the match result. Use !memcmp() there as well.
--- drivers/scsi/scsi_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/scsi_debug.c +2 -2
@@ -3077,8 +3077,8 @@ static bool comp_write_worker(struct sdeif (!res)return res;if (rest) - res =memcmp (fsp, arr + ((num - rest) * lb_size), - rest * lb_size); + res = !memcmp (fsp, arr + ((num - rest) * lb_size), + rest * lb_size);if (!res)return res;if (compare_only)
Greg Kroah-Hartman
maintainerPATCH 149/156 sctp: keep chunk->transport in step with the list it is queued on
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baul Lee <[email protected]>
commit 9f2cf069a9a72a2d6b97ca8b4c70e714aac99749 upstream.
__sctp_outq_flush_rtx() moves a gap-acked chunk onto another transport's transmitted list without updating chunk->transport:
if (chunk->tsn_gap_acked) {
list_move_tail(&chunk->transmitted_list,
&transport->transmitted);
continue;
}The chunk then sits on a live transport's list while chunk->transport still names a different one. If that transport is removed - sctp_assoc_rm_peer() from an ASCONF Delete-IP - sctp_transport_free() RCU-frees it and the chunk is left with a dangling pointer. sctp_assoc_rm_peer() scrubs peer->transmitted and asoc->outqueue.out_chunk_list, but the chunk is on neither.
The pointer is not followed while tsn_gap_acked is set. A SACK that reneges on the TSN clears the flag, and the next SACK reaches
tchunk->transport->flight_size -= sctp_data_size(tchunk);
inside the freed transport. KASAN reports a slab-use-after-free read in sctp_check_transmitted(), freed from sctp_assoc_rm_peer(). Both the removal and the SACKs come from the association peer.
Set chunk->transport at the move. The ordinary resend path needs nothing:
it reaches its list_move_tail() only after sctp_packet_append_chunk() returned SCTP_XMIT_OK, and __sctp_packet_append_chunk() has rebound the chunk by then.
Discovered by XBOW, triaged by Baul Lee <[email protected]>
--- net/sctp/outqueue.c | 1 + 1 file changed, 1 insertion(+)
net/sctp/outqueue.c +1 -0
@@ -650,6 +650,7 @@ static int __sctp_outq_flush_rtx(structif (chunk->tsn_gap_acked) {list_move_tail (&chunk->transmitted_list, &transport->transmitted); + chunk->transport = transport;continue ; }
Greg Kroah-Hartman
maintainerPATCH 150/156 sctp: fix use-after-free of cached ASCONF chunk
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuxiang Yang <[email protected]>
commit 8c283e7b56adce00193837f3311b06662466fb21 upstream.
addip_last_asconf caches the outstanding outbound ASCONF chunk. The normal ASCONF-ACK completion path releases the chunk and clears the pointer.
However, sctp_asconf_queue_teardown() releases the cached chunk without clearing addip_last_asconf. During peer restart handling, sctp_sf_do_dupcook_a() queues SCTP_CMD_PURGE_ASCONF_QUEUE, which invokes sctp_asconf_queue_teardown() while the association remains alive and leaves the pointer dangling.
A delayed authenticated ASCONF-ACK can then reach sctp_sf_do_asconf_ack(), which accesses the stale chunk and passes it to sctp_process_asconf_ack(), causing a use-after-free and a second release.
Clearing the pointer exposes a race with T4 expiry. Peer restart handling queues the timer stop before the purge, but SCTP_CMD_TIMER_STOP uses timer_delete(), which does not wait for a callback already running on another CPU. Such a callback can reach sctp_sf_t4_timer_expire() after the purge and dereference NULL.
Clear addip_last_asconf after releasing the cached chunk, and make sctp_sf_t4_timer_expire() consume a stale T4 expiry if no outstanding ASCONF remains.
--- net/sctp/associola.c | 4 +++- net/sctp/sm_statefuns.c | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-)
net/sctp/associola.c +3 -1
@@ -1731,6 +1731,8 @@ void sctp_asconf_queue_teardown(struct ssctp_assoc_free_asconf_queue (asoc);/* Free any cached ASCONF chunk. */ -if (asoc->addip_last_asconf) +if (asoc->addip_last_asconf) {sctp_chunk_free (asoc->addip_last_asconf); + asoc->addip_last_asconf =NULL ; + } }
net/sctp/sm_statefuns.c +5 -1
@@ -6109,8 +6109,12 @@ enum sctp_disposition sctp_sf_t4_timer_e struct sctp_cmd_seq *commands) {struct sctp_chunk *chunk = asoc->addip_last_asconf; -struct sctp_transport *transport = chunk->transport; +struct sctp_transport *transport; +if (!chunk) +return SCTP_DISPOSITION_CONSUME ; + + transport = chunk->transport;SCTP_INC_STATS (net,SCTP_MIB_T4_RTO_EXPIREDS );/* ADDIP 4.1 B1) Increment the error counters and perform path failure
Greg Kroah-Hartman
maintainerPATCH 151/156 sctp: clear new_transport when removing a peer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qing Ming <[email protected]>
commit beb33f8ee1ca83acddb2a5ae80f3d22ec550b4c3 upstream.
sctp_process_asconf_param() stores a newly added peer transport in asoc->new_transport. After all parameters in the ASCONF chunk have been processed, sctp_sf_do_asconf() uses this pointer to send a HEARTBEAT to the new transport.
An authenticated ASCONF from a remote SCTP peer can add a transport and remove it again with a wildcard DEL-IP parameter in the same chunk. The wildcard deletion preserves the transport on which the ASCONF arrived, but removes the newly added transport through sctp_assoc_del_nonprimary_peers(). The removal does not clear asoc->new_transport, leaving it pointing to the removed transport.
sctp_sf_do_asconf() then creates a HEARTBEAT whose chunk->transport points to the removed transport without holding a transport reference. During local address replacement, src_out_of_asoc_ok keeps this HEARTBEAT on control_chunk_list. After the transport is freed by RCU, a successful ASCONF_ACK for the replacement address releases the queued HEARTBEAT and sctp_outq_select_transport() reads the freed transport's state.
The issue was found during a static audit of SCTP objects. With an authenticated peer, the reproducer triggered the same KASAN report in 2 of 2 unpatched runs on a KASAN-enabled netdev/main kernel:
BUG: KASAN: slab-use-after-free in sctp_outq_select_transport Read of size 4 at addr ffff88800b9bd95c by task python3/197 Call Trace: sctp_outq_select_transport+0x549/0x8b0 [sctp] sctp_outq_flush+0x306/0x2c60 [sctp] sctp_transport_immediate_rtx+0xaf/0x260 [sctp] sctp_process_asconf_ack+0xa48/0xf70 [sctp] Allocated by task 197: sctp_transport_new+0x68/0x650 [sctp] sctp_assoc_add_peer+0x258/0x12a0 [sctp] sctp_process_asconf+0x5e9/0x1090 [sctp] Last potentially related work creation: __call_rcu_common.constprop.0+0x77/0xb70 sctp_assoc_del_nonprimary_peers+0x7c/0xd0 [sctp] sctp_process_asconf+0xd9c/0x1090 [sctp]
The first invalid access was a four-byte read of transport->state at net/sctp/outqueue.c:833. The same reproducer completed the full authenticated ASCONF and local-address replacement sequence with this change without a KASAN report or oops.
Clear new_transport when its peer is removed, before it can be used to create the HEARTBEAT.
--- net/sctp/associola.c | 3 +++ 1 file changed, 3 insertions(+)
net/sctp/associola.c +3 -0
@@ -543,6 +543,9 @@ void sctp_assoc_rm_peer(struct sctp_asso asoc->addip_last_asconf->transport == peer) asoc->addip_last_asconf->transport = NULL; +if (asoc->new_transport == peer) + asoc->new_transport =NULL ; +/* If we have something on the transmitted list, we have to * save it off. The best place is the active path. */
Greg Kroah-Hartman
maintainerPATCH 152/156 thunderbolt: Bound the DROM dual link port number before indexing sw->ports
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryam Vargas <[email protected]>
commit d6764992f17b23d91ff93ce905ab53c2aa7191f0 upstream.
tb_drom_parse_entry_port() validates the device-supplied header->index against sw->config.max_port_number before indexing sw->ports[], but the sibling field entry->dual_link_port_nr -- a 6-bit value also read from the DROM -- indexes the same array with no such check. A malicious or malformed Thunderbolt device can set dual_link_port_nr beyond the allocated sw->ports[] (max_port_number + 1 entries), producing an out-of-bounds tb_port pointer that is stored and later dereferenced.
Reject a port entry whose dual_link_port_nr exceeds max_port_number, the same bound already applied to header->index.
--- drivers/thunderbolt/eeprom.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/thunderbolt/eeprom.c +8 -1
@@ -392,9 +392,16 @@ static int tb_drom_parse_entry_port(strureturn -EIO ; } port->link_nr = entry->link_nr; -if (entry->has_dual_link_port) +if (entry->has_dual_link_port) { +if (entry->dual_link_port_nr > sw->config.max_port_number) { +tb_sw_warn (sw, +"port entry has invalid dual link port number %u\n" , + entry->dual_link_port_nr); +return -EIO ; + } port->dual_link_port = &port->sw->ports[entry->dual_link_port_nr]; + } }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 153/156 bpf: tcp: fix double sock release on batch realloc
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei (Microsoft) <[email protected]>
commit 980a813452754f8001704744e92f7aa697c53dd3 upstream.
bpf_iter_tcp_batch() releases the current batch via bpf_iter_tcp_put_batch(), which drops the socket refs and rewrites each slot with the socket cookie, then grows the batch. cur_sk/end_sk are kept for bpf_iter_tcp_resume(), but on realloc failure the function returns ERR_PTR() before resume runs, leaving cur_sk < end_sk over slots that now hold cookies rather than sock pointers. bpf_iter_tcp_seq_stop() then calls bpf_iter_tcp_put_batch() again and dereferences a cookie as a struct sock.
Empty the batch on the failure path so stop() does not release it again. The sockets were already freed by the first bpf_iter_tcp_put_batch(), so nothing leaks, and a later read() rescans the bucket from the start instead of skipping it. The sibling GFP_NOWAIT failure path still holds real socket references and is left for stop() to release.
BUG: KASAN: null-ptr-deref in __sock_gen_cookie Read of size 8 at addr 0000000000000059 by task exploit ... __sock_gen_cookie (net/core/sock_diag.c:28) bpf_iter_tcp_put_batch (net/ipv4/tcp_ipv4.c:2918) bpf_iter_tcp_seq_stop (net/ipv4/tcp_ipv4.c:3270) bpf_seq_read (kernel/bpf/bpf_iter.c:205) vfs_read (fs/read_write.c:572) ksys_read (fs/read_write.c:716) do_syscall_64 entry_SYSCALL_64_after_hwframe Kernel panic - not syncing: Fatal exception
--- net/ipv4/tcp_ipv4.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/ipv4/tcp_ipv4.c +4 -1
@@ -3061,8 +3061,11 @@ again:bpf_iter_tcp_put_batch (iter); err =bpf_iter_tcp_realloc_batch (iter, expected *3 /2 ,GFP_USER ); -if (err) +if (err) { + iter->cur_sk =0 ; + iter->end_sk =0 ;return ERR_PTR (err); + } sk =bpf_iter_tcp_resume (seq);if (!sk)
Greg Kroah-Hartman
maintainerPATCH 154/156 net/tcp_sigpool: Fix some off by one bugs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 74da77921333171766031ea213b11f1e650814f9 upstream.
The "cpool_populated" variable is the number of elements in the cpool[] array that have been populated. It is incremented in tcp_sigpool_alloc_ahash() every time we populate a new element. Unpopulated elements are NULL but if we have populated every element then this code will read one element beyond the end of the array.
--- net/ipv4/tcp_sigpool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/ipv4/tcp_sigpool.c +4 -4
@@ -231,7 +231,7 @@ static void cpool_schedule_cleanup(struc*/ void tcp_sigpool_release (unsigned int id) { -if (WARN_ON_ONCE (id > cpool_populated || !cpool[id].alg)) +if (WARN_ON_ONCE (id >= cpool_populated || !cpool[id].alg))return ;/* slow-path */
@@ -245,7 +245,7 @@ EXPORT_SYMBOL_GPL(tcp_sigpool_release);*/ void tcp_sigpool_get (unsigned int id) { -if (WARN_ON_ONCE (id > cpool_populated || !cpool[id].alg)) +if (WARN_ON_ONCE (id >= cpool_populated || !cpool[id].alg))return ;kref_get (&cpool[id].kref); }
@@ -256,7 +256,7 @@ int tcp_sigpool_start(unsigned int id, sstruct crypto_ahash *hash;rcu_read_lock_bh (); -if (WARN_ON_ONCE (id > cpool_populated || !cpool[id].alg)) { +if (WARN_ON_ONCE (id >= cpool_populated || !cpool[id].alg)) {rcu_read_unlock_bh ();return -EINVAL ; }
@@ -301,7 +301,7 @@ EXPORT_SYMBOL_GPL(tcp_sigpool_end);*/ size_t tcp_sigpool_algo (unsigned int id,char *buf,size_t buf_len) { -if (WARN_ON_ONCE (id > cpool_populated || !cpool[id].alg)) +if (WARN_ON_ONCE (id >= cpool_populated || !cpool[id].alg))return -EINVAL ;return strscpy (buf, cpool[id].alg, buf_len);
Greg Kroah-Hartman
maintainerPATCH 155/156 net/tcp_sigpool: Use kref_get_unless_zero()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Safonov <[email protected]>
commit b901a4e276943f61e11ddb597a0abc1e7dfadf0f upstream.
The freeing and re-allocation of algorithm are protected by cpool_mutex, so it doesn't fix an actual use-after-free, but avoids a deserved refcount_warn_saturate() warning.
A trivial fix for the racy behavior.
--- net/ipv4/tcp_sigpool.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
net/ipv4/tcp_sigpool.c +2 -3
@@ -162,9 +162,8 @@ int tcp_sigpool_alloc_ahash(const char *if (strcmp (cpool[i].alg, alg))continue ; -if (kref_read (&cpool[i].kref) >0 ) -kref_get (&cpool[i].kref); -else +/* pairs with tcp_sigpool_release() */ +if (!kref_get_unless_zero (&cpool[i].kref))kref_init (&cpool[i].kref); ret = i; goto out;
Greg Kroah-Hartman
maintainerPATCH 156/156 regulator: devres: fix devm_regulator_get_enable_read_voltage() return
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 257b2335eebf51e318db1f3b2d023512da46fa66 upstream.
The devm_regulator_get_enable_read_voltage() function is supposed to return the voltage that the regulator is currently set to. However, it currently returns 0.
--- drivers/regulator/devres.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/devres.c +1 -1
@@ -193,7 +193,7 @@ int devm_regulator_get_enable_read_voltaif (ret <0 ) goto err_release_action; -return 0 ; +return ret; err_release_action:devm_release_action (dev, regulator_action_disable, r);
Am 17.08.2026 um 15:32 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.6.y
Best regards,
Pavel
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2026 13:23:44 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.152-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2026 13:23:44 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.152-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Build tested in our x86,arm64,loongarch,riscv config successfully without error.
Best Regards
Wentao Guan
Log:
Linux version 6.6.152-rc1-arm64-desktop-hwe-g9a239823f9ad (guanwentao@uos-PC) (aarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) # SMP PREEMPT Linux version 6.6.152-rc1-arm64-desktop-hwe-g9a239823f9ad (guanwentao@uos-PC) (aarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #2 SMP PREEMPT Tue Aug 18 02:58:25 CST 2026 Linux version 6.6.152-rc1-loong64-desktop-hwe-g9a239823f9ad (guanwentao@uos-PC) (loongarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) # SMP PREEMPT Linux version 6.6.152-rc1-loong64-desktop-hwe-g9a239823f9ad (guanwentao@uos-PC) (loongarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #3 SMP PREEMPT Tue Aug 18 03:15:28 CST 2026 Linux version 6.6.152-rc1-riscv64-desktop-hwe+ (guanwentao@uos-PC) (riscv64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) # SMP
Linux version 6.6.152-rc1-riscv64-desktop-hwe+ (guanwentao@uos-PC) (riscv64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #4 SMP Tue Aug 18 03:31:15 CST 2026 Linux version 6.6.152-rc1-amd64-desktop-hwe-g9a239823f9ad (guanwentao@uos-PC) (gcc (Deepin 12.3.0-17deepin15) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) # SMP PREEMPT_DYNAMIC
Linux version 6.6.152-rc1-amd64-desktop-hwe-g9a239823f9ad (guanwentao@uos-PC) (gcc (Deepin 12.3.0-17deepin15) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #1 SMP PREEMPT_DYNAMIC Tue Aug 18 02:40:05 CST 2026
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2026 13:23:44 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.152-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.6.152-rc1-g9a239823f9ad #1 SMP PREEMPT_DYNAMIC Tue Aug 18 13:55:00 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2026 13:23:44 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.152-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 8 lines · On Mon, 17 Aug 2026 15:32:14 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.6.152 release. There are 156 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 19 Aug 2026 13:23:44 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64:
Thanks!
Cheers,
Miguel