Linux kernel -stable discussions
 help / color / mirror / Atom feed
* Re: [PATCH] staging: rtl8723bs: fix frame length underflow in OnAuthClient
From: Dan Carpenter @ 2026-04-14 12:48 UTC (permalink / raw)
  To: Alexandru Hossu
  Cc: gregkh, linux-staging, linux-kernel, dan.carpenter, hansg, stable
In-Reply-To: <20260414100804.871764-1-hossu.alexandru@gmail.com>

On Tue, Apr 14, 2026 at 12:08:04PM +0200, Alexandru Hossu wrote:
> If pkt_len is less than WLAN_HDR_A3_LEN + offset + 6, the reads of
> the seq and status fields go beyond the frame buffer. Additionally,
> when pkt_len < WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_ (30 bytes), the
> subtraction passed to rtw_get_ie() wraps around since pkt_len is
> unsigned, causing rtw_get_ie() to scan well past the end of the buffer.
> 
> Add a minimum length check after computing offset to reject frames
> that are too short before any fixed field access.
> 
> Reported-by: Dan Carpenter <error27@gmail.com>
> Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
> ---
>  drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
> index 90f27665667a..6b0ac54ad3d4 100644
> --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
> +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
> @@ -869,6 +869,9 @@ unsigned int OnAuthClient(struct adapter *padapter, union recv_frame *precv_fram
>  
>  	offset = (GetPrivacy(pframe)) ? 4 : 0;
                             ^^^^^^
Do we know for sure that this is within bounds?  And there is earlier
code which pokes in pframe as well.  This code is quite complicated.

I looked at how to do bounds checking but it all seems pretty
complicated to me and I haven't investigated this enough to know the
right answers.

regards,
dan carpenter

>  
> +	if (pkt_len < WLAN_HDR_A3_LEN + offset + 6)
> +		goto authclnt_fail;
> +
>  	seq	= le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
>  	status	= le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
>  
> -- 
> 2.53.0

^ permalink raw reply

* Re: [net,PATCH v3 2/2] net: ks8851: Avoid excess softirq scheduling
From: Sebastian Andrzej Siewior @ 2026-04-14 13:02 UTC (permalink / raw)
  To: Marek Vasut
  Cc: netdev, stable, David S. Miller, Andrew Lunn, Eric Dumazet,
	Jakub Kicinski, Nicolai Buchwitz, Paolo Abeni, Ronald Wahl,
	Yicong Hui, linux-kernel
In-Reply-To: <20260414103327.113500-2-marex@nabladev.com>

On 2026-04-14 12:32:53 [+0200], Marek Vasut wrote:
> The code injects a packet into netif_rx() repeatedly, which will add
> it to its internal NAPI and schedule a softirq, and process it. It is
> more efficient to queue multiple packets and process them all at the
> local_bh_enable() time.
> 
> Fixes: e0863634bf9f ("net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marek Vasut <marex@nabladev.com>

Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

Sebastian

^ permalink raw reply

* Re: [net,PATCH v3 1/2] net: ks8851: Reinstate disabling of BHs around IRQ handler
From: Sebastian Andrzej Siewior @ 2026-04-14 12:57 UTC (permalink / raw)
  To: Marek Vasut
  Cc: netdev, stable, David S. Miller, Andrew Lunn, Eric Dumazet,
	Jakub Kicinski, Nicolai Buchwitz, Paolo Abeni, Ronald Wahl,
	Yicong Hui, linux-kernel
In-Reply-To: <20260414103327.113500-1-marex@nabladev.com>

On 2026-04-14 12:32:52 [+0200], Marek Vasut wrote:
> If CONFIG_PREEMPT_RT=y is set AND the driver executes ks8851_irq() AND
> KSZ_ISR register bit IRQ_RXI is set AND ks8851_rx_pkts() detects that
> there are packets in the RX FIFO, then netdev_alloc_skb_ip_align() is
> called to allocate SKBs. If netdev_alloc_skb_ip_align() is called with
> BH enabled, local_bh_enable() at the end of netdev_alloc_skb_ip_align()
> will call __local_bh_enable_ip(), which will call __do_softirq(), which
> may trigger net_tx_action() softirq, which may ultimately call the xmit
> callback ks8851_start_xmit_par(). The ks8851_start_xmit_par() will try
> to lock struct ks8851_net_par .lock spinlock, which is already locked
> by ks8851_irq() from which ks8851_start_xmit_par() was called. This
> leads to a deadlock, which is reported by the kernel, including a trace
> listed below.

#1 [received RX packet and a] TX packet has been sent
#2 Driver enables TX queue via netif_wake_queue() which schedules TX
   softirq to queue packets for this device.
#2 After spin_unlock_bh(&ks->statelock) the pending softirqs will be
   processed
#3 This deadlocks because of recursive locking via ks8851_net::lock in
   ks8851_irq() and ks8851_start_xmit_par().

This is what happens since commit 0913ec336a6c0 ("net: ks8851: Fix
deadlock with the SPI chip variant"). Before that commit the softirq
execution will be picked up by netdev_alloc_skb_ip_align() and requires
PREEMPT_RT and a RX packet in #1 to trigger the deadlock.

> Fix the problem by disabling BH around critical sections, including the
> IRQ handler, thus preventing the net_tx_action() softirq from triggering
> during these critical sections. The net_tx_action() softirq is triggered
> at the end of the IRQ handler, once all the other IRQ handler actions have
> been completed.
> 
>  __schedule from schedule_rtlock+0x1c/0x34
>  schedule_rtlock from rtlock_slowlock_locked+0x548/0x904
>  rtlock_slowlock_locked from rt_spin_lock+0x60/0x9c
>  rt_spin_lock from ks8851_start_xmit_par+0x74/0x1a8
>  ks8851_start_xmit_par from netdev_start_xmit+0x20/0x44
>  netdev_start_xmit from dev_hard_start_xmit+0xd0/0x188
>  dev_hard_start_xmit from sch_direct_xmit+0xb8/0x25c
>  sch_direct_xmit from __qdisc_run+0x1f8/0x4ec
>  __qdisc_run from qdisc_run+0x1c/0x28
>  qdisc_run from net_tx_action+0x1f0/0x268
>  net_tx_action from handle_softirqs+0x1a4/0x270
>  handle_softirqs from __local_bh_enable_ip+0xcc/0xe0
>  __local_bh_enable_ip from __alloc_skb+0xd8/0x128
>  __alloc_skb from __netdev_alloc_skb+0x3c/0x19c
>  __netdev_alloc_skb from ks8851_irq+0x388/0x4d4
>  ks8851_irq from irq_thread_fn+0x24/0x64
>  irq_thread_fn from irq_thread+0x178/0x28c
>  irq_thread from kthread+0x12c/0x138
>  kthread from ret_from_fork+0x14/0x28

The backtrace here and the description is based on an older kernel.
However

Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

> Fixes: e0863634bf9f ("net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marek Vasut <marex@nabladev.com>

Sebastian

^ permalink raw reply

* Re: [PATCH] udf: reject descriptors with oversized CRC length
From: Jan Kara @ 2026-04-14 12:43 UTC (permalink / raw)
  To: Michael Bommarito; +Cc: Jan Kara, linux-fsdevel, stable
In-Reply-To: <20260413211240.853662-1-michael.bommarito@gmail.com>

On Mon 13-04-26 17:12:40, Michael Bommarito wrote:
> udf_read_tagged() skips CRC verification when descCRCLength +
> sizeof(struct tag) exceeds the block size.  A crafted UDF image can
> set descCRCLength to an oversized value to bypass CRC validation
> entirely; the descriptor is then accepted based solely on the 8-bit
> tag checksum, which is trivially recomputable.
> 
> Reject such descriptors instead of silently accepting them.  A
> legitimate single-block descriptor should never have a CRC length that
> exceeds the block.
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-4-6
> Assisted-by: Codex:gpt-5-4
> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>

Thanks for the fix! It looks good to me. I'll merge it into my tree later
this week once the pull requests for the merge window are done.

								Honza

> ---
> Found during a filesystem security audit.  The CRC validation
> condition in udf_read_tagged() uses OR logic: the first arm
> (descCRCLength too large) short-circuits the second arm (CRC
> comparison), so an oversized descCRCLength causes the function to
> return the buffer head without verifying the CRC.  The descriptor
> is accepted based solely on the 8-bit tag checksum.
> 
> A crafted UDF image with descCRCLength set to blocksize (e.g. 2048
> on a 2048-byte-block filesystem, vs the 2032 limit) in both the
> main and reserve Volume Descriptor Sequences mounts successfully
> with corrupted descriptor bodies.
> 
> Reproduced on UML (ARCH=um, KASAN-enabled v7.0-rc7) with a
> mkudffs-generated 20 MiB image, both LVD copies patched to
> descCRCLength=2040, CRC left stale, body byte flipped, tag
> checksum recomputed.  Mount succeeds (MOUNT=0) with the corrupt
> LVD accepted.  With this patch applied, mount fails with EINVAL
> and the new "CRC length ... exceeds block size" error is logged.
> 
> Reproducer details and UML console logs available on request.
> 
>  fs/udf/misc.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/udf/misc.c b/fs/udf/misc.c
> index 0788593b6a1d..6928e378fbbd 100644
> --- a/fs/udf/misc.c
> +++ b/fs/udf/misc.c
> @@ -230,8 +230,12 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
>  	}
>  
>  	/* Verify the descriptor CRC */
> -	if (le16_to_cpu(tag_p->descCRCLength) + sizeof(struct tag) > sb->s_blocksize ||
> -	    le16_to_cpu(tag_p->descCRC) == crc_itu_t(0,
> +	if (le16_to_cpu(tag_p->descCRCLength) + sizeof(struct tag) > sb->s_blocksize) {
> +		udf_err(sb, "block %u: CRC length %u exceeds block size\n",
> +			block, le16_to_cpu(tag_p->descCRCLength));
> +		goto error_out;
> +	}
> +	if (le16_to_cpu(tag_p->descCRC) == crc_itu_t(0,
>  					bh->b_data + sizeof(struct tag),
>  					le16_to_cpu(tag_p->descCRCLength)))
>  		return bh;
> -- 
> 2.53.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply

* [PATCH] crypto: octeontx2: fix IRQ vector leak in otx2_cptpf_probe()
From: Guangshuo Li @ 2026-04-14 12:38 UTC (permalink / raw)
  To: Srujana Challa, Bharat Bhushan, Herbert Xu, David S. Miller,
	Thorsten Blum, Guangshuo Li, Kees Cook, Lukasz Bartosik,
	Suheil Chandran, linux-crypto, linux-kernel
  Cc: stable

otx2_cptpf_probe() allocates MSI-X vectors with pci_alloc_irq_vectors()
before initializing the AF-PF mailbox, registering mailbox interrupts
and setting up the PF device.

When cptpf_afpf_mbox_init(), cptpf_register_afpf_mbox_intr(),
cptpf_device_init(), cn10k_cptpf_lmtst_init(),
otx2_cpt_init_eng_grps(), sysfs_create_group() or
otx2_cpt_register_dl() fails after IRQ vectors have been allocated
successfully, the function unwinds mailbox, interrupt and engine group
state, but fails to free the allocated IRQ vectors.

The issue was identified by a static analysis tool I developed and
confirmed by manual review. Add a dedicated error path to call
pci_free_irq_vectors() after pci_alloc_irq_vectors() succeeds.

Fixes: 83ffcf78627f ("crypto: octeontx2 - add mailbox communication with AF")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
 drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
index 346d1345f11c..059f702dbf5c 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
@@ -783,7 +783,7 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
 	/* Initialize AF-PF mailbox */
 	err = cptpf_afpf_mbox_init(cptpf);
 	if (err)
-		goto clear_drvdata;
+		goto free_irq_vectors;
 	/* Register mailbox interrupt */
 	err = cptpf_register_afpf_mbox_intr(cptpf);
 	if (err)
@@ -826,6 +826,8 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
 	cptpf_disable_afpf_mbox_intr(cptpf);
 destroy_afpf_mbox:
 	cptpf_afpf_mbox_destroy(cptpf);
+free_irq_vectors:
+	pci_free_irq_vectors(pdev);
 clear_drvdata:
 	pci_set_drvdata(pdev, NULL);
 	return err;
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH 6.12 00/70] 6.12.82-rc1 review
From: Francesco Dolcini @ 2026-04-14 12:32 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
	patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
In-Reply-To: <20260413155728.181580293@linuxfoundation.org>

On Mon, Apr 13, 2026 at 05:59:55PM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 6.12.82 release.
> There are 70 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.

Tested-by: Francesco Dolcini <francesco.dolcini@toradex.com>


^ permalink raw reply

* Re: [PATCH 6.6 00/50] 6.6.135-rc1 review
From: Francesco Dolcini @ 2026-04-14 12:31 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
	patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
In-Reply-To: <20260413155724.497323914@linuxfoundation.org>

On Mon, Apr 13, 2026 at 06:00:27PM +0200, Greg Kroah-Hartman wrote:
> 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.

Tested-by: Francesco Dolcini <francesco.dolcini@toradex.com>

^ permalink raw reply

* Re: [PATCH 6.1 00/55] 6.1.169-rc1 review
From: Francesco Dolcini @ 2026-04-14 12:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
	patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
In-Reply-To: <20260413155724.820472494@linuxfoundation.org>

On Mon, Apr 13, 2026 at 06:00:34PM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 6.1.169 release.
> There are 55 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.

Tested-by: Francesco Dolcini <francesco.dolcini@toradex.com>


^ permalink raw reply

* Re: [PATCH] mm: Call ->free_folio() directly in folio_unmap_invalidate()
From: Jan Kara @ 2026-04-14 12:28 UTC (permalink / raw)
  To: Matthew Wilcox (Oracle)
  Cc: Andrew Morton, Jan Kara, linux-fsdevel, linux-mm, Jens Axboe,
	stable, Google Big Sleep
In-Reply-To: <20260413184314.3419945-1-willy@infradead.org>

On Mon 13-04-26 19:43:11, Matthew Wilcox (Oracle) wrote:
> We can only call filemap_free_folio() if we have a reference to (or hold a
> lock on) the mapping.  Otherwise, we've already removed the folio from the
> mapping so it no longer pins the mapping and the mapping can be removed,
> causing a use-after-free when accessing mapping->a_ops.
> 
> Follow the same pattern as __remove_mapping() and load the free_folio
> function pointer before dropping the lock on the mapping.  That lets
> us make filemap_free_folio() static as this was the only caller outside
> filemap.c.
> 
> Fixes: 4a9e23159fd3 (mm/truncate: add folio_unmap_invalidate() helper)
> Cc: Jens Axboe <axboe@kernel.dk>
> Cc: stable@vger.kernel.org
> Reported-by: Google Big Sleep <big-sleep-vuln-reports+bigsleep-501448199@google.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>

The fix looks good to me. Regarding the Fixes tag, Christoph is right that
at that point and even for some time after that folio_unmap_invalidate()
was fine as it was only called when holding inode reference. It was more
like fb7d3bc41493 ("mm/filemap: drop streaming/uncached pages when
writeback completes") when the problem started.

								Honza

> ---
>  mm/filemap.c  | 3 ++-
>  mm/internal.h | 1 -
>  mm/truncate.c | 6 +++++-
>  3 files changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/filemap.c b/mm/filemap.c
> index 406cef06b684..5a4fecb24257 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -228,7 +228,8 @@ void __filemap_remove_folio(struct folio *folio, void *shadow)
>  	page_cache_delete(mapping, folio, shadow);
>  }
>  
> -void filemap_free_folio(struct address_space *mapping, struct folio *folio)
> +static void filemap_free_folio(const struct address_space *mapping,
> +		struct folio *folio)
>  {
>  	void (*free_folio)(struct folio *);
>  
> diff --git a/mm/internal.h b/mm/internal.h
> index cb0af847d7d9..546114d3ee44 100644
> --- a/mm/internal.h
> +++ b/mm/internal.h
> @@ -540,7 +540,6 @@ unsigned find_lock_entries(struct address_space *mapping, pgoff_t *start,
>  		pgoff_t end, struct folio_batch *fbatch, pgoff_t *indices);
>  unsigned find_get_entries(struct address_space *mapping, pgoff_t *start,
>  		pgoff_t end, struct folio_batch *fbatch, pgoff_t *indices);
> -void filemap_free_folio(struct address_space *mapping, struct folio *folio);
>  int truncate_inode_folio(struct address_space *mapping, struct folio *folio);
>  bool truncate_inode_partial_folio(struct folio *folio, loff_t start,
>  		loff_t end);
> diff --git a/mm/truncate.c b/mm/truncate.c
> index 12467c1bd711..8617a12cb169 100644
> --- a/mm/truncate.c
> +++ b/mm/truncate.c
> @@ -622,6 +622,7 @@ static int folio_launder(struct address_space *mapping, struct folio *folio)
>  int folio_unmap_invalidate(struct address_space *mapping, struct folio *folio,
>  			   gfp_t gfp)
>  {
> +	void (*free_folio)(struct folio *);
>  	int ret;
>  
>  	VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
> @@ -648,9 +649,12 @@ int folio_unmap_invalidate(struct address_space *mapping, struct folio *folio,
>  	xa_unlock_irq(&mapping->i_pages);
>  	if (mapping_shrinkable(mapping))
>  		inode_lru_list_add(mapping->host);
> +	free_folio = mapping->a_ops->free_folio;
>  	spin_unlock(&mapping->host->i_lock);
>  
> -	filemap_free_folio(mapping, folio);
> +	if (free_folio)
> +		free_folio(folio);
> +	folio_put_refs(folio, folio_nr_pages(folio));
>  	return 1;
>  failed:
>  	xa_unlock_irq(&mapping->i_pages);
> -- 
> 2.47.3
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply

* [RESEND PATCH] ALSA: control: Validate buf_len before strnlen() in snd_ctl_elem_init_enum_names()
From: Ziqing Chen @ 2026-04-14 12:18 UTC (permalink / raw)
  To: tiwai, perex; +Cc: linux-sound, linux-kernel, stable, Ziqing Chen
In-Reply-To: <20260414090542.151447-1-chenziqing@xiaomi.com>

snd_ctl_elem_init_enum_names() advances pointer p through the names
buffer while decrementing buf_len. If buf_len reaches zero but items
remain, the next iteration calls strnlen(p, 0).

While strnlen(p, 0) returns 0 and would hit the existing name_len == 0
error path, CONFIG_FORTIFY_SOURCE's fortified strnlen() first checks
maxlen against __builtin_dynamic_object_size(). When Clang loses track
of p's object size inside the loop, this triggers a BRK exception panic
before the return value is examined.

Add a buf_len == 0 guard at the loop entry to prevent calling fortified
strnlen() on an exhausted buffer.

Found by kernel fuzz testing through Xiaomi Smartphone.

Fixes: 8d448162bda5 ("ALSA: control: add support for ENUMERATED user space controls")
Cc: stable@vger.kernel.org
Signed-off-by: Ziqing Chen <chenziqing@xiaomi.com>
---
 sound/core/control.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sound/core/control.c b/sound/core/control.c
index 0ddade871b52..6ceb5f977fcd 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1574,6 +1574,10 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue)
        /* check that there are enough valid names */
        p = names;
        for (i = 0; i < ue->info.value.enumerated.items; ++i) {
+               if (buf_len == 0) {
+                       kvfree(names);
+                       return -EINVAL;
+               }
                name_len = strnlen(p, buf_len);
                if (name_len == 0 || name_len >= 64 || name_len == buf_len) {
                        kvfree(names);
--
2.52.0

#/******±¾Óʼþ¼°Æä¸½¼þº¬ÓÐСÃ×¹«Ë¾µÄ±£ÃÜÐÅÏ¢£¬½öÏÞÓÚ·¢Ë͸øÉÏÃæµØÖ·ÖÐÁгöµÄ¸öÈË»òȺ×é¡£½ûÖ¹ÈÎºÎÆäËûÈËÒÔÈκÎÐÎʽʹÓ㨰üÀ¨µ«²»ÏÞÓÚÈ«²¿»ò²¿·ÖµØÐ¹Â¶¡¢¸´ÖÆ¡¢»òÉ¢·¢£©±¾ÓʼþÖеÄÐÅÏ¢¡£Èç¹ûÄú´íÊÕÁ˱¾Óʼþ£¬ÇëÄúÁ¢¼´µç»°»òÓʼþ֪ͨ·¢¼þÈ˲¢É¾³ý±¾Óʼþ£¡ This e-mail and its attachments contain confidential information from XIAOMI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!******/#

^ permalink raw reply related

* [PATCH 6.6.y] net: add proper RCU protection to /proc/net/ptype
From: XiaoHua Wang @ 2026-04-14 12:11 UTC (permalink / raw)
  To: gregkh, sashal, stable
  Cc: Eric Dumazet, Yin Fengwei, Dong Chenchen, Willem de Bruijn,
	Jakub Kicinski, XiaoHua Wang

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit f613e8b4afea0cd17c7168e8b00e25bc8d33175d ]

Yin Fengwei reported an RCU stall in ptype_seq_show() and provided
a patch.

Real issue is that ptype_seq_next() and ptype_seq_show() violate
RCU rules.

ptype_seq_show() runs under rcu_read_lock(), and reads pt->dev
to get device name without any barrier.

At the same time, concurrent writers can remove a packet_type structure
(which is correctly freed after an RCU grace period) and clear pt->dev
without an RCU grace period.

Define ptype_iter_state to carry a dev pointer along seq_net_private:

struct ptype_iter_state {
	struct seq_net_private	p;
	struct net_device	*dev; // added in this patch
};

We need to record the device pointer in ptype_get_idx() and
ptype_seq_next() so that ptype_seq_show() is safe against
concurrent pt->dev changes.

We also need to add full RCU protection in ptype_seq_next().
(Missing READ_ONCE() when reading list.next values)

Many thanks to Dong Chenchen for providing a repro.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Fixes: 1d10f8a1f40b ("net-procfs: show net devices bound packet types")
Fixes: c353e8983e0d ("net: introduce per netns packet chains")
Reported-by: Yin Fengwei <fengwei_yin@linux.alibaba.com>
Reported-by: Dong Chenchen <dongchenchen2@huawei.com>
Closes: https://lore.kernel.org/netdev/CANn89iKRRKPnWjJmb-_3a=sq+9h6DvTQM4DBZHT5ZRGPMzQaiA@mail.gmail.com/T/#m7b80b9fc9b9267f90e0b7aad557595f686f9c50d

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Tested-by: Yin Fengwei <fengwei_yin@linux.alibaba.com>
Link: https://patch.msgid.link/20260202205217.2881198-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Some adjustments have been made. ]
Signed-off-by: XiaoHua Wang <561399680@139.com>
---
 net/core/net-procfs.c | 49 +++++++++++++++++++++++++++++--------------
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/net/core/net-procfs.c b/net/core/net-procfs.c
index 09f7ed1a04e8..d6d139b49384 100644
--- a/net/core/net-procfs.c
+++ b/net/core/net-procfs.c
@@ -200,8 +200,14 @@ static const struct seq_operations softnet_seq_ops = {
 	.show  = softnet_seq_show,
 };
 
+struct ptype_iter_state {
+	struct seq_net_private	p;
+	struct net_device	*dev;
+};
+
 static void *ptype_get_idx(struct seq_file *seq, loff_t pos)
 {
+	struct ptype_iter_state *iter = seq->private;
 	struct list_head *ptype_list = NULL;
 	struct packet_type *pt = NULL;
 	struct net_device *dev;
@@ -211,12 +217,16 @@ static void *ptype_get_idx(struct seq_file *seq, loff_t pos)
 	for_each_netdev_rcu(seq_file_net(seq), dev) {
 		ptype_list = &dev->ptype_all;
 		list_for_each_entry_rcu(pt, ptype_list, list) {
-			if (i == pos)
+			if (i == pos) {
+				iter->dev = dev;
 				return pt;
+			}
 			++i;
 		}
 	}
 
+	iter->dev = NULL;
+
 	list_for_each_entry_rcu(pt, &ptype_all, list) {
 		if (i == pos)
 			return pt;
@@ -242,6 +252,7 @@ static void *ptype_seq_start(struct seq_file *seq, loff_t *pos)
 
 static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
+	struct ptype_iter_state *iter = seq->private;
 	struct net_device *dev;
 	struct packet_type *pt;
 	struct list_head *nxt;
@@ -252,20 +263,21 @@ static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 		return ptype_get_idx(seq, 0);
 
 	pt = v;
-	nxt = pt->list.next;
-	if (pt->dev) {
-		if (nxt != &pt->dev->ptype_all)
+	nxt = READ_ONCE(pt->list.next);
+	dev = iter->dev;
+	if (dev) {
+		if (nxt != &dev->ptype_all)
 			goto found;
 
-		dev = pt->dev;
 		for_each_netdev_continue_rcu(seq_file_net(seq), dev) {
-			if (!list_empty(&dev->ptype_all)) {
-				nxt = dev->ptype_all.next;
+			nxt = READ_ONCE(dev->ptype_all.next);
+			if (nxt != &dev->ptype_all) {
+				iter->dev = dev;
 				goto found;
 			}
 		}
-
-		nxt = ptype_all.next;
+		iter->dev = NULL;
+		nxt = READ_ONCE(ptype_all.next);
 		goto ptype_all;
 	}
 
@@ -274,14 +286,14 @@ static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 		if (nxt != &ptype_all)
 			goto found;
 		hash = 0;
-		nxt = ptype_base[0].next;
+		nxt = READ_ONCE(ptype_base[0].next);
 	} else
 		hash = ntohs(pt->type) & PTYPE_HASH_MASK;
 
 	while (nxt == &ptype_base[hash]) {
 		if (++hash >= PTYPE_HASH_SIZE)
 			return NULL;
-		nxt = ptype_base[hash].next;
+		nxt = READ_ONCE(ptype_base[hash].next);
 	}
 found:
 	return list_entry(nxt, struct packet_type, list);
@@ -295,19 +307,24 @@ static void ptype_seq_stop(struct seq_file *seq, void *v)
 
 static int ptype_seq_show(struct seq_file *seq, void *v)
 {
+	struct ptype_iter_state *iter = seq->private;
 	struct packet_type *pt = v;
+	struct net_device *dev;
 
-	if (v == SEQ_START_TOKEN)
+	if (v == SEQ_START_TOKEN) {
 		seq_puts(seq, "Type Device      Function\n");
-	else if ((!pt->af_packet_net || net_eq(pt->af_packet_net, seq_file_net(seq))) &&
-		 (!pt->dev || net_eq(dev_net(pt->dev), seq_file_net(seq)))) {
+		return 0;
+	}
+	dev = iter->dev;
+	if ((!pt->af_packet_net || net_eq(pt->af_packet_net, seq_file_net(seq))) &&
+		 (!dev || net_eq(dev_net(dev), seq_file_net(seq)))) {
 		if (pt->type == htons(ETH_P_ALL))
 			seq_puts(seq, "ALL ");
 		else
 			seq_printf(seq, "%04x", ntohs(pt->type));
 
 		seq_printf(seq, " %-8s %ps\n",
-			   pt->dev ? pt->dev->name : "", pt->func);
+			   dev ? dev->name : "", pt->func);
 	}
 
 	return 0;
@@ -331,7 +348,7 @@ static int __net_init dev_proc_net_init(struct net *net)
 			 &softnet_seq_ops))
 		goto out_dev;
 	if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
-			sizeof(struct seq_net_private)))
+			sizeof(struct ptype_iter_state)))
 		goto out_softnet;
 
 	if (wext_proc_init(net))
-- 
2.43.0



^ permalink raw reply related

* [PATCH 6.6.y] net: skb: fix cross-cache free of KFENCE-allocated skb head
From: Sasha Levin @ 2026-04-14 12:11 UTC (permalink / raw)
  To: stable; +Cc: Jiayuan Chen, Antonius, Eric Dumazet, Jakub Kicinski, Sasha Levin
In-Reply-To: <2026041339-celery-ribbon-dc62@gregkh>

From: Jiayuan Chen <jiayuan.chen@linux.dev>

[ Upstream commit 0f42e3f4fe2a58394e37241d02d9ca6ab7b7d516 ]

SKB_SMALL_HEAD_CACHE_SIZE is intentionally set to a non-power-of-2
value (e.g. 704 on x86_64) to avoid collisions with generic kmalloc
bucket sizes. This ensures that skb_kfree_head() can reliably use
skb_end_offset to distinguish skb heads allocated from
skb_small_head_cache vs. generic kmalloc caches.

However, when KFENCE is enabled, kfence_ksize() returns the exact
requested allocation size instead of the slab bucket size. If a caller
(e.g. bpf_test_init) allocates skb head data via kzalloc() and the
requested size happens to equal SKB_SMALL_HEAD_CACHE_SIZE, then
slab_build_skb() -> ksize() returns that exact value. After subtracting
skb_shared_info overhead, skb_end_offset ends up matching
SKB_SMALL_HEAD_HEADROOM, causing skb_kfree_head() to incorrectly free
the object to skb_small_head_cache instead of back to the original
kmalloc cache, resulting in a slab cross-cache free:

  kmem_cache_free(skbuff_small_head): Wrong slab cache. Expected
  skbuff_small_head but got kmalloc-1k

Fix this by always calling kfree(head) in skb_kfree_head(). This keeps
the free path generic and avoids allocator-specific misclassification
for KFENCE objects.

Fixes: bf9f1baa279f ("net: add dedicated kmem_cache for typical/small skb->head")
Reported-by: Antonius <antonius@bluedragonsec.com>
Closes: https://lore.kernel.org/netdev/CAK8a0jxC5L5N7hq-DT2_NhUyjBxrPocoiDazzsBk4TGgT1r4-A@mail.gmail.com/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260403014517.142550-1-jiayuan.chen@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted variable names ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/skbuff.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4c28954f915fa..c81ef99d39b04 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -943,10 +943,7 @@ static bool skb_pp_recycle(struct sk_buff *skb, void *data, bool napi_safe)
 
 static void skb_kfree_head(void *head, unsigned int end_offset)
 {
-	if (end_offset == SKB_SMALL_HEAD_HEADROOM)
-		kmem_cache_free(skb_small_head_cache, head);
-	else
-		kfree(head);
+	kfree(head);
 }
 
 static void skb_free_head(struct sk_buff *skb, bool napi_safe)
-- 
2.53.0


^ permalink raw reply related

* [PATCH] accel/amdxdna: fix IRQ vector leak in aie2_init()
From: Guangshuo Li @ 2026-04-14 12:10 UTC (permalink / raw)
  To: Min Ma, Lizhi Hou, Oded Gabbay, Jeff Hugo, George Yang,
	Narendra Gutta, dri-devel, linux-kernel
  Cc: Guangshuo Li, stable

aie2_init() allocates MSI-X vectors with pci_alloc_irq_vectors() before
creating the PSP handle, starting the hardware and initializing the
resolver.

When aie2m_psp_create(), aie2_hw_start() or xrsm_init() fails after IRQ
vectors have been allocated successfully, the function releases the
firmware and unwinds hardware state, but fails to free the allocated
IRQ vectors.

The issue was identified by a static analysis tool I developed and
confirmed by manual review. Add a dedicated error path to free the IRQ
vectors after pci_alloc_irq_vectors() succeeds.

Fixes: 8c9ff1b181ba ("accel/amdxdna: Add a new driver for AMD AI Engine")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
 drivers/accel/amdxdna/aie2_pci.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c
index 4924a9da55b6..f05f49f691b5 100644
--- a/drivers/accel/amdxdna/aie2_pci.c
+++ b/drivers/accel/amdxdna/aie2_pci.c
@@ -591,14 +591,14 @@ static int aie2_init(struct amdxdna_dev *xdna)
 	if (!ndev->psp_hdl) {
 		XDNA_ERR(xdna, "failed to create psp");
 		ret = -ENOMEM;
-		goto release_fw;
+		goto free_irq_vectors;
 	}
 	xdna->dev_handle = ndev;
 
 	ret = aie2_hw_start(xdna);
 	if (ret) {
 		XDNA_ERR(xdna, "start npu failed, ret %d", ret);
-		goto release_fw;
+		goto free_irq_vectors;
 	}
 
 	xrs_cfg.clk_list.num_levels = ndev->max_dpm_level + 1;
@@ -623,6 +623,8 @@ static int aie2_init(struct amdxdna_dev *xdna)
 
 stop_hw:
 	aie2_hw_stop(xdna);
+free_irq_vectors:
+	pci_free_irq_vectors(pdev);
 release_fw:
 	release_firmware(fw);
 
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH 5.10 474/491] mmc: core: Drop superfluous validations in mmc_hw|sw_reset()
From: Sasha Levin @ 2026-04-14 12:08 UTC (permalink / raw)
  To: Ben Hutchings, Ulf Hansson; +Cc: stable, gregkh
In-Reply-To: <CAPDyKFo1DWRbidKrMg+DkwOxsdzDrfF5+YVhjjzGZzkAC7=Yfg@mail.gmail.com>

On Mon, 14 Apr 2026, Ulf Hansson wrote:
> Yes, good point, this commit is needed as well!

The companion fix (406e14808ee6) doesn't apply cleanly to 5.10, so I've
dropped this patch and its dependency chain from the 5.10 queue instead.

Thanks for the review.

^ permalink raw reply

* Re: [PATCH 6.12 28/70] mptcp: fix soft lockup in mptcp_recvmsg()
From: Sasha Levin @ 2026-04-14 12:08 UTC (permalink / raw)
  To: Li Xiasong; +Cc: stable, gregkh, matttbe, kuba
In-Reply-To: <14313177-4f06-4666-9c74-7dd3ca797744@huawei.com>

On Tue, 14 Apr 2026 09:52:25 +0800, Li Xiasong wrote:
> Same issue as 6.6.y - queue mismatch in mptcp_recvmsg()
> (msk->receive_queue vs sk->sk_receive_queue), so the fix is not
> applicable to 6.12.y either.

Dropped from the 6.12 and 6.6 queues, thanks.

^ permalink raw reply

* Re: [PATCH 6.6 14/50] mptcp: fix soft lockup in mptcp_recvmsg()
From: Sasha Levin @ 2026-04-14 12:08 UTC (permalink / raw)
  To: Li Xiasong; +Cc: stable, gregkh, matttbe, kuba
In-Reply-To: <52ea906c-0953-4d2c-98ee-b873ecc6a075@huawei.com>

On Tue, 14 Apr 2026 09:30:06 +0800, Li Xiasong wrote:
> 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.

^ permalink raw reply

* Re: [PATCH] usb: dwc3: Fix GUID register programming order
From: Selvarasu Ganesan @ 2026-04-14 12:05 UTC (permalink / raw)
  To: Thinh Nguyen
  Cc: gregkh@linuxfoundation.org, paulz@synopsys.com, balbi@ti.com,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	jh0801.jung@samsung.com, akash.m5@samsung.com,
	h10.kim@samsung.com, alim.akhtar@samsung.com,
	thiagu.r@samsung.com, muhammed.ali@samsung.com,
	stable@vger.kernel.org, Pritam Manohar Sutar
In-Reply-To: <20260414010532.sxciijnzak3ldw35@synopsys.com>


On 4/14/2026 6:35 AM, Thinh Nguyen wrote:
> On Fri, Apr 10, 2026, Selvarasu Ganesan wrote:
>> The Linux Version Code is currently written to the GUID register before
>> dwc3_core_soft_reset() is executed. Since the core soft reset clears the
>> GUID register back to its default value, the version information is
>> subsequently lost.
> This is not right. Soft reset should not clear the GUID register.
> Something else must have cleared it. Did you assert Vcc reset (hard
> reset) during phy reset/initialization?
>
> BR,
> Thinh

Hi Thinh,

Thank you for the clarification. Yes, you are correct, this issue is not 
related to a dwc3 core soft reset. Instead, the GUID value reverts to 
its default state when the PHY link_sw_reset completes during PHY init 
sequence.

We are using the Synopsys eUSB PHY, this reset is triggered from our 
downstream driver during the PHY init sequence (invoked through 
|dwc3_core_init|).

Could you please suggest the best way to retrieve the correct linux 
version information from the GUID?
Additionally, would it be feasible to update the GUID register after the 
PHY init sequence (triggered by |dwc3_core_init|) completes?

Thanks, Selva

>
>> Move the GUID register programming to occur after the core soft reset
>> has completed to ensure the value persists.
>>
>> Fixes: fa0ea13e9f1c ("usb: dwc3: core: write LINUX_VERSION_CODE to our GUID register")
>> Cc: stable@vger.kernel.org
>> Reported-by: Pritam Manohar Sutar <pritam.sutar@samsung.com>
>> Signed-off-by: Selvarasu Ganesan <selvarasu.g@samsung.com>
>> ---
>>   drivers/usb/dwc3/core.c | 12 ++++++------
>>   1 file changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 161a4d58b2cec..0d3c7e7b2262f 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -1341,12 +1341,6 @@ int dwc3_core_init(struct dwc3 *dwc)
>>   
>>   	hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
>>   
>> -	/*
>> -	 * Write Linux Version Code to our GUID register so it's easy to figure
>> -	 * out which kernel version a bug was found.
>> -	 */
>> -	dwc3_writel(dwc, DWC3_GUID, LINUX_VERSION_CODE);
>> -
>>   	ret = dwc3_phy_setup(dwc);
>>   	if (ret)
>>   		return ret;
>> @@ -1378,6 +1372,12 @@ int dwc3_core_init(struct dwc3 *dwc)
>>   	if (ret)
>>   		goto err_exit_phy;
>>   
>> +	/*
>> +	 * Write Linux Version Code to our GUID register so it's easy to figure
>> +	 * out which kernel version a bug was found.
>> +	 */
>> +	dwc3_writel(dwc, DWC3_GUID, LINUX_VERSION_CODE);
>> +
>>   	dwc3_core_setup_global_control(dwc);
>>   	dwc3_core_num_eps(dwc);
>>   
>> -- 
>> 2.34.1

^ permalink raw reply

* [PATCH 5.10.y] rxrpc: reject undecryptable rxkad response tickets
From: Sasha Levin @ 2026-04-14 12:05 UTC (permalink / raw)
  To: stable
  Cc: Yuqi Xu, Yifan Wu, Juefei Pu, Yuan Tan, Xin Liu, Ren Wei, Ren Wei,
	David Howells, Marc Dionne, Simon Horman, linux-afs, stable,
	Jakub Kicinski, Sasha Levin
In-Reply-To: <2026041319-rejoicing-drainpipe-edb3@gregkh>

From: Yuqi Xu <xuyuqiabc@gmail.com>

[ Upstream commit fe4447cd95623b1cfacc15f280aab73a6d7340b2 ]

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.

Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Suggested-by: Xin Liu <bird@lzu.edu.cn>
Tested-by: Ren Wei <enjou1224z@gmail.com>
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
Link: https://patch.msgid.link/20260408121252.2249051-12-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted `rxrpc_abort_conn()` call to existing `goto other_error` error-handling pattern ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/rxrpc/rxkad.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index 5345e8eefd33c..c9966722dcf78 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -941,8 +941,13 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
 	sg_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) {
+		abort_code = RXKADBADTICKET;
+		ret = -EPROTO;
+		goto other_error;
+	}
 
 	p = ticket;
 	end = p + ticket_len;
-- 
2.53.0


^ permalink raw reply related

* [PATCH 6.6.y 2/2] rxrpc: proc: size address buffers for %pISpc output
From: Sasha Levin @ 2026-04-14 12:05 UTC (permalink / raw)
  To: stable
  Cc: Pengpeng Hou, David Howells, Marc Dionne, Anderson Nascimento,
	Simon Horman, linux-afs, stable, Jakub Kicinski, Sasha Levin
In-Reply-To: <20260414120511.569429-1-sashal@kernel.org>

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit a44ce6aa2efb61fe44f2cfab72bb01544bbca272 ]

The AF_RXRPC procfs helpers format local and remote socket addresses into
fixed 50-byte stack buffers with "%pISpc".

That is too small for the longest current-tree IPv6-with-port form the
formatter can produce. In lib/vsprintf.c, the compressed IPv6 path uses a
dotted-quad tail not only for v4mapped addresses, but also for ISATAP
addresses via ipv6_addr_is_isatap().

As a result, a case such as

  [ffff:ffff:ffff:ffff:0:5efe:255.255.255.255]:65535

is possible with the current formatter. That is 50 visible characters, so
51 bytes including the trailing NUL, which does not fit in the existing
char[50] buffers used by net/rxrpc/proc.c.

Size the buffers from the formatter's maximum textual form and switch the
call sites to scnprintf().

Changes since v1:
- correct the changelog to cite the actual maximum current-tree case
  explicitly
- frame the proof around the ISATAP formatting path instead of the earlier
  mapped-v4 example

Fixes: 75b54cb57ca3 ("rxrpc: Add IPv6 support")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Anderson Nascimento <anderson@allelesecurity.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
Link: https://patch.msgid.link/20260408121252.2249051-22-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted buffer size changes ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/rxrpc/proc.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c
index 55a95f064df08..f698796976c50 100644
--- a/net/rxrpc/proc.c
+++ b/net/rxrpc/proc.c
@@ -10,6 +10,10 @@
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
 
+#define RXRPC_PROC_ADDRBUF_SIZE \
+	(sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + \
+	 sizeof(":12345"))
+
 static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES] = {
 	[RXRPC_CONN_UNUSED]			= "Unused  ",
 	[RXRPC_CONN_CLIENT_UNSECURED]		= "ClUnsec ",
@@ -54,7 +58,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
 	enum rxrpc_call_state state;
 	unsigned long timeout = 0;
 	rxrpc_seq_t acks_hard_ack;
-	char lbuff[50], rbuff[50];
+	char lbuff[RXRPC_PROC_ADDRBUF_SIZE], rbuff[RXRPC_PROC_ADDRBUF_SIZE];
 
 	if (v == &rxnet->calls) {
 		seq_puts(seq,
@@ -69,11 +73,11 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
 
 	local = call->local;
 	if (local)
-		sprintf(lbuff, "%pISpc", &local->srx.transport);
+		scnprintf(lbuff, sizeof(lbuff), "%pISpc", &local->srx.transport);
 	else
 		strcpy(lbuff, "no_local");
 
-	sprintf(rbuff, "%pISpc", &call->dest_srx.transport);
+	scnprintf(rbuff, sizeof(rbuff), "%pISpc", &call->dest_srx.transport);
 
 	state = rxrpc_call_state(call);
 	if (state != RXRPC_CALL_SERVER_PREALLOC) {
@@ -144,7 +148,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
 	struct rxrpc_connection *conn;
 	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
 	const char *state;
-	char lbuff[50], rbuff[50];
+	char lbuff[RXRPC_PROC_ADDRBUF_SIZE], rbuff[RXRPC_PROC_ADDRBUF_SIZE];
 
 	if (v == &rxnet->conn_proc_list) {
 		seq_puts(seq,
@@ -163,8 +167,8 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
 		goto print;
 	}
 
-	sprintf(lbuff, "%pISpc", &conn->local->srx.transport);
-	sprintf(rbuff, "%pISpc", &conn->peer->srx.transport);
+	scnprintf(lbuff, sizeof(lbuff), "%pISpc", &conn->local->srx.transport);
+	scnprintf(rbuff, sizeof(rbuff), "%pISpc", &conn->peer->srx.transport);
 print:
 	state = rxrpc_is_conn_aborted(conn) ?
 		rxrpc_call_completions[conn->completion] :
@@ -205,7 +209,7 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v)
 {
 	struct rxrpc_peer *peer;
 	time64_t now;
-	char lbuff[50], rbuff[50];
+	char lbuff[RXRPC_PROC_ADDRBUF_SIZE], rbuff[RXRPC_PROC_ADDRBUF_SIZE];
 
 	if (v == SEQ_START_TOKEN) {
 		seq_puts(seq,
@@ -218,9 +222,9 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v)
 
 	peer = list_entry(v, struct rxrpc_peer, hash_link);
 
-	sprintf(lbuff, "%pISpc", &peer->local->srx.transport);
+	scnprintf(lbuff, sizeof(lbuff), "%pISpc", &peer->local->srx.transport);
 
-	sprintf(rbuff, "%pISpc", &peer->srx.transport);
+	scnprintf(rbuff, sizeof(rbuff), "%pISpc", &peer->srx.transport);
 
 	now = ktime_get_seconds();
 	seq_printf(seq,
@@ -330,7 +334,7 @@ const struct seq_operations rxrpc_peer_seq_ops = {
 static int rxrpc_local_seq_show(struct seq_file *seq, void *v)
 {
 	struct rxrpc_local *local;
-	char lbuff[50];
+	char lbuff[RXRPC_PROC_ADDRBUF_SIZE];
 
 	if (v == SEQ_START_TOKEN) {
 		seq_puts(seq,
@@ -341,7 +345,7 @@ static int rxrpc_local_seq_show(struct seq_file *seq, void *v)
 
 	local = hlist_entry(v, struct rxrpc_local, link);
 
-	sprintf(lbuff, "%pISpc", &local->srx.transport);
+	scnprintf(lbuff, sizeof(lbuff), "%pISpc", &local->srx.transport);
 
 	seq_printf(seq,
 		   "UDP   %-47.47s %3u %3u %3u\n",
-- 
2.53.0


^ permalink raw reply related

* [PATCH 6.6.y 1/2] rxrpc: Don't need barrier for ->tx_bottom and ->acks_hard_ack
From: Sasha Levin @ 2026-04-14 12:05 UTC (permalink / raw)
  To: stable; +Cc: David Howells, Marc Dionne, linux-afs, Jakub Kicinski,
	Sasha Levin
In-Reply-To: <2026041327-hydroxide-proofread-7f9e@gregkh>

From: David Howells <dhowells@redhat.com>

[ Upstream commit 6396b48ac0a77165f9c2c40ab03d6c8188c89739 ]

We don't need a barrier for the ->tx_bottom value (which indicates the
lowest sequence still in the transmission queue) and the ->acks_hard_ack
value (which tracks the DATA packets hard-ack'd by the latest ACK packet
received and thus indicates which DATA packets can now be discarded) as the
app thread doesn't use either value as a reference to memory to access.
Rather, the app thread merely uses these as a guide to how much space is
available in the transmission queue

Change the code to use READ/WRITE_ONCE() instead.

Also, change rxrpc_check_tx_space() to use the same value for tx_bottom
throughout.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20241204074710.990092-18-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: a44ce6aa2efb ("rxrpc: proc: size address buffers for %pISpc output")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/rxrpc/sendmsg.c | 8 +++++---
 net/rxrpc/txbuf.c   | 4 ++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index b9f2f12281b33..3feace069cd20 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -93,9 +93,11 @@ static int rxrpc_wait_to_be_connected(struct rxrpc_call *call, long *timeo)
  */
 static bool rxrpc_check_tx_space(struct rxrpc_call *call, rxrpc_seq_t *_tx_win)
 {
+	rxrpc_seq_t tx_bottom = READ_ONCE(call->tx_bottom);
+
 	if (_tx_win)
-		*_tx_win = call->tx_bottom;
-	return call->tx_prepared - call->tx_bottom < 256;
+		*_tx_win = tx_bottom;
+	return call->tx_prepared - tx_bottom < 256;
 }
 
 /*
@@ -137,7 +139,7 @@ static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx,
 		rtt = 2;
 
 	timeout = rtt;
-	tx_start = smp_load_acquire(&call->acks_hard_ack);
+	tx_start = READ_ONCE(call->acks_hard_ack);
 
 	for (;;) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
diff --git a/net/rxrpc/txbuf.c b/net/rxrpc/txbuf.c
index d43be85123864..84d067fbc2fd1 100644
--- a/net/rxrpc/txbuf.c
+++ b/net/rxrpc/txbuf.c
@@ -112,14 +112,14 @@ void rxrpc_shrink_call_tx_buffer(struct rxrpc_call *call)
 
 	while ((txb = list_first_entry_or_null(&call->tx_buffer,
 					       struct rxrpc_txbuf, call_link))) {
-		hard_ack = smp_load_acquire(&call->acks_hard_ack);
+		hard_ack = call->acks_hard_ack;
 		if (before(hard_ack, txb->seq))
 			break;
 
 		if (txb->seq != call->tx_bottom + 1)
 			rxrpc_see_txbuf(txb, rxrpc_txbuf_see_out_of_step);
 		ASSERTCMP(txb->seq, ==, call->tx_bottom + 1);
-		smp_store_release(&call->tx_bottom, call->tx_bottom + 1);
+		WRITE_ONCE(call->tx_bottom, call->tx_bottom + 1);
 		list_del_rcu(&txb->call_link);
 
 		trace_rxrpc_txqueue(call, rxrpc_txqueue_dequeue);
-- 
2.53.0


^ permalink raw reply related

* [PATCH] rust_binder: avoid calling pending_oneway_finished() on TF_UPDATE_TXN
From: Alice Ryhl @ 2026-04-14 12:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Carlos Llamas
  Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, rust-for-linux, linux-kernel, stable

When an outdated transaction is removed from `oneway_todo` due to
`TF_UPDATE_TXN`, its `Allocation` is dropped. The current implementation
of `Allocation::drop` calls `pending_oneway_finished()`, assuming the
transaction was executed. This leads to premature execution of the next
queued one-way transaction.

Fix this by taking the `oneway_node` from the `Allocation` of the
outdated transaction before it is dropped. This prevents
`Allocation::drop` from signaling completion.

We do not call `take_oneway_node()` from `Transaction::cancel` because
it's actually correct to call `pending_oneway_finished()` on cancel if
the transaction did not come from `oneway_todo`. This ensures that if
`BINDER_THREAD_EXIT` is invoked and cancels a oneway transaction, then
the next transaction is taken from `oneway_todo`.

This bug does not lead to any issues in the kernel, but may lead to
Binder delivering transactions to userspace earlier than userspace
expected to receive them.

Cc: stable@vger.kernel.org
Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver")
Assisted-by: Antigravity:gemini
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 drivers/android/binder/allocation.rs  |  8 ++++++++
 drivers/android/binder/transaction.rs | 11 ++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/android/binder/allocation.rs b/drivers/android/binder/allocation.rs
index 0cab959e4b7e..b7b05e72970a 100644
--- a/drivers/android/binder/allocation.rs
+++ b/drivers/android/binder/allocation.rs
@@ -157,6 +157,14 @@ pub(crate) fn set_info_target_node(&mut self, target_node: NodeRef) {
         self.get_or_init_info().target_node = Some(target_node);
     }
 
+    pub(crate) fn take_oneway_node(&mut self) -> Option<DArc<Node>> {
+        if let Some(info) = self.allocation_info.as_mut() {
+            info.oneway_node.take()
+        } else {
+            None
+        }
+    }
+
     /// Reserve enough space to push at least `num_fds` fds.
     pub(crate) fn info_add_fd_reserve(&mut self, num_fds: usize) -> Result {
         self.get_or_init_info()
diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
index 47d5e4d88b07..1d9b66920a21 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -270,7 +270,8 @@ fn drop_outstanding_txn(&self) {
     /// Not used for replies.
     pub(crate) fn submit(self: DLArc<Self>, info: &mut TransactionInfo) -> BinderResult {
         // Defined before `process_inner` so that the destructor runs after releasing the lock.
-        let mut _t_outdated;
+        let _t_outdated;
+        let _oneway_node;
 
         let oneway = self.flags & TF_ONE_WAY != 0;
         let process = self.to.clone();
@@ -287,6 +288,14 @@ pub(crate) fn submit(self: DLArc<Self>, info: &mut TransactionInfo) -> BinderRes
                         if let Some(t_outdated) =
                             target_node.take_outdated_transaction(&self, &mut process_inner)
                         {
+                            let mut alloc_guard = t_outdated.allocation.lock();
+                            if let Some(alloc) = (*alloc_guard).as_mut() {
+                                // Take the oneway node to prevent `Allocation::drop` from calling
+                                // `pending_oneway_finished()`, which would be incorrect as this
+                                // transaction is not being submitted.
+                                _oneway_node = alloc.take_oneway_node();
+                            }
+                            drop(alloc_guard);
                             // Save the transaction to be dropped after locks are released.
                             _t_outdated = t_outdated;
                         }

---
base-commit: 0990a71f678aa0f045f2c126b39b6b581844d3b0
change-id: 20260414-tf-update-txn-fix-8cef91add11c

Best regards,
-- 
Alice Ryhl <aliceryhl@google.com>


^ permalink raw reply related

* [PATCH] ALSA: control: Validate buf_len before strnlen() in snd_ctl_elem_init_enum_names()
From: Ziqing Chen @ 2026-04-14 12:01 UTC (permalink / raw)
  To: chzq96; +Cc: Ziqing Chen, stable

snd_ctl_elem_init_enum_names() advances pointer p through the names
buffer while decrementing buf_len. If buf_len reaches zero but items
remain, the next iteration calls strnlen(p, 0).

While strnlen(p, 0) returns 0 and would hit the existing name_len == 0
error path, CONFIG_FORTIFY_SOURCE's fortified strnlen() first checks
maxlen against __builtin_dynamic_object_size(). When Clang loses track
of p's object size inside the loop, this triggers a BRK exception panic
before the return value is examined.

Add a buf_len == 0 guard at the loop entry to prevent calling fortified
strnlen() on an exhausted buffer.

Found by kernel fuzz testing through Xiaomi Smartphone.

Fixes: 8d448162bda5 ("ALSA: control: add support for ENUMERATED user space controls")
Cc: stable@vger.kernel.org
Signed-off-by: Ziqing Chen <chenziqing@xiaomi.com>
---
 sound/core/control.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sound/core/control.c b/sound/core/control.c
index 0ddade871b52..6ceb5f977fcd 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1574,6 +1574,10 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue)
        /* check that there are enough valid names */
        p = names;
        for (i = 0; i < ue->info.value.enumerated.items; ++i) {
+               if (buf_len == 0) {
+                       kvfree(names);
+                       return -EINVAL;
+               }
                name_len = strnlen(p, buf_len);
                if (name_len == 0 || name_len >= 64 || name_len == buf_len) {
                        kvfree(names);
--
2.52.0

#/******±¾Óʼþ¼°Æä¸½¼þº¬ÓÐСÃ×¹«Ë¾µÄ±£ÃÜÐÅÏ¢£¬½öÏÞÓÚ·¢Ë͸øÉÏÃæµØÖ·ÖÐÁгöµÄ¸öÈË»òȺ×é¡£½ûÖ¹ÈÎºÎÆäËûÈËÒÔÈκÎÐÎʽʹÓ㨰üÀ¨µ«²»ÏÞÓÚÈ«²¿»ò²¿·ÖµØÐ¹Â¶¡¢¸´ÖÆ¡¢»òÉ¢·¢£©±¾ÓʼþÖеÄÐÅÏ¢¡£Èç¹ûÄú´íÊÕÁ˱¾Óʼþ£¬ÇëÄúÁ¢¼´µç»°»òÓʼþ֪ͨ·¢¼þÈ˲¢É¾³ý±¾Óʼþ£¡ This e-mail and its attachments contain confidential information from XIAOMI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!******/#

^ permalink raw reply related

* Re: [PATCH 5.15 000/570] 5.15.203-rc1 review
From: Ron Economos @ 2026-04-14 11:58 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
	lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
	rwarsow, conor, hargar, broonie, achill, sr
In-Reply-To: <20260413155830.386096114@linuxfoundation.org>

On 4/13/26 08:52, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.15.203 release.
> There are 570 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/v5.x/stable-review/patch-5.15.203-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-5.15.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h

Built and booted successfully on RISC-V RV64 (HiFive Unmatched).

Tested-by: Ron Economos <re@w6rz.net>


^ permalink raw reply

* [PATCH 5.10.y] rxrpc: only handle RESPONSE during service challenge
From: Sasha Levin @ 2026-04-14 11:56 UTC (permalink / raw)
  To: stable
  Cc: Wang Jie, Yifan Wu, Juefei Pu, Yuan Tan, Xin Liu, Yang Yang,
	David Howells, Marc Dionne, Jeffrey Altman, Simon Horman,
	linux-afs, stable, Jakub Kicinski, Sasha Levin
In-Reply-To: <2026041312-chirping-bling-3a09@gregkh>

From: Wang Jie <jiewang2024@lzu.edu.cn>

[ Upstream commit c43ffdcfdbb5567b1f143556df8a04b4eeea041c ]

Only process RESPONSE packets while the service connection is still in
RXRPC_CONN_SERVICE_CHALLENGING. Check that state under state_lock before
running response verification and security initialization, then use a local
secured flag to decide whether to queue the secured-connection work after
the state transition. This keeps duplicate or late RESPONSE packets from
re-running the setup path and removes the unlocked post-transition state
test.

Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Suggested-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Jie Wang <jiewang2024@lzu.edu.cn>
Signed-off-by: Yang Yang <n05ec@lzu.edu.cn>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Jeffrey Altman <jaltman@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
Link: https://patch.msgid.link/20260408121252.2249051-21-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted to spin_lock_bh usage, 3-arg verify_response(), and direct rxrpc_call_is_secure() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/rxrpc/conn_event.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c
index 9081e84295844..205d2e4942389 100644
--- a/net/rxrpc/conn_event.c
+++ b/net/rxrpc/conn_event.c
@@ -293,6 +293,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
 			       u32 *_abort_code)
 {
 	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+	bool secured = false;
 	__be32 wtmp;
 	u32 abort_code;
 	int loop, ret;
@@ -337,6 +338,13 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
 							    _abort_code);
 
 	case RXRPC_PACKET_TYPE_RESPONSE:
+		spin_lock_bh(&conn->state_lock);
+		if (conn->state != RXRPC_CONN_SERVICE_CHALLENGING) {
+			spin_unlock_bh(&conn->state_lock);
+			return 0;
+		}
+		spin_unlock_bh(&conn->state_lock);
+
 		ret = conn->security->verify_response(conn, skb, _abort_code);
 		if (ret < 0)
 			return ret;
@@ -351,17 +359,18 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
 
 		spin_lock(&conn->bundle->channel_lock);
 		spin_lock_bh(&conn->state_lock);
-
 		if (conn->state == RXRPC_CONN_SERVICE_CHALLENGING) {
 			conn->state = RXRPC_CONN_SERVICE;
-			spin_unlock_bh(&conn->state_lock);
+			secured = true;
+		}
+		spin_unlock_bh(&conn->state_lock);
+
+		if (secured) {
 			for (loop = 0; loop < RXRPC_MAXCALLS; loop++)
 				rxrpc_call_is_secure(
 					rcu_dereference_protected(
 						conn->channels[loop].call,
 						lockdep_is_held(&conn->bundle->channel_lock)));
-		} else {
-			spin_unlock_bh(&conn->state_lock);
 		}
 
 		spin_unlock(&conn->bundle->channel_lock);
-- 
2.53.0


^ permalink raw reply related

* [PATCH 5.15.y] rxrpc: reject undecryptable rxkad response tickets
From: Sasha Levin @ 2026-04-14 11:56 UTC (permalink / raw)
  To: stable
  Cc: Yuqi Xu, Yifan Wu, Juefei Pu, Yuan Tan, Xin Liu, Ren Wei, Ren Wei,
	David Howells, Marc Dionne, Simon Horman, linux-afs, stable,
	Jakub Kicinski, Sasha Levin
In-Reply-To: <2026041319-ethanol-outflank-3480@gregkh>

From: Yuqi Xu <xuyuqiabc@gmail.com>

[ Upstream commit fe4447cd95623b1cfacc15f280aab73a6d7340b2 ]

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.

Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Suggested-by: Xin Liu <bird@lzu.edu.cn>
Tested-by: Ren Wei <enjou1224z@gmail.com>
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
Link: https://patch.msgid.link/20260408121252.2249051-12-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted `rxrpc_abort_conn()` call to existing `goto other_error` error-handling pattern ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/rxrpc/rxkad.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index db47844f4ac99..45a64eafa2006 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -1013,8 +1013,13 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
 	sg_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) {
+		abort_code = RXKADBADTICKET;
+		ret = -EPROTO;
+		goto other_error;
+	}
 
 	p = ticket;
 	end = p + ticket_len;
-- 
2.53.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox