6.6.135-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 6.6.135-rc1 review
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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, 15 Apr 2026 15:57:08 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.135-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.6.135-rc1
Manivannan Sadhasivam <[email protected]>
Revert "PCI: Enable ACS after configuring IOMMU for OF platforms"
David Howells <[email protected]>
rxrpc: Fix missing error checks for rxkad encryption/decryption failure
David Howells <[email protected]>
rxrpc: Fix key/keyring checks in setsockopt(RXRPC_SECURITY_KEY/KEYRING)
Luxiao Xu <[email protected]>
rxrpc: fix reference count leak in rxrpc_server_keyring()
Yuqi Xu <[email protected]>
rxrpc: reject undecryptable rxkad response tickets
Douya Le <[email protected]>
rxrpc: Only put the call ref if one was acquired
Anderson Nascimento <[email protected]>
rxrpc: Fix key reference count leak from call->key
David Howells <[email protected]>
rxrpc: Fix call removal to use RCU safe deletion
David Carlier <[email protected]>
net: lan966x: fix page_pool error handling in lan966x_fdma_rx_alloc_page_pool()
Baolin Wang <[email protected]>
mm: filemap: fix nr_pages calculation overflow in filemap_map_pages()
Tyllis Xu <[email protected]>
net: stmmac: fix integer underflow in chain mode
Pengpeng Hou <[email protected]>
net: qualcomm: qca_uart: report the consumed byte on RX skb allocation failure
Johan Hovold <[email protected]>
mmc: vub300: fix NULL-deref on disconnect
Jacky Bai <[email protected]>
pmdomain: imx8mp-blk-ctrl: Keep the NOC_HDCP clock enabled
Michael Guralnik <[email protected]>
net/mlx5: Update the list of the PCI supported devices
Sebastian Brzezinka <[email protected]>
drm/i915/gt: fix refcount underflow in intel_engine_park_heartbeat
Haoze Xie <[email protected]>
batman-adv: hold claim backbone gateways by reference
David Carlier <[email protected]>
net: altera-tse: fix skb leak on DMA mapping error in tse_start_xmit()
Muhammad Alifa Ramdhan <[email protected]>
net/tls: fix use-after-free in -EBUSY error path of tls_do_encryption
Borislav Petkov (AMD) <[email protected]>
EDAC/mc: Fix error path ordering in edac_mc_alloc()
Lukas Wunner <[email protected]>
X.509: Fix out-of-bounds access when parsing extensions
Ruide Cao <[email protected]>
batman-adv: reject oversized global TT response buffers
Pengpeng Hou <[email protected]>
nfc: pn533: allocate rx skb before consuming bytes
Shawn Guo <[email protected]>
arm64: dts: hisilicon: hi3798cv200: Add missing dma-ranges
Shawn Guo <[email protected]>
arm64: dts: hisilicon: poplar: Correct PCIe reset GPIO polarity
Sebastian Krzyszkowiak <[email protected]>
arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V
Sebastian Krzyszkowiak <[email protected]>
Revert "arm64: dts: imx8mq-librem5: Set the DVS voltages lower"
Thomas Fourier <[email protected]>
wifi: brcmsmac: Fix dma_free_coherent() size
Oleh Konko <[email protected]>
tipc: fix bc_ackers underflow on duplicate GRP_ACK_MSG
Yasuaki Torimaru <[email protected]>
xfrm: clear trailing padding in build_polexpire()
Tuan Do <[email protected]>
netfilter: nft_ct: fix use-after-free in timeout object destroy
Maarten Lankhorst <[email protected]>
Revert "drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug"
Florian Westphal <[email protected]>
netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR
Andrea Mayer <[email protected]>
seg6: separate dst_cache for input and output paths in seg6 lwtunnel
Matthieu Baerts (NGI0) <[email protected]>
Revert "mptcp: add needs_id for netlink appending addr"
Michael Zimmermann <[email protected]>
usb: gadget: f_hid: move list and spinlock inits from bind to alloc
Li Xiasong <[email protected]>
mptcp: fix soft lockup in mptcp_recvmsg()
Srujana Challa <[email protected]>
virtio_net: clamp rss_max_key_size to NETDEV_RSS_KEY_LEN
André Draszik <[email protected]>
scsi: ufs: core: Fix use-after free in init error and remove paths
Kuninori Morimoto <[email protected]>
ASoC: simple-card-utils: Don't use __free(device_node) at graph_util_parse_dai()
Maciej W. Rozycki <[email protected]>
MIPS: mm: Rewrite TLB uniquification for the hidden bit feature
Maciej W. Rozycki <[email protected]>
MIPS: mm: Suppress TLB uniquification on EHINV hardware
Maciej W. Rozycki <[email protected]>
MIPS: Always record SEGBITS in cpu_data.vmbits
Dmitry Torokhov <[email protected]>
Input: uinput - take event lock when submitting FF request "event"
Mikhail Gavrilov <[email protected]>
Input: uinput - fix circular locking dependency with ff-core
Jiayuan Chen <[email protected]>
mptcp: fix slab-use-after-free in __inet_lookup_established
Greg Kroah-Hartman <[email protected]>
net: rfkill: prevent unlimited numbers of rfkill events from being created
Greg Kroah-Hartman <[email protected]>
xfrm_user: fix info leak in build_report()
Johan Hovold <[email protected]>
wifi: rt2x00usb: fix devres lifetime
Eric Biggers <[email protected]>
lib/crypto: chacha: Zeroize permuted_state before it leaves scope
-------------
Diffstat:
Makefile | 4 +- .../arm64/boot/dts/freescale/imx8mq-librem5-r3.dts | 2 +- arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 24 +- .../boot/dts/hisilicon/hi3798cv200-poplar.dts | 2 +- arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 1 + arch/mips/include/asm/cpu-features.h | 1 - arch/mips/include/asm/cpu-info.h | 2 - arch/mips/include/asm/mipsregs.h | 2 + arch/mips/kernel/cpu-probe.c | 13 +- arch/mips/kernel/cpu-r3k-probe.c | 2 + arch/mips/mm/tlb-r4k.c | 285 +++++++++++++++++---- crypto/asymmetric_keys/x509_cert_parser.c | 8 +- drivers/edac/edac_mc.c | 6 +- drivers/gpu/drm/drm_file.c | 5 +- drivers/gpu/drm/drm_mode_config.c | 9 +- drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c | 26 +- drivers/input/misc/uinput.c | 35 ++- drivers/mmc/host/vub300.c | 2 +- drivers/net/ethernet/altera/altera_tse_main.c | 1 + drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 + .../net/ethernet/microchip/lan966x/lan966x_fdma.c | 2 + drivers/net/ethernet/qualcomm/qca_uart.c | 2 +- drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 11 +- drivers/net/virtio_net.c | 16 +- .../net/wireless/broadcom/brcm80211/brcmsmac/dma.c | 2 +- drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 2 +- drivers/nfc/pn533/uart.c | 11 +- drivers/pci/pci-driver.c | 8 - drivers/pci/pci.c | 10 +- drivers/pci/pci.h | 1 - drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 8 +- drivers/ufs/core/ufshcd.c | 31 ++- drivers/ufs/host/ufshcd-pci.c | 2 - drivers/ufs/host/ufshcd-pltfrm.c | 25 +- drivers/usb/gadget/function/f_hid.c | 11 +- include/net/netfilter/nf_conntrack_timeout.h | 1 + include/trace/events/rxrpc.h | 2 +- include/ufs/ufshcd.h | 1 - lib/crypto/chacha.c | 4 + mm/filemap.c | 11 +- net/batman-adv/bridge_loop_avoidance.c | 27 +- net/batman-adv/translation-table.c | 9 +- net/ipv6/seg6_iptunnel.c | 41 ++- net/mptcp/pm_netlink.c | 24 +- net/mptcp/protocol.c | 13 +- net/mptcp/protocol.h | 1 + net/mptcp/subflow.c | 15 +- net/netfilter/nft_ct.c | 2 +- net/netfilter/nft_set_pipapo.c | 20 +- net/rfkill/core.c | 35 ++- net/rxrpc/af_rxrpc.c | 6 - net/rxrpc/call_object.c | 25 +- net/rxrpc/io_thread.c | 3 +- net/rxrpc/key.c | 2 +- net/rxrpc/rxkad.c | 63 +++-- net/rxrpc/server_key.c | 3 + net/tipc/group.c | 6 +- net/tls/tls_sw.c | 10 + net/xfrm/xfrm_user.c | 3 + sound/soc/generic/simple-card-utils.c | 7 +- 60 files changed, 599 insertions(+), 308 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/50 lib/crypto: chacha: Zeroize permuted_state before it leaves scope
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit e5046823f8fa3677341b541a25af2fcb99a5b1e0 upstream.
Since the ChaCha permutation is invertible, the local variable 'permuted_state' is sufficient to compute the original 'state', and thus the key, even after the permutation has been done.
While the kernel is quite inconsistent about zeroizing secrets on the stack (and some prominent userspace crypto libraries don't bother at all since it's not guaranteed to work anyway), the kernel does try to do it as a best practice, especially in cases involving the RNG.
Thus, explicitly zeroize 'permuted_state' before it goes out of scope.
--- lib/crypto/chacha.c | 4 ++++ 1 file changed, 4 insertions(+)
lib/crypto/chacha.c +4 -0
@@ -86,6 +86,8 @@ void chacha_block_generic(u32 *state, u8put_unaligned_le32 (x[i] + state[i], &stream[i *sizeof (u32)]); state[12 ]++; + +memzero_explicit (x,sizeof (x)); }EXPORT_SYMBOL (chacha_block_generic);
@@ -110,5 +112,7 @@ void hchacha_block_generic(const u32 *stmemcpy (&stream[0 ], &x[0 ],16 );memcpy (&stream[4 ], &x[12 ],16 ); + +memzero_explicit (x,sizeof (x)); }EXPORT_SYMBOL (hchacha_block_generic);
Greg Kroah-Hartman
maintainerPATCH 2/50 wifi: rt2x00usb: fix devres lifetime
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 25369b22223d1c56e42a0cd4ac9137349d5a898e upstream.
USB drivers bind to USB interfaces and any device managed resources should have their lifetime tied to the interface rather than parent USB device. This avoids issues like memory leaks when drivers are unbound without their devices being physically disconnected (e.g. on probe deferral or configuration changes).
Fix the USB anchor lifetime so that it is released on driver unbind.
--- drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +1 -1
@@ -830,7 +830,7 @@ int rt2x00usb_probe(struct usb_interfaceif (retval) goto exit_free_device; - rt2x00dev->anchor =devm_kmalloc (&usb_dev->dev, + rt2x00dev->anchor =devm_kmalloc (&usb_intf->dev,sizeof (struct usb_anchor ),GFP_KERNEL );if (!rt2x00dev->anchor) {
Greg Kroah-Hartman
maintainerPATCH 3/50 xfrm_user: fix info leak in build_report()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
commit d10119968d0e1f2b669604baf2a8b5fdb72fa6b4 upstream.
struct xfrm_user_report is a __u8 proto field followed by a struct xfrm_selector which means there is three "empty" bytes of padding, but the padding is never zeroed before copying to userspace. Fix that up by zeroing the structure before setting individual member variables.
--- net/xfrm/xfrm_user.c | 1 + 1 file changed, 1 insertion(+)
net/xfrm/xfrm_user.c +1 -0
@@ -3740,6 +3740,7 @@ static int build_report(struct sk_buff *return -EMSGSIZE ; ur =nlmsg_data (nlh); +memset (ur,0 ,sizeof (*ur)); ur->proto = proto;memcpy (&ur->sel, sel,sizeof (ur->sel));
Greg Kroah-Hartman
maintainerPATCH 4/50 net: rfkill: prevent unlimited numbers of rfkill events from being created
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
commit ea245d78dec594372e27d8c79616baf49e98a4a1 upstream.
Userspace can create an unlimited number of rfkill events if the system is so configured, while not consuming them from the rfkill file descriptor, causing a potential out of memory situation. Prevent this from bounding the number of pending rfkill events at a "large" number (i.e. 1000) to prevent abuses like this.
--- net/rfkill/core.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-)
net/rfkill/core.c +24 -11
@@ -73,11 +73,14 @@ struct rfkill_int_event {struct rfkill_event_ext ev; }; +/* Max rfkill events that can be "in-flight" for one data source */ +#define MAX_RFKILL_EVENT 1000struct rfkill_data {struct list_head list;struct list_head events;struct mutex mtx;wait_queue_head_t read_wait; +u32 event_count;bool input_handler;u8 max_size; };
@@ -255,10 +258,12 @@ static void rfkill_global_led_trigger_un }#endif /* CONFIG_RFKILL_LEDS */ -static void rfkill_fill_event (struct rfkill_event_ext *ev, -struct rfkill *rfkill, -enum rfkill_operation op) +static int rfkill_fill_event (struct rfkill_int_event *int_ev, +struct rfkill *rfkill, +struct rfkill_data *data, +enum rfkill_operation op) { +struct rfkill_event_ext *ev = &int_ev->ev;unsigned long flags; ev->idx = rfkill->idx;
@@ -271,6 +276,15 @@ static void rfkill_fill_event(struct rfk RFKILL_BLOCK_SW_PREV)); ev->hard_block_reasons = rfkill->hard_block_reasons;spin_unlock_irqrestore (&rfkill->lock, flags); + + scoped_guard(mutex, &data->mtx) { +if (data->event_count++ >MAX_RFKILL_EVENT ) { + data->event_count--; +return -ENOSPC ; + } +list_add_tail (&int_ev->list, &data->events); + } +return 0 ; }static void rfkill_send_events (struct rfkill *rfkill,enum rfkill_operation op)
@@ -282,10 +296,10 @@ static void rfkill_send_events(struct rf ev =kzalloc (sizeof (*ev),GFP_KERNEL );if (!ev)continue ; -rfkill_fill_event (&ev->ev, rfkill, op); -mutex_lock (&data->mtx); -list_add_tail (&ev->list, &data->events); -mutex_unlock (&data->mtx); +if (rfkill_fill_event (ev, rfkill, data, op)) { +kfree (ev); +continue ; + }wake_up_interruptible (&data->read_wait); } }
@@ -1190,10 +1204,8 @@ static int rfkill_fop_open(struct inodeif (!ev) goto free;rfkill_sync (rfkill); -rfkill_fill_event (&ev->ev, rfkill,RFKILL_OP_ADD ); -mutex_lock (&data->mtx); -list_add_tail (&ev->list, &data->events); -mutex_unlock (&data->mtx); +if (rfkill_fill_event (ev, rfkill, data,RFKILL_OP_ADD )) +kfree (ev); }list_add (&data->list, &rfkill_fds);mutex_unlock (&rfkill_global_mutex);
@@ -1263,6 +1275,7 @@ static ssize_t rfkill_fop_read(struct fi ret = -EFAULT ;list_del (&ev->list); + data->event_count--;kfree (ev); out:mutex_unlock (&data->mtx);
Greg Kroah-Hartman
maintainerPATCH 5/50 mptcp: fix slab-use-after-free in __inet_lookup_established
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
commit 9b55b253907e7431210483519c5ad711a37dafa1 upstream.
The ehash table lookups are lockless and rely on SLAB_TYPESAFE_BY_RCU to guarantee socket memory stability during RCU read-side critical sections. Both tcp_prot and tcpv6_prot have their slab caches created with this flag via proto_register().
However, MPTCP's mptcp_subflow_init() copies tcpv6_prot into tcpv6_prot_override during inet_init() (fs_initcall, level 5), before inet6_init() (module_init/device_initcall, level 6) has called proto_register(&tcpv6_prot). At that point, tcpv6_prot.slab is still NULL, so tcpv6_prot_override.slab remains NULL permanently.
This causes MPTCP v6 subflow child sockets to be allocated via kmalloc (falling into kmalloc-4k) instead of the TCPv6 slab cache. The kmalloc-4k cache lacks SLAB_TYPESAFE_BY_RCU, so when these sockets are freed without SOCK_RCU_FREE (which is cleared for child sockets by design), the memory can be immediately reused. Concurrent ehash lookups under rcu_read_lock can then access freed memory, triggering a slab-use-after-free in __inet_lookup_established.
Fix this by splitting the IPv6-specific initialization out of mptcp_subflow_init() into a new mptcp_subflow_v6_init(), called from mptcp_proto_v6_init() before protocol registration. This ensures tcpv6_prot_override.slab correctly inherits the SLAB_TYPESAFE_BY_RCU slab cache.
--- net/mptcp/protocol.c | 2 ++ net/mptcp/protocol.h | 1 + net/mptcp/subflow.c | 15 +++++++++------ 3 files changed, 12 insertions(+), 6 deletions(-)
net/mptcp/protocol.c +2 -0
@@ -4301,6 +4301,8 @@ int __init mptcp_proto_v6_init(void) {int err; +mptcp_subflow_v6_init (); + mptcp_v6_prot = mptcp_prot;strcpy (mptcp_v6_prot.name,"MPTCPv6" ); mptcp_v6_prot.slab =NULL ;
net/mptcp/protocol.h +1 -0
@@ -746,6 +746,7 @@ static inline void mptcp_subflow_tcp_falvoid __init mptcp_proto_init (void );#if IS_ENABLED (CONFIG_MPTCP_IPV6 )int __init mptcp_proto_v6_init (void ); +void __init mptcp_subflow_v6_init (void );#endif struct sock *mptcp_sk_clone_init(const struct sock *sk,
net/mptcp/subflow.c +9 -6
@@ -2092,7 +2092,15 @@ void __init mptcp_subflow_init(void) tcp_prot_override.psock_update_sk_prot =NULL ;#endif +mptcp_diag_subflow_init (&subflow_ulp_ops); + +if (tcp_register_ulp (&subflow_ulp_ops) !=0 ) +panic ("MPTCP: failed to register subflows to ULP\n" ); +} +#if IS_ENABLED (CONFIG_MPTCP_IPV6 ) +void __init mptcp_subflow_v6_init (void ) +{/* In struct mptcp_subflow_request_sock, we assume the TCP request sock * structures for v4 and v6 have the same size. It should not changed in * the future but better to make sure to be warned if it is no longer
@@ -2132,10 +2140,5 @@ void __init mptcp_subflow_init(void)/* Disable sockmap processing for subflows */ tcpv6_prot_override.psock_update_sk_prot =NULL ; #endif -#endif - -mptcp_diag_subflow_init (&subflow_ulp_ops); - -if (tcp_register_ulp (&subflow_ulp_ops) !=0 ) -panic ("MPTCP: failed to register subflows to ULP\n" ); } +#endif
Greg Kroah-Hartman
maintainerPATCH 6/50 Input: uinput - fix circular locking dependency with ff-core
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Gavrilov <[email protected]>
commit 4cda78d6f8bf2b700529f2fbccb994c3e826d7c2 upstream.
A lockdep circular locking dependency warning can be triggered reproducibly when using a force-feedback gamepad with uinput (for example, playing ELDEN RING under Wine with a Flydigi Vader 5 controller):
ff->mutex -> udev->mutex -> input_mutex -> dev->mutex -> ff->mutex
The cycle is caused by four lock acquisition paths:
1. ff upload: input_ff_upload() holds ff->mutex and calls uinput_dev_upload_effect() -> uinput_request_submit() -> uinput_request_send(), which acquires udev->mutex.
2. device create: uinput_ioctl_handler() holds udev->mutex and calls uinput_create_device() -> input_register_device(), which acquires input_mutex.
3. device register: input_register_device() holds input_mutex and calls kbd_connect() -> input_register_handle(), which acquires dev->mutex.
4. evdev release: evdev_release() calls input_flush_device() under dev->mutex, which calls input_ff_flush() acquiring ff->mutex.
Fix this by introducing a new state_lock spinlock to protect udev->state and udev->dev access in uinput_request_send() instead of acquiring udev->mutex. The function only needs to atomically check device state and queue an input event into the ring buffer via uinput_dev_event() -- both operations are safe under a spinlock (ktime_get_ts64() and wake_up_interruptible() do not sleep). This breaks the ff->mutex -> udev->mutex link since a spinlock is a leaf in the lock ordering and cannot form cycles with mutexes.
To keep state transitions visible to uinput_request_send(), protect writes to udev->state in uinput_create_device() and uinput_destroy_device() with the same state_lock spinlock.
Additionally, move init_completion(&request->done) from uinput_request_send() to uinput_request_submit() before uinput_request_reserve_slot(). Once the slot is allocated, uinput_flush_requests() may call complete() on it at any time from the destroy path, so the completion must be initialised before the request becomes visible.
Lock ordering after the fix:
ff->mutex -> state_lock (spinlock, leaf)
udev->mutex -> state_lock (spinlock, leaf)
udev->mutex -> input_mutex -> dev->mutex -> ff->mutex (no back-edge)
--- drivers/input/misc/uinput.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
drivers/input/misc/uinput.c +21 -7
@@ -57,6 +57,7 @@ struct uinput_device {struct input_dev *dev;struct mutex mutex;enum uinput_state state; +spinlock_t state_lock;wait_queue_head_t waitq;unsigned char ready;unsigned char head;
@@ -146,19 +147,15 @@ static void uinput_request_release_slot(static int uinput_request_send (struct uinput_device *udev,struct uinput_request *request) { -int retval; +int retval =0 ; - retval =mutex_lock_interruptible (&udev->mutex); -if (retval) -return retval; +spin_lock (&udev->state_lock);if (udev->state !=UIST_CREATED ) { retval = -ENODEV ; goto out; } -init_completion (&request->done); -/* * Tell our userspace application about this new request * by queueing an input event.
@@ -166,7 +163,7 @@ static int uinput_request_send(struct uiuinput_dev_event (udev->dev,EV_UINPUT , request->code, request->id); out: -mutex_unlock (&udev->mutex); +spin_unlock (&udev->state_lock);return retval; }
@@ -175,6 +172,13 @@ static int uinput_request_submit(struct {int retval; +/* +* Initialize completion before allocating the request slot. +* Once the slot is allocated, uinput_flush_requests() may +* complete it at any time, so it must be initialized first. +*/ +init_completion (&request->done); + retval =uinput_request_reserve_slot (udev, request);if (retval)return retval;
@@ -289,7 +293,14 @@ static void uinput_destroy_device(structstruct input_dev *dev = udev->dev;enum uinput_state old_state = udev->state; +/* +* Update state under state_lock so that concurrent +* uinput_request_send() sees the state change before we +* flush pending requests and tear down the device. +*/ +spin_lock (&udev->state_lock); udev->state =UIST_NEW_DEVICE ; +spin_unlock (&udev->state_lock);if (dev) { name = dev->name;
@@ -366,7 +377,9 @@ static int uinput_create_device(struct uif (error) goto fail2; +spin_lock (&udev->state_lock); udev->state =UIST_CREATED ; +spin_unlock (&udev->state_lock);return 0 ;
@@ -384,6 +397,7 @@ static int uinput_open(struct inode *inoreturn -ENOMEM ;mutex_init (&newdev->mutex); +spin_lock_init (&newdev->state_lock);spin_lock_init (&newdev->requests_lock);init_waitqueue_head (&newdev->requests_waitq);init_waitqueue_head (&newdev->waitq);
Greg Kroah-Hartman
maintainerPATCH 7/50 Input: uinput - take event lock when submitting FF request "event"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit ff14dafde15c11403fac61367a34fea08926e9ee upstream.
To avoid racing with FF playback events and corrupting device's event queue take event_lock spinlock when calling uinput_dev_event() when submitting a FF upload or erase "event".
--- drivers/input/misc/uinput.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/input/misc/uinput.c +7 -0
@@ -25,8 +25,10 @@#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> +#include <linux/lockdep.h> #include <linux/miscdevice.h> #include <linux/overflow.h> +#include <linux/spinlock.h> #include <linux/input/mt.h> #include "../input-compat.h"
@@ -76,6 +78,8 @@ static int uinput_dev_event(struct inputstruct uinput_device *udev =input_get_drvdata (dev);struct timespec64 ts; +lockdep_assert_held (&dev->event_lock); +ktime_get_ts64 (&ts); udev->buff[udev->head] = (struct input_event ) {
@@ -147,6 +151,7 @@ static void uinput_request_release_slot(static int uinput_request_send (struct uinput_device *udev,struct uinput_request *request) { +unsigned long flags;int retval =0 ;spin_lock (&udev->state_lock);
@@ -160,7 +165,9 @@ static int uinput_request_send(struct ui* Tell our userspace application about this new request * by queueing an input event. */ +spin_lock_irqsave (&udev->dev->event_lock, flags);uinput_dev_event (udev->dev,EV_UINPUT , request->code, request->id); +spin_unlock_irqrestore (&udev->dev->event_lock, flags); out:spin_unlock (&udev->state_lock);
Greg Kroah-Hartman
maintainerPATCH 8/50 MIPS: Always record SEGBITS in cpu_data.vmbits
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit 8374c2cb83b95b3c92f129fd56527225c20a058c upstream.
With a 32-bit kernel running on 64-bit MIPS hardware the hardcoded value of `cpu_vmbits' only records the size of compatibility useg and does not reflect the size of native xuseg or the complete range of values allowed in the VPN2 field of TLB entries.
An upcoming change will need the actual VPN2 value range permitted even in 32-bit kernel configurations, so always include the vmbits' member in struct cpuinfo_mips' and probe for SEGBITS when running on 64-bit hardware and resorting to the currently hardcoded value of 31 on 32-bit processors. No functional change for users of `cpu_vmbits'.
--- arch/mips/include/asm/cpu-features.h | 1 - arch/mips/include/asm/cpu-info.h | 2 -- arch/mips/include/asm/mipsregs.h | 2 ++ arch/mips/kernel/cpu-probe.c | 13 ++++++++----- arch/mips/kernel/cpu-r3k-probe.c | 2 ++ 5 files changed, 12 insertions(+), 8 deletions(-)
arch/mips/include/asm/cpu-features.h +0 -1
@@ -484,7 +484,6 @@# endif # ifndef cpu_vmbits# define cpu_vmbits cpu_data[0].vmbits -# define __NEED_VMBITS_PROBE# endif #endif
arch/mips/include/asm/cpu-info.h +0 -2
@@ -80,9 +80,7 @@ struct cpuinfo_mips {int srsets;/* Shadow register sets */ int package;/* physical package number */ unsigned int globalnumber; -#ifdef CONFIG_64BIT int vmbits;/* Virtual memory size in bits */ -#endif void *data;/* Additional data */ unsigned int watch_reg_count;/* Number that exist */ unsigned int watch_reg_use_cnt;/* Usable by ptrace */
arch/mips/include/asm/mipsregs.h +2 -0
@@ -1714,6 +1714,8 @@ do { \#define read_c0_entryhi () __read_ulong_c0_register($10, 0)#define write_c0_entryhi (val) __write_ulong_c0_register($10, 0, val) +#define read_c0_entryhi_64 () __read_64bit_c0_register($10, 0) +#define write_c0_entryhi_64 (val) __write_64bit_c0_register($10, 0, val)#define read_c0_guestctl1 () __read_32bit_c0_register($10, 4)#define write_c0_guestctl1 (val) __write_32bit_c0_register($10, 4, val)
arch/mips/kernel/cpu-probe.c +8 -5
@@ -208,11 +208,14 @@ static inline void set_elf_base_platform(const char *plat)static inline void cpu_probe_vmbits (struct cpuinfo_mips *c) { -#ifdef __NEED_VMBITS_PROBE -write_c0_entryhi (0x3fffffffffffe000ULL ); -back_to_back_c0_hazard (); - c->vmbits =fls64 (read_c0_entryhi () &0x3fffffffffffe000ULL ); -#endif +int vmbits =31 ; + +if (cpu_has_64bits) { +write_c0_entryhi_64 (0x3fffffffffffe000ULL ); +back_to_back_c0_hazard (); + vmbits =fls64 (read_c0_entryhi_64 () &0x3fffffffffffe000ULL ); + } + c->vmbits = vmbits; }static void set_isa (struct cpuinfo_mips *c,unsigned int isa)
arch/mips/kernel/cpu-r3k-probe.c +2 -0
@@ -138,6 +138,8 @@ void cpu_probe(void)else cpu_set_nofpu_opts (c); + c->vmbits =31 ; +reserve_exception_space (0 ,0x400 ); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 9/50 MIPS: mm: Suppress TLB uniquification on EHINV hardware
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit 74283cfe216392c7b776ebf6045b5b15ed9dffcd upstream.
Hardware that supports the EHINV feature, mandatory for R6 ISA and FTLB implementation, lets software mark TLB entries invalid, which eliminates the need to ensure no duplicate matching entries are ever created. This feature is already used by local_flush_tlb_all(), via the UNIQUE_ENTRYHI macro, making the preceding call to r4k_tlb_uniquify() superfluous.
The next change will also modify uniquification code such that it'll become incompatible with the FTLB and MMID features, as well as MIPSr6 CPUs that do not implement 4KiB pages.
Therefore prevent r4k_tlb_uniquify() from being used on EHINV hardware, as denoted by `cpu_has_tlbinv'.
--- arch/mips/mm/tlb-r4k.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/mips/mm/tlb-r4k.c +2 -1
@@ -638,7 +638,8 @@ static void r4k_tlb_configure(void) temp_tlb_entry = current_cpu_data.tlbsize -1 ;/* From this point on the ARC firmware is dead. */ -r4k_tlb_uniquify (); +if (!cpu_has_tlbinv) +r4k_tlb_uniquify ();local_flush_tlb_all ();/* Did I tell you that ARC SUCKS? */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 10/50 MIPS: mm: Rewrite TLB uniquification for the hidden bit feature
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit 540760b77b8fc49d39d1b2b76196e5ec57711a32 upstream.
Before the introduction of the EHINV feature, which lets software mark TLB entries invalid, certain older implementations of the MIPS ISA were equipped with an analogous bit, as a vendor extension, which however is hidden from software and only ever set at reset, and then any software write clears it, making the intended TLB entry valid.
This feature makes it unsafe to read a TLB entry with TLBR, modify the page mask, and write the entry back with TLBWI, because this operation will implicitly clear the hidden bit and this may create a duplicate entry, as with the presence of the hidden bit there is no guarantee all the entries across the TLB are unique each.
Usually the firmware has already uniquified TLB entries before handing control over, in which case we only need to guarantee at bootstrap no clash will happen with the VPN2 values chosen in local_flush_tlb_all().
However with systems such as Mikrotik RB532 we get handed the TLB as at reset, with the hidden bit set across the entries and possibly duplicate entries present. This then causes a machine check exception when page sizes are reset in r4k_tlb_uniquify() and prevents the system from booting.
Rewrite the algorithm used in r4k_tlb_uniquify() then such as to avoid the reuse of ASID/VPN values across the TLB. Get rid of global entries first as they may be blocking the entire address space, e.g. 16 256MiB pages will exhaust the whole address space of a 32-bit CPU and a single big page can exhaust the 32-bit compatibility space on a 64-bit CPU.
Details of the algorithm chosen are given across the code itself.
--- arch/mips/mm/tlb-r4k.c | 282 +++++++++++++++++++++++++++++++++-------- 1 file changed, 228 insertions(+), 54 deletions(-)
arch/mips/mm/tlb-r4k.c +228 -54
@@ -13,6 +13,7 @@#include <linux/sched.h> #include <linux/smp.h> #include <linux/memblock.h> +#include <linux/minmax.h> #include <linux/mm.h> #include <linux/hugetlb.h> #include <linux/export.h>
@@ -24,6 +25,7 @@#include <asm/hazards.h> #include <asm/mmu_context.h> #include <asm/tlb.h> +#include <asm/tlbdebug.h> #include <asm/tlbmisc.h> extern void build_tlb_refill_handler (void );
@@ -509,87 +511,259 @@ static int __init set_ntlb(char *str)__setup ("ntlb=" , set_ntlb); -/* Comparison function for EntryHi VPN fields. */ -static int r4k_vpn_cmp (const void *a,const void *b) +/* The start bit position of VPN2 and Mask in EntryHi/PageMask registers. */ +#define VPN2_SHIFT 13 + +/* Read full EntryHi even with CONFIG_32BIT. */ +static inline unsigned long long read_c0_entryhi_native (void ) +{ +return cpu_has_64bits ?read_c0_entryhi_64 () :read_c0_entryhi (); +} + +/* Write full EntryHi even with CONFIG_32BIT. */ +static inline void write_c0_entryhi_native (unsigned long long v) { -long v = *(unsigned long *)a - *(unsigned long *)b; -int s =sizeof (long ) >sizeof (int ) ?sizeof (long ) *8 -1 :0 ; -return s ? (v !=0 ) | v >> s : v; +if (cpu_has_64bits) +write_c0_entryhi_64 (v); +else +write_c0_entryhi (v); } +/* TLB entry state for uniquification. */ +struct tlbent { +unsigned long long wired:1 ; +unsigned long long global:1 ; +unsigned long long asid:10 ; +unsigned long long vpn:51 ; +unsigned long long pagesz:5 ; +unsigned long long index:14 ; +}; +/* -* Initialise all TLB entries with unique values that do not clash with -* what we have been handed over and what we'll be using ourselves. +* Comparison function for TLB entry sorting. Place wired entries first, +* then global entries, then order by the increasing VPN/ASID and the +* decreasing page size. This lets us avoid clashes with wired entries +* easily and get entries for larger pages out of the way first. +* +* We could group bits so as to reduce the number of comparisons, but this +* is seldom executed and not performance-critical, so prefer legibility. */ -static void __ref r4k_tlb_uniquify (void ) +static int r4k_entry_cmp (const void *a,const void *b) { -int tlbsize = current_cpu_data.tlbsize; -bool use_slab =slab_is_available (); -int start =num_wired_entries (); -phys_addr_t tlb_vpn_size; -unsigned long *tlb_vpns; -unsigned long vpn_mask; -int cnt, ent, idx, i; - - vpn_mask =GENMASK (cpu_vmbits -1 ,13 ); - vpn_mask |=IS_ENABLED (CONFIG_64BIT ) ?3ULL <<62 :1 <<31 ; +struct tlbent ea = *(struct tlbent *)a, eb = *(struct tlbent *)b; + +if (ea.wired > eb.wired) +return -1 ; +else if (ea.wired < eb.wired) +return 1 ; +else if (ea.global > eb.global) +return -1 ; +else if (ea.global < eb.global) +return 1 ; +else if (ea.vpn < eb.vpn) +return -1 ; +else if (ea.vpn > eb.vpn) +return 1 ; +else if (ea.asid < eb.asid) +return -1 ; +else if (ea.asid > eb.asid) +return 1 ; +else if (ea.pagesz > eb.pagesz) +return -1 ; +else if (ea.pagesz < eb.pagesz) +return 1 ; +else +return 0 ; +} - tlb_vpn_size = tlbsize *sizeof (*tlb_vpns); - tlb_vpns = (use_slab ? -kmalloc (tlb_vpn_size,GFP_ATOMIC ) : -memblock_alloc_raw (tlb_vpn_size,sizeof (*tlb_vpns))); -if (WARN_ON (!tlb_vpns)) -return ;/* Pray local_flush_tlb_all() is good enough. */ +/* +* Fetch all the TLB entries. Mask individual VPN values retrieved with +* the corresponding page mask and ignoring any 1KiB extension as we'll +* be using 4KiB pages for uniquification. +*/ +static void __ref r4k_tlb_uniquify_read (struct tlbent *tlb_vpns,int tlbsize) +{ +int start =num_wired_entries (); +unsigned long long vpn_mask; +bool global; +int i; -htw_stop (); + vpn_mask =GENMASK (current_cpu_data.vmbits -1 ,VPN2_SHIFT ); + vpn_mask |= cpu_has_64bits ?3ULL <<62 :1 <<31 ; -for (i = start, cnt =0 ; i < tlbsize; i++, cnt++) { -unsigned long vpn; +for (i =0 ; i < tlbsize; i++) { +unsigned long long entryhi, vpn, mask, asid; +unsigned int pagesz;write_c0_index (i);mtc0_tlbr_hazard ();tlb_read ();tlb_read_hazard (); - vpn =read_c0_entryhi (); - vpn &= vpn_mask &PAGE_MASK ; - tlb_vpns[cnt] = vpn; -/* Prevent any large pages from overlapping regular ones. */ -write_c0_pagemask (read_c0_pagemask () &PM_DEFAULT_MASK ); -mtc0_tlbw_hazard (); -tlb_write_indexed (); -tlbw_use_hazard (); + global = !!(read_c0_entrylo0 () &ENTRYLO_G ); + entryhi =read_c0_entryhi_native (); + mask =read_c0_pagemask (); + + asid = entryhi &cpu_asid_mask (¤t_cpu_data); + vpn = (entryhi & vpn_mask & ~mask) >>VPN2_SHIFT ; + pagesz =ilog2 ((mask >>VPN2_SHIFT ) +1 ); + + tlb_vpns[i].global = global; + tlb_vpns[i].asid = global ?0 : asid; + tlb_vpns[i].vpn = vpn; + tlb_vpns[i].pagesz = pagesz; + tlb_vpns[i].wired = i < start; + tlb_vpns[i].index = i; } +} -sort (tlb_vpns, cnt,sizeof (tlb_vpns[0 ]), r4k_vpn_cmp,NULL ); +/* +* Write unique values to all but the wired TLB entries each, using +* the 4KiB page size. This size might not be supported with R6, but +* EHINV is mandatory for R6, so we won't ever be called in that case. +* +* A sorted table is supplied with any wired entries at the beginning, +* followed by any global entries, and then finally regular entries. +* We start at the VPN and ASID values of zero and only assign user +* addresses, therefore guaranteeing no clash with addresses produced +* by UNIQUE_ENTRYHI. We avoid any VPN values used by wired or global +* entries, by increasing the VPN value beyond the span of such entry. +* +* When a VPN/ASID clash is found with a regular entry we increment the +* ASID instead until no VPN/ASID clash has been found or the ASID space +* has been exhausted, in which case we increase the VPN value beyond +* the span of the largest clashing entry. +* +* We do not need to be concerned about FTLB or MMID configurations as +* those are required to implement the EHINV feature. +*/ +static void __ref r4k_tlb_uniquify_write (struct tlbent *tlb_vpns,int tlbsize) +{ +unsigned long long asid, vpn, vpn_size, pagesz; +int widx, gidx, idx, sidx, lidx, i; -write_c0_pagemask (PM_DEFAULT_MASK ); + vpn_size =1ULL << (current_cpu_data.vmbits -VPN2_SHIFT ); + pagesz =ilog2 ((PM_4K >>VPN2_SHIFT ) +1 ); + +write_c0_pagemask (PM_4K );write_c0_entrylo0 (0 );write_c0_entrylo1 (0 ); - idx =0 ; - ent = tlbsize; -for (i = start; i < tlbsize; i++) -while (1 ) { -unsigned long entryhi, vpn; + asid =0 ; + vpn =0 ; + widx =0 ; + gidx =0 ; +for (sidx =0 ; sidx < tlbsize && tlb_vpns[sidx].wired; sidx++) + ; +for (lidx = sidx; lidx < tlbsize && tlb_vpns[lidx].global; lidx++) + ; + idx = gidx = sidx +1 ; +for (i = sidx; i < tlbsize; i++) { +unsigned long long entryhi, vpn_pagesz =0 ; - entryhi =UNIQUE_ENTRYHI (ent); - vpn = entryhi & vpn_mask &PAGE_MASK ; +while (1 ) { +if (WARN_ON (vpn >= vpn_size)) { +dump_tlb_all (); +/* Pray local_flush_tlb_all() will cope. */ +return ; + } -if (idx >= cnt || vpn < tlb_vpns[idx]) { -write_c0_entryhi (entryhi); -write_c0_index (i); -mtc0_tlbw_hazard (); -tlb_write_indexed (); - ent++; -break ; - }else if (vpn == tlb_vpns[idx]) { - ent++; - }else { +/* VPN must be below the next wired entry. */ +if (widx < sidx && vpn >= tlb_vpns[widx].vpn) { + vpn =max (vpn, + (tlb_vpns[widx].vpn + + (1ULL << tlb_vpns[widx].pagesz))); + asid =0 ; + widx++; +continue ; + } +/* VPN must be below the next global entry. */ +if (gidx < lidx && vpn >= tlb_vpns[gidx].vpn) { + vpn =max (vpn, + (tlb_vpns[gidx].vpn + + (1ULL << tlb_vpns[gidx].pagesz))); + asid =0 ; + gidx++; +continue ; + } +/* Try to find a free ASID so as to conserve VPNs. */ +if (idx < tlbsize && vpn == tlb_vpns[idx].vpn && + asid == tlb_vpns[idx].asid) { +unsigned long long idx_pagesz; + + idx_pagesz = tlb_vpns[idx].pagesz; + vpn_pagesz =max (vpn_pagesz, idx_pagesz); +do + idx++; +while (idx < tlbsize && + vpn == tlb_vpns[idx].vpn && + asid == tlb_vpns[idx].asid); + asid++; +if (asid >cpu_asid_mask (¤t_cpu_data)) { + vpn += vpn_pagesz; + asid =0 ; + vpn_pagesz =0 ; + } +continue ; + } +/* VPN mustn't be above the next regular entry. */ +if (idx < tlbsize && vpn > tlb_vpns[idx].vpn) { + vpn =max (vpn, + (tlb_vpns[idx].vpn + + (1ULL << tlb_vpns[idx].pagesz))); + asid =0 ; idx++; +continue ; } +break ; } + entryhi = (vpn <<VPN2_SHIFT ) | asid; +write_c0_entryhi_native (entryhi); +write_c0_index (tlb_vpns[i].index); +mtc0_tlbw_hazard (); +tlb_write_indexed (); + + tlb_vpns[i].asid = asid; + tlb_vpns[i].vpn = vpn; + tlb_vpns[i].pagesz = pagesz; + + asid++; +if (asid >cpu_asid_mask (¤t_cpu_data)) { + vpn +=1ULL << pagesz; + asid =0 ; + } + } +} + +/* +* Initialise all TLB entries with unique values that do not clash with +* what we have been handed over and what we'll be using ourselves. +*/ +static void __ref r4k_tlb_uniquify (void ) +{ +int tlbsize = current_cpu_data.tlbsize; +bool use_slab =slab_is_available (); +phys_addr_t tlb_vpn_size; +struct tlbent *tlb_vpns; + + tlb_vpn_size = tlbsize *sizeof (*tlb_vpns); + tlb_vpns = (use_slab ? +kmalloc (tlb_vpn_size,GFP_ATOMIC ) : +memblock_alloc_raw (tlb_vpn_size,sizeof (*tlb_vpns))); +if (WARN_ON (!tlb_vpns)) +return ;/* Pray local_flush_tlb_all() is good enough. */ + +htw_stop (); + +r4k_tlb_uniquify_read (tlb_vpns, tlbsize); + +sort (tlb_vpns, tlbsize,sizeof (*tlb_vpns), r4k_entry_cmp,NULL ); + +r4k_tlb_uniquify_write (tlb_vpns, tlbsize); + +write_c0_pagemask (PM_DEFAULT_MASK ); +tlbw_use_hazard ();htw_start ();flush_micro_tlb ();
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 11/50 ASoC: simple-card-utils: Dont use __free(device_node) at graph_util_parse_dai()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuninori Morimoto <[email protected]>
[ Upstream commit de74ec718e0788e1998eb7289ad07970e27cae27 ]
commit 419d1918105e ("ASoC: simple-card-utils: use __free(device_node) for device node") uses __free(device_node) for dlc->of_node, but we need to keep it while driver is in use.
Don't use __free(device_node) in graph_util_parse_dai().
[ The function asoc_graph_parse_dai() was renamed to graph_util_parse_dai() in commit b5a95c5bf6d6 ("ASoC: simple_card_utils.h: convert not to use asoc_xxx()") in 6.7. The fix should be applied to asoc_graph_parse_dai() instead in 6.6. ]
--- sound/soc/generic/simple-card-utils.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
sound/soc/generic/simple-card-utils.c +5 -2
@@ -1061,6 +1061,7 @@ static int graph_get_dai_id(struct device_node *ep)int asoc_graph_parse_dai (struct device *dev,struct device_node *ep,struct snd_soc_dai_link_component *dlc,int *is_single_link) { +struct device_node *node;struct of_phandle_args args = {};struct snd_soc_dai *dai;int ret;
@@ -1068,7 +1069,7 @@ int asoc_graph_parse_dai(struct device *dev, struct device_node *ep,if (!ep)return 0 ; - struct device_node *node __free(device_node) = of_graph_get_port_parent(ep); + node =of_graph_get_port_parent (ep);/* * Try to find from DAI node
@@ -1110,8 +1111,10 @@ int asoc_graph_parse_dai(struct device *dev, struct device_node *ep,* if he unbinded CPU or Codec. */ ret =snd_soc_get_dlc (&args, dlc); -if (ret <0 ) +if (ret <0 ) { +of_node_put (node);return ret; + } parse_dai_end:if (is_single_link)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 12/50 scsi: ufs: core: Fix use-after free in init error and remove paths
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <[email protected]>
[ Upstream commit f8fb2403ddebb5eea0033d90d9daae4c88749ada ]
devm_blk_crypto_profile_init() registers a cleanup handler to run when the associated (platform-) device is being released. For UFS, the crypto private data and pointers are stored as part of the ufs_hba's data structure 'struct ufs_hba::crypto_profile'. This structure is allocated as part of the underlying ufshcd and therefore Scsi_host allocation.
During driver release or during error handling in ufshcd_pltfrm_init(), this structure is released as part of ufshcd_dealloc_host() before the (platform-) device associated with the crypto call above is released. Once this device is released, the crypto cleanup code will run, using the just-released 'struct ufs_hba::crypto_profile'. This causes a use-after-free situation:
Call trace: kfree+0x60/0x2d8 (P) kvfree+0x44/0x60 blk_crypto_profile_destroy_callback+0x28/0x70 devm_action_release+0x1c/0x30 release_nodes+0x6c/0x108 devres_release_all+0x98/0x100 device_unbind_cleanup+0x20/0x70 really_probe+0x218/0x2d0
In other words, the initialisation code flow is:
platform-device probe
ufshcd_pltfrm_init()
ufshcd_alloc_host()
scsi_host_alloc()
allocation of struct ufs_hba
creation of scsi-host devices
devm_blk_crypto_profile_init()
devm registration of cleanup handler using platform-device
and during error handling of ufshcd_pltfrm_init() or during driver removal:
ufshcd_dealloc_host()
scsi_host_put()
put_device(scsi-host)
release of struct ufs_hba
put_device(platform-device)
crypto cleanup handler
To fix this use-after free, change ufshcd_alloc_host() to register a devres action to automatically cleanup the underlying SCSI device on ufshcd destruction, without requiring explicit calls to ufshcd_dealloc_host(). This way:
* the crypto profile and all other ufs_hba-owned resources are destroyed before SCSI (as they've been registered after)
* a memleak is plugged in tc-dwc-g210-pci.c remove() as a side-effect
* EXPORT_SYMBOL_GPL(ufshcd_dealloc_host) can be removed fully as it's not needed anymore
* no future drivers using ufshcd_alloc_host() could ever forget adding the cleanup
[ Delete modifications about ufshcd_parse_operating_points() for it's added from commit 72208ebe181e3("scsi: ufs: core: Add support for parsing OPP") and that in ufshcd_pltfrm_remove() for it's added from commit 897df60c16d54("scsi: ufs: pltfrm: Dellocate HBA during ufshcd_pltfrm_remove()"). ]
--- drivers/ufs/core/ufshcd.c | 31 +++++++++++++++++++++---------- drivers/ufs/host/ufshcd-pci.c | 2 -- drivers/ufs/host/ufshcd-pltfrm.c | 25 ++++++++----------------- include/ufs/ufshcd.h | 1 - 4 files changed, 29 insertions(+), 30 deletions(-)
drivers/ufs/core/ufshcd.c +21 -10
@@ -10475,16 +10475,6 @@ int ufshcd_system_thaw(struct device *dev)EXPORT_SYMBOL_GPL (ufshcd_system_thaw);#endif /* CONFIG_PM_SLEEP */ -/** -* ufshcd_dealloc_host - deallocate Host Bus Adapter (HBA) -* @hba: pointer to Host Bus Adapter (HBA) -*/ -void ufshcd_dealloc_host (struct ufs_hba *hba) -{ -scsi_host_put (hba->host); -} -EXPORT_SYMBOL_GPL (ufshcd_dealloc_host); -/** * ufshcd_set_dma_mask - Set dma mask based on the controller * addressing capability
@@ -10503,12 +10493,26 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba)return dma_set_mask_and_coherent (hba->dev,DMA_BIT_MASK (32 )); } +/** +* ufshcd_devres_release - devres cleanup handler, invoked during release of +* hba->dev +* @host: pointer to SCSI host +*/ +static void ufshcd_devres_release (void *host) +{ +scsi_host_put (host); +} +/** * ufshcd_alloc_host - allocate Host Bus Adapter (HBA) * @dev: pointer to device handle * @hba_handle: driver private handle * * Return: 0 on success, non-zero value on failure. +* +* NOTE: There is no corresponding ufshcd_dealloc_host() because this function +* keeps track of its allocations using devres and deallocates everything on +* device removal automatically. */ int ufshcd_alloc_host (struct device *dev,struct ufs_hba **hba_handle) {
@@ -10530,6 +10534,13 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) err = -ENOMEM ; goto out_error; } + + err =devm_add_action_or_reset (dev, ufshcd_devres_release, + host); +if (err) +return dev_err_probe (dev, err, +"failed to add ufshcd dealloc action\n" ); + host->nr_maps =HCTX_TYPE_POLL +1 ; hba =shost_priv (host); hba->host = host;
drivers/ufs/host/ufshcd-pci.c +0 -2
@@ -620,7 +620,6 @@ static void ufshcd_pci_remove(struct pci_dev *pdev)pm_runtime_forbid (&pdev->dev);pm_runtime_get_noresume (&pdev->dev);ufshcd_remove (hba); -ufshcd_dealloc_host (hba); }/**
@@ -665,7 +664,6 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) err =ufshcd_init (hba, mmio_base, pdev->irq);if (err) {dev_err (&pdev->dev,"Initialization failed\n" ); -ufshcd_dealloc_host (hba);return err; }
drivers/ufs/host/ufshcd-pltfrm.c +8 -17
@@ -339,21 +339,17 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,struct device *dev = &pdev->dev; mmio_base =devm_platform_ioremap_resource (pdev,0 ); -if (IS_ERR (mmio_base)) { - err =PTR_ERR (mmio_base); - goto out; - } +if (IS_ERR (mmio_base)) +return PTR_ERR (mmio_base); irq =platform_get_irq (pdev,0 ); -if (irq <0 ) { - err = irq; - goto out; - } +if (irq <0 ) +return irq; err =ufshcd_alloc_host (dev, &hba);if (err) {dev_err (dev,"Allocation failed\n" ); - goto out; +return err; } hba->vops = vops;
@@ -362,13 +358,13 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,if (err) {dev_err (dev,"%s: clock parse failed %d\n" , __func__, err); - goto dealloc_host; +return err; } err =ufshcd_parse_regulator_info (hba);if (err) {dev_err (dev,"%s: regulator init failed %d\n" , __func__, err); - goto dealloc_host; +return err; }ufshcd_init_lanes_per_dir (hba);
@@ -377,18 +373,13 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,if (err) {dev_err_probe (dev, err,"Initialization failed with error %d\n" , err); - goto dealloc_host; +return err; }pm_runtime_set_active (dev);pm_runtime_enable (dev);return 0 ; - -dealloc_host: -ufshcd_dealloc_host (hba); -out: -return err; }EXPORT_SYMBOL_GPL (ufshcd_pltfrm_init);
include/ufs/ufshcd.h +0 -1
@@ -1286,7 +1286,6 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg) }int ufshcd_alloc_host (struct device *,struct ufs_hba **); -void ufshcd_dealloc_host (struct ufs_hba *);int ufshcd_hba_enable (struct ufs_hba *hba);int ufshcd_init (struct ufs_hba *,void __iomem *,unsigned int );int ufshcd_link_recovery (struct ufs_hba *hba);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 13/50 virtio_net: clamp rss_max_key_size to NETDEV_RSS_KEY_LEN
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srujana Challa <[email protected]>
[ Upstream commit b4e5f04c58a29c499faa85d12952ca9a4faf1cb9 ]
rss_max_key_size in the virtio spec is the maximum key size supported by the device, not a mandatory size the driver must use. Also the value 40 is a spec minimum, not a spec maximum.
The current code rejects RSS and can fail probe when the device reports a larger rss_max_key_size than the driver buffer limit. Instead, clamp the effective key length to min(device rss_max_key_size, NETDEV_RSS_KEY_LEN) and keep RSS enabled.
This keeps probe working on devices that advertise larger maximum key sizes while respecting the netdev RSS key buffer size limit.
--- drivers/net/virtio_net.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/net/virtio_net.c +8 -8
@@ -4465,6 +4465,7 @@ static int virtnet_probe(struct virtio_dstruct virtnet_info *vi;u16 max_queue_pairs;int mtu =0 ; +u16 key_sz;/* Find if host supports multiqueue/rss virtio_net device */ max_queue_pairs =1 ;
@@ -4589,14 +4590,13 @@ static int virtnet_probe(struct virtio_d }if (vi->has_rss || vi->has_rss_hash_report) { - vi->rss_key_size = -virtio_cread8 (vdev, offsetof(struct virtio_net_config , rss_max_key_size)); -if (vi->rss_key_size >VIRTIO_NET_RSS_MAX_KEY_SIZE ) { -dev_err (&vdev->dev,"rss_max_key_size=%u exceeds the limit %u.\n" , - vi->rss_key_size,VIRTIO_NET_RSS_MAX_KEY_SIZE ); - err = -EINVAL ; - goto free; - } + key_sz =virtio_cread8 (vdev, offsetof(struct virtio_net_config , rss_max_key_size)); + + vi->rss_key_size =min_t (u16, key_sz,VIRTIO_NET_RSS_MAX_KEY_SIZE ); +if (key_sz > vi->rss_key_size) +dev_warn (&vdev->dev, +"rss_max_key_size=%u exceeds driver limit %u, clamping\n" , + key_sz, vi->rss_key_size); vi->rss_hash_types_supported =virtio_cread32 (vdev, offsetof(struct virtio_net_config , supported_hash_types));
Greg Kroah-Hartman
maintainerPATCH 14/50 mptcp: fix soft lockup in mptcp_recvmsg()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Xiasong <[email protected]>
commit 5dd8025a49c268ab6b94d978532af3ad341132a7 upstream.
syzbot reported a soft lockup in mptcp_recvmsg() [0].
When receiving data with MSG_PEEK | MSG_WAITALL flags, the skb is not removed from the sk_receive_queue. This causes sk_wait_data() to always find available data and never perform actual waiting, leading to a soft lockup.
Fix this by adding a 'last' parameter to track the last peeked skb. This allows sk_wait_data() to make informed waiting decisions and prevent infinite loops when MSG_PEEK is used.
[0]:
watchdog: BUG: soft lockup - CPU#2 stuck for 156s! [server:1963] Modules linked in: CPU: 2 UID: 0 PID: 1963 Comm: server Not tainted 6.19.0-rc8 #61 PREEMPT(none) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:sk_wait_data+0x15/0x190 Code: 80 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 41 56 41 55 41 54 49 89 f4 55 48 89 d5 53 48 89 fb <48> 83 ec 30 65 48 8b 05 17 a4 6b 01 48 89 44 24 28 31 c0 65 48 8b RSP: 0018:ffffc90000603ca0 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffff888102bf0800 RCX: 0000000000000001 RDX: 0000000000000000 RSI: ffffc90000603d18 RDI: ffff888102bf0800 RBP: 0000000000000000 R08: 0000000000000002 R09: 0000000000000101 R10: 0000000000000000 R11: 0000000000000075 R12: ffffc90000603d18 R13: ffff888102bf0800 R14: ffff888102bf0800 R15: 0000000000000000 FS: 00007f6e38b8c4c0(0000) GS:ffff8881b877e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055aa7bff1680 CR3: 0000000105cbe000 CR4: 00000000000006f0 Call Trace: <TASK> mptcp_recvmsg+0x547/0x8c0 net/mptcp/protocol.c:2329 inet_recvmsg+0x11f/0x130 net/ipv4/af_inet.c:891 sock_recvmsg+0x94/0xc0 net/socket.c:1100 __sys_recvfrom+0xb2/0x130 net/socket.c:2256 __x64_sys_recvfrom+0x1f/0x30 net/socket.c:2267 do_syscall_64+0x59/0x2d0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e arch/x86/entry/entry_64.S:131 RIP: 0033:0x7f6e386a4a1d Code: 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 f1 de 2c 00 41 89 ca 8b 00 85 c0 75 20 45 31 c9 45 31 c0 b8 2d 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 6b f3 c3 66 0f 1f 84 00 00 00 00 00 41 56 41 RSP: 002b:00007ffc3c4bb078 EFLAGS: 00000246 ORIG_RAX: 000000000000002d RAX: ffffffffffffffda RBX: 000000000000861e RCX: 00007f6e386a4a1d RDX: 00000000000003ff RSI: 00007ffc3c4bb150 RDI: 0000000000000004 RBP: 00007ffc3c4bb570 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000103 R11: 0000000000000246 R12: 00005605dbc00be0 R13: 00007ffc3c4bb650 R14: 0000000000000000 R15: 0000000000000000 </TASK>
[ Conflicts in protocol.c, because commit bc68b0efa1bf ("mptcp: move the
whole rx path under msk socket lock protection") and commit d88b2127b242 ("mptcp: add eat_recv_skb helper") (with some dependences) are not in this version. These conflicts were in the context, and not related to this fix. ]
--- net/mptcp/protocol.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
net/mptcp/protocol.c +8 -3
@@ -1960,7 +1960,7 @@ static int __mptcp_recvmsg_mskq(struct mstruct msghdr *msg, size_t len, int flags, int copied_total, struct scm_timestamping_internal *tss, - int *cmsg_flags) + int *cmsg_flags, struct sk_buff **last) { struct sk_buff *skb, *tmp;int total_data_len =0 ;
@@ -1976,6 +1976,7 @@ static int __mptcp_recvmsg_mskq(struct m/* skip already peeked skbs */ if (total_data_len + data_len <= copied_total) { total_data_len += data_len; + *last = skb;continue ; }
@@ -2016,6 +2017,8 @@ static int __mptcp_recvmsg_mskq(struct mWRITE_ONCE (msk->rmem_released, msk->rmem_released + skb->truesize);__skb_unlink (skb, &msk->receive_queue);__kfree_skb (skb); + }else { + *last = skb; }if (copied >= len)
@@ -2237,10 +2240,12 @@ static int mptcp_recvmsg(struct sock *sk cmsg_flags =MPTCP_CMSG_INQ ;while (copied < len) { +struct sk_buff *last =NULL ;int err, bytes_read; bytes_read =__mptcp_recvmsg_mskq (msk, msg, len - copied, flags, - copied, &tss, &cmsg_flags); + copied, &tss, &cmsg_flags, + &last);if (unlikely (bytes_read <0 )) {if (!copied) copied = bytes_read;
@@ -2298,7 +2303,7 @@ static int mptcp_recvmsg(struct sock *skpr_debug ("block timeout %ld\n" , timeo);mptcp_cleanup_rbuf (msk, copied); - err =sk_wait_data (sk, &timeo,NULL ); + err =sk_wait_data (sk, &timeo, last);if (err <0 ) { err = copied ? : err; goto out_err;
Re: [PATCH 6.6 14/50] mptcp: fix soft lockup in mptcp_recvmsg()
Hi Greg,
Quoted 2 lines · Greg Kroah-Hartman
6.6-stable review patch. If anyone has any objections, please let me know.
Sorry for the delayed reply. Please drop this patch from 6.6.y - the fix targets mptcp_recvmsg() soft lockup, but the receive queue handling differs between mainline and 6.6:
- Mainline: both MSG_PEEK data access and sk_wait_data usesk->sk_receive_queue
- 6.6.y: MSG_PEEK data access uses msk->receive_queue, while sk_wait_data
waits on sk->sk_receive_queue
This structural difference means the fix is not applicable to 6.6.y.
Note that the soft lockup issue still exists in 6.6. A different approach may be needed for this branch.
Thanks,
Li Xiasong
Quoted 121 lines
------------------
From: Li Xiasong <[email protected]>
commit
5dd8025a49c268ab6b94d978532af3ad341132a7upstream.syzbot reported a soft lockup in
mptcp_recvmsg()[0].When receiving data with
MSG_PEEK|MSG_WAITALLflags, the skb is not removed from thesk_receive_queue. This causessk_wait_data()to always find available data and never perform actual waiting, leading to a soft lockup.Fix this by adding a 'last' parameter to track the last peeked skb. This allows
sk_wait_data()to make informed waiting decisions and prevent infinite loops whenMSG_PEEKis used.[0]:
watchdog: BUG: soft lockup - CPU#2 stuck for 156s! [server:1963] Modules linked in: CPU: 2 UID: 0 PID: 1963 Comm: server Not tainted 6.19.0-rc8 #61 PREEMPT(none) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:sk_wait_data+0x15/0x190 Code: 80 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 41 56 41 55 41 54 49 89 f4 55 48 89 d5 53 48 89 fb <48> 83 ec 30 65 48 8b 05 17 a4 6b 01 48 89 44 24 28 31 c0 65 48 8b RSP: 0018:ffffc90000603ca0 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffff888102bf0800 RCX: 0000000000000001 RDX: 0000000000000000 RSI: ffffc90000603d18 RDI: ffff888102bf0800 RBP: 0000000000000000 R08: 0000000000000002 R09: 0000000000000101 R10: 0000000000000000 R11: 0000000000000075 R12: ffffc90000603d18 R13: ffff888102bf0800 R14: ffff888102bf0800 R15: 0000000000000000 FS: 00007f6e38b8c4c0(0000) GS:ffff8881b877e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055aa7bff1680 CR3: 0000000105cbe000 CR4: 00000000000006f0 Call Trace: <TASK> mptcp_recvmsg+0x547/0x8c0 net/mptcp/protocol.c:2329 inet_recvmsg+0x11f/0x130 net/ipv4/af_inet.c:891 sock_recvmsg+0x94/0xc0 net/socket.c:1100 __sys_recvfrom+0xb2/0x130 net/socket.c:2256 __x64_sys_recvfrom+0x1f/0x30 net/socket.c:2267 do_syscall_64+0x59/0x2d0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e arch/x86/entry/entry_64.S:131 RIP: 0033:0x7f6e386a4a1d Code: 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 f1 de 2c 00 41 89 ca 8b 00 85 c0 75 20 45 31 c9 45 31 c0 b8 2d 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 6b f3 c3 66 0f 1f 84 00 00 00 00 00 41 56 41 RSP: 002b:00007ffc3c4bb078 EFLAGS: 00000246 ORIG_RAX: 000000000000002d RAX: ffffffffffffffda RBX: 000000000000861e RCX: 00007f6e386a4a1d RDX: 00000000000003ff RSI: 00007ffc3c4bb150 RDI: 0000000000000004 RBP: 00007ffc3c4bb570 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000103 R11: 0000000000000246 R12: 00005605dbc00be0 R13: 00007ffc3c4bb650 R14: 0000000000000000 R15: 0000000000000000 </TASK>Fixes 8e04ce45a8db ("mptcp: fix MSG_PEEK stream corruption")Signed-off-by Li Xiasong <[email protected]>Reviewed-by Matthieu Baerts (NGI0) <[email protected]>Signed-off-by Jakub Kicinski <[email protected]>[ Conflicts in
protocol.c, because commitbc68b0efa1bf("mptcp: move the
whole rx path under msk socket lock protection") and commitd88b2127b242("mptcp: addeat_recv_skbhelper") (with some dependences) are not in this version. These conflicts were in the context, and not related to this fix. ]Signed-off-by Matthieu Baerts (NGI0) <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- net/mptcp/protocol.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)net/mptcp/protocol.c +8
-3@@ -1960,7 +1960,7 @@ static int __mptcp_recvmsg_mskq(struct mstruct msghdr *msg, size_t len, int flags, int copied_total, struct scm_timestamping_internal *tss, - int *cmsg_flags) + int *cmsg_flags, struct sk_buff **last) { struct sk_buff *skb, *tmp;int total_data_len =0 ;@@ -1976,6 +1976,7 @@ static int __mptcp_recvmsg_mskq(struct m/* skip already peeked skbs */ if (total_data_len + data_len <= copied_total) { total_data_len += data_len; + *last = skb;continue ; }@@ -2016,6 +2017,8 @@ static int __mptcp_recvmsg_mskq(struct mWRITE_ONCE (msk->rmem_released, msk->rmem_released + skb->truesize);__skb_unlink (skb, &msk->receive_queue);__kfree_skb (skb); + }else { + *last = skb; }if (copied >= len)@@ -2237,10 +2240,12 @@ static int mptcp_recvmsg(struct sock *sk cmsg_flags =MPTCP_CMSG_INQ ;while (copied < len) { +struct sk_buff *last =NULL ;int err, bytes_read; bytes_read =__mptcp_recvmsg_mskq (msk, msg, len - copied, flags, - copied, &tss, &cmsg_flags); + copied, &tss, &cmsg_flags, + &last);if (unlikely (bytes_read <0 )) {if (!copied) copied = bytes_read;@@ -2298,7 +2303,7 @@ static int mptcp_recvmsg(struct sock *skpr_debug ("block timeout %ld\n" , timeo);mptcp_cleanup_rbuf (msk, copied); - err =sk_wait_data (sk, &timeo,NULL ); + err =sk_wait_data (sk, &timeo, last);if (err <0 ) { err = copied ? : err; goto out_err;
Sasha Levin
maintainerRe: [PATCH 6.6 14/50] mptcp: fix soft lockup in mptcp_recvmsg()
Quoted 3 lines · Li Xiasong
Please drop this patch from 6.6.y - the fix targets
mptcp_recvmsg()soft lockup, but the receive queue handling differs between mainline and 6.6.
Dropped from the 6.6 and 6.12 queues, thanks.
Re: [PATCH 6.12 28/70] mptcp: fix soft lockup in mptcp_recvmsg()
In reply to Li XiasongHi, Xiasong
Could you share how to reproduce the issue?
I used the following code to reproduce it, and do the test in v6.18.32. but the test results are the same with and without the fix(I revert the commit 58b58b9ba89c43914eea90c18928e51852d10c24). The client task will be waked up after 10 minutes. There is not soft lockup.
client.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define IPPROTO_MPTCP 262
#define PORT 9999
int main(void) {
int fd;
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(PORT),
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
};
fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
if (fd < 0) {
perror("socket");
return 1;
}
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("connect");
return 1;
}
printf("Connected. Calling recv(MSG_PEEK | MSG_WAITALL)...\n");
printf("On vulnerable 6.6 kernel, this will soft lockup a CPU.\n");
printf("Monitor with: dmesg -w\n\n");
/*
* BUG TRIGGER: MSG_PEEK | MSG_WAITALL
*
* - MSG_PEEK: don't remove skb from receive queue
* - MSG_WAITALL: wait until buffer is full (1024 bytes)
* - Server only sent 512 bytes
*
* Result on vulnerable kernel:
* sk_wait_data() sees data (512 bytes still in queue due to PEEK)
* → returns immediately → mptcp_recvmsg loops → never waits
* → infinite loop → soft lockup
*
* Fix: pass 'last' skb to sk_wait_data() so it knows
* no NEW data arrived and actually sleeps.
*/
char buf[1024];
int ret = recv(fd, buf, sizeof(buf), MSG_PEEK | MSG_WAITALL);
/* On patched kernel, this eventually returns or times out */
printf("recv returned %d (kernel is patched or not vulnerable)\n", ret);
close(fd);
return 0;
}server.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define IPPROTO_MPTCP 262
#define PORT 9999
int main(void) {
int sfd, cfd;
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(PORT),
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
};
sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
if (sfd < 0) {
perror("socket (try IPPROTO_TCP if MPTCP unavailable)");
return 1;
}
int opt = 1;
setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bind(sfd, (struct sockaddr *)&addr, sizeof(addr));
listen(sfd, 1);
printf("Server listening on port %d...\n", PORT);
cfd = accept(sfd, NULL, NULL);
printf("Client connected.\n");
/* Send data so client has something to peek */
char buf[512];
memset(buf, 'A', sizeof(buf));
write(cfd, buf, sizeof(buf));
printf("Sent %zu bytes. Keeping connection open...\n", sizeof(buf));
/* Keep alive */
sleep(600);
close(cfd);
close(sfd);
return 0;
}Thanks,
Jiping
Re: [PATCH 6.12 28/70] mptcp: fix soft lockup in mptcp_recvmsg()
Hi, Jiping
Quoted 6 lines · Jiping Ma
Hi, Xiasong
Could you share how to reproduce the issue?
I used the following code to reproduce it, and do the test in v6.18.32. but the test results are the same with and without the fix(I revert the commit58b58b9ba89c43914eea90c18928e51852d10c24). The client task will be waked up after 10 minutes. There is not soft lockup.
Thanks for sharing the reproducer.
Your test program itself looks fine to me, and I can reproduce the issue with the reproducer you provided in my test environment.[0]
I think the reproduction result depends on the kernel preemption model. The issue is easier to trigger with a non-preemptible kernel (e.g. PREEMPT_NONE). On other preemption configurations, it may be harder to reproduce, but the program can still be observed consuming nearly 100% system CPU. So the same test can show different behavior under different CONFIG_PREEMPT* settings.
Also, if you want to reproduce this on 6.6.y or 6.12.y, based on the previous analysis, have the sender transmit two packets with an interval between them.
Hope this helps.
[0] Relevant dmesg log:
Linux ubuntu 6.18.32+ #15 SMP PREEMPT_DYNAMIC Wed May 27 15:25:52 CST 2026 x86_64 x86_64 x86_64 GNU/Linux
root@ubuntu:~# [ 960.743413] watchdog: BUG: soft lockup - CPU#5 stuck for 261s! [client:1260] [ 960.743433] Modules linked in: [ 960.743463] CPU: 5 UID: 0 PID: 1260 Comm: client Not tainted 6.18.32+ #15 PREEMPT(none) [ 960.743469] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 [ 960.743474] RIP: 0010:_raw_spin_lock_bh+0x1b/0x60 [ 960.743518] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 65 81 05 d0 a2 a1 01 01 02 00 00 31 c0 ba 01 00 00 00 f0 0f b1 17 <75> 1b 31 c0 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 [ 960.743521] RSP: 0018:ffffc9000259fb08 EFLAGS: 00000246 [ 960.743524] RAX: 0000000000000000 RBX: ffff888106efc480 RCX: 0000000000000000 [ 960.743529] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff888106efc5c0 [ 960.743531] RBP: ffffc9000259fb68 R08: 0000000000000000 R09: 0000000000000000 [ 960.743533] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 [ 960.743535] R13: ffff888106efc5c0 R14: ffff888106efc528 R15: 0000000000000000 [ 960.743537] FS: 000079482a7b7740(0000) GS:ffff8881b70e7000(0000) knlGS:0000000000000000 [ 960.743540] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 960.743542] CR2: 00005a8d794c3008 CR3: 00000001033ea000 CR4: 00000000000006f0 [ 960.743547] Call Trace: [ 960.743550] <TASK> [ 960.743552] ? sk_wait_data+0xc2/0x1a0 [ 960.743564] ? __pfx_woken_wake_function+0x10/0x10 [ 960.743571] mptcp_recvmsg+0x623/0x9a0 [ 960.743578] ? __wake_up+0x45/0x70 [ 960.743582] inet_recvmsg+0x124/0x130 [ 960.743588] ? apparmor_socket_recvmsg+0x25/0x40 [ 960.743595] ? security_socket_recvmsg+0x1a9/0x1d0 [ 960.743602] sock_recvmsg+0xb7/0xc0 [ 960.743608] __sys_recvfrom+0xd2/0x170 [ 960.743612] ? ksys_write+0x69/0xf0 [ 960.743618] ? __x64_sys_write+0x19/0x30 [ 960.743622] ? x64_sys_call+0x18fc/0x2760 [ 960.743628] ? do_syscall_64+0xb8/0x1300 [ 960.743635] ? do_syscall_64+0xb8/0x1300 [ 960.743640] __x64_sys_recvfrom+0x24/0x40 [ 960.743642] x64_sys_call+0x2694/0x2760 [ 960.743646] do_syscall_64+0x80/0x1300 [ 960.743650] ? count_memcg_events+0xed/0x1e0 [ 960.743655] ? handle_mm_fault+0x210/0x2f0 [ 960.743661] ? do_user_addr_fault+0x300/0x8d0 [ 960.743666] ? irqentry_exit_to_user_mode+0x2e/0x330 [ 960.743670] ? irqentry_exit+0x43/0x50 [ 960.743672] ? exc_page_fault+0x93/0x1b0 [ 960.743675] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 960.743678] RIP: 0033:0x79482a49eba6 [ 960.743691] Code: 00 00 48 8b 15 53 12 17 00 64 89 02 48 c7 c2 ff ff ff ff 48 8b 5d f8 c9 48 89 d0 c3 0f 1f 84 00 00 00 00 00 48 8b 45 10 0f 05 <48> 63 d0 3d 00 f0 ff ff 77 10 48 8b 5d f8 48 89 d0 c9 c3 0f 1f 80 [ 960.743693] RSP: 002b:00007ffd26c7bdc0 EFLAGS: 00000202 ORIG_RAX: 000000000000002d [ 960.743696] RAX: ffffffffffffffda RBX: 000079482a7b7740 RCX: 000079482a49eba6 [ 960.743698] RDX: 0000000000000400 RSI: 00007ffd26c7be20 RDI: 0000000000000003 [ 960.743699] RBP: 00007ffd26c7bdd0 R08: 0000000000000000 R09: 0000000000000000 [ 960.743701] R10: 0000000000000102 R11: 0000000000000202 R12: 0000000000000001 [ 960.743702] R13: 0000000000000000 R14: 00005a8d75ae6d78 R15: 000079482a806000 [ 960.743707] </TASK>
Quoted 109 lines
client.c#include <
stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define
IPPROTO_MPTCP262
#define PORT 9999int main(void) { int fd; struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = htonl(INADDR_LOOPBACK), }; fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); if (fd < 0) { perror("socket"); return 1; } if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("connect"); return 1; } printf("Connected. Calling recv(MSG_PEEK | MSG_WAITALL)...\n"); printf("On vulnerable 6.6 kernel, this will soft lockup a CPU.\n"); printf("Monitor with: dmesg -w\n\n"); /* * BUG TRIGGER: MSG_PEEK | MSG_WAITALL * * - MSG_PEEK: don't remove skb from receive queue * - MSG_WAITALL: wait until buffer is full (1024 bytes) * - Server only sent 512 bytes * * Result on vulnerable kernel: * sk_wait_data() sees data (512 bytes still in queue due to PEEK) * → returns immediately → mptcp_recvmsg loops → never waits * → infinite loop → soft lockup * * Fix: pass 'last' skb to sk_wait_data() so it knows * no NEW data arrived and actually sleeps. */ char buf[1024]; int ret = recv(fd, buf, sizeof(buf), MSG_PEEK | MSG_WAITALL); /* On patched kernel, this eventually returns or times out */ printf("recv returned %d (kernel is patched or not vulnerable)\n", ret); close(fd); return 0; }
server.c#include <
stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define
IPPROTO_MPTCP262
#define PORT 9999int main(void) { int sfd, cfd; struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = htonl(INADDR_LOOPBACK), }; sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); if (sfd < 0) { perror("socket (try IPPROTO_TCP if MPTCP unavailable)"); return 1; } int opt = 1; setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); bind(sfd, (struct sockaddr *)&addr, sizeof(addr)); listen(sfd, 1); printf("Server listening on port %d...\n", PORT); cfd = accept(sfd, NULL, NULL); printf("Client connected.\n"); /* Send data so client has something to peek */ char buf[512]; memset(buf, 'A', sizeof(buf)); write(cfd, buf, sizeof(buf)); printf("Sent %zu bytes. Keeping connection open...\n", sizeof(buf)); /* Keep alive */ sleep(600); close(cfd); close(sfd); return 0; }Thanks,
Jiping
Re: [PATCH 6.12 28/70] mptcp: fix soft lockup in mptcp_recvmsg()
Hi,
One clarification to my previous email:
The v6.18.32 kernel used in my test was built with commit 58b58b9ba89c ("mptcp: fix soft lockup in mptcp_recvmsg()") reverted. So the reproduction result I reported for v6.18.32 is based on a kernel without that patch.
Regards,
Li Xiasong
Quoted 80 lines · Li Xiasong
Hi, Jiping
Quoted 6 lines · Jiping Ma
Hi, Xiasong
Could you share how to reproduce the issue?
I used the following code to reproduce it, and do the test in v6.18.32. but the test results are the same with and without the fix(I revert the commit58b58b9ba89c43914eea90c18928e51852d10c24). The client task will be waked up after 10 minutes. There is not soft lockup.Thanks for sharing the reproducer.
Your test program itself looks fine to me, and I can reproduce the issue with the reproducer you provided in my test environment.[0]
I think the reproduction result depends on the kernel preemption model. The issue is easier to trigger with a non-preemptible kernel (e.g.
PREEMPT_NONE). On other preemption configurations, it may be harder to reproduce, but the program can still be observed consuming nearly 100% system CPU. So the same test can show different behavior under differentCONFIG_PREEMPT*settings.Also, if you want to reproduce this on
6.6.yor6.12.y, based on the previous analysis, have the sender transmit two packets with an interval between them.Hope this helps.
[0] Relevant dmesg log:
Linux ubuntu 6.18.32+ #15 SMPPREEMPT_DYNAMICWed May 27 15:25:52 CST 2026x86_64x86_64x86_64GNU/Linuxroot@ubuntu:~# [ 960.743413] watchdog: BUG: soft lockup - CPU#5 stuck for 261s! [client:1260] [ 960.743433] Modules linked in: [ 960.743463] CPU: 5 UID: 0 PID: 1260 Comm: client Not tainted 6.18.32+ #15 PREEMPT(none) [ 960.743469] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 [ 960.743474] RIP: 0010:_raw_spin_lock_bh+0x1b/0x60 [ 960.743518] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 65 81 05 d0 a2 a1 01 01 02 00 00 31 c0 ba 01 00 00 00 f0 0f b1 17 <75> 1b 31 c0 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 [ 960.743521] RSP: 0018:ffffc9000259fb08 EFLAGS: 00000246 [ 960.743524] RAX: 0000000000000000 RBX: ffff888106efc480 RCX: 0000000000000000 [ 960.743529] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff888106efc5c0 [ 960.743531] RBP: ffffc9000259fb68 R08: 0000000000000000 R09: 0000000000000000 [ 960.743533] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 [ 960.743535] R13: ffff888106efc5c0 R14: ffff888106efc528 R15: 0000000000000000 [ 960.743537] FS: 000079482a7b7740(0000) GS:ffff8881b70e7000(0000) knlGS:0000000000000000 [ 960.743540] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 960.743542] CR2: 00005a8d794c3008 CR3: 00000001033ea000 CR4: 00000000000006f0 [ 960.743547] Call Trace: [ 960.743550] <TASK> [ 960.743552] ? sk_wait_data+0xc2/0x1a0 [ 960.743564] ? __pfx_woken_wake_function+0x10/0x10 [ 960.743571] mptcp_recvmsg+0x623/0x9a0 [ 960.743578] ? __wake_up+0x45/0x70 [ 960.743582] inet_recvmsg+0x124/0x130 [ 960.743588] ? apparmor_socket_recvmsg+0x25/0x40 [ 960.743595] ? security_socket_recvmsg+0x1a9/0x1d0 [ 960.743602] sock_recvmsg+0xb7/0xc0 [ 960.743608] __sys_recvfrom+0xd2/0x170 [ 960.743612] ? ksys_write+0x69/0xf0 [ 960.743618] ? __x64_sys_write+0x19/0x30 [ 960.743622] ? x64_sys_call+0x18fc/0x2760 [ 960.743628] ? do_syscall_64+0xb8/0x1300 [ 960.743635] ? do_syscall_64+0xb8/0x1300 [ 960.743640] __x64_sys_recvfrom+0x24/0x40 [ 960.743642] x64_sys_call+0x2694/0x2760 [ 960.743646] do_syscall_64+0x80/0x1300 [ 960.743650] ? count_memcg_events+0xed/0x1e0 [ 960.743655] ? handle_mm_fault+0x210/0x2f0 [ 960.743661] ? do_user_addr_fault+0x300/0x8d0 [ 960.743666] ? irqentry_exit_to_user_mode+0x2e/0x330 [ 960.743670] ? irqentry_exit+0x43/0x50 [ 960.743672] ? exc_page_fault+0x93/0x1b0 [ 960.743675] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 960.743678] RIP: 0033:0x79482a49eba6 [ 960.743691] Code: 00 00 48 8b 15 53 12 17 00 64 89 02 48 c7 c2 ff ff ff ff 48 8b 5d f8 c9 48 89 d0 c3 0f 1f 84 00 00 00 00 00 48 8b 45 10 0f 05 <48> 63 d0 3d 00 f0 ff ff 77 10 48 8b 5d f8 48 89 d0 c9 c3 0f 1f 80 [ 960.743693] RSP: 002b:00007ffd26c7bdc0 EFLAGS: 00000202 ORIG_RAX: 000000000000002d [ 960.743696] RAX: ffffffffffffffda RBX: 000079482a7b7740 RCX: 000079482a49eba6 [ 960.743698] RDX: 0000000000000400 RSI: 00007ffd26c7be20 RDI: 0000000000000003 [ 960.743699] RBP: 00007ffd26c7bdd0 R08: 0000000000000000 R09: 0000000000000000 [ 960.743701] R10: 0000000000000102 R11: 0000000000000202 R12: 0000000000000001 [ 960.743702] R13: 0000000000000000 R14: 00005a8d75ae6d78 R15: 000079482a806000 [ 960.743707] </TASK>
Re: [PATCH 6.12 28/70] mptcp: fix soft lockup in mptcp_recvmsg()
Thanks for your share info.
After enabling mptcp_recvmsg with dynamic_debug, I observed an infinite stream of logs:
"MPTCP: block timeout 9223372036854775807" on kernel v6.18.32 (without the fix).
In contrast, on Linux 6.12 and 6.6, the same setup only produces two such log lines, not an infinite loop. which matches the behavior seen on v6.18.32. This indicates that the issue does not exist in Linux 6.6 and 6.12,
Thanks,
Jiping
Quoted 169 lines
Also, if you want to reproduce this on
6.6.yor6.12.y, based on the previous analysis, have the sender transmit two packets with an interval between them.Hope this helps.
[0] Relevant dmesg log:
Linux ubuntu 6.18.32+ #15 SMPPREEMPT_DYNAMICWed May 27 15:25:52 CST 2026x86_64x86_64x86_64GNU/Linuxroot@ubuntu:~# [ 960.743413] watchdog: BUG: soft lockup - CPU#5 stuck for 261s! [client:1260] [ 960.743433] Modules linked in: [ 960.743463] CPU: 5 UID: 0 PID: 1260 Comm: client Not tainted 6.18.32+ #15 PREEMPT(none) [ 960.743469] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 [ 960.743474] RIP: 0010:_raw_spin_lock_bh+0x1b/0x60 [ 960.743518] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 65 81 05 d0 a2 a1 01 01 02 00 00 31 c0 ba 01 00 00 00 f0 0f b1 17 <75> 1b 31 c0 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 45 [ 960.743521] RSP: 0018:ffffc9000259fb08 EFLAGS: 00000246 [ 960.743524] RAX: 0000000000000000 RBX: ffff888106efc480 RCX: 0000000000000000 [ 960.743529] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff888106efc5c0 [ 960.743531] RBP: ffffc9000259fb68 R08: 0000000000000000 R09: 0000000000000000 [ 960.743533] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 [ 960.743535] R13: ffff888106efc5c0 R14: ffff888106efc528 R15: 0000000000000000 [ 960.743537] FS: 000079482a7b7740(0000) GS:ffff8881b70e7000(0000) knlGS:0000000000000000 [ 960.743540] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 960.743542] CR2: 00005a8d794c3008 CR3: 00000001033ea000 CR4: 00000000000006f0 [ 960.743547] Call Trace: [ 960.743550] <TASK> [ 960.743552] ? sk_wait_data+0xc2/0x1a0 [ 960.743564] ? __pfx_woken_wake_function+0x10/0x10 [ 960.743571] mptcp_recvmsg+0x623/0x9a0 [ 960.743578] ? __wake_up+0x45/0x70 [ 960.743582] inet_recvmsg+0x124/0x130 [ 960.743588] ? apparmor_socket_recvmsg+0x25/0x40 [ 960.743595] ? security_socket_recvmsg+0x1a9/0x1d0 [ 960.743602] sock_recvmsg+0xb7/0xc0 [ 960.743608] __sys_recvfrom+0xd2/0x170 [ 960.743612] ? ksys_write+0x69/0xf0 [ 960.743618] ? __x64_sys_write+0x19/0x30 [ 960.743622] ? x64_sys_call+0x18fc/0x2760 [ 960.743628] ? do_syscall_64+0xb8/0x1300 [ 960.743635] ? do_syscall_64+0xb8/0x1300 [ 960.743640] __x64_sys_recvfrom+0x24/0x40 [ 960.743642] x64_sys_call+0x2694/0x2760 [ 960.743646] do_syscall_64+0x80/0x1300 [ 960.743650] ? count_memcg_events+0xed/0x1e0 [ 960.743655] ? handle_mm_fault+0x210/0x2f0 [ 960.743661] ? do_user_addr_fault+0x300/0x8d0 [ 960.743666] ? irqentry_exit_to_user_mode+0x2e/0x330 [ 960.743670] ? irqentry_exit+0x43/0x50 [ 960.743672] ? exc_page_fault+0x93/0x1b0 [ 960.743675] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 960.743678] RIP: 0033:0x79482a49eba6 [ 960.743691] Code: 00 00 48 8b 15 53 12 17 00 64 89 02 48 c7 c2 ff ff ff ff 48 8b 5d f8 c9 48 89 d0 c3 0f 1f 84 00 00 00 00 00 48 8b 45 10 0f 05 <48> 63 d0 3d 00 f0 ff ff 77 10 48 8b 5d f8 48 89 d0 c9 c3 0f 1f 80 [ 960.743693] RSP: 002b:00007ffd26c7bdc0 EFLAGS: 00000202 ORIG_RAX: 000000000000002d [ 960.743696] RAX: ffffffffffffffda RBX: 000079482a7b7740 RCX: 000079482a49eba6 [ 960.743698] RDX: 0000000000000400 RSI: 00007ffd26c7be20 RDI: 0000000000000003 [ 960.743699] RBP: 00007ffd26c7bdd0 R08: 0000000000000000 R09: 0000000000000000 [ 960.743701] R10: 0000000000000102 R11: 0000000000000202 R12: 0000000000000001 [ 960.743702] R13: 0000000000000000 R14: 00005a8d75ae6d78 R15: 000079482a806000 [ 960.743707] </TASK>Quoted 109 lines
client.c#include <
stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define
IPPROTO_MPTCP262
#define PORT 9999int main(void) { int fd; struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = htonl(INADDR_LOOPBACK), }; fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); if (fd < 0) { perror("socket"); return 1; } if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("connect"); return 1; } printf("Connected. Calling recv(MSG_PEEK | MSG_WAITALL)...\n"); printf("On vulnerable 6.6 kernel, this will soft lockup a CPU.\n"); printf("Monitor with: dmesg -w\n\n"); /* * BUG TRIGGER: MSG_PEEK | MSG_WAITALL * * - MSG_PEEK: don't remove skb from receive queue * - MSG_WAITALL: wait until buffer is full (1024 bytes) * - Server only sent 512 bytes * * Result on vulnerable kernel: * sk_wait_data() sees data (512 bytes still in queue due to PEEK) * → returns immediately → mptcp_recvmsg loops → never waits * → infinite loop → soft lockup * * Fix: pass 'last' skb to sk_wait_data() so it knows * no NEW data arrived and actually sleeps. */ char buf[1024]; int ret = recv(fd, buf, sizeof(buf), MSG_PEEK | MSG_WAITALL); /* On patched kernel, this eventually returns or times out */ printf("recv returned %d (kernel is patched or not vulnerable)\n", ret); close(fd); return 0; }
server.c#include <
stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define
IPPROTO_MPTCP262
#define PORT 9999int main(void) { int sfd, cfd; struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = htonl(INADDR_LOOPBACK), }; sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); if (sfd < 0) { perror("socket (try IPPROTO_TCP if MPTCP unavailable)"); return 1; } int opt = 1; setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); bind(sfd, (struct sockaddr *)&addr, sizeof(addr)); listen(sfd, 1); printf("Server listening on port %d...\n", PORT); cfd = accept(sfd, NULL, NULL); printf("Client connected.\n"); /* Send data so client has something to peek */ char buf[512]; memset(buf, 'A', sizeof(buf)); write(cfd, buf, sizeof(buf)); printf("Sent %zu bytes. Keeping connection open...\n", sizeof(buf)); /* Keep alive */ sleep(600); close(cfd); close(sfd); return 0; }Thanks,
Jiping
Greg Kroah-Hartman
maintainerPATCH 15/50 usb: gadget: f_hid: move list and spinlock inits from bind to alloc
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Zimmermann <[email protected]>
[ Upstream commit 4e0a88254ad59f6c53a34bf5fa241884ec09e8b2 ]
There was an issue when you did the following:
- setup and bind an hid gadget
- open /dev/hidg0
- use the resulting fd in EPOLL_CTL_ADD
- unbind the UDC
- bind the UDC
- use the fd in EPOLL_CTL_DEL
When CONFIG_DEBUG_LIST was enabled, a list_del corruption was reported within remove_wait_queue (via ep_remove_wait_queue). After some debugging I found out that the queues, which f_hid registers via poll_wait were the problem. These were initialized using init_waitqueue_head inside hidg_bind. So effectively, the bind function re-initialized the queues while there were still items in them.
The solution is to move the initialization from hidg_bind to hidg_alloc to extend their lifetimes to the lifetime of the function instance.
Additionally, I found many other possibly problematic init calls in the bind function, which I moved as well.
--- drivers/usb/gadget/function/f_hid.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/usb/gadget/function/f_hid.c +6 -5
@@ -1000,13 +1000,8 @@ static int hidg_bind(struct usb_configurif (status) goto fail; -spin_lock_init (&hidg->write_spinlock); hidg->write_pending =1 ; hidg->req =NULL ; -spin_lock_init (&hidg->read_spinlock); -init_waitqueue_head (&hidg->write_queue); -init_waitqueue_head (&hidg->read_queue); -INIT_LIST_HEAD (&hidg->completed_out_req);/* create char device */ cdev_init (&hidg->cdev, &f_hidg_fops);
@@ -1275,6 +1270,12 @@ static struct usb_function *hidg_alloc(smutex_lock (&opts->lock); +spin_lock_init (&hidg->write_spinlock); +spin_lock_init (&hidg->read_spinlock); +init_waitqueue_head (&hidg->write_queue); +init_waitqueue_head (&hidg->read_queue); +INIT_LIST_HEAD (&hidg->completed_out_req); +device_initialize (&hidg->dev); hidg->dev.release = hidg_release; hidg->dev.class = &hidg_class;
Greg Kroah-Hartman
maintainerPATCH 16/50 Revert "mptcp: add needs_id for netlink appending addr"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 8e2760eaab778494fc1fa257031e0e1799647f46 ]
This commit was originally adding the ability to add MPTCP endpoints with ID 0 by accident. The in-kernel PM, handling MPTCP endpoints at the net namespace level, is not supposed to handle endpoints with such ID, because this ID 0 is reserved to the initial subflow, as mentioned in the MPTCPv1 protocol [1], a per-connection setting.
Note that 'ip mptcp endpoint add id 0' stops early with an error, but other tools might still request the in-kernel PM to create MPTCP endpoints with this restricted ID 0.
In other words, it was wrong to call the mptcp_pm_has_addr_attr_id helper to check whether the address ID attribute is set: if it was set to 0, a new MPTCP endpoint would be created with ID 0, which is not expected, and might cause various issues later.
--- net/mptcp/pm_netlink.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-)
net/mptcp/pm_netlink.c +5 -19
@@ -1079,7 +1079,7 @@ static void __mptcp_pm_release_addr_entrstatic int mptcp_pm_nl_append_new_local_addr (struct pm_nl_pernet *pernet,struct mptcp_pm_addr_entry *entry, -bool needs_id,bool replace) +bool replace) {struct mptcp_pm_addr_entry *cur, *del_entry =NULL ;unsigned int addr_max;
@@ -1138,7 +1138,7 @@ static int mptcp_pm_nl_append_new_local_ } } -if (!entry->addr.id && needs_id) { +if (!entry->addr.id) { find_next: entry->addr.id = find_next_zero_bit(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1,
@@ -1149,7 +1149,7 @@ find_next: } } -if (!entry->addr.id && needs_id) +if (!entry->addr.id) goto out;__set_bit (entry->addr.id, pernet->id_bitmap);
@@ -1282,7 +1282,7 @@ int mptcp_pm_nl_get_local_id(struct mptc entry->ifindex =0 ; entry->flags =MPTCP_PM_ADDR_FLAG_IMPLICIT ; entry->lsk =NULL ; - ret =mptcp_pm_nl_append_new_local_addr (pernet, entry, true, false); + ret =mptcp_pm_nl_append_new_local_addr (pernet, entry, false);if (ret <0 )kfree (entry);
@@ -1524,18 +1524,6 @@ next:return 0 ; } -static bool mptcp_pm_has_addr_attr_id (const struct nlattr *attr, -struct genl_info *info) -{ -struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX +1 ]; - -if (!nla_parse_nested_deprecated (tb,MPTCP_PM_ADDR_ATTR_MAX , attr, - mptcp_pm_addr_policy, info->extack) && - tb[MPTCP_PM_ADDR_ATTR_ID ]) -return true; -return false; -} -static int mptcp_nl_cmd_add_addr (struct sk_buff *skb,struct genl_info *info) {struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR ];
@@ -1577,9 +1565,7 @@ static int mptcp_nl_cmd_add_addr(struct goto out_free; } } - ret =mptcp_pm_nl_append_new_local_addr (pernet, entry, - !mptcp_pm_has_addr_attr_id (attr, info), - true); + ret =mptcp_pm_nl_append_new_local_addr (pernet, entry, true);if (ret <0 ) {GENL_SET_ERR_MSG_FMT (info,"too many addresses or duplicate one: %d" , ret); goto out_free;
Greg Kroah-Hartman
maintainerPATCH 17/50 seg6: separate dst_cache for input and output paths in seg6 lwtunnel
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Mayer <[email protected]>
[ Upstream commit c3812651b522fe8437ebb7063b75ddb95b571643 ]
The seg6 lwtunnel uses a single dst_cache per encap route, shared between seg6_input_core() and seg6_output_core(). These two paths can perform the post-encap SID lookup in different routing contexts (e.g., ip rules matching on the ingress interface, or VRF table separation). Whichever path runs first populates the cache, and the other reuses it blindly, bypassing its own lookup.
Fix this by splitting the cache into cache_input and cache_output, so each path maintains its own cached dst independently.
--- net/ipv6/seg6_iptunnel.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-)
net/ipv6/seg6_iptunnel.c +28 -13
@@ -48,7 +48,8 @@ static size_t seg6_lwt_headroom(struct s }struct seg6_lwt { -struct dst_cache cache; +struct dst_cache cache_input; +struct dst_cache cache_output;struct seg6_iptunnel_encap tuninfo[]; };
@@ -486,7 +487,7 @@ static int seg6_input_core(struct net *n slwt =seg6_lwt_lwtunnel (lwtst);local_bh_disable (); - dst =dst_cache_get (&slwt->cache); + dst =dst_cache_get (&slwt->cache_input);local_bh_enable (); err =seg6_do_srh (skb, dst);
@@ -500,7 +501,7 @@ static int seg6_input_core(struct net *n/* cache only if we don't create a dst reference loop */ if (!dst->error && lwtst != dst->lwtstate) {local_bh_disable (); -dst_cache_set_ip6 (&slwt->cache, dst, +dst_cache_set_ip6 (&slwt->cache_input, dst, &ipv6_hdr (skb)->saddr);local_bh_enable (); }
@@ -560,7 +561,7 @@ static int seg6_output_core(struct net * slwt =seg6_lwt_lwtunnel (orig_dst->lwtstate);local_bh_disable (); - dst =dst_cache_get (&slwt->cache); + dst =dst_cache_get (&slwt->cache_output);local_bh_enable (); err =seg6_do_srh (skb, dst);
@@ -585,9 +586,12 @@ static int seg6_output_core(struct net * goto drop; } -local_bh_disable (); -dst_cache_set_ip6 (&slwt->cache, dst, &fl6.saddr); -local_bh_enable (); +/* cache only if we don't create a dst reference loop */ +if (orig_dst->lwtstate != dst->lwtstate) { +local_bh_disable (); +dst_cache_set_ip6 (&slwt->cache_output, dst, &fl6.saddr); +local_bh_enable (); + } err =skb_cow_head (skb,LL_RESERVED_SPACE (dst->dev));if (unlikely (err))
@@ -694,11 +698,13 @@ static int seg6_build_state(struct net * slwt =seg6_lwt_lwtunnel (newts); - err =dst_cache_init (&slwt->cache,GFP_ATOMIC ); -if (err) { -kfree (newts); -return err; - } + err =dst_cache_init (&slwt->cache_input,GFP_ATOMIC ); +if (err) + goto err_free_newts; + + err =dst_cache_init (&slwt->cache_output,GFP_ATOMIC ); +if (err) + goto err_destroy_input;memcpy (&slwt->tuninfo, tuninfo, tuninfo_len);
@@ -713,11 +719,20 @@ static int seg6_build_state(struct net * *ts = newts;return 0 ; + +err_destroy_input: +dst_cache_destroy (&slwt->cache_input); +err_free_newts: +kfree (newts); +return err; }static void seg6_destroy_state (struct lwtunnel_state *lwt) { -dst_cache_destroy (&seg6_lwt_lwtunnel (lwt)->cache); +struct seg6_lwt *slwt =seg6_lwt_lwtunnel (lwt); + +dst_cache_destroy (&slwt->cache_input); +dst_cache_destroy (&slwt->cache_output); } static int seg6_fill_encap_info(struct sk_buff *skb,
Greg Kroah-Hartman
maintainerPATCH 18/50 netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 07ace0bbe03b3d8e85869af1dec5e4087b1d57b8 upstream
pipapo relies on kmalloc(0) returning ZERO_SIZE_PTR (i.e., not NULL but pointer is invalid).
Rework this to not call slab allocator when we'd request a 0-byte allocation.
[Keerthana: In older stable branches (v6.6 and earlier), the allocation logic in pipapo_clone() still relies on src->rules rather than src->rules_alloc (introduced in v6.9 via 9f439bd6ef4f). Consequently, the previously backported INT_MAX clamping check uses src->rules. This patch correctly moves that src->rules > (INT_MAX / ...) check inside the newif (src->rules > 0) block]
--- net/netfilter/nft_set_pipapo.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
net/netfilter/nft_set_pipapo.c +14 -6
@@ -525,6 +525,8 @@ static struct nft_pipapo_elem *pipapo_geint i; m = priv->clone; +if (m->bsize_max ==0 ) +return ret; res_map =kmalloc_array (m->bsize_max,sizeof (*res_map),GFP_ATOMIC );if (!res_map) {
@@ -1394,14 +1396,20 @@ static struct nft_pipapo_match *pipapo_c src->bsize *sizeof (*dst->lt) * src->groups * NFT_PIPAPO_BUCKETS(src->bb)); -if (src->rules > (INT_MAX /sizeof (*src->mt))) - goto out_mt; +if (src->rules >0 ) { +if (src->rules > (INT_MAX /sizeof (*src->mt))) + goto out_mt; + + dst->mt =kvmalloc_array (src->rules,sizeof (*src->mt), +GFP_KERNEL ); +if (!dst->mt) + goto out_mt; - dst->mt =kvmalloc (src->rules *sizeof (*src->mt),GFP_KERNEL_ACCOUNT ); -if (!dst->mt) - goto out_mt; +memcpy (dst->mt, src->mt, src->rules *sizeof (*src->mt)); + }else { + dst->mt =NULL ; + } -memcpy (dst->mt, src->mt, src->rules *sizeof (*src->mt)); src++; dst++; }
Greg Kroah-Hartman
maintainerPATCH 19/50 Revert "drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maarten Lankhorst <[email protected]>
commit 45ebe43ea00d6b9f5b3e0db9c35b8ca2a96b7e70 upstream.
This reverts commit 6bee098b91417654703e17eb5c1822c6dfd0c01d.
Den 2026-03-25 kl. 22:11, skrev Simona Vetter:
Quoted 96 lines · Guenter Roeck
Quoted 8 lines
Hi,
Quoted 5 lines · Maarten Lankhorst
When trying to do a rather aggressive test of igt's "
xe_module_load--r reload" with a full desktop environment and game running I noticed a few OOPSes when dereferencing freed pointers, related to framebuffers and property blobs after the compositor exits.Quoted 7 lines
Quoted 4 lines
Solve this by guarding the freeing in
drm_filewith drm_dev_enter/exit, and immediately put the references from structdrm_fileobjects duringdrm_dev_unplug().With this patch in v6.18.20, I get the warning backtraces below. The backtraces are gone with the patch reverted.
Yeah, this needs to be reverted, reasoning below. Maarten, can you please take care of that and feed the revert through the usual channels? I don't think it's critical enough that we need to fast-track this into drm.git directly.
Quoting the patch here again:
Quoted 17 lines
drivers/gpu/drm/drm_file.c| 5 ++++- drivers/gpu/drm/drm_mode_config.c | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-)drivers/gpu/drm/drm_file.c +1
-0@@ -233,6 +233,7 @@ static void drm_events_release(struct drm_file *file_priv)void drm_file_free (struct drm_file *file) {struct drm_device *dev; +int idx;if (!file)return ;drivers/gpu/drm/drm_file.c void drm_file_free(struct drm_file *file) · line 254
Quoted 6 lines
drivers/gpu/drm/drm_file.c +2
-1@@ -249,9 +250,11 @@ void drm_file_free(struct drm_file *file)drm_events_release (file); -if (drm_core_check_feature (dev,DRIVER_MODESET )) { +if (drm_core_check_feature (dev,DRIVER_MODESET ) && +drm_dev_enter (dev, &idx)) {This is misplaced for two reasons:
- Even if we'd want to guarantee that we hold a drm_dev_enter/exit reference during framebuffer teardown, we'd need to do this
_consistentlyover all callsites. Not ad-hoc in just one place that a testcase hits. This also means kerneldoc updates of the relevant hooks and at least a bunch of acks from other driver people to document the consensus.- More importantly, this is driver responsibilities in general unless we have extremely good reasons to the contrary. Which means this must be placed in xe.
Quoted 11 lines
drivers/gpu/drm/drm_file.c +1
-0drm_fb_release (file);drm_property_destroy_user_blobs (dev, file); +drm_dev_exit (idx); }if (drm_core_check_feature (dev,DRIVER_SYNCOBJ ))drivers/gpu/drm/drm_mode_config.c +0
-0drivers/gpu/drm/drm_mode_config.c void drm_mode_config_cleanup(struct drm_device *dev) · line 587
Quoted 6 lines
drivers/gpu/drm/drm_mode_config.c +2
-1@@ -583,10 +583,13 @@ void drm_mode_config_cleanup(struct drm_device *dev)*/ WARN_ON (!list_empty (&dev->mode_config.fb_list)); list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { -struct drm_printer p =drm_dbg_printer (dev,DRM_UT_KMS ,"[leaked fb]" ); +if (list_empty (&fb->filp_head) ||drm_framebuffer_read_refcount (fb) >1 ) { +struct drm_printer p =drm_dbg_printer (dev,DRM_UT_KMS ,"[leaked fb]" );This is also wrong:
- Firstly, it's a completely independent bug, we do not smash two bugfixes into one patch.
- Secondly, it's again a driver bug:
drm_mode_cleanupmust be called when the lastdrm_devicereference disappears (hence the existence ofdrmm_mode_config_init), not when the driver gets unbound. The fact that this shows up in a callchain from a devres cleanup means the intel driver gets this wrong (like almost everyone else because historically we didn't know better).If we don't follow this rule, then we get races with this code here running concurrently with
drm_filefb cleanups, which just does not work. Review pointed that out, but then shrugged it off with a confused explanation:
Quoted 6 lines
https://lore.kernel.org/all/[email protected]/
Yes this also means a lot of the other
drm_deviceteardown that drivers do happens way too early. There is a massive can of worms here of a magnitude that most likely is much, much bigger than what you can backport to stable kernels. Hotunplug is _hard_.
Back to the drawing board, and fixing it in the intel display driver instead.
--- drivers/gpu/drm/drm_file.c | 5 +---- drivers/gpu/drm/drm_mode_config.c | 9 +++------ 2 files changed, 4 insertions(+), 10 deletions(-)
drivers/gpu/drm/drm_file.c +1 -4
@@ -243,7 +243,6 @@ static void drm_events_release(struct drvoid drm_file_free (struct drm_file *file) {struct drm_device *dev; -int idx;if (!file)return ;
@@ -269,11 +268,9 @@ void drm_file_free(struct drm_file *filedrm_events_release (file); -if (drm_core_check_feature (dev,DRIVER_MODESET ) && -drm_dev_enter (dev, &idx)) { +if (drm_core_check_feature (dev,DRIVER_MODESET )) {drm_fb_release (file);drm_property_destroy_user_blobs (dev, file); -drm_dev_exit (idx); }if (drm_core_check_feature (dev,DRIVER_SYNCOBJ ))
drivers/gpu/drm/drm_mode_config.c +3 -6
@@ -546,13 +546,10 @@ void drm_mode_config_cleanup(struct drm_*/ WARN_ON (!list_empty (&dev->mode_config.fb_list));list_for_each_entry_safe (fb, fbt, &dev->mode_config.fb_list, head) { -if (list_empty (&fb->filp_head) ||drm_framebuffer_read_refcount (fb) >1 ) { -struct drm_printer p =drm_debug_printer ("[leaked fb]" ); +struct drm_printer p =drm_debug_printer ("[leaked fb]" ); -drm_printf (&p,"framebuffer[%u]:\n" , fb->base.id); -drm_framebuffer_print_info (&p,1 , fb); - } -list_del_init (&fb->filp_head); +drm_printf (&p,"framebuffer[%u]:\n" , fb->base.id); +drm_framebuffer_print_info (&p,1 , fb);drm_framebuffer_free (&fb->base.refcount); }
Greg Kroah-Hartman
maintainerPATCH 20/50 netfilter: nft_ct: fix use-after-free in timeout object destroy
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tuan Do <[email protected]>
commit f8dca15a1b190787bbd03285304b569631160eda upstream.
nft_ct_timeout_obj_destroy() frees the timeout object with kfree() immediately after nf_ct_untimeout(), without waiting for an RCU grace period. Concurrent packet processing on other CPUs may still hold RCU-protected references to the timeout object obtained via rcu_dereference() in nf_ct_timeout_data().
Add an rcu_head to struct nf_ct_timeout and use kfree_rcu() to defer freeing until after an RCU grace period, matching the approach already used in nfnetlink_cttimeout.c.
KASAN report:
BUG: KASAN: slab-use-after-free in nf_conntrack_tcp_packet+0x1381/0x29d0 Read of size 4 at addr ffff8881035fe19c by task exploit/80 Call Trace: nf_conntrack_tcp_packet+0x1381/0x29d0 nf_conntrack_in+0x612/0x8b0 nf_hook_slow+0x70/0x100 __ip_local_out+0x1b2/0x210 tcp_sendmsg_locked+0x722/0x1580 __sys_sendto+0x2d8/0x320 Allocated by task 75: nft_ct_timeout_obj_init+0xf6/0x290 nft_obj_init+0x107/0x1b0 nf_tables_newobj+0x680/0x9c0 nfnetlink_rcv_batch+0xc29/0xe00 Freed by task 26: nft_obj_destroy+0x3f/0xa0 nf_tables_trans_destroy_work+0x51c/0x5c0 process_one_work+0x2c4/0x5a0
--- include/net/netfilter/nf_conntrack_timeout.h | 1 + net/netfilter/nft_ct.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
include/net/netfilter/nf_conntrack_timeout.h +1 -0
@@ -14,6 +14,7 @@struct nf_ct_timeout {__u16 l3num;const struct nf_conntrack_l4proto *l4proto; +struct rcu_head rcu;char data[]; };
net/netfilter/nft_ct.c +1 -1
@@ -1002,7 +1002,7 @@ static void nft_ct_timeout_obj_destroy(cnf_queue_nf_hook_drop (ctx->net);nf_ct_untimeout (ctx->net, timeout);nf_ct_netns_put (ctx->net, ctx->family); -kfree (priv->timeout); +kfree_rcu (priv->timeout, rcu); } static int nft_ct_timeout_obj_dump(struct sk_buff *skb,
Greg Kroah-Hartman
maintainerPATCH 21/50 xfrm: clear trailing padding in build_polexpire()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yasuaki Torimaru <[email protected]>
commit 71a98248c63c535eaa4d4c22f099b68d902006d0 upstream.
build_expire() clears the trailing padding bytes of struct xfrm_user_expire after setting the hard field via memset_after(), but the analogous function build_polexpire() does not do this for struct xfrm_user_polexpire.
The padding bytes after the __u8 hard field are left uninitialized from the heap allocation, and are then sent to userspace via netlink multicast to XFRMNLGRP_EXPIRE listeners, leaking kernel heap memory contents.
Add the missing memset_after() call, matching build_expire().
--- net/xfrm/xfrm_user.c | 2 ++ 1 file changed, 2 insertions(+)
net/xfrm/xfrm_user.c +2 -0
@@ -3583,6 +3583,8 @@ static int build_polexpire(struct sk_bufreturn err; } upe->hard = !!hard; +/* clear the padding bytes */ +memset_after (upe,0 , hard);nlmsg_end (skb, nlh);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 22/50 tipc: fix bc_ackers underflow on duplicate GRP_ACK_MSG
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleh Konko <[email protected]>
commit 48a5fe38772b6f039522469ee6131a67838221a8 upstream.
The GRP_ACK_MSG handler in tipc_group_proto_rcv() currently decrements bc_ackers on every inbound group ACK, even when the same member has already acknowledged the current broadcast round.
Because bc_ackers is a u16, a duplicate ACK received after the last legitimate ACK wraps the counter to 65535. Once wrapped, tipc_group_bc_cong() keeps reporting congestion and later group broadcasts on the affected socket stay blocked until the group is recreated.
Fix this by ignoring duplicate or stale ACKs before touching bc_acked or bc_ackers. This makes repeated GRP_ACK_MSG handling idempotent and prevents the underflow path.
--- net/tipc/group.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/tipc/group.c +5 -1
@@ -746,6 +746,7 @@ void tipc_group_proto_rcv(struct tipc_gru32 port =msg_origport (hdr);struct tipc_member *m, *pm;u16 remitted, in_flight; +u16 acked;if (!grp)return ;
@@ -798,7 +799,10 @@ void tipc_group_proto_rcv(struct tipc_grcase GRP_ACK_MSG :if (!m)return ; - m->bc_acked =msg_grp_bc_acked (hdr); + acked =msg_grp_bc_acked (hdr); +if (less_eq (acked, m->bc_acked)) +return ; + m->bc_acked = acked;if (--grp->bc_ackers)return ;list_del_init (&m->small_win);
Greg Kroah-Hartman
maintainerPATCH 23/50 wifi: brcmsmac: Fix dma_free_coherent() size
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
commit 12cd7632757a54ce586e36040210b1a738a0fc53 upstream.
dma_alloc_consistent() may change the size to align it. The new size is saved in alloced.
Change the free size to match the allocation size.
--- drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c +1 -1
@@ -483,7 +483,7 @@ static void *dma_ringalloc(struct dma_inif (((desc_strtaddr + size -1 ) & boundary) != (desc_strtaddr & boundary)) { *alignbits =dma_align_sizetobits (size); -dma_free_coherent (di->dmadev, size, va, *descpa); +dma_free_coherent (di->dmadev, *alloced, va, *descpa); va =dma_alloc_consistent (di, size, *alignbits, alloced, descpa); }
Greg Kroah-Hartman
maintainerPATCH 24/50 Revert "arm64: dts: imx8mq-librem5: Set the DVS voltages lower"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Krzyszkowiak <[email protected]>
commit 4cd46ea0eb4504f7f4fea92cb4601c5c9a3e545e upstream.
This reverts commit c24a9b698fb02cd0723fa8375abab07f94b97b10.
It's been found that there's a significant per-unit variance in accepted supply voltages and the current set still makes some units unstable.
Revert back to nominal values.
--- arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts | 2 - arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 22 +++++--------------- 2 files changed, 7 insertions(+), 17 deletions(-)
arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts +1 -1
@@ -7,7 +7,7 @@ &a53_opp_table { opp-1000000000 { - opp-microvolt = <950000>; + opp-microvolt = <1000000>; }; };
arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi +6 -16
@@ -847,8 +847,8 @@ regulator-max-microvolt = <1300000>; regulator-boot-on; regulator-ramp-delay = <1250>; - rohm,dvs-run-voltage = <880000>; - rohm,dvs-idle-voltage = <820000>; + rohm,dvs-run-voltage = <900000>; + rohm,dvs-idle-voltage = <850000>; rohm,dvs-suspend-voltage = <810000>; regulator-always-on; };
@@ -859,8 +859,8 @@ regulator-max-microvolt = <1300000>; regulator-boot-on; regulator-ramp-delay = <1250>; - rohm,dvs-run-voltage = <950000>; - rohm,dvs-idle-voltage = <850000>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; regulator-always-on; };
@@ -869,14 +869,14 @@ regulator-min-microvolt = <700000>; regulator-max-microvolt = <1300000>; regulator-boot-on; - rohm,dvs-run-voltage = <850000>; + rohm,dvs-run-voltage = <900000>; }; buck4_reg: BUCK4 { regulator-name = "buck4"; regulator-min-microvolt = <700000>; regulator-max-microvolt = <1300000>; - rohm,dvs-run-voltage = <930000>; + rohm,dvs-run-voltage = <1000000>; }; buck5_reg: BUCK5 {
@@ -1410,13 +1410,3 @@ fsl,ext-reset-output; status = "okay"; }; - -&a53_opp_table { - opp-1000000000 { - opp-microvolt = <850000>; - }; - - opp-1500000000 { - opp-microvolt = <950000>; - }; -};
Greg Kroah-Hartman
maintainerPATCH 25/50 arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Krzyszkowiak <[email protected]>
commit 511f76bf1dce5acf8907b65a7d1bc8f7e7c0d637 upstream.
The minimal voltage of VDD_SOC sourced from BUCK1 is 0.81V, which is the currently set value. However, BD71837 only guarantees accuracy of ±0.01V, and this still doesn't factor other reasons for actual voltage to slightly drop in, resulting in the possibility of running out of the operational range.
Bump the voltage up to 0.85V, which should give enough headroom.
--- arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi +1 -1
@@ -849,7 +849,7 @@ regulator-ramp-delay = <1250>; rohm,dvs-run-voltage = <900000>; rohm,dvs-idle-voltage = <850000>; - rohm,dvs-suspend-voltage = <810000>; + rohm,dvs-suspend-voltage = <850000>; regulator-always-on; };
Greg Kroah-Hartman
maintainerPATCH 26/50 arm64: dts: hisilicon: poplar: Correct PCIe reset GPIO polarity
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Guo <[email protected]>
commit c1f2b0f2b5e37b2c27540a175aea2755a3799433 upstream.
The PCIe reset GPIO on Poplar is actually active low. The active high worked before because kernel driver didn't respect the setting from DT. This is changed since commit 1d26a55fbeb9 ("PCI: histb: Switch to using gpiod API"), and thus PCIe on Poplar got brken since then.
Fix the problem by correcting the polarity.
--- arch/arm64/boot/dts/hisilicon/hi3798cv200-poplar.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/hisilicon/hi3798cv200-poplar.dts +1 -1
@@ -179,7 +179,7 @@ }; &pcie { - reset-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio4 4 GPIO_ACTIVE_LOW>; vpcie-supply = <®_pcie>; status = "okay"; };
Greg Kroah-Hartman
maintainerPATCH 27/50 arm64: dts: hisilicon: hi3798cv200: Add missing dma-ranges
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Guo <[email protected]>
commit 1af997cad473d505248df6d9577183bb91f69670 upstream.
Reboot starts failing on Poplar since commit 8424ecdde7df ("arm64: mm:
Set ZONE_DMA size based on devicetree's dma-ranges"), which effectively changes zone_dma_bits from 30 to 32 for arm64 platforms that do not properly define dma-ranges in device tree. It's unclear how Poplar reboot gets broken by this change exactly, but a dma-ranges limiting zone_dma to the first 1 GB fixes the regression.
--- arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi +1 -0
@@ -81,6 +81,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x0 0xf0000000 0x10000000>; + dma-ranges = <0x0 0x0 0x0 0x40000000>; crg: clock-reset-controller@8a22000 { compatible = "hisilicon,hi3798cv200-crg", "syscon", "simple-mfd";
Greg Kroah-Hartman
maintainerPATCH 28/50 nfc: pn533: allocate rx skb before consuming bytes
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
commit c71ba669b570c7b3f86ec875be222ea11dacb352 upstream.
pn532_receive_buf() reports the number of accepted bytes to the serdev core. The current code consumes bytes into recv_skb and may already hand a complete frame to pn533_recv_frame() before allocating a fresh receive buffer.
If that alloc_skb() fails, the callback returns 0 even though it has already consumed bytes, and it leaves recv_skb as NULL for the next receive callback. That breaks the receive_buf() accounting contract and can also lead to a NULL dereference on the next skb_put_u8().
Allocate the receive skb lazily before consuming the next byte instead. If allocation fails, return the number of bytes already accepted.
--- drivers/nfc/pn533/uart.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/nfc/pn533/uart.c +8 -3
@@ -211,6 +211,13 @@ static int pn532_receive_buf(struct serddel_timer (&dev->cmd_timeout);for (i =0 ; i < count; i++) { +if (!dev->recv_skb) { + dev->recv_skb =alloc_skb (PN532_UART_SKB_BUFF_LEN , +GFP_KERNEL ); +if (!dev->recv_skb) +return i; + } +if (unlikely (!skb_tailroom (dev->recv_skb)))skb_trim (dev->recv_skb,0 );
@@ -219,9 +226,7 @@ static int pn532_receive_buf(struct serdcontinue ;pn533_recv_frame (dev->priv, dev->recv_skb,0 ); - dev->recv_skb =alloc_skb (PN532_UART_SKB_BUFF_LEN ,GFP_KERNEL ); -if (!dev->recv_skb) -return 0 ; + dev->recv_skb =NULL ; }return i;
Greg Kroah-Hartman
maintainerPATCH 29/50 batman-adv: reject oversized global TT response buffers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruide Cao <[email protected]>
commit 3a359bf5c61d52e7f09754108309d637532164a6 upstream.
batadv_tt_prepare_tvlv_global_data() builds the allocation length for a global TT response in 16-bit temporaries. When a remote originator advertises a large enough global TT, the TT payload length plus the VLAN header offset can exceed 65535 and wrap before kmalloc().
The full-table response path still uses the original TT payload length when it fills tt_change, so the wrapped allocation is too small and batadv_tt_prepare_tvlv_global_data() writes past the end of the heap object before the later packet-size check runs.
Fix this by rejecting TT responses whose TVLV value length cannot fit in the 16-bit TVLV payload length field.
--- net/batman-adv/translation-table.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
net/batman-adv/translation-table.c +7 -2
@@ -844,8 +844,8 @@ batadv_tt_prepare_tvlv_global_data(struc {u16 num_vlan =0 ;u16 num_entries =0 ; -u16 change_offset; -u16 tvlv_len; +u16 tvlv_len =0 ; +unsigned int change_offset;struct batadv_tvlv_tt_vlan_data *tt_vlan;struct batadv_orig_node_vlan *vlan;u8 *tt_change_ptr;
@@ -863,6 +863,11 @@ batadv_tt_prepare_tvlv_global_data(strucif (*tt_len <0 ) *tt_len =batadv_tt_len (num_entries); +if (change_offset >U16_MAX || *tt_len >U16_MAX - change_offset) { + *tt_len =0 ; + goto out; + } + tvlv_len = *tt_len; tvlv_len += change_offset;
Greg Kroah-Hartman
maintainerPATCH 30/50 X.509: Fix out-of-bounds access when parsing extensions
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
commit d702c3408213bb12bd570bb97204d8340d141c51 upstream.
Leo reports an out-of-bounds access when parsing a certificate with empty Basic Constraints or Key Usage extension because the first byte of the extension is read before checking its length. Fix it.
The bug can be triggered by an unprivileged user by submitting a specially crafted certificate to the kernel through the keyrings(7) API. Leo has demonstrated this with a proof-of-concept program responsibly disclosed off-list.
--- crypto/asymmetric_keys/x509_cert_parser.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
crypto/asymmetric_keys/x509_cert_parser.c +4 -4
@@ -592,10 +592,10 @@ int x509_process_extension(void *context* 0x04 is where keyCertSign lands in this bit string * 0x80 is where digitalSignature lands in this bit string */ -if (v[0 ] !=ASN1_BTS ) -return -EBADMSG ;if (vlen <4 )return -EBADMSG ; +if (v[0 ] !=ASN1_BTS ) +return -EBADMSG ;if (v[2 ] >=8 )return -EBADMSG ;if (v[3 ] &0x80 )
@@ -628,10 +628,10 @@ int x509_process_extension(void *context* (Expect 0xFF if the CA is TRUE) * vlen should match the entire extension size */ -if (v[0 ] != (ASN1_CONS_BIT |ASN1_SEQ )) -return -EBADMSG ;if (vlen <2 )return -EBADMSG ; +if (v[0 ] != (ASN1_CONS_BIT |ASN1_SEQ )) +return -EBADMSG ;if (v[1 ] != vlen -2 )return -EBADMSG ;/* Empty SEQUENCE means CA:FALSE (default value omitted per DER) */
Greg Kroah-Hartman
maintainerPATCH 31/50 EDAC/mc: Fix error path ordering in edac_mc_alloc()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Borislav Petkov (AMD) <[email protected]>
commit 51520e03e70d6c73e33ee7cbe0319767d05764fe upstream.
When the mci->pvt_info allocation in edac_mc_alloc() fails, the error path will call put_device() which will end up calling the device's release function.
However, the init ordering is wrong such that device_initialize() happens *after* the failed allocation and thus the device itself and the release function pointer are not initialized yet when they're called:
MCE: In-kernel MCE decoding enabled.
------------[ cut here ]------------ kobject: '(null)': is not initialized, yet kobject_put() is being called. WARNING: lib/kobject.c:734 at kobject_put, CPU#22: systemd-udevd CPU: 22 UID: 0 PID: 538 Comm: systemd-udevd Not tainted 7.0.0-rc1+ #2 PREEMPT(full) RIP: 0010:kobject_put Call Trace: <TASK> edac_mc_alloc+0xbe/0xe0 [edac_core] amd64_edac_init+0x7a4/0xff0 [amd64_edac] ? __pfx_amd64_edac_init+0x10/0x10 [amd64_edac] do_one_initcall ...
Reorder the calling sequence so that the device is initialized and thus the release function pointer is properly set before it can be used.
This was found by Claude while reviewing another EDAC patch.
--- drivers/edac/edac_mc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/edac/edac_mc.c +3 -3
@@ -369,13 +369,13 @@ struct mem_ctl_info *edac_mc_alloc(unsigif (!mci->layers) goto error; + mci->dev.release = mci_release; +device_initialize (&mci->dev); + mci->pvt_info =kzalloc (sz_pvt,GFP_KERNEL );if (!mci->pvt_info) goto error; - mci->dev.release = mci_release; -device_initialize (&mci->dev); -/* setup index and various internal pointers */ mci->mc_idx = mc_num; mci->tot_dimms = tot_dimms;
Greg Kroah-Hartman
maintainerPATCH 32/50 net/tls: fix use-after-free in -EBUSY error path of tls_do_encryption
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Alifa Ramdhan <[email protected]>
commit a9b8b18364fffce4c451e6f6fd218fa4ab646705 upstream.
The -EBUSY handling in tls_do_encryption(), introduced by commit 859054147318 ("net: tls: handle backlogging of crypto requests"), has a use-after-free due to double cleanup of encrypt_pending and the scatterlist entry.
When crypto_aead_encrypt() returns -EBUSY, the request is enqueued to the cryptd backlog and the async callback tls_encrypt_done() will be invoked upon completion. That callback unconditionally restores the scatterlist entry (sge->offset, sge->length) and decrements ctx->encrypt_pending. However, if tls_encrypt_async_wait() returns an error, the synchronous error path in tls_do_encryption() performs the same cleanup again, double-decrementing encrypt_pending and double-restoring the scatterlist.
The double-decrement corrupts the encrypt_pending sentinel (initialized to 1), making tls_encrypt_async_wait() permanently skip the wait for pending async callbacks. A subsequent sendmsg can then free the tls_rec via bpf_exec_tx_verdict() while a cryptd callback is still pending, resulting in a use-after-free when the callback fires on the freed record.
Fix this by skipping the synchronous cleanup when the -EBUSY async wait returns an error, since the callback has already handled encrypt_pending and sge restoration.
--- net/tls/tls_sw.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
net/tls/tls_sw.c +10 -0
@@ -584,6 +584,16 @@ static int tls_do_encryption(struct sockif (rc == -EBUSY ) { rc =tls_encrypt_async_wait (ctx); rc = rc ?: -EINPROGRESS ; +/* +* The async callback tls_encrypt_done() has already +* decremented encrypt_pending and restored the sge on +* both success and error. Skip the synchronous cleanup +* below on error, just remove the record and return. +*/ +if (rc != -EINPROGRESS ) { +list_del (&rec->list); +return rc; + } }if (!rc || rc != -EINPROGRESS ) {atomic_dec (&ctx->encrypt_pending);
Greg Kroah-Hartman
maintainerPATCH 33/50 net: altera-tse: fix skb leak on DMA mapping error in tse_start_xmit()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <[email protected]>
commit 6dede3967619b5944003227a5d09fdc21ed57d10 upstream.
When dma_map_single() fails in tse_start_xmit(), the function returns NETDEV_TX_OK without freeing the skb. Since NETDEV_TX_OK tells the stack the packet was consumed, the skb is never freed, leaking memory on every DMA mapping failure.
Add dev_kfree_skb_any() before returning to properly free the skb.
--- drivers/net/ethernet/altera/altera_tse_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/altera/altera_tse_main.c +1 -0
@@ -574,6 +574,7 @@ static netdev_tx_t tse_start_xmit(struct DMA_TO_DEVICE);if (dma_mapping_error (priv->device, dma_addr)) {netdev_err (priv->dev,"%s: DMA mapping error\n" , __func__); +dev_kfree_skb_any (skb); ret =NETDEV_TX_OK ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 34/50 batman-adv: hold claim backbone gateways by reference
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoze Xie <[email protected]>
commit 82d8701b2c930d0e96b0dbc9115a218d791cb0d2 upstream.
batadv_bla_add_claim() can replace claim->backbone_gw and drop the old gateway's last reference while readers still follow the pointer.
The netlink claim dump path dereferences claim->backbone_gw->orig and takes claim->backbone_gw->crc_lock without pinning the underlying backbone gateway. batadv_bla_check_claim() still has the same naked pointer access pattern.
Reuse batadv_bla_claim_get_backbone_gw() in both readers so they operate on a stable gateway reference until the read-side work is complete. This keeps the dump and claim-check paths aligned with the lifetime rules introduced for the other BLA claim readers.
--- net/batman-adv/bridge_loop_avoidance.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
net/batman-adv/bridge_loop_avoidance.c +18 -9
@@ -2132,6 +2132,7 @@ batadv_bla_claim_dump_entry(struct sk_bu struct batadv_bla_claim *claim) {const u8 *primary_addr = primary_if->net_dev->dev_addr; +struct batadv_bla_backbone_gw *backbone_gw;u16 backbone_crc;bool is_own;void *hdr;
@@ -2147,32 +2148,35 @@ batadv_bla_claim_dump_entry(struct sk_bugenl_dump_check_consistent (cb, hdr); - is_own =batadv_compare_eth (claim->backbone_gw->orig, - primary_addr); + backbone_gw =batadv_bla_claim_get_backbone_gw (claim); + + is_own =batadv_compare_eth (backbone_gw->orig, primary_addr); -spin_lock_bh (&claim->backbone_gw->crc_lock); - backbone_crc = claim->backbone_gw->crc; -spin_unlock_bh (&claim->backbone_gw->crc_lock); +spin_lock_bh (&backbone_gw->crc_lock); + backbone_crc = backbone_gw->crc; +spin_unlock_bh (&backbone_gw->crc_lock);if (is_own)if (nla_put_flag (msg,BATADV_ATTR_BLA_OWN )) {genlmsg_cancel (msg, hdr); - goto out; + goto put_backbone_gw; }if (nla_put (msg,BATADV_ATTR_BLA_ADDRESS ,ETH_ALEN , claim->addr) ||nla_put_u16 (msg,BATADV_ATTR_BLA_VID , claim->vid) ||nla_put (msg,BATADV_ATTR_BLA_BACKBONE ,ETH_ALEN , - claim->backbone_gw->orig) || + backbone_gw->orig) ||nla_put_u16 (msg,BATADV_ATTR_BLA_CRC , backbone_crc)) {genlmsg_cancel (msg, hdr); - goto out; + goto put_backbone_gw; }genlmsg_end (msg, hdr); ret =0 ; +put_backbone_gw: +batadv_backbone_gw_put (backbone_gw); out:return ret; }
@@ -2468,6 +2472,7 @@ out:bool batadv_bla_check_claim (struct batadv_priv *bat_priv,u8 *addr,unsigned short vid) { +struct batadv_bla_backbone_gw *backbone_gw;struct batadv_bla_claim search_claim;struct batadv_bla_claim *claim =NULL ;struct batadv_hard_iface *primary_if =NULL ;
@@ -2490,9 +2495,13 @@ bool batadv_bla_check_claim(struct batad* return false. */ if (claim) { -if (!batadv_compare_eth (claim->backbone_gw->orig, + backbone_gw =batadv_bla_claim_get_backbone_gw (claim); + +if (!batadv_compare_eth (backbone_gw->orig, primary_if->net_dev->dev_addr)) ret = false; + +batadv_backbone_gw_put (backbone_gw);batadv_claim_put (claim); }
Greg Kroah-Hartman
maintainerPATCH 35/50 drm/i915/gt: fix refcount underflow in intel_engine_park_heartbeat
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Brzezinka <[email protected]>
commit 4c71fd099513bfa8acab529b626e1f0097b76061 upstream.
A use-after-free / refcount underflow is possible when the heartbeat worker and intel_engine_park_heartbeat() race to release the same engine->heartbeat.systole request.
The heartbeat worker reads engine->heartbeat.systole and calls i915_request_put() on it when the request is complete, but clears the pointer in a separate, non-atomic step. Concurrently, a request retirement on another CPU can drop the engine wakeref to zero, triggering __engine_park() -> intel_engine_park_heartbeat(). If the heartbeat timer is pending at that point, cancel_delayed_work() returns true and intel_engine_park_heartbeat() reads the stale non-NULL systole pointer and calls i915_request_put() on it again, causing a refcount underflow:
``` <4> [487.221889] Workqueue: i915-unordered engine_retire [i915] <4> [487.222640] RIP: 0010:refcount_warn_saturate+0x68/0xb0 ... <4> [487.222707] Call Trace: <4> [487.222711] <TASK> <4> [487.222716] intel_engine_park_heartbeat.part.0+0x6f/0x80 [i915] <4> [487.223115] intel_engine_park_heartbeat+0x25/0x40 [i915] <4> [487.223566] __engine_park+0xb9/0x650 [i915] <4> [487.223973] ____intel_wakeref_put_last+0x2e/0xb0 [i915] <4> [487.224408] __intel_wakeref_put_last+0x72/0x90 [i915] <4> [487.224797] intel_context_exit_engine+0x7c/0x80 [i915] <4> [487.225238] intel_context_exit+0xf1/0x1b0 [i915] <4> [487.225695] i915_request_retire.part.0+0x1b9/0x530 [i915] <4> [487.226178] i915_request_retire+0x1c/0x40 [i915] <4> [487.226625] engine_retire+0x122/0x180 [i915] <4> [487.227037] process_one_work+0x239/0x760 <4> [487.227060] worker_thread+0x200/0x3f0 <4> [487.227068] ? __pfx_worker_thread+0x10/0x10 <4> [487.227075] kthread+0x10d/0x150 <4> [487.227083] ? __pfx_kthread+0x10/0x10 <4> [487.227092] ret_from_fork+0x3d4/0x480 <4> [487.227099] ? __pfx_kthread+0x10/0x10 <4> [487.227107] ret_from_fork_asm+0x1a/0x30 <4> [487.227141] </TASK> ```
Fix this by replacing the non-atomic pointer read + separate clear with xchg() in both racing paths. xchg() is a single indivisible hardware instruction that atomically reads the old pointer and writes NULL. This guarantees only one of the two concurrent callers obtains the non-NULL pointer and performs the put, the other gets NULL and skips it.
--- drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c | 26 +++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c +18 -8
@@ -144,10 +144,12 @@ static void heartbeat(struct work_struct/* Just in case everything has gone horribly wrong, give it a kick */ intel_engine_flush_submission (engine); - rq = engine->heartbeat.systole; -if (rq &&i915_request_completed (rq)) { -i915_request_put (rq); - engine->heartbeat.systole =NULL ; + rq =xchg (&engine->heartbeat.systole,NULL ); +if (rq) { +if (i915_request_completed (rq)) +i915_request_put (rq); +else + engine->heartbeat.systole = rq; }if (!intel_engine_pm_get_if_awake (engine))
@@ -228,8 +230,11 @@ static void heartbeat(struct work_struct unlock:mutex_unlock (&ce->timeline->mutex); out: -if (!engine->i915->params.enable_hangcheck || !next_heartbeat (engine)) -i915_request_put (fetch_and_zero (&engine->heartbeat.systole)); +if (!engine->i915->params.enable_hangcheck || !next_heartbeat (engine)) { + rq =xchg (&engine->heartbeat.systole,NULL ); +if (rq) +i915_request_put (rq); + }intel_engine_pm_put (engine); }
@@ -243,8 +248,13 @@ void intel_engine_unpark_heartbeat(strucvoid intel_engine_park_heartbeat (struct intel_engine_cs *engine) { -if (cancel_delayed_work (&engine->heartbeat.work)) -i915_request_put (fetch_and_zero (&engine->heartbeat.systole)); +if (cancel_delayed_work (&engine->heartbeat.work)) { +struct i915_request *rq; + + rq =xchg (&engine->heartbeat.systole,NULL ); +if (rq) +i915_request_put (rq); + } }void intel_gt_unpark_heartbeats (struct intel_gt *gt)
Greg Kroah-Hartman
maintainerPATCH 36/50 net/mlx5: Update the list of the PCI supported devices
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
commit a9d4f4f6e65e0bf9bbddedecc84d67249991979c upstream.
Add the upcoming ConnectX-10 NVLink-C2C device ID to the table of supported PCI device IDs.
--- drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/main.c +1 -0
@@ -2208,6 +2208,7 @@ static const struct pci_device_id mlx5_c { PCI_VDEVICE(MELLANOX, 0x1023) }, /* ConnectX-8 */ { PCI_VDEVICE(MELLANOX, 0x1025) }, /* ConnectX-9 */ { PCI_VDEVICE(MELLANOX, 0x1027) }, /* ConnectX-10 */ + { PCI_VDEVICE(MELLANOX, 0x2101) }, /* ConnectX-10 NVLink-C2C */ { PCI_VDEVICE(MELLANOX, 0xa2d2) }, /* BlueField integrated ConnectX-5 network controller */ { PCI_VDEVICE(MELLANOX, 0xa2d3), MLX5_PCI_DEV_IS_VF}, /* BlueField integrated ConnectX-5 network controller VF */ { PCI_VDEVICE(MELLANOX, 0xa2d6) }, /* BlueField-2 integrated ConnectX-6 Dx network controller */
Greg Kroah-Hartman
maintainerPATCH 37/50 pmdomain: imx8mp-blk-ctrl: Keep the NOC_HDCP clock enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacky Bai <[email protected]>
commit e91d5f94acf68618ea3ad9c92ac28614e791ae7d upstream.
Keep the NOC_HDCP clock always enabled to fix the potential hang caused by the NoC ADB400 port power down handshake.
--- drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/pmdomain/imx/imx8mp-blk-ctrl.c +1 -7
@@ -352,9 +352,6 @@ static void imx8mp_hdmi_blk_ctrl_power_oregmap_set_bits (bc->regmap,HDMI_RTX_RESET_CTL0 ,BIT (12 ));regmap_clear_bits (bc->regmap,HDMI_TX_CONTROL0 ,BIT (3 ));break ; -case IMX8MP_HDMIBLK_PD_HDCP : -regmap_set_bits (bc->regmap,HDMI_RTX_CLK_CTL0 ,BIT (11 )); -break ;case IMX8MP_HDMIBLK_PD_HRV :regmap_set_bits (bc->regmap,HDMI_RTX_CLK_CTL1 ,BIT (3 ) |BIT (4 ) |BIT (5 ));regmap_set_bits (bc->regmap,HDMI_RTX_RESET_CTL0 ,BIT (15 ));
@@ -408,9 +405,6 @@ static void imx8mp_hdmi_blk_ctrl_power_oregmap_clear_bits (bc->regmap,HDMI_RTX_CLK_CTL0 ,BIT (7 ));regmap_clear_bits (bc->regmap,HDMI_RTX_CLK_CTL1 ,BIT (22 ) |BIT (24 ));break ; -case IMX8MP_HDMIBLK_PD_HDCP : -regmap_clear_bits (bc->regmap,HDMI_RTX_CLK_CTL0 ,BIT (11 )); -break ;case IMX8MP_HDMIBLK_PD_HRV :regmap_clear_bits (bc->regmap,HDMI_RTX_RESET_CTL0 ,BIT (15 ));regmap_clear_bits (bc->regmap,HDMI_RTX_CLK_CTL1 ,BIT (3 ) |BIT (4 ) |BIT (5 ));
@@ -439,7 +433,7 @@ static int imx8mp_hdmi_power_notifier(stregmap_write (bc->regmap,HDMI_RTX_CLK_CTL0 ,0x0 );regmap_write (bc->regmap,HDMI_RTX_CLK_CTL1 ,0x0 );regmap_set_bits (bc->regmap,HDMI_RTX_CLK_CTL0 , -BIT (0 ) |BIT (1 ) |BIT (10 )); +BIT (0 ) |BIT (1 ) |BIT (10 ) |BIT (11 ));regmap_set_bits (bc->regmap,HDMI_RTX_RESET_CTL0 ,BIT (0 ));/*
Greg Kroah-Hartman
maintainerPATCH 38/50 mmc: vub300: fix NULL-deref on disconnect
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit dff34ef879c5e73298443956a8b391311ba78d57 upstream.
Make sure to deregister the controller before dropping the reference to the driver data on disconnect to avoid NULL-pointer dereferences or use-after-free.
--- drivers/mmc/host/vub300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/vub300.c +1 -1
@@ -2369,8 +2369,8 @@ static void vub300_disconnect(struct usbusb_set_intfdata (interface,NULL );/* prevent more I/O from starting */ vub300->interface =NULL ; -kref_put (&vub300->kref, vub300_delete);mmc_remove_host (mmc); +kref_put (&vub300->kref, vub300_delete);pr_info ("USB vub300 remote SDIO host controller[%d]" " now disconnected" , ifnum);return ;
Greg Kroah-Hartman
maintainerPATCH 39/50 net: qualcomm: qca_uart: report the consumed byte on RX skb allocation failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
commit b76254c55dc8f23edc089027dd3f8792554c69fb upstream.
qca_tty_receive() consumes each input byte before checking whether a completed frame needs a fresh receive skb. When the current byte completes a frame, the driver delivers that frame and then allocates a new skb for the next one.
If that allocation fails, the current code returns i even though data[i] has already been consumed and may already have completed the delivered frame. Since serdev interprets the return value as the number of accepted bytes, this under-reports progress by one byte and can replay the final byte of the completed frame into a fresh parser state on the next call.
Return i + 1 in that failure path so the accepted-byte count matches the actual receive-state progress.
--- drivers/net/ethernet/qualcomm/qca_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/qualcomm/qca_uart.c +1 -1
@@ -114,7 +114,7 @@ qca_tty_receive(struct serdev_device *seif (!qca->rx_skb) {netdev_dbg (netdev,"recv: out of RX resources\n" ); n_stats->rx_errors++; -return i; +return i +1 ; } } }
Greg Kroah-Hartman
maintainerPATCH 40/50 net: stmmac: fix integer underflow in chain mode
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tyllis Xu <[email protected]>
commit 51f4e090b9f87b40c21b6daadb5c06e6c0a07b67 upstream.
The jumbo_frm() chain-mode implementation unconditionally computes
len = nopaged_len - bmax;
where nopaged_len = skb_headlen(skb) (linear bytes only) and bmax is BUF_SIZE_8KiB or BUF_SIZE_2KiB. However, the caller stmmac_xmit() decides to invoke jumbo_frm() based on skb->len (total length including page fragments):
is_jumbo = stmmac_is_jumbo_frm(priv, skb->len, enh_desc);
When a packet has a small linear portion (nopaged_len <= bmax) but a large total length due to page fragments (skb->len > bmax), the subtraction wraps as an unsigned integer, producing a huge len value (~0xFFFFxxxx). This causes the while (len != 0) loop to execute hundreds of thousands of iterations, passing skb->data + bmax * i pointers far beyond the skb buffer to dma_map_single(). On IOMMU-less SoCs (the typical deployment for stmmac), this maps arbitrary kernel memory to the DMA engine, constituting a kernel memory disclosure and potential memory corruption from hardware.
Fix this by introducing a buf_len local variable clamped to min(nopaged_len, bmax). Computing len = nopaged_len - buf_len is then always safe: it is zero when the linear portion fits within a single descriptor, causing the while (len != 0) loop to be skipped naturally, and the fragment loop in stmmac_xmit() handles page fragments afterward.
--- drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/net/ethernet/stmicro/stmmac/chain_mode.c +6 -5
@@ -20,7 +20,7 @@ static int jumbo_frm(struct stmmac_tx_quunsigned int nopaged_len =skb_headlen (skb);struct stmmac_priv *priv = tx_q->priv_data;unsigned int entry = tx_q->cur_tx; -unsigned int bmax, des2; +unsigned int bmax, buf_len, des2;unsigned int i =1 , len;struct dma_desc *desc;
@@ -31,17 +31,18 @@ static int jumbo_frm(struct stmmac_tx_quelse bmax = BUF_SIZE_2KiB; - len = nopaged_len - bmax; + buf_len = min_t(unsigned int, nopaged_len, bmax); + len = nopaged_len - buf_len; des2 =dma_map_single (priv->device, skb->data, - bmax,DMA_TO_DEVICE ); + buf_len,DMA_TO_DEVICE ); desc->des2 =cpu_to_le32 (des2);if (dma_mapping_error (priv->device, des2))return -1 ; tx_q->tx_skbuff_dma[entry].buf = des2; - tx_q->tx_skbuff_dma[entry].len = bmax; + tx_q->tx_skbuff_dma[entry].len = buf_len;/* do not close the descriptor and do not set own bit */ -stmmac_prepare_tx_desc (priv, desc,1 , bmax, csum,STMMAC_CHAIN_MODE , +stmmac_prepare_tx_desc (priv, desc,1 , buf_len, csum,STMMAC_CHAIN_MODE ,0 , false, skb->len);while (len !=0 ) {
Greg Kroah-Hartman
maintainerPATCH 41/50 mm: filemap: fix nr_pages calculation overflow in filemap_map_pages()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Wang <[email protected]>
commit f58df566524ebcdfa394329c64f47e3c9257516e upstream.
When running stress-ng on my Arm64 machine with v7.0-rc3 kernel, I encountered some very strange crash issues showing up as "Bad page state":
"
[ 734.496287] BUG: Bad page state in process stress-ng-env pfn:415735fb [ 734.496427] page: refcount:0 mapcount:1 mapping:0000000000000000 index:0x4cf316 pfn:0x415735fb [ 734.496434] flags: 0x57fffe000000800(owner_2|node=1|zone=2|lastcpupid=0x3ffff) [ 734.496439] raw: 057fffe000000800 0000000000000000 dead000000000122 0000000000000000 [ 734.496440] raw: 00000000004cf316 0000000000000000 0000000000000000 0000000000000000 [ 734.496442] page dumped because: nonzero mapcount
"
After analyzing this page’s state, it is hard to understand why the mapcount is not 0 while the refcount is 0, since this page is not where the issue first occurred. By enabling the CONFIG_DEBUG_VM config, I can reproduce the crash as well and captured the first warning where the issue appears:
"
[ 734.469226] page: refcount:33 mapcount:0 mapping:00000000bef2d187 index:0x81a0 pfn:0x415735c0 [ 734.469304] head: order:5 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [ 734.469315] memcg:ffff000807a8ec00 [ 734.469320] aops:ext4_da_aops ino:100b6f dentry name(?):"stress-ng-mmaptorture-9397-0-2736200540" [ 734.469335] flags: 0x57fffe400000069(locked|uptodate|lru|head|node=1|zone=2|lastcpupid=0x3ffff) ...... [ 734.469364] page dumped because: VM_WARN_ON_FOLIO((_Generic((page + nr_pages - 1), const struct page *: (const struct folio *)_compound_head(page + nr_pages - 1), struct page *: (struct folio *)_compound_head(page + nr_pages - 1))) != folio) [ 734.469390] ------------[ cut here ]------------ [ 734.469393] WARNING: ./include/linux/rmap.h:351 at folio_add_file_rmap_ptes+0x3b8/0x468, CPU#90: stress-ng-mlock/9430 [ 734.469551] folio_add_file_rmap_ptes+0x3b8/0x468 (P) [ 734.469555] set_pte_range+0xd8/0x2f8 [ 734.469566] filemap_map_folio_range+0x190/0x400 [ 734.469579] filemap_map_pages+0x348/0x638 [ 734.469583] do_fault_around+0x140/0x198 ...... [ 734.469640] el0t_64_sync+0x184/0x188
"
The code that triggers the warning is: "VM_WARN_ON_FOLIO(page_folio(page + nr_pages - 1) != folio, folio)", which indicates that set_pte_range() tried to map beyond the large folio’s size.
By adding more debug information, I found that 'nr_pages' had overflowed in filemap_map_pages(), causing set_pte_range() to establish mappings for a range exceeding the folio size, potentially corrupting fields of pages that do not belong to this folio (e.g., page->_mapcount).
After above analysis, I think the possible race is as follows:
CPU 0 CPU 1filemap_map_pages() ext4_setattr()
//get and lock folio with old inode->i_size
next_uptodate_folio()
.......
//shrink the inode->i_size
i_size_write(inode, attr->ia_size); //calculate the end_pgoff with the new inode->i_size
file_end = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE) - 1;
end_pgoff = min(end_pgoff, file_end);
......
//nr_pages can be overflowed, cause xas.xa_index > end_pgoff
end = folio_next_index(folio) - 1;
nr_pages = min(end, end_pgoff) - xas.xa_index + 1;
......
//map large folio
filemap_map_folio_range()
......
//truncate folios
truncate_pagecache(inode, inode->i_size);To fix this issue, move the 'end_pgoff' calculation before next_uptodate_folio(), so the retrieved folio stays consistent with the file end to avoid 'nr_pages' calculation overflow. After this patch, the crash issue is gone.
--- mm/filemap.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
mm/filemap.c +8 -3
@@ -3616,14 +3616,19 @@ vm_fault_t filemap_map_pages(struct vm_funsigned int nr_pages =0 , mmap_miss =0 , mmap_miss_saved;bool can_map_large; +/* +* Recalculate end_pgoff based on file_end before calling +* next_uptodate_folio() to avoid races with concurrent +* truncation. +*/ + file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ) -1 ; + end_pgoff =min (end_pgoff, file_end); +rcu_read_lock (); folio =next_uptodate_folio (&xas, mapping, end_pgoff);if (!folio) goto out; - file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ) -1 ; - end_pgoff =min (end_pgoff, file_end); -/* * Do not allow to map with PTEs beyond i_size and with PMD * across i_size to preserve SIGBUS semantics.
Greg Kroah-Hartman
maintainerPATCH 42/50 net: lan966x: fix page_pool error handling in lan966x_fdma_rx_alloc_page_pool()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <[email protected]>
commit 3fd0da4fd8851a7e62d009b7db6c4a05b092bc19 upstream.
page_pool_create() can return an ERR_PTR on failure. The return value is used unconditionally in the loop that follows, passing the error pointer through xdp_rxq_info_reg_mem_model() into page_pool_use_xdp_mem(), which dereferences it, causing a kernel oops.
Add an IS_ERR check after page_pool_create() to return early on failure.
--- drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c +2 -0
@@ -85,6 +85,8 @@ static int lan966x_fdma_rx_alloc_page_po pp_params.dma_dir =DMA_BIDIRECTIONAL ; rx->page_pool =page_pool_create (&pp_params); +if (unlikely (IS_ERR (rx->page_pool))) +return PTR_ERR (rx->page_pool);for (int i =0 ; i < lan966x->num_phys_ports; ++i) {struct lan966x_port *port;
Greg Kroah-Hartman
maintainerPATCH 43/50 rxrpc: Fix call removal to use RCU safe deletion
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit 146d4ab94cf129ee06cd467cb5c71368a6b5bad6 upstream.
Fix rxrpc call removal from the rxnet->calls list to use list_del_rcu() rather than list_del_init() to prevent stuffing up reading /proc/net/rxrpc/calls from potentially getting into an infinite loop.
This, however, means that list_empty() no longer works on an entry that's been deleted from the list, making it harder to detect prior deletion. Fix this by:
Firstly, make rxrpc_destroy_all_calls() only dump the first ten calls that are unexpectedly still on the list. Limiting the number of steps means there's no need to call cond_resched() or to remove calls from the list here, thereby eliminating the need for rxrpc_put_call() to check for that.
rxrpc_put_call() can then be fixed to unconditionally delete the call from the list as it is the only place that the deletion occurs.
--- include/trace/events/rxrpc.h | 2 +- net/rxrpc/call_object.c | 24 +++++++++--------------- 2 files changed, 10 insertions(+), 16 deletions(-)
include/trace/events/rxrpc.h +1 -1
@@ -294,7 +294,7 @@ EM(rxrpc_call_see_release, "SEE release ") \ EM(rxrpc_call_see_userid_exists, "SEE u-exists") \ EM(rxrpc_call_see_waiting_call, "SEE q-conn ") \ - E_(rxrpc_call_see_zap, "SEE zap ") + E_(rxrpc_call_see_still_live, "SEE !still-l")#define rxrpc_txqueue_traces \ EM(rxrpc_txqueue_await_reply, "AWR") \
net/rxrpc/call_object.c +9 -15
@@ -645,11 +645,9 @@ void rxrpc_put_call(struct rxrpc_call *cif (dead) { ASSERTCMP(__rxrpc_call_state(call), ==, RXRPC_CALL_COMPLETE); -if (!list_empty (&call->link)) { -spin_lock (&rxnet->call_lock); -list_del_init (&call->link); -spin_unlock (&rxnet->call_lock); - } +spin_lock (&rxnet->call_lock); +list_del_rcu (&call->link); +spin_unlock (&rxnet->call_lock);rxrpc_cleanup_call (call); }
@@ -733,24 +731,20 @@ void rxrpc_destroy_all_calls(struct rxrp_enter ("" );if (!list_empty (&rxnet->calls)) { -spin_lock (&rxnet->call_lock); +int shown =0 ; -while (!list_empty (&rxnet->calls)) { - call =list_entry (rxnet->calls.next, - struct rxrpc_call, link); -_debug ("Zapping call %p" , call); +spin_lock (&rxnet->call_lock); -rxrpc_see_call (call, rxrpc_call_see_zap); -list_del_init (&call->link); +list_for_each_entry (call, &rxnet->calls, link) { +rxrpc_see_call (call, rxrpc_call_see_still_live);pr_err ("Call %p still in use (%d,%s,%lx,%lx)!\n" , call,refcount_read (&call->ref), rxrpc_call_states[__rxrpc_call_state (call)], call->flags, call->events); -spin_unlock (&rxnet->call_lock); -cond_resched (); -spin_lock (&rxnet->call_lock); +if (++shown >=10 ) +break ; }spin_unlock (&rxnet->call_lock);
Greg Kroah-Hartman
maintainerPATCH 44/50 rxrpc: Fix key reference count leak from call->key
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anderson Nascimento <[email protected]>
commit d666540d217e8d420544ebdfbadeedd623562733 upstream.
When creating a client call in rxrpc_alloc_client_call(), the code obtains a reference to the key. This is never cleaned up and gets leaked when the call is destroyed.
Fix this by freeing call->key in rxrpc_destroy_call().
Before the patch, it shows the key reference counter elevated:
$ cat /proc/keys | grep afs@54321 1bffe9cd I--Q--i 8053480 4169w 3b010000 1000 1000 rxrpc afs@54321: ka $
After the patch, the invalidated key is removed when the code exits:
$ cat /proc/keys | grep afs@54321 $
--- net/rxrpc/call_object.c | 1 + 1 file changed, 1 insertion(+)
net/rxrpc/call_object.c +1 -0
@@ -695,6 +695,7 @@ static void rxrpc_destroy_call(struct worxrpc_put_bundle (call->bundle, rxrpc_bundle_put_call);rxrpc_put_peer (call->peer, rxrpc_peer_put_call);rxrpc_put_local (call->local, rxrpc_local_put_call); +key_put (call->key);call_rcu (&call->rcu, rxrpc_rcu_free_call); }
Greg Kroah-Hartman
maintainerPATCH 45/50 rxrpc: Only put the call ref if one was acquired
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douya Le <[email protected]>
commit 6331f1b24a3e85465f6454e003a3e6c22005a5c5 upstream.
rxrpc_input_packet_on_conn() can process a to-client packet after the current client call on the channel has already been torn down. In that case chan->call is NULL, rxrpc_try_get_call() returns NULL and there is no reference to drop.
The client-side implicit-end error path does not account for that and unconditionally calls rxrpc_put_call(). This turns a protocol error path into a kernel crash instead of rejecting the packet.
Only drop the call reference if one was actually acquired. Keep the existing protocol error handling unchanged.
--- net/rxrpc/io_thread.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/rxrpc/io_thread.c +2 -1
@@ -389,7 +389,8 @@ static int rxrpc_input_packet_on_conn(stif (sp->hdr.callNumber > chan->call_id) {if (rxrpc_to_client (sp)) { -rxrpc_put_call (call, rxrpc_call_put_input); +if (call) +rxrpc_put_call (call, rxrpc_call_put_input);return rxrpc_protocol_error (skb, rxrpc_eproto_unexpected_implicit_end); }
Greg Kroah-Hartman
maintainerPATCH 46/50 rxrpc: reject undecryptable rxkad response tickets
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqi Xu <[email protected]>
commit fe4447cd95623b1cfacc15f280aab73a6d7340b2 upstream.
rxkad_decrypt_ticket() decrypts the RXKAD response ticket and then parses the buffer as plaintext without checking whether crypto_skcipher_decrypt() succeeded.
A malformed RESPONSE can therefore use a non-block-aligned ticket length, make the decrypt operation fail, and still drive the ticket parser with attacker-controlled bytes.
Check the decrypt result and abort the connection with RXKADBADTICKET when ticket decryption fails.
--- net/rxrpc/rxkad.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/rxrpc/rxkad.c +5 -1
@@ -869,6 +869,7 @@ static int rxkad_decrypt_ticket(struct rstruct in_addr addr;unsigned int life;time64_t issue, now; +int ret;bool little_endian;u8 *p, *q, *name, *end;
@@ -888,8 +889,11 @@ static int rxkad_decrypt_ticket(struct rsg_init_one (&sg[0 ], ticket, ticket_len);skcipher_request_set_callback (req,0 ,NULL ,NULL );skcipher_request_set_crypt (req, sg, sg, ticket_len, iv.x); -crypto_skcipher_decrypt (req); + ret =crypto_skcipher_decrypt (req);skcipher_request_free (req); +if (ret <0 ) +return rxrpc_abort_conn (conn, skb,RXKADBADTICKET , -EPROTO , + rxkad_abort_resp_tkt_short); p = ticket; end = p + ticket_len;
Greg Kroah-Hartman
maintainerPATCH 47/50 rxrpc: fix reference count leak in rxrpc_server_keyring()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luxiao Xu <[email protected]>
commit f125846ee79fcae537a964ce66494e96fa54a6de upstream.
This patch fixes a reference count leak in rxrpc_server_keyring() by checking if rx->securities is already set.
--- net/rxrpc/server_key.c | 3 +++ 1 file changed, 3 insertions(+)
net/rxrpc/server_key.c +3 -0
@@ -125,6 +125,9 @@ int rxrpc_server_keyring(struct rxrpc_so_enter ("" ); +if (rx->securities) +return -EINVAL ; +if (optlen <=0 || optlen >PAGE_SIZE -1 )return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 48/50 rxrpc: Fix key/keyring checks in setsockopt(RXRPC_SECURITY_KEY/KEYRING)
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit 2afd86ccbb2082a3c4258aea8c07e5bb6267bc2f upstream.
An AF_RXRPC socket can be both client and server at the same time. When sending new calls (ie. it's acting as a client), it uses rx->key to set the security, and when accepting incoming calls (ie. it's acting as a server), it uses rx->securities.
setsockopt(RXRPC_SECURITY_KEY) sets rx->key to point to an rxrpc-type key and setsockopt(RXRPC_SECURITY_KEYRING) sets rx->securities to point to a keyring of rxrpc_s-type keys.
Now, it should be possible to use both rx->key and rx->securities on the same socket - but for userspace AF_RXRPC sockets rxrpc_setsockopt() prevents that.
Fix this by:
(1) Remove the incorrect check rxrpc_setsockopt(RXRPC_SECURITY_KEYRING)
makes on rx->key.
(2) Move the check that rxrpc_setsockopt(RXRPC_SECURITY_KEY) makes on
rx->key down into rxrpc_request_key().
(3) Remove rxrpc_request_key()'s check on rx->securities.
This (in combination with a previous patch) pushes the checks down into the functions that set those pointers and removes the cross-checks that prevent both key and keyring being set.
--- net/rxrpc/af_rxrpc.c | 6 ------ net/rxrpc/key.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-)
net/rxrpc/af_rxrpc.c +0 -6
@@ -635,9 +635,6 @@ static int rxrpc_setsockopt(struct socke goto success;case RXRPC_SECURITY_KEY : - ret = -EINVAL ; -if (rx->key) - goto error; ret = -EISCONN ;if (rx->sk.sk_state !=RXRPC_UNBOUND ) goto error;
@@ -645,9 +642,6 @@ static int rxrpc_setsockopt(struct socke goto error;case RXRPC_SECURITY_KEYRING : - ret = -EINVAL ; -if (rx->key) - goto error; ret = -EISCONN ;if (rx->sk.sk_state !=RXRPC_UNBOUND ) goto error;
net/rxrpc/key.c +1 -1
@@ -452,7 +452,7 @@ int rxrpc_request_key(struct rxrpc_sock_enter ("" ); -if (optlen <=0 || optlen >PAGE_SIZE -1 || rx->securities) +if (optlen <=0 || optlen >PAGE_SIZE -1 || rx->key)return -EINVAL ; description =memdup_sockptr_nul (optval, optlen);
Greg Kroah-Hartman
maintainerPATCH 49/50 rxrpc: Fix missing error checks for rxkad encryption/decryption failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit f93af41b9f5f798823d0d0fb8765c2a936d76270 upstream.
Add error checking for failure of crypto_skcipher_en/decrypt() to various rxkad function as the crypto functions can fail with ENOMEM at least.
--- net/rxrpc/rxkad.c | 57 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 19 deletions(-)
net/rxrpc/rxkad.c +38 -19
@@ -189,6 +189,7 @@ static int rxkad_prime_packet_security(sstruct rxrpc_crypt iv;__be32 *tmpbuf;size_t tmpsize =4 *sizeof (__be32); +int ret;_enter ("" );
@@ -217,13 +218,13 @@ static int rxkad_prime_packet_security(sskcipher_request_set_sync_tfm (req, ci);skcipher_request_set_callback (req,0 ,NULL ,NULL );skcipher_request_set_crypt (req, &sg, &sg, tmpsize, iv.x); -crypto_skcipher_encrypt (req); + ret =crypto_skcipher_encrypt (req);skcipher_request_free (req);memcpy (&conn->rxkad.csum_iv, tmpbuf +2 ,sizeof (conn->rxkad.csum_iv));kfree (tmpbuf); -_leave (" = 0" ); -return 0 ; +_leave (" = %d" , ret); +return ret; }/*
@@ -256,6 +257,7 @@ static int rxkad_secure_packet_auth(consstruct scatterlist sg;size_t pad;u16 check; +int ret;_enter ("" );
@@ -278,11 +280,11 @@ static int rxkad_secure_packet_auth(consskcipher_request_set_sync_tfm (req, call->conn->rxkad.cipher);skcipher_request_set_callback (req,0 ,NULL ,NULL );skcipher_request_set_crypt (req, &sg, &sg,8 , iv.x); -crypto_skcipher_encrypt (req); + ret =crypto_skcipher_encrypt (req);skcipher_request_zero (req); -_leave (" = 0" ); -return 0 ; +_leave (" = %d" , ret); +return ret; }/*
@@ -340,7 +342,7 @@ static int rxkad_secure_packet(struct rxunion {__be32 buf[2 ]; } crypto__aligned(8) ; -u32 x, y; +u32 x, y =0 ;int ret; _enter("{%d{%x}},{#%u},%u,",
@@ -371,8 +373,10 @@ static int rxkad_secure_packet(struct rxskcipher_request_set_sync_tfm (req, call->conn->rxkad.cipher);skcipher_request_set_callback (req,0 ,NULL ,NULL );skcipher_request_set_crypt (req, &sg, &sg,8 , iv.x); -crypto_skcipher_encrypt (req); + ret =crypto_skcipher_encrypt (req);skcipher_request_zero (req); +if (ret <0 ) + goto out; y =ntohl (crypto.buf[1 ]); y = (y >>16 ) &0xffff ;
@@ -395,6 +399,7 @@ static int rxkad_secure_packet(struct rxbreak ; } +out:skcipher_request_free (req);_leave (" = %d [set %x]" , ret, y);return ret;
@@ -435,8 +440,10 @@ static int rxkad_verify_packet_1(structskcipher_request_set_sync_tfm (req, call->conn->rxkad.cipher);skcipher_request_set_callback (req,0 ,NULL ,NULL );skcipher_request_set_crypt (req, sg, sg,8 , iv.x); -crypto_skcipher_decrypt (req); + ret =crypto_skcipher_decrypt (req);skcipher_request_zero (req); +if (ret <0 ) +return ret;/* Extract the decrypted packet length */ if (skb_copy_bits (skb, sp->offset, &sechdr,sizeof (sechdr)) <0 )
@@ -513,10 +520,14 @@ static int rxkad_verify_packet_2(structskcipher_request_set_sync_tfm (req, call->conn->rxkad.cipher);skcipher_request_set_callback (req,0 ,NULL ,NULL );skcipher_request_set_crypt (req, sg, sg, sp->len, iv.x); -crypto_skcipher_decrypt (req); + ret =crypto_skcipher_decrypt (req);skcipher_request_zero (req);if (sg != _sg)kfree (sg); +if (ret <0 ) { +WARN_ON_ONCE (ret != -ENOMEM ); +return ret; + }/* Extract the decrypted packet length */ if (skb_copy_bits (skb, sp->offset, &sechdr,sizeof (sechdr)) <0 )
@@ -584,8 +595,10 @@ static int rxkad_verify_packet(struct rxskcipher_request_set_sync_tfm (req, call->conn->rxkad.cipher);skcipher_request_set_callback (req,0 ,NULL ,NULL );skcipher_request_set_crypt (req, &sg, &sg,8 , iv.x); -crypto_skcipher_encrypt (req); + ret =crypto_skcipher_encrypt (req);skcipher_request_zero (req); +if (ret <0 ) + goto out; y =ntohl (crypto.buf[1 ]); cksum = (y >>16 ) &0xffff ;
@@ -988,21 +1001,23 @@ static int rxkad_decrypt_ticket(struct r/* * decrypt the response packet */ -static void rxkad_decrypt_response (struct rxrpc_connection *conn, -struct rxkad_response *resp, -const struct rxrpc_crypt *session_key) +static int rxkad_decrypt_response (struct rxrpc_connection *conn, +struct rxkad_response *resp, +const struct rxrpc_crypt *session_key) {struct skcipher_request *req = rxkad_ci_req;struct scatterlist sg[1 ];struct rxrpc_crypt iv; +int ret;_enter (",,%08x%08x" ,ntohl (session_key->n[0 ]),ntohl (session_key->n[1 ]));mutex_lock (&rxkad_ci_mutex); -if (crypto_sync_skcipher_setkey (rxkad_ci, session_key->x, -sizeof (*session_key)) <0 ) -BUG (); + ret =crypto_sync_skcipher_setkey (rxkad_ci, session_key->x, +sizeof (*session_key)); +if (ret <0 ) + goto unlock;memcpy (&iv, session_key,sizeof (iv));
@@ -1011,12 +1026,14 @@ static void rxkad_decrypt_response(strucskcipher_request_set_sync_tfm (req, rxkad_ci);skcipher_request_set_callback (req,0 ,NULL ,NULL );skcipher_request_set_crypt (req, sg, sg,sizeof (resp->encrypted), iv.x); -crypto_skcipher_decrypt (req); + ret =crypto_skcipher_decrypt (req);skcipher_request_zero (req); +unlock:mutex_unlock (&rxkad_ci_mutex);_leave ("" ); +return ret; }/*
@@ -1109,7 +1126,9 @@ static int rxkad_verify_response(struct/* use the session key from inside the ticket to decrypt the * response */ -rxkad_decrypt_response (conn, response, &session_key); + ret =rxkad_decrypt_response (conn, response, &session_key); +if (ret <0 ) + goto temporary_error_free_ticket; if (ntohl(response->encrypted.epoch) != conn->proto.epoch || ntohl(response->encrypted.cid) != conn->proto.cid ||
Greg Kroah-Hartman
maintainerPATCH 50/50 Revert "PCI: Enable ACS after configuring IOMMU for OF platforms"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
This reverts commit ec494c0260bf57a6fa3aa43a91daf7a774f8bd97 which is commit c41e2fb67e26b04d919257875fa954aa5f6e392e upstream.
The original commit attempted to enable ACS in pci_dma_configure() prior to IOMMU group assignment in iommu_init_device() to fix the ACS enablement issue for OF platforms. But that assumption doesn't hold true for kernel versions prior to v6.15, because on these older kernels, pci_dma_configure() is called *after* iommu_init_device(). So the IOMMU groups are already created before the ACS gets enabled. This causes the devices that should have been split into separate groups by ACS, getting merged into one group, thereby breaking the IOMMU isolation as reported on the AMD machines.
So revert the offending commit to restore the IOMMU group assignment on those affected machines. It should be noted that ACS has never really worked on kernel versions prior to v6.15, so the revert doesn't make any difference for OF platforms.
--- drivers/pci/pci-driver.c | 8 -------- drivers/pci/pci.c | 10 +++++++++- drivers/pci/pci.h | 1 - 3 files changed, 9 insertions(+), 10 deletions(-)
drivers/pci/pci-driver.c +0 -8
@@ -1668,14 +1668,6 @@ static int pci_dma_configure(struct devi ret =acpi_dma_configure (dev,acpi_get_dma_attr (adev)); } -/* -* Attempt to enable ACS regardless of capability because some Root -* Ports (e.g. those quirked with *_intel_pch_acs_*) do not have -* the standard ACS capability but still support ACS via those -* quirks. -*/ -pci_enable_acs (to_pci_dev (dev)); -pci_put_host_bridge_device (bridge);if (!ret && !driver->driver_managed_dma) {
drivers/pci/pci.c +9 -1
@@ -1046,7 +1046,7 @@ static void pci_std_enable_acs(struct pc* pci_enable_acs - enable ACS if hardware support it * @dev: the PCI device */ -void pci_enable_acs (struct pci_dev *dev) +static void pci_enable_acs (struct pci_dev *dev) {if (!pci_acs_enable) goto disable_acs_redir;
@@ -3823,6 +3823,14 @@ bool pci_acs_path_enabled(struct pci_devvoid pci_acs_init (struct pci_dev *dev) { dev->acs_cap =pci_find_ext_capability (dev,PCI_EXT_CAP_ID_ACS ); + +/* +* Attempt to enable ACS regardless of capability because some Root +* Ports (e.g. those quirked with *_intel_pch_acs_*) do not have +* the standard ACS capability but still support ACS via those +* quirks. +*/ +pci_enable_acs (dev); }/**
drivers/pci/pci.h +0 -1
@@ -557,7 +557,6 @@ static inline resource_size_t pci_resour }void pci_acs_init (struct pci_dev *dev); -void pci_enable_acs (struct pci_dev *dev);#ifdef CONFIG_PCI_QUIRKS int pci_dev_specific_acs_enabled (struct pci_dev *dev,u16 acs_flags);int pci_dev_specific_enable_acs (struct pci_dev *dev);
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.6.135-rc1-gd20afc4dec68 #1 SMP PREEMPT_DYNAMIC Mon Apr 13 17:31:56 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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, 15 Apr 2026 15:57:08 +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.135-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.135 release. There are 50 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, 15 Apr 2026 15:57:08 +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.135-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
All tests passing for Tegra ...
Test results for stable-v6.6:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
122 tests: 122 pass, 0 failLinux version: 6.6.135-rc1-gd20afc4dec68
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000,
tegra194-p3509-0000+p3668-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra234-p3737-0000+p3701-0000, tegra30-cardhu-a04Jon
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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
Am 13.04.2026 um 18:00 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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]
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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, 15 Apr 2026 15:57:08 +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.135-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).
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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.135 release. There are 50 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, 15 Apr 2026 15:57:08 +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.135-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
Tested on an amd64 laptop (Lenovo ThinkPad T14 Gen 1). Working well, no regressions observed.
Signature · 1 line
-Barry K. Nathan <[email protected]>
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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, 15 Apr 2026 15:57:08 +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.135-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, 13 Apr 2026 18:00:27 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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, 15 Apr 2026 15:57:08 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64:
Thanks!
Cheers,
Miguel
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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, 15 Apr 2026 15:57:08 +0000. Anything received after that time might be too late.
test_progs, test_progs-no_alu32, test_progs-cpuv4, test_maps, test_verifier in BPF selftests all passes[1] on x86_64.
1: https://github.com/shunghsiyu/libbpf/actions/runs/24418242274/job/71333106580
[...]
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.135 release. There are 50 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.