]> git.ipfire.org Git - thirdparty/kernel/linux.git/log
thirdparty/kernel/linux.git
3 weeks agoxfs: use the rt version of the cow staging checker
Darrick J. Wong [Tue, 14 Jul 2026 06:05:26 +0000 (23:05 -0700)] 
xfs: use the rt version of the cow staging checker

LOLLM also noticed that xchk_rtrmapbt_xref ought to be using the rtdev
version of the "is this a cow extent?" helper function, not the datadev
one.

Cc: stable@vger.kernel.org # v6.14
Fixes: 91683bb3f264c0 ("xfs: cross-reference checks with the rt refcount btree")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
3 weeks agoxfs: use rtrefcount btree cursor in xchk_xref_is_rt_cow_staging
Darrick J. Wong [Tue, 14 Jul 2026 06:05:10 +0000 (23:05 -0700)] 
xfs: use rtrefcount btree cursor in xchk_xref_is_rt_cow_staging

LOLLM points out that we pass the wrong btree cursor here.  We want the
rtrefcount btree cursor, not the non-rt one.  This is fairly benign
since it only affects tracing data.

Cc: stable@vger.kernel.org # v6.14
Fixes: 91683bb3f264c0 ("xfs: cross-reference checks with the rt refcount btree")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
3 weeks agoxfs: don't wrap around quota ids in dqiterate
Darrick J. Wong [Tue, 14 Jul 2026 06:04:55 +0000 (23:04 -0700)] 
xfs: don't wrap around quota ids in dqiterate

LOLLM noticed that q_id is an unsigned 32-bit variable.  If it happens
to be set to XFS_DQ_ID_MAX due to a filesystem that actually has a dquot
for ID_MAX, then this addition will truncate to zero and the iteration
starts over.  Fix this by casting to u64.

Cc: stable@vger.kernel.org # v6.8
Fixes: 21d7500929c8a0 ("xfs: improve dquot iteration for scrub")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
3 weeks agoxfs: move cow_replace_mapping to xfs_bmap_util.c
Darrick J. Wong [Tue, 14 Jul 2026 06:04:39 +0000 (23:04 -0700)] 
xfs: move cow_replace_mapping to xfs_bmap_util.c

Move the actual details of (partially) replacing a COW fork mapping to
xfs_bmap_util.c so that all the code doing hairy operations on subsets
of bmbt_irecs are kept together.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
3 weeks agoxfs: make cow repair somewhat flaky when debugging knob enabled
Darrick J. Wong [Tue, 14 Jul 2026 06:04:24 +0000 (23:04 -0700)] 
xfs: make cow repair somewhat flaky when debugging knob enabled

Introduce a new behavior for the cow fork repair code: if the debugging
knob is enabled, we'll pick a random subrange of each cow fork mapping
to mark as bad.  This will exercise the xrep_cow_replace_mapping more
thoroughly.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
3 weeks agoxfs: don't replace the wrong part of the cow fork
Darrick J. Wong [Tue, 14 Jul 2026 06:04:08 +0000 (23:04 -0700)] 
xfs: don't replace the wrong part of the cow fork

LOLLM points out that xfs_iext_lookup_extent can return a @got where
got->br_startoff < startoff.  In this case, xrep_cow_replace_range
replaces the entire mapping instead of just the part that had been
marked bad in the bitmap, but advances the bitmap cursor in
xrep_cow_replace by the amount replaced.  As a result, we fail to
replace the end of the bad range, and replace part of the good range.

Fix this by rewriting the replace method to handle replacing the middle
of a cow fork mapping.  This we do by returning both the current mapping
as @got, and the subset of the mapping that we want to replace as @rep,
using @rep to store the results of the new allocation, and comparing
@rep to @got to figure out the exact transformations needed.

Cc: stable@vger.kernel.org # v6.8
Fixes: dbbdbd0086320a ("xfs: repair problems in CoW forks")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
3 weeks agox86/boot: Validate console=uart8250 baud rate to fix early boot hang
Thorsten Blum [Mon, 13 Jul 2026 19:49:25 +0000 (21:49 +0200)] 
x86/boot: Validate console=uart8250 baud rate to fix early boot hang

When the baud rate is empty, 0, invalid, or overflows to 0 when stored
as an int, the system will hang during early boot because of a division
by zero in early_serial_init().

Fall back to DEFAULT_BAUD when the resulting baud rate is 0 to prevent
an early system hang.

Fixes: ce0aa5dd20e4 ("x86, setup: Make the setup code also accept console=uart8250")
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260713194924.126472-3-thorsten.blum@linux.dev
3 weeks agoxfs: resample the data fork mapping after cycling ILOCK
Darrick J. Wong [Tue, 14 Jul 2026 06:03:44 +0000 (23:03 -0700)] 
xfs: resample the data fork mapping after cycling ILOCK

xfs_reflink_fill_{cow_hole,delalloc} are both presented with an inode,
a data fork mapping, and a cow fork mapping.  Unfortunately, these two
helpers cycle the ILOCK to grab a transaction, which means that the
mappings are stale as soon as we reacquire the ILOCK.  Currently we
refresh the cow fork mapping by re-calling xfs_find_trim_cow_extent, but
we don't refresh the data fork mapping beforehand, which means that the
xfs_bmap_trim_cow in that function queries the refcount btree about the
wrong physical blocks and returns an inaccurate value in *shared.

If *shared is now false, the directio write proceeds with a stale data
fork mapping.  Fix this by querying the data fork mapping if the
sequence counter changes across the ILOCK cycle.

Cc: hch@lst.de
Cc: stable@vger.kernel.org # v4.11
Fixes: 3c68d44a2b49a0 ("xfs: allocate direct I/O COW blocks in iomap_begin")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
3 weeks agocan: esd_usb: kill anchored URBs before freeing netdevs
Fan Wu [Thu, 9 Jul 2026 16:41:59 +0000 (16:41 +0000)] 
can: esd_usb: kill anchored URBs before freeing netdevs

esd_usb_disconnect() frees each CAN netdev with free_candev() inside
its per-netdev loop and only calls unlink_all_urbs(dev) afterwards.
The per-netdev private data (struct esd_usb_net_priv) is embedded in
the net_device allocation returned by alloc_candev(), so once
free_candev() has run, dev->nets[i] points to freed memory.
unlink_all_urbs() then dereferences the freed dev->nets[i] to kill the
per-netdev TX anchor (usb_kill_anchored_urbs(&priv->tx_submitted)),
clear active_tx_jobs, and reset priv->tx_contexts[].

Reorder the teardown so the anchored URBs are killed before the netdevs
are freed, matching other CAN/USB drivers in the same directory such as
ems_usb, usb_8dev and mcba_usb, which unregister, then unlink, then
free: unregister the netdevs first (which stops their TX queues), call
unlink_all_urbs(dev) once, then free the netdevs.

This issue was found by an in-house static analysis tool.

Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.5
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260709164159.497640-1-fanwu01@zju.edu.cn
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
3 weeks agocan: vxcan: Kconfig: fix description stating no local echo provided
Alexander Hölzl [Fri, 19 Jun 2026 09:00:35 +0000 (11:00 +0200)] 
can: vxcan: Kconfig: fix description stating no local echo provided

The Kconfig description of the vxcan kernel module erroneously states the
the vxcan interface does not provide a local echo of sent can frames.
However this behavior changed in commit 259bdba27e32 ("vxcan: enable local
echo for sent CAN frames") and vxcan interfaces now provide a local echo.

Change the description of the vxcan module in the Kconfig to reflect this
change.

Signed-off-by: Alexander Hölzl <alexander.hoelzl@gmx.net>
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20260619090035.17769-1-alexander.hoelzl@gmx.net
[mkl: rephrase patch description]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
3 weeks agoarm64: dts: renesas: ironhide: Describe inline ECC carveouts
Marek Vasut [Fri, 10 Jul 2026 16:04:22 +0000 (18:04 +0200)] 
arm64: dts: renesas: ironhide: Describe inline ECC carveouts

The DBSC5 DRAM controller protects DRAM content using inline ECC.
The inline ECC utilizes areas of DRAM for its operation, which are
in the DRAM address range, but must not be accessed or modified.
Describe the inline ECC carveout areas used by the DBSC5 controller
on this hardware as reserved-memory, which must not be accessed.
Include DRAM areas which are unprotected by ECC as well, those are
parts of the DRAM which directly precede the ECC carveout.

In case of high DRAM utilization, unless the inline ECC carveouts
are properly reserved, Linux may use and corrupt the memory used
by the DBSC5 DRAM controller for inline ECC, which would lead to
the system becoming unstable.

Fixes: ad142a4ef710 ("arm64: dts: renesas: r8a78000: Add initial Ironhide board support")
Cc: stable@vger.kernel.org
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260710160450.64967-1-marek.vasut+renesas@mailbox.org
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
3 weeks agobtrfs: fix GET_SUBVOL_INFO after compat refactor
Daan De Meyer [Mon, 13 Jul 2026 07:50:42 +0000 (09:50 +0200)] 
btrfs: fix GET_SUBVOL_INFO after compat refactor

btrfs_search_slot() returns a positive value when the search key does
not exactly match an item. This is expected here, since offset 0 is used
to find the first ROOT_BACKREF for the subvolume and the actual key has
the parent root ID as its offset.

Before the compat ioctl refactoring, the native handler still copied the
filled structure to userspace when the search returned 1. After the
lookup was moved to a shared helper, both native and compat callers
treat the positive return value as a failure and skip copy_to_user(),
leaving BTRFS_IOC_GET_SUBVOL_INFO unusable for non-top-level
subvolumes.

Reset ret after successfully validating and reading the ROOT_BACKREF so
the helper reports success and both callers copy the result to
userspace.

Fixes: 538e5bdbc899 ("btrfs: add 32-bit compat ioctl for BTRFS_IOC_GET_SUBVOL_INFO")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Daan De Meyer <daan@amutable.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: free mapping node on duplicate reloc root insert
Guanghui Yang [Sun, 12 Jul 2026 03:17:28 +0000 (03:17 +0000)] 
btrfs: free mapping node on duplicate reloc root insert

__add_reloc_root() allocates a mapping_node before inserting it into
rc->reloc_root_tree.  If rb_simple_insert() finds an existing entry, it
returns the existing rb_node and leaves the newly allocated node unlinked.

The error path then returns -EEXIST without freeing the new node.  Since
the node was never inserted into reloc_root_tree, the later cleanup in
put_reloc_control() cannot find it either.

Free the newly allocated node before returning -EEXIST.

The callers currently assert that -EEXIST should not happen, so this is a
defensive cleanup for an unexpected duplicate insert path.  If the path is
ever reached, the local allocation should still be released.

Fixes: 57a304cfd43b ("btrfs: do not panic in __add_reloc_root")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Guanghui Yang <3497809730@qq.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: fix a regression where PAGECACHE_TAG_DIRTY is never cleared
Qu Wenruo [Tue, 7 Jul 2026 06:54:30 +0000 (16:24 +0930)] 
btrfs: fix a regression where PAGECACHE_TAG_DIRTY is never cleared

[BUG]
The following script (already submitted as generic/798) will report
incorrect dirty page numbers, with 64K page size systems and 4K fs block
size:

 # mkfs.btrfs -s 4k -f $dev
 # mount $dev $mnt
 # xfs_io -f -c "pwrite 0 64K" -c fsync -c "cachestat 0 64K" $mnt/foobar
 Cached: 1, Dirty: 1, Writeback: 0, Evicted: 0, Recently Evicted: 0

Note that the dirtied page number is still 1.

[CAUSE]
The cachestat() goes through the XArray of the page cache, but
instead of checking each folio's flag, it uses the
PAGECACHE_TAG_DIRTY tag to report dirty pages.

Since commit 095be159f3eb ("btrfs: unify folio dirty flag clearing"),
btrfs replaced a folio_clear_dirty_for_io() call inside
extent_write_cache_pages() with folio_test_dirty().

This will cause the following call sequence for the folio at file offset
0:

 extent_write_cache_pages()
 |- folio_test_dirty()
 |  The folio is still dirty, continue to writeback.
 |
 |- extent_writepage()
    |- extent_writepage_io()
       |- submit_one_sector() for range [0, 4K)
       |  |- btrfs_folio_clear_dirty()
       |  |- btrfs_folio_set_writeback()
       |     |- folio_start_writeback()
       |        It's the first writeback block, we set the writeback
       | flag for the folio.
       | But the folio is still dirty, PAGECACHE_TAG_DIRTY is
       | kept
       |
       |- submit_one_sector() for range [4K, 8K)
       |  |- btrfs_folio_clear_dirty()
       |  |- btrfs_folio_set_writeback()
       |     The folio already has writeback flag, no need to call
       |     folio_start_writeback()
       |
       | ...
       |- submit_one_sector() for range [60K, 64K)
  |- btrfs_folio_clear_dirty()
  |- btrfs_folio_set_writeback()
             The folio already has writeback flag, no need to call
             folio_start_writeback()

So the PAGECACHE_TAG_DIRTY is never cleared.

Meanwhile for the old code, before that commit, the sequence looks
like:

 extent_write_cache_pages()
 |- folio_clear_dirty_for_io()
 |  The folio is still dirty, so continue to writeback.
 |  But the folio dirty flag is cleared now.
 |
 |- extent_writepage()
    |- extent_writepage_io()
       |- submit_one_sector() for range [0, 4K)
       |  |- btrfs_folio_clear_dirty()
       |  |- btrfs_folio_set_writeback()
       |     |- folio_start_writeback()
       |        |- xas_clear(PAGECACHE_TAG)
       |
       |        It's the first writeback block, we set the writeback
       | flag for the folio.
       | And the folio is not dirty, PAGECACHE_TAG_DIRTY is
       |        cleared
       |
       |- submit_one_sector() for range [4K, 8K)
       |  |- btrfs_folio_clear_dirty()
       |  |- btrfs_folio_set_writeback()
       |     The folio already has writeback flag, no need to call
       |     folio_start_writeback()
       |
       | ...
       |- submit_one_sector() for range [60K, 64K)
  |- btrfs_folio_clear_dirty()
  |- btrfs_folio_set_writeback()
             The folio already has writeback flag, no need to call
             folio_start_writeback()

Unlike the new code, old code will clear PAGECACHE_TAG_DIRTY for the
first writeback block.

There is a deeper problem, dirty and writeback folio flags are updated
at very different timing.
The dirty flag is only cleared when the last sub-folio block has dirty
flag cleared.
But the writeback flag is set when the first block starts writeback, and
later blocks that go through writeback will not call
folio_start_writeback() again.

If we rely on folio_start_writeback() to update the
PAGECACHE_TAG_DIRTY and PAGECACHE_TAG_TOWRITE, it will always be
incorrect in one way or another.

[FIX]
Do not let folio_start_writeback() do any PAGECACHE_TAG_TOWRITE
handling.

Instead, manually clear both PAGECACHE_TAG_TOWRITE and
PAGECACHE_TAG_DIRTY flags when the folio is no longer dirty during
btrfs_subpage_set_writeback().

However this is only a hot-fix, for the long term solution we will
follow iomap, by calling folio_start_writeback() immediately for the
whole folio, and folio_end_writeback() after all writeback finished
for the folio.

Fixes: 095be159f3eb ("btrfs: unify folio dirty flag clearing")
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: don't propagate EXTENT_FLAG_LOGGING to split extent maps
Leo Martins [Tue, 30 Jun 2026 19:58:05 +0000 (12:58 -0700)] 
btrfs: don't propagate EXTENT_FLAG_LOGGING to split extent maps

When btrfs_drop_extent_map_range() splits an extent map, the new split
maps inherit the original map's flags through a local 'flags' variable.
Commit f86f7a75e2fb ("btrfs: use the flags of an extent map to identify
the compression type") changed the EXTENT_FLAG_LOGGING clearing to
operate on em->flags instead of that local 'flags' copy, so a split of
an extent map that is currently being logged wrongly inherits
EXTENT_FLAG_LOGGING.

The flag is then never cleared on the split, and when it is freed while
still on the inode's modified_extents list (for example by the extent
map shrinker) it trips the WARN_ON(!list_empty(&em->list)) in
btrfs_free_extent_map() and leads to a use-after-free.

Clear EXTENT_FLAG_LOGGING from the local 'flags' copy used for the
splits and only clear EXTENT_FLAG_PINNED from em->flags, restoring the
behaviour prior to f86f7a75e2fb.

CC: Jeff Layton <jlayton@kernel.org>
Link: https://lore.kernel.org/all/20260629-btrfs-skip-logging-v1-1-4e3a28c1acaf@kernel.org/
Fixes: f86f7a75e2fb ("btrfs: use the flags of an extent map to identify the compression type")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Leo Martins <loemra.dev@gmail.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: fix u32 to s64 type conversion in dirty_metadata_bytes accounting
Dave Chen [Mon, 29 Jun 2026 07:08:43 +0000 (15:08 +0800)] 
btrfs: fix u32 to s64 type conversion in dirty_metadata_bytes accounting

The percpu_counter dirty_metadata_bytes is updated by negating eb->len
and passing it to percpu_counter_add_batch(), whose amount parameter is
s64.  Since commit 84cda1a6087d ("btrfs: cache folio size and shift in
extent_buffer"), eb->len is u32.  The u32 result of -eb->len, when
widened to the s64 parameter, becomes a large positive value instead of
the intended negative value.  For eb->len == 16384 the counter adds
+4294950912 instead of subtracting 16384.

The counter therefore grows on every metadata writeback instead of
shrinking by the extent buffer size, permanently exceeding
BTRFS_DIRTY_METADATA_THRESH and causing __btrfs_btree_balance_dirty()
to trigger balance_dirty_pages_ratelimited() unconditionally, adding
unnecessary writeback pressure.

Cast eb->len to s64 before negation at both call sites so the
subtraction is performed in signed 64-bit arithmetic.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Fixes: 84cda1a6087d ("btrfs: cache folio size and shift in extent_buffer")
Signed-off-by: Dave Chen <davechen@synology.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: fix NULL pointer deref during assertion in btrfs_backref_free_node()
Filipe Manana [Mon, 29 Jun 2026 14:47:34 +0000 (15:47 +0100)] 
btrfs: fix NULL pointer deref during assertion in btrfs_backref_free_node()

In btrfs_backref_free_node() we have the following assertion:

  ASSERT(node->eb == NULL, "node->eb->start=%llu", node->eb->start);

and a user reported the following crash:

  Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
  KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
  CPU: 0 UID: 0 PID: 10422 Comm: syz.0.17 Not tainted 7.1.0-02765-g6b5a2b7d9bc1-dirty #44 PREEMPT(full)
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
  RIP: 0010:btrfs_backref_free_node fs/btrfs/backref.c:3057 [inline]
  RIP: 0010:btrfs_backref_free_node+0xb9/0x200 fs/btrfs/backref.c:3051
  Code: 00 fc ff (...)
  RSP: 0018:ffa0000006b0f3c0 EFLAGS: 00010246
  RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff840eb78b
  RDX: 0000000000000000 RSI: ffffffff840eafa5 RDI: ff110000742ab768
  RBP: ff110000742ab700 R08: 0000000000000000 R09: 0000000000000000
  R10: ff110000742ab700 R11: 00000000000a81f9 R12: ff11000107a92020
  R13: ff1100005c182ea8 R14: 0000000000000000 R15: dffffc0000000000
  FS:  0000555575536500(0000) GS:ff11000183985000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00007fa3d0e9d580 CR3: 000000002232a000 CR4: 0000000000753ef0
  PKRU: 00000000
  Call Trace:
   <TASK>
   btrfs_backref_cleanup_node+0x27/0x30 fs/btrfs/backref.c:3133
   relocate_tree_block fs/btrfs/relocation.c:2604 [inline]
   relocate_tree_blocks+0x11b0/0x1a20 fs/btrfs/relocation.c:2707
   relocate_block_group+0x499/0xf30 fs/btrfs/relocation.c:3635
   do_nonremap_reloc fs/btrfs/relocation.c:5323 [inline]
   btrfs_relocate_block_group+0x1749/0x5fb0 fs/btrfs/relocation.c:5490
   btrfs_relocate_chunk+0x12b/0x950 fs/btrfs/volumes.c:3647
   __btrfs_balance fs/btrfs/volumes.c:4586 [inline]
   btrfs_balance+0x1c7f/0x55c0 fs/btrfs/volumes.c:4973
   btrfs_ioctl_balance fs/btrfs/ioctl.c:3474 [inline]
   btrfs_ioctl+0x38a4/0x5d20 fs/btrfs/ioctl.c:5570
   vfs_ioctl fs/ioctl.c:51 [inline]
   __do_sys_ioctl fs/ioctl.c:597 [inline]
   __se_sys_ioctl fs/ioctl.c:583 [inline]
   __x64_sys_ioctl+0x18f/0x210 fs/ioctl.c:583
   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
   do_syscall_64+0x11f/0x860 arch/x86/entry/syscall_64.c:94
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
   RIP: 0033:0x7fb38e3b56dd
   Code: 02 b8 ff (...)
   RSP: 002b:00007fff04115788 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
   RAX: ffffffffffffffda RBX: 00007fb38f6b0020 RCX: 00007fb38e3b56dd
   RDX: 00002000000003c0 RSI: 00000000c4009420 RDI: 0000000000000004
   RBP: 00007fb38e451b48 R08: 0000000000000000 R09: 0000000000000000
   R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
   R13: 0000000000000000 R14: 00007fb38f6b0020 R15: 00007fb38f6b002c
   </TASK>

It seems that this happens on some systems for some reason, when the
ASSERT() macro calls the inline function verify_assert_printk_format()
to evaluate the format string and arguments, causing the NULL pointer
dereference on node->eb.

So change the assertion to check for a NULL node->eb before dereferencing
it. Also, while at it, make the assertion more useful by printing the
owner of the extent buffer as well as its level.

Reported-by: Yue Sun <samsun1006219@gmail.com>
Link: https://lore.kernel.org/linux-btrfs/20260626065542.38413-1-samsun1006219@gmail.com/
Fixes: c4e7778580d6 ("btrfs: use verbose assertions in backref.c")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: only account delalloc bytes for regular file inodes in btrfs_getattr()
Dave Chen [Fri, 26 Jun 2026 06:45:24 +0000 (14:45 +0800)] 
btrfs: only account delalloc bytes for regular file inodes in btrfs_getattr()

btrfs_getattr() unconditionally reads BTRFS_I(inode)->new_delalloc_bytes
and adds it (sector-aligned) to stat->blocks for every inode type.
However, new_delalloc_bytes lives in a union with last_dir_index_offset:

    union {
        u64 new_delalloc_bytes;     /* files only */
        u64 last_dir_index_offset;  /* directories only */
    };

For a directory inode this memory holds last_dir_index_offset, which is
set during directory logging (e.g. flush_dir_items_batch()) to the
offset of the last logged BTRFS_DIR_INDEX_KEY.  That offset grows with
the number of entries ever created in the directory (dir indexes are
monotonic and never reused), so it can be arbitrarily large.

As a result, after a directory has been logged (e.g. via an fsync that
triggers directory logging), btrfs_getattr() reports inflated st_blocks
for that directory.  The inflation is purely in-core and disappears
after the inode is evicted and reloaded (btrfs_alloc_inode() zeroes the
union), e.g. after a remount.

Reproducer (on a btrfs filesystem):

    D=/mnt/btrfs/d
    mkdir -p $D
    for i in $(seq 1 20000); do touch $D/f$i; done
    sync                      # commit, push dir index high
    touch $D/trigger          # dirty the dir in a new transaction
    xfs_io -c fsync $D        # log the directory -> sets last_dir_index_offset
    stat -c '%b' $D           # st_blocks is now inflated (e.g. 40)
    # umount + mount -> st_blocks drops back to the correct value

The evict path already knows this union is type-dependent and guards the
corresponding WARN_ON with !S_ISDIR() in btrfs_destroy_inode(); only
btrfs_getattr() was missing the equivalent check.

Only read new_delalloc_bytes for regular files, which are the only
inodes that ever set it.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Dave Chen <davechen@synology.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: reject inline file extents item in get_new_location()
Qu Wenruo [Tue, 23 Jun 2026 11:37:15 +0000 (21:07 +0930)] 
btrfs: reject inline file extents item in get_new_location()

Commit a6908f88c9da ("btrfs: validate data reloc tree file extent item
members") introduced extra checks on file extent items for data reloc
inodes, but it checked the file extent offset without checking if the file
extent is inlined.

This can lead to either false alerts (as the offset member is inside the
inlined data) or even reading beyond the item range.

This has already triggered a warning in a syzbot report.
Although the root fix is to avoid compression for data reloc inodes, for
the sake of consistency, reject inlined file extents first.

Fixes: a6908f88c9da ("btrfs: validate data reloc tree file extent item members")
CC: stable@vger.kernel.org
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: do not try compression for data reloc inodes
Qu Wenruo [Tue, 23 Jun 2026 11:37:14 +0000 (21:07 +0930)] 
btrfs: do not try compression for data reloc inodes

[BUG]
There is a syzbot report that the check inside get_new_location()
triggered:

  BTRFS info (device loop0): found 31 extents, stage: move data extents
  BTRFS info (device loop0): leaf 8908800 gen 16 total ptrs 28 free space 1676 owner 18446744073709551607
         item 0 key (256 INODE_ITEM 0) itemoff 3835 itemsize 160
                 inode generation 5 transid 0 size 0 nbytes 0
                 block group 0 mode 40755 links 1 uid 0 gid 0
                 rdev 0 sequence 0 flags 0x0
                 atime 1669132761.0
                 ctime 1669132761.0
                 mtime 1669132761.0
                 otime 0.0
         item 1 key (256 INODE_REF 256) itemoff 3823 itemsize 12
                 index 0 name_len 2
         item 2 key (258 INODE_ITEM 0) itemoff 3663 itemsize 160
                 inode generation 1 transid 16 size 733184 nbytes 106496
                 block group 0 mode 100600 links 0 uid 0 gid 0
                 rdev 0 sequence 24 flags 0x18
         item 3 key (258 EXTENT_DATA 0) itemoff 3595 itemsize 68
                 generation 16 type 0
                 inline extent data size 47 ram_bytes 4096 compression 1
  [...]
         item 27 key (18446744073709551611 ORPHAN_ITEM 258) itemoff 2376 itemsize 0
  BTRFS error (device loop0): unexpected non-zero offset in file extent item for data reloc inode 258 key offset 0 offset 9277520992061368337
  ------------[ cut here ]------------
  btrfs_abort_should_print_stack(__error)

[CAUSE]
The above dump tree shows the first file extent item is inlined, which
should make no sense for data reloc inodes, as such inodes just
represent where the data extents are in the relocation destination chunk.

However the relocation path preallocates space for each block,
then dirties them, cluster by cluster.
It's possible to have a single block at the beginning of the block
group, and no other block in the same cluster.

So relocation will preallocate a file extent for that block and dirty
the first block.  Then memory pressure forces the data reloc inode to be
written back, before any other blocks are dirtied/allocated.

Finally commit 3eaf5f082c4c ("btrfs: extract inlined creation into a dedicated
delalloc helper") changed the sequence of delalloc. Before that commit we
always tried NOCOW first, so that dirtied block would be written back into
the preallocated space, and appear as a regular extent.

But with that commit, we always try inline first, and since compression
is forced, we try compressing the first block, and then inline the
compressed data, resulting in the above inlined file extent in the data
reloc tree.

Then the check in get_new_location() will check the file offset, without
checking if the file extent is inlined or not, resulting in the above
failure.

[FIX]
Do not allow compression for data reloc inodes.

Since data reloc inode sizes are always block aligned, as long as we do
not compress, @data_len will always be at least one block, and
that will cause can_cow_file_range_inline() to return false, thus no
inlined extent will be created.

Reported-by: syzbot+d950c6ba09b79f6e1864@syzkaller.appspotmail.com
Link: https://lore.kernel.org/linux-btrfs/6a373dc5.764cf64f.168fbe.0001.GAE@google.com/
Fixes: 3eaf5f082c4c ("btrfs: extract inlined creation into a dedicated delalloc helper")
CC: stable@vger.kernel.org
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: declare btrfs_ioctl_search_args_v2::buf as __u8
You-Kai Zheng [Tue, 16 Jun 2026 10:39:07 +0000 (18:39 +0800)] 
btrfs: declare btrfs_ioctl_search_args_v2::buf as __u8

The variable-sized buffer buf in struct btrfs_ioctl_search_args_v2 is
declared as __u64[], but it holds a packed byte stream of search results,
where all offsets into the buffer are in bytes.

Declaring buf as __u64[] makes it easy for user space to write incorrect
pointer arithmetic: adding a byte offset directly to a __u64 pointer
scales the offset by 8, landing at byte position offset*8 instead of
offset.

This recently caused an infinite loop in btrfs-progs: the accessor read
all-zero data from misaddressed items, which fed zeroed search keys back
into the ioctl loop and spun forever. The issue was worked around at the
time by disabling TREE_SEARCH_V2 entirely in btrfs-progs (d73e69824854:
"btrfs-progs: temporarily disable usage of v2 of search tree ioctl").

The kernel side already treats buf as a byte buffer, so change the
declaration to __u8[] to match the actual semantics and prevent similar
misuse in user space. The change is ABI compatible: both the structure size
and alignment are unchanged.

Fixes: cc68a8a5a433 ("btrfs: new ioctl TREE_SEARCH_V2")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: You-Kai Zheng <ykzheng@synology.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: fix reloc root cleanup in merge_reloc_roots()
Filipe Manana [Fri, 12 Jun 2026 10:52:55 +0000 (11:52 +0100)] 
btrfs: fix reloc root cleanup in merge_reloc_roots()

If the root we got has zero root refs in its root item, we are resetting
the root's ->reloc_root without using barriers like we do everywhere else.
Sashiko complained about this while reviewing another patch, and it's
correct (see the Link tag below).

Also, we should not clear BTRFS_ROOT_DEAD_RELOC_TREE from the root unless
the root points to the reloc root we have.

Fix this by using clear_reloc_root(), which issues the memory barrier
after setting the root's ->reloc_root to NULL and before clearing the bit
BTRFS_ROOT_DEAD_RELOC_TREE from the root.

Link: https://sashiko.dev/#/patchset/cf84f1a217c719e25b6b69e4298dd7afd36c9427.1781194426.git.fdmanana%40suse.com
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agobtrfs: fix use-after-free on reloc root after error in insert_dirty_subvol()
Filipe Manana [Tue, 9 Jun 2026 15:45:39 +0000 (16:45 +0100)] 
btrfs: fix use-after-free on reloc root after error in insert_dirty_subvol()

If during relocation we fail in insert_dirty_subvol() because
btrfs_update_reloc_root() returned an error, we will leave a root's
reloc_root field pointing to a reloc root that was freed instead of NULL,
resulting later in a use-after-free, or double free attempt during
unmount.

The sequence of steps is this:

1) During relocation the call to btrfs_update_reloc_root() in
   insert_dirty_subvol() fails, so insert_dirty_subvol() returns the
   error to merge_reloc_root() without adding the root to the list
   rc->dirty_subvol_roots;

2) Then merge_reloc_root() aborts the current transaction because
   insert_dirty_subvol() returned an error;

3) Up the call chain, merge_reloc_roots() gets the error, adds the
   reloc root for root X to the local reloc_roots list and jumps to the
   'out' label, where it calls free_reloc_roots() to free all the reloc
   roots in the local reloc_roots list. This frees the reloc root for
   root X;

4) We go up the call chain to relocate_block_group() which calls
   clean_dirty_subvols() to go over dirty roots and set their
   ->reloc_root field to NULL, but root X is not in the dirty_subvol_roots
   list, so its ->reloc_root still points to a reloc root;

5) Relocation finishes, with an error and a transaction abort, but the
   ->reloc_root field for root X still points to the reloc root that was
   freed in step 3;

6) When unmounting the fs we end up calling:

     btrfs_free_fs_roots()
        btrfs_drop_and_free_fs_root()
           --> calls btrfs_put_root() against root X's ->reloc_root
               which is not NULL and points to the already freed
               reloc root in step 4 above

  Resulting in a use-after-free to a double free attempt.

Syzbot reported this with the following dmesg/syslog:

   [  106.004389][ T5339] BTRFS error (device loop0 state A): Transaction aborted (error -5)
   [  106.014266][ T5339] BTRFS: error (device loop0 state A) in merge_reloc_root:1655: errno=-5 IO failure
   [  106.021891][ T1061] BTRFS error (device loop0 state A): error while writing out transaction: -5
   [  106.026964][ T1061] BTRFS warning (device loop0 state A): Skipping commit of aborted transaction.
   [  106.033807][ T5340] BTRFS error (device loop0 state A): bdev /dev/loop0 errs: wr 3, rd 0, flush 0, corrupt 0, gen 0
   [  106.039265][ T1061] BTRFS: error (device loop0 state A) in cleanup_transaction:2067: errno=-5 IO failure
   [  106.044382][ T5339] BTRFS info (device loop0 state EA): forced readonly
   [  106.074329][ T5339] BTRFS: error (device loop0 state EA) in merge_reloc_roots:1887: errno=-5 IO failure
   [  106.081004][ T5356] BTRFS info (device loop0 state EA): scrub: started on devid 1
   [  106.085611][ T5339] BTRFS info (device loop0 state EA): balance: ended with status: -30
   [  106.089517][ T5356] BTRFS info (device loop0 state EA): scrub: not finished on devid 1 with status: -30
   [  106.662365][ T5338] BTRFS info (device loop0 state EA): last unmount of filesystem 3a375e4e-b156-4d76-a2ad-16e198ce1409
   [  106.682946][ T5338] ==================================================================
   [  106.686574][ T5338] BUG: KASAN: slab-use-after-free in btrfs_put_root+0x2f/0x250
   [  106.690090][ T5338] Write of size 4 at addr ffff88803f978630 by task syz.0.0/5338
   [  106.693173][ T5338]
   [  106.694279][ T5338] CPU: 0 UID: 0 PID: 5338 Comm: syz.0.0 Not tainted syzkaller #0 PREEMPT(full)
   [  106.694293][ T5338] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
   [  106.694300][ T5338] Call Trace:
   [  106.694308][ T5338]  <TASK>
   [  106.694314][ T5338]  dump_stack_lvl+0xe8/0x150
   [  106.694331][ T5338]  print_address_description+0x55/0x1e0
   [  106.694343][ T5338]  ? btrfs_put_root+0x2f/0x250
   [  106.694358][ T5338]  print_report+0x58/0x70
   [  106.694368][ T5338]  kasan_report+0x117/0x150
   [  106.694384][ T5338]  ? btrfs_put_root+0x2f/0x250
   [  106.694399][ T5338]  kasan_check_range+0x264/0x2c0
   [  106.694416][ T5338]  btrfs_put_root+0x2f/0x250
   [  106.694430][ T5338]  btrfs_drop_and_free_fs_root+0x160/0x210
   [  106.694447][ T5338]  btrfs_free_fs_roots+0x2f9/0x3c0
   [  106.694464][ T5338]  ? __pfx_btrfs_free_fs_roots+0x10/0x10
   [  106.694479][ T5338]  ? free_root_pointers+0x5bf/0x5f0
   [  106.694494][ T5338]  close_ctree+0x798/0x12d0
   [  106.694511][ T5338]  ? __pfx_close_ctree+0x10/0x10
   [  106.694526][ T5338]  ? _raw_spin_unlock_irqrestore+0x74/0x80
   [  106.694599][ T5338]  ? rcu_preempt_deferred_qs_irqrestore+0x906/0xbc0
   [  106.694620][ T5338]  ? __rcu_read_unlock+0x83/0xe0
   [  106.694636][ T5338]  ? btrfs_put_super+0x48/0x1c0
   [  106.694652][ T5338]  ? __pfx_btrfs_put_super+0x10/0x10
   [  106.694667][ T5338]  generic_shutdown_super+0x13d/0x2d0
   [  106.694682][ T5338]  kill_anon_super+0x3b/0x70
   [  106.694695][ T5338]  btrfs_kill_super+0x41/0x50
   [  106.694710][ T5338]  deactivate_locked_super+0xbc/0x130
   [  106.694722][ T5338]  cleanup_mnt+0x437/0x4d0
   [  106.694736][ T5338]  ? _raw_spin_unlock_irq+0x23/0x50
   [  106.694752][ T5338]  task_work_run+0x1d9/0x270
   [  106.694769][ T5338]  ? __pfx_task_work_run+0x10/0x10
   [  106.694784][ T5338]  ? do_raw_spin_unlock+0x4d/0x210
   [  106.694802][ T5338]  do_exit+0x70f/0x22c0
   [  106.694817][ T5338]  ? trace_irq_disable+0x3b/0x140
   [  106.694835][ T5338]  ? __pfx_do_exit+0x10/0x10
   [  106.694848][ T5338]  ? preempt_schedule_thunk+0x16/0x30
   [  106.694863][ T5338]  ? preempt_schedule_common+0x82/0xd0
   [  106.694878][ T5338]  ? preempt_schedule_thunk+0x16/0x30
   [  106.694892][ T5338]  do_group_exit+0x21b/0x2d0
   [  106.694906][ T5338]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
   [  106.694918][ T5338]  __x64_sys_exit_group+0x3f/0x40
   [  106.694932][ T5338]  x64_sys_call+0x221a/0x2240
   [  106.694944][ T5338]  do_syscall_64+0x174/0x580
   [  106.694954][ T5338]  ? clear_bhb_loop+0x40/0x90
   [  106.694967][ T5338]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
   [  106.694978][ T5338] RIP: 0033:0x7f958ef9ce59
   [  106.694988][ T5338] Code: Unable to access opcode bytes at 0x7f958ef9ce2f.
   [  106.694994][ T5338] RSP: 002b:00007fffd4058318 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
   [  106.695008][ T5338] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f958ef9ce59
   [  106.695015][ T5338] RDX: 00007f958c3f8000 RSI: 0000000000000000 RDI: 0000000000000000
   [  106.695022][ T5338] RBP: 0000000000000003 R08: 0000000000000000 R09: 00007f958f1e73e0
   [  106.695028][ T5338] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
   [  106.695034][ T5338] R13: 00007f958f1e73e0 R14: 0000000000000003 R15: 00007fffd40583d0
   [  106.695046][ T5338]  </TASK>
   [  106.695050][ T5338]
   [  106.821635][ T5338] Allocated by task 1061:
   [  106.823446][ T5338]  kasan_save_track+0x3e/0x80
   [  106.825498][ T5338]  __kasan_kmalloc+0x93/0xb0
   [  106.827381][ T5338]  __kmalloc_cache_noprof+0x31c/0x660
   [  106.829525][ T5338]  btrfs_alloc_root+0x75/0x930
   [  106.831458][ T5338]  read_tree_root_path+0x127/0xb00
   [  106.833556][ T5338]  btrfs_read_tree_root+0x34/0x60
   [  106.835553][ T5338]  create_reloc_root+0x6b3/0xcb0
   [  106.837556][ T5338]  btrfs_init_reloc_root+0x2ec/0x4b0
   [  106.839557][ T5338]  record_root_in_trans+0x2ab/0x350
   [  106.841685][ T5338]  btrfs_record_root_in_trans+0x15c/0x180
   [  106.844237][ T5338]  start_transaction+0x39c/0x1820
   [  106.846638][ T5338]  btrfs_finish_one_ordered+0x88e/0x2680
   [  106.849436][ T5338]  btrfs_work_helper+0x37b/0xc20
   [  106.851549][ T5338]  process_scheduled_works+0xb5d/0x1860
   [  106.853807][ T5338]  worker_thread+0xa53/0xfc0
   [  106.855773][ T5338]  kthread+0x389/0x470
   [  106.857548][ T5338]  ret_from_fork+0x514/0xb70
   [  106.859493][ T5338]  ret_from_fork_asm+0x1a/0x30
   [  106.861504][ T5338]
   [  106.862527][ T5338] Freed by task 5339:
   [  106.864224][ T5338]  kasan_save_track+0x3e/0x80
   [  106.866180][ T5338]  kasan_save_free_info+0x46/0x50
   [  106.868371][ T5338]  __kasan_slab_free+0x5c/0x80
   [  106.870462][ T5338]  kfree+0x1c5/0x640
   [  106.872180][ T5338]  __del_reloc_root+0x341/0x3b0
   [  106.874290][ T5338]  free_reloc_roots+0x5f/0x90
   [  106.876282][ T5338]  merge_reloc_roots+0x73f/0x8a0
   [  106.878489][ T5338]  relocate_block_group+0xbcc/0xe70
   [  106.880742][ T5338]  do_nonremap_reloc+0xa8/0x5b0
   [  106.882885][ T5338]  btrfs_relocate_block_group+0x7e6/0xc40
   [  106.885336][ T5338]  btrfs_relocate_chunk+0x115/0x820
   [  106.887502][ T5338]  __btrfs_balance+0x1db0/0x2ae0
   [  106.889543][ T5338]  btrfs_balance+0xaf3/0x11b0
   [  106.891456][ T5338]  btrfs_ioctl_balance+0x3d3/0x610
   [  106.893672][ T5338]  __se_sys_ioctl+0xfc/0x170
   [  106.895530][ T5338]  do_syscall_64+0x174/0x580
   [  106.897518][ T5338]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
   [  106.900101][ T5338]
   [  106.901123][ T5338] The buggy address belongs to the object at ffff88803f978000
   [  106.901123][ T5338]  which belongs to the cache kmalloc-4k of size 4096
   [  106.906907][ T5338] The buggy address is located 1584 bytes inside of
   [  106.906907][ T5338]  freed 4096-byte region [ffff88803f978000ffff88803f979000)
   [  106.912980][ T5338]
   [  106.914022][ T5338] The buggy address belongs to the physical page:
   [  106.916716][ T5338] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x3f978
   [  106.920390][ T5338] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
   [  106.923834][ T5338] flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff)
   [  106.927104][ T5338] page_type: f5(slab)
   [  106.928898][ T5338] raw: 04fff00000000040 ffff88801ac42140 dead000000000122 0000000000000000
   [  106.932507][ T5338] raw: 0000000000000000 0000000800040004 00000000f5000000 0000000000000000
   [  106.936193][ T5338] head: 04fff00000000040 ffff88801ac42140 dead000000000122 0000000000000000
   [  106.939856][ T5338] head: 0000000000000000 0000000800040004 00000000f5000000 0000000000000000
   [  106.943601][ T5338] head: 04fff00000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
   [  106.947268][ T5338] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
   [  106.950988][ T5338] page dumped because: kasan: bad access detected
   [  106.953710][ T5338] page_owner tracks the page as allocated
   [  106.956198][ T5338] page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 24, tgid 24 (kworker/u4:2), ts 105728970387, free_ts 29540875453
   [  106.964984][ T5338]  post_alloc_hook+0x22d/0x280
   [  106.966956][ T5338]  get_page_from_freelist+0x2593/0x2610
   [  106.969307][ T5338]  __alloc_frozen_pages_noprof+0x18d/0x380
   [  106.971839][ T5338]  allocate_slab+0x77/0x660
   [  106.973709][ T5338]  refill_objects+0x339/0x3d0
   [  106.975696][ T5338]  __pcs_replace_empty_main+0x321/0x720
   [  106.978136][ T5338]  __kmalloc_node_track_caller_noprof+0x572/0x7b0
   [  106.981009][ T5338]  __alloc_skb+0x2c1/0x7d0
   [  106.982983][ T5338]  nsim_dev_trap_report_work+0x29a/0xb90
   [  106.985356][ T5338]  process_scheduled_works+0xb5d/0x1860
   [  106.987710][ T5338]  worker_thread+0xa53/0xfc0
   [  106.989847][ T5338]  kthread+0x389/0x470
   [  106.991727][ T5338]  ret_from_fork+0x514/0xb70
   [  106.993722][ T5338]  ret_from_fork_asm+0x1a/0x30
   [  106.995900][ T5338] page last free pid 77 tgid 77 stack trace:
   [  106.998479][ T5338]  __free_frozen_pages+0xc1c/0xd30
   [  107.000819][ T5338]  vfree+0x1d1/0x2f0
   [  107.002631][ T5338]  delayed_vfree_work+0x55/0x80
   [  107.004848][ T5338]  process_scheduled_works+0xb5d/0x1860
   [  107.007366][ T5338]  worker_thread+0xa53/0xfc0
   [  107.009388][ T5338]  kthread+0x389/0x470
   [  107.011177][ T5338]  ret_from_fork+0x514/0xb70
   [  107.013313][ T5338]  ret_from_fork_asm+0x1a/0x30
   [  107.015454][ T5338]
   [  107.016460][ T5338] Memory state around the buggy address:
   [  107.019052][ T5338]  ffff88803f978500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
   [  107.022691][ T5338]  ffff88803f978580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
   [  107.026264][ T5338] >ffff88803f978600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
   [  107.029721][ T5338]                                      ^
   [  107.032062][ T5338]  ffff88803f978680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
   [  107.035547][ T5338]  ffff88803f978700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
   [  107.038865][ T5338] ==================================================================

Fix this by resetting a root's ->reloc_root if we get an error while
trying to merge a reloc root.

Reported-by: syzbot+b3d472d13f9d7bf20669@syzkaller.appspotmail.com
Link: https://lore.kernel.org/linux-btrfs/6a1ebde9.c1435f33.112120.0176.GAE@google.com/
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
3 weeks agoMerge tag 'cgroup-for-7.2-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel...
Linus Torvalds [Mon, 13 Jul 2026 23:14:06 +0000 (16:14 -0700)] 
Merge tag 'cgroup-for-7.2-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup

Pull cgroup fixes from Tejun Heo:

 - A cpuset that never set its memory nodes could divide by zero when a
   task's mempolicy rebinds on CPU hotplug. Rebind against the effective
   nodes, which are always populated

 - Documentation fixes for memory.stat, io.stat, and the misc and v1
   RDMA controllers

* tag 'cgroup-for-7.2-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  Docs/admin-guide/cgroup-v2: note blkcg_debug_stats gates io.latency stats
  Docs/admin-guide/cgroup-v1: document rdma.peak, rdma.events and rdma.events.local
  Docs/admin-guide/cgroup-v2: drop stale misc interface file count
  cgroup/cpuset: rebind mm mempolicy to effective_mems, not mems_allowed
  Docs/admin-guide/cgroup-v2: fix memory.stat doc details

3 weeks agoMerge tag 'sched_ext-for-7.2-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel...
Linus Torvalds [Mon, 13 Jul 2026 22:55:17 +0000 (15:55 -0700)] 
Merge tag 'sched_ext-for-7.2-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext

Pull sched_ext fixes from Tejun Heo:

 - Lifecycle fixes for the new sub-scheduler support: two
   use-after-frees and an enable-failure path that left a
   half-initialized sub-scheduler linked.

 - Two dispatch-path locking bugs: a spurious scheduler abort from a
   migration race, and a lockdep splat from stale runqueue-lock
   tracking.

 - Callback and task-state fixes: stale scheduler-owned state on a task
   leaving SCX, a weight callback running after disable, and a bogus
   warning on core-scheduling forced idle.

 - On nohz_full, finite-slice tasks could miss the tick that expires
   their slice. Enable it when such a task is picked, with a selftest.

 - Smaller fixes: userspace CPU-mask helpers, ratelimited deprecation
   warnings, docs and a sparse annotation.

* tag 'sched_ext-for-7.2-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext:
  sched_ext: Skip ops.set_weight() for disabled tasks
  tools/sched_ext: scx - Fix cmask_subset(), cmask_equal() and cmask_weight()
  sched_ext: Fix premature ops->priv publication in scx_alloc_and_add_sched()
  sched_ext: Record an error on errno-only sub-enable failure
  selftests/sched_ext: Verify nohz_full tick behavior
  sched_ext: Enable tick for finite slices on nohz_full
  sched_ext: Preserve rq tracking across local DSQ dispatch
  sched_ext: Documentation: Fix ops table header reference
  sched_ext: Don't warn on core-sched forced idle in put_prev_task_scx()
  sched_ext: Pin parent scx_sched across a child sub-scheduler's lifetime
  sched_ext: Annotate ksyncs with __rcu in alloc/free_kick_syncs()
  sched_ext: Check remote rq eligibility under task's rq lock
  sched_ext: Reset dsq_vtime and slice when a task leaves SCX
  sched_ext: Avoid flooding the log with deprecation warnings

3 weeks agoMerge tag 'trace-tools-v7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git...
Linus Torvalds [Mon, 13 Jul 2026 22:22:58 +0000 (15:22 -0700)] 
Merge tag 'trace-tools-v7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull RTLA fixes from Steven Rostedt:

 - Fix missing unistd include

   A missing #include <unistd.h> broke build on uclibc systems.
   Add the include to fix it.

 - Fix missing tools/lib/ctype.c dependency

   RTLA links tools/lib/string.c as a dependency of libsubcmd, some of
   its functions require _ctype. Link tools/lib/ctype.c as well, to fix
   build without GCC LTO.

* tag 'trace-tools-v7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  rtla: Also link in ctype.c
  rtla: Fix missing unistd include

3 weeks agodrm/i915/gt: use correct selftest config symbol
Pengpeng Hou [Sun, 5 Jul 2026 08:02:25 +0000 (16:02 +0800)] 
drm/i915/gt: use correct selftest config symbol

intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running
the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST,
without the trailing "S", and the rest of i915 uses
CONFIG_DRM_I915_SELFTEST.

Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol,
the IS_ENABLED() test is always false. Use the existing selftest symbol
so the debug/selftest guarded path can be reached when selftests are
enabled.

This is a source-level fix. It does not claim dynamic hardware
reproduction; the evidence is the Kconfig definition and the inconsistent
guard in intel_engine_user.c.

Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn
(cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
3 weeks agoASoC: amd: acp: add ACP70 DMI override for new ASUS TUF platforms
Syed Saba Kareem [Fri, 10 Jul 2026 10:29:19 +0000 (15:59 +0530)] 
ASoC: amd: acp: add ACP70 DMI override for new ASUS TUF platforms

Some ASUS TUF ACP70-based systems expose ACP ACPI configuration flags
that select a non-working fallback audio path, similar to previously
affected ASUS platforms.

Add DMI-based overrides in snd_amd_acp_find_config() for the following
systems to skip ACP ACPI flag-based selection:

  - ASUS TUF Gaming Vivobook 18
  - ASUS TUF Gaming A14 FA401EA

This ensures the intended SoundWire-based machine driver is selected on
these platforms.

Signed-off-by: Syed Saba Kareem <Syed.SabaKareem@amd.com>
Link: https://patch.msgid.link/20260710102926.1633385-1-syed.sabakareem@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
3 weeks agoriscv: vdso: Do not use LTO for the vDSO
Thomas Weißschuh [Wed, 1 Jul 2026 09:21:22 +0000 (11:21 +0200)] 
riscv: vdso: Do not use LTO for the vDSO

With LTO enabled the compiler assumes that the vDSO functions are not
used and optimizes them away completely. Currently this happens to
__vdso_clock_getres(), __vdso_clock_gettime(), __vdso_getrandom(),
__vdso_gettimeofday() and __vdso_riscv_hwprobe().

Disable LTO for the vDSO, as these functions are hand-optimized anyways.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202606301855.WvkSC4kD-lkp@intel.com/
Fixes: 021d23428bdb ("RISC-V: build: Allow LTO to be selected")
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Link: https://patch.msgid.link/20260701-riscv-vdso-lto-v1-1-89db0cd82077@linutronix.de
Signed-off-by: Paul Walmsley <pjw@kernel.org>
3 weeks agoriscv: io: avoid null-pointer arithmetic in PIO helpers
Yunhui Cui [Fri, 3 Jul 2026 12:28:30 +0000 (20:28 +0800)] 
riscv: io: avoid null-pointer arithmetic in PIO helpers

When port I/O is not supported, exposing the port-string helpers is both
unnecessary and can make clang diagnose null-pointer arithmetic from the
PCI_IOBASE based address expression.  Keep the MMIO string helpers
available as before, but only provide the port I/O variants when
CONFIG_HAS_IOPORT is enabled.

Signed-off-by: Yunhui Cui <cuiyunhui@bytedance.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20260703122832.15984-2-cuiyunhui@bytedance.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
3 weeks agoriscv: Gate FUNCTION_ALIGNMENT_4B on DYNAMIC_FTRACE
Rui Qi [Mon, 6 Jul 2026 13:04:14 +0000 (21:04 +0800)] 
riscv: Gate FUNCTION_ALIGNMENT_4B on DYNAMIC_FTRACE

The FUNCTION_ALIGNMENT_4B select forces the whole kernel to be built
with -fmin-function-alignment=4. This alignment is only needed so the
patchable-function-entry NOPs, which arch/riscv/Makefile emits under
CONFIG_DYNAMIC_FTRACE, can be patched reliably on RISCV_ISA_C=y builds
where compressed instructions otherwise allow 2-byte function
alignment.

The select is currently gated on HAVE_DYNAMIC_FTRACE, a capability bit
that is selected whenever the toolchain supports dynamic ftrace, rather
than on whether tracing is actually enabled. As a result every
RISCV_ISA_C=y build gets 4-byte function alignment across the entire
kernel even when function tracing is disabled, needlessly growing the
kernel image and wasting instruction cache for a feature that is not
in use.

Gate the select on DYNAMIC_FTRACE instead, matching the condition under
which arch/riscv/Makefile emits -fpatchable-function-entry, so the
alignment is only applied when it is actually needed.

Fixes: c41bf4326c7b ("riscv: ftrace: align patchable functions to 4 Byte boundary")
Signed-off-by: Rui Qi <qirui.001@bytedance.com>
Link: https://patch.msgid.link/20260706130415.463682-1-qirui.001@bytedance.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
3 weeks agomm/sparse-vmemmap: flush_cache_vmap() after hotplugging vmemmap
Vivian Wang [Mon, 13 Jul 2026 17:29:52 +0000 (11:29 -0600)] 
mm/sparse-vmemmap: flush_cache_vmap() after hotplugging vmemmap

section_activate() does not flush TLB after populating new vmemmap
pages. On most architectures, this is okay. However it is a problem on
RISC-V since there the TLB caching non-present entries is permitted,
which causes spurious faults on some hardwares.

This seems to be most easily reproduced with DEBUG_VM=y and
PAGE_POISONING=y, which causes these newly mapped struct pages to be
poisoned i.e. written to immediately after mapping.

Extend the RISC-V flush_cache_vmap() to also handle the vmemmap range,
and call it after hotplugging vmemmap, which gets the possible spurious
fault handled in the exception handler.

At least for now, the only other architecture with both
SPARSEMEM_VMEMMAP and flush_cache_vmap() is PowerPC, which has a similar
problem with newly valid PTEs. But there flush_cache_vmap() is just a
ptesync. So it should be safe to do this for generic code while having
minimal performance impact.

Suggested-by: Muchun Song <muchun.song@linux.dev>
Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Link: https://patch.msgid.link/20260713-mark-after-vmemmap-populate-v6-2-b945ceba29d4@iscas.ac.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>
3 weeks agoriscv: mm: Make mark_new_valid_map() stuff depend on 64BIT && MMU
Vivian Wang [Mon, 13 Jul 2026 17:29:52 +0000 (11:29 -0600)] 
riscv: mm: Make mark_new_valid_map() stuff depend on 64BIT && MMU

None of the code relating to mark_new_valid_map() does anything useful
without CONFIG_64BIT=y && CONFIG_MMU=y, because the
new_valid_map_cpus_check code is only used if CONFIG_64BIT, and the
exception codes checked there can only happen with CONFIG_MMU=y.

Therefore, make these conditional on CONFIG_64BIT=y && CONFIG_MMU=y to
simplify programming, since we do not have to handle CONFIG_MMU=n when
changing this code in the future. This also removes some unused code on
the entry path for CONFIG_MMU=n.

Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
Link: https://patch.msgid.link/20260713-mark-after-vmemmap-populate-v6-1-b945ceba29d4@iscas.ac.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>
3 weeks agoiommufd: Reject DMABUF pages from the access pin path
Peiyang He [Thu, 9 Jul 2026 05:08:00 +0000 (13:08 +0800)] 
iommufd: Reject DMABUF pages from the access pin path

DMABUF pages are not supported for iommufd access pinning.
iommufd_access_pin_pages() returns struct page pointers for
in-kernel CPU access, but DMABUF-backed iopt_pages do not carry
a userspace address that can be passed to the GUP path.

iopt_pages_rw_access() already rejects IOPT_ADDRESS_DMABUF before doing
CPU access. Apply the same rejection to iopt_area_add_access() before it
takes pages->mutex and calls iopt_pages_fill_xarray().
Otherwise a DMABUF-backed iopt_pages can reach the hole-fill path, where
pfn_reader_user_pin() interprets the union as uptr and
calls pin_user_pages_fast()/pin_user_pages_remote().

This fix also avoids the lockdep warning reported from that path, where
pages_dmabuf_mutex_key is held while gup_fast_fallback() may acquire
mmap_lock.

Link: https://patch.msgid.link/r/CD68F549BF3761B7+20260709050800.520607-1-peiyang_he@smail.nju.edu.cn
Reported-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Closes: https://lore.kernel.org/all/E8540D7D05768C91+8b2ef227-3368-494e-909d-7b28e1489dfb@smail.nju.edu.cn/
Fixes: 71db84a092c3 ("iommufd: Add DMABUF to iopt_pages")
Cc: stable@vger.kernel.org
Tested-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
3 weeks agoiommufd: Fix wrong hwpt passed to iommufd_auto_response_faults on replace
Peiyang He [Fri, 10 Jul 2026 12:29:52 +0000 (20:29 +0800)] 
iommufd: Fix wrong hwpt passed to iommufd_auto_response_faults on replace

iommufd_hwpt_replace_device() calls:

iommufd_auto_response_faults(hwpt, old_handle);

passing the *new* hwpt together with the handle of
the device's *old* domain. This should be a parameter mismatch:

1. Semantically, iommufd_auto_response_faults(x, handle) scans
   x->fault's deliver list and response xarray for groups matching
   "handle". A group is queued under the hwpt that was attached at
   fault-delivery time. old_handle is fetched *before* the domain switch,
   so its group lives on old->fault, not on the new hwpt->fault.

2. Historically, the first argument was "old". The routine was
   introduced by commit b7d8833677ba ("iommufd: Fault-capable hwpt
   attach/detach/replace") as __fault_domain_replace_dev() in
   fault.c, correctly calling iommufd_auto_response_faults(old, curr).
   Commit fb21b1568ada ("iommufd: Make attach_handle generic than
   fault specific") moved this into iommufd_hwpt_replace_device() in
   device.c and swapped it to "hwpt". This should be a refactor regression,
   not an intentional change.

Fix this by passing "old" instead.

Link: https://patch.msgid.link/r/9D652384339C69D5+20260710122952.885325-1-peiyang_he@smail.nju.edu.cn
Fixes: fb21b1568ada ("iommufd: Make attach_handle generic than fault specific")
Cc: stable@vger.kernel.org
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
3 weeks agodrm/virtio: fix deadlock in display_info_cb by removing hotplug from dequeue worker
Ryosuke Yasuoka [Mon, 13 Jul 2026 13:01:00 +0000 (22:01 +0900)] 
drm/virtio: fix deadlock in display_info_cb by removing hotplug from dequeue worker

A probe-time deadlock can occur between the dequeue worker and
drm_client_register(). During probe, drm_client_register() holds
clientlist_mutex and calls the fbdev hotplug callback, which triggers an
atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs()
waiting for virtqueue space. The dequeue worker that would free that
space calls virtio_gpu_cmd_get_display_info_cb(), which invokes
drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting
to acquire the same clientlist_mutex. Since wake_up() is only called
after the resp_cb loop, the probe thread is never woken and both threads
deadlock.

Fix this by removing the hotplug notification from
virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info)
is still updated synchronously in the callback.

For the init path, drm_client_register() already fires an initial
hotplug when the client is registered, which picks up the connector
state updated by display_info_cb.

For the runtime config_changed path, add a wait_event_timeout() in
config_changed_work_func() so that display_info_cb updates the connector
data before the hotplug notification is sent. Also replace
drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since
virtio-gpu never calls drm_kms_helper_poll_init() and thus
drm_helper_hpd_irq_event() always returns false without doing anything.

Fixes: 27655b9bb9f0 ("drm/client: Send hotplug event after registering a client")
Closes: https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224
Closes: https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e
Suggested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260713-virtiogpu_syzbot-v2-1-2958fa37d46d@redhat.com
3 weeks agodrm/virtio: Don't detach GEM from a non-created context
Jason Macnak [Thu, 25 Jun 2026 17:08:28 +0000 (10:08 -0700)] 
drm/virtio: Don't detach GEM from a non-created context

Applies the same treatment as commit 7cf6dd467e87 ("drm/virtio:
Don't attach GEM to a non-created context in gem_object_open()")
to virtio_gpu_gem_object_close() to avoid trying to detach
a resource that was never attached due to a context
never being created when context_init is supported.

Fixes: 086b9f27f0ab ("drm/virtio: Don't create a context with default param if context_init is supported")
Cc: <stable@vger.kernel.org> # v6.14+
Signed-off-by: Jason Macnak <natsu@google.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260625170828.3335431-1-natsu@google.com
3 weeks agoMerge tag 'nfsd-7.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Linus Torvalds [Mon, 13 Jul 2026 15:38:01 +0000 (08:38 -0700)] 
Merge tag 'nfsd-7.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull nfsd fix from Chuck Lever:

 - Fix a use-after-free when unlocking a filesystem

* tag 'nfsd-7.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
  NFSD: Prevent post-shutdown use-after-free in NFSD_CMD_UNLOCK_FILESYSTEM

3 weeks agosmb: client: reject overlapping data areas in SMB2 responses
Shoichiro Miyamoto [Sat, 11 Jul 2026 13:33:26 +0000 (22:33 +0900)] 
smb: client: reject overlapping data areas in SMB2 responses

Commit 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to
responses without data area") restricted the implied bcc[0] length
exception to responses without a data area. However, the overlap
handling in __smb2_calc_size() clears data_length, which can make an
invalid response appear to have no data area and so qualify for the
exception.

Track data area overlap separately and reject such responses before
applying the length compatibility exceptions.

Fixes: 53b7c271f06b ("smb: client: restrict implied bcc[0] exemption to responses without data area")
Cc: stable@vger.kernel.org
Signed-off-by: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
3 weeks agosmb/client: refresh allocation after EOF-extending fallocate
Huiwen He [Fri, 3 Jul 2026 05:32:59 +0000 (13:32 +0800)] 
smb/client: refresh allocation after EOF-extending fallocate

Before this change, xfstests generic/496 was not supported on ksmbd:

        generic/496 ... [not run] fallocated swap not supported here

ksmbd handles SetEOF as truncate, so EOF extension alone does not
allocate backing blocks. A fallocated swapfile can therefore still
look sparse to swapon.

Request allocation for EOF-extending fallocate ranges that can be
represented by FILE_ALLOCATION_INFORMATION, and refresh the allocation
state afterwards.

With this change, xfstests generic/496 and generic/701 pass on ksmbd.

However, Samba "strict allocate = no" now exposes the real generic/701
failure: the old pass came from inflated local i_blocks, not from
server allocation. generic/213 also fails in that case because an
oversized allocation request may not return ENOSPC.

Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
3 weeks agosmb/client: emulate small EOF-extending mode 0 fallocate ranges
Huiwen He [Fri, 3 Jul 2026 05:32:58 +0000 (13:32 +0800)] 
smb/client: emulate small EOF-extending mode 0 fallocate ranges

When a mode 0 fallocate extends EOF from 1G to 2G + 1M, the client
currently sends SetEOF for 2G + 1M. This can make fallocate return
success without allocating the requested range, or allocate extra
space before that range.

For example, on a fresh file:

        xfs_io -f \
          -c "falloc 0 1G" \
          -c "falloc 2G 1M" \
          -c "truncate 3G" test

The second fallocate should allocate [2G, 2G + 1M), leaving [1G, 2G)
as a hole.

Before this change, the result depended on the server allocation policy.
With Samba "strict allocate = no", SetEOF could return success without
allocating [2G, 2G + 1M). With "strict allocate = yes":

# filefrag -v test
        [0, 1G)             allocated
        [1G, 2G)            allocated unexpectedly
        [2G, 2G + 1M)       allocated

SMB cannot allocate that arbitrary range, so write zeroes to small
EOF-extending ranges instead. Limit this to 1 MiB to bound the
client-side I/O cost.

With "strict allocate = no", the requested range [2G, 2G + 1M) is
allocated by the writes. With "strict allocate = yes":

# filefrag -v test
        [0, 1G)             allocated
        [1G, 2G)            hole
        [2G, 2G + 1M)       allocated

This fixes the small EOF-extending range case exercised by generic/213.

Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
3 weeks agosmb/client: reduce fallocate zero buffer allocation
Huiwen He [Fri, 3 Jul 2026 05:32:57 +0000 (13:32 +0800)] 
smb/client: reduce fallocate zero buffer allocation

The fallocate emulation allocates a 1 MiB zero-filled buffer even
though each SMB2_write request is limited to SMB2_MAX_BUFFER_SIZE,
which is 64 KiB. A high-order 1 MiB allocation is more likely to
fail on a fragmented system.

Allocate only the smaller of the requested range and SMB2_MAX_BUFFER_SIZE,
and reuse that zero-filled buffer for every write request. Also reject
a successful write that makes no progress to avoid looping indefinitely.

This reduces the contiguous allocation required by fallocate emulation
without changing the written data or range semantics.

Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
3 weeks agosmb/client: handle overlapping allocated ranges in fallocate
Huiwen He [Fri, 3 Jul 2026 05:32:56 +0000 (13:32 +0800)] 
smb/client: handle overlapping allocated ranges in fallocate

smb3_simple_fallocate_range() can skip holes when an allocated range
returned by the server starts before the current fallocate offset. The
skipped hole is not zero-filled, but fallocate still returns success. A
later write to that hole may therefore fail with ENOSPC.

The function queries allocated ranges so that it can preserve existing
contents and write zeroes only into holes. However, the server may return
a range that starts before the current fallocate offset.

For example, assume the fallocate request is [100, 400) and the only
allocated range returned by the server is [0, 200):

        Request:      [100, 400)
        Server range: [  0, 200)  allocated

        Correct:
        [100, 200)    allocated data, skip
        [200, 400)    hole, zero-fill

        Current:
        [100, 300)    skipped
        [300, 400)    zero-filled afterwards

The current code adds the full server range length, 200, to the current
offset 100 and moves to 300. As a result, the hole in [200, 300) is
skipped without being zero-filled.

Fix this by advancing only over the part of the allocated range that
overlaps the current fallocate offset.  Ignore ranges that end before the
current offset and reject ranges whose end offset overflows.

This also prevents a malformed range length from causing an out-of-bounds
zero-buffer read.

Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
3 weeks agosmb/client: refresh allocation size after duplicate extents
Huiwen He [Fri, 3 Jul 2026 05:32:55 +0000 (13:32 +0800)] 
smb/client: refresh allocation size after duplicate extents

FSCTL_DUPLICATE_EXTENTS_TO_FILE changes the target file extents on the
server, but the client does not refresh the target AllocationSize/i_blocks.
Callers can observe or use the wrong st_blocks value immediately after the
clone, before a later attribute revalidation corrects it.

For example, create a reflinked file with a leading hole:

        xfs_io -f -c "pwrite -S 0x61 0 64k" src
        touch dst
        chmod 600 dst
        xfs_io -c "reflink src 0 1m 64k" dst
        mkswap dst
        swapon dst

The file still has a hole after mkswap:

        /mnt/scratch/dst:
          [0..7]:       allocated
          [8..2047]:    hole
          [2048..2175]: allocated

The server also reports only the allocated ranges:

        server dst size=1114112 blocks=144

but the client reported EOF-derived blocks:

        client dst size=1114112 blocks=2176

and swapon succeeded:

        swapon_result=success
        /mnt/scratch/dst 1.1M 0B -1

So EOF-derived i_blocks can let a sparse reflinked file pass the CIFS
swapfile hole check.

Fix this by querying FILE_ALL_INFORMATION on the target handle after a
successful duplicate extents request. Update i_blocks from AllocationSize
and keep the refreshed target inode attributes valid so a following stat
does not immediately revalidate again.

If the query fails, mark the cached inode attributes stale so a later
getattr can refresh them.

This also fixes the xfstests generic/370 regression introduced by the
i_blocks accounting change, as tested on a Samba "vfs objects = btrfs"
share.

Fixes: 99cd0a6eeb6c ("smb/client: do not account EOF extension as allocation")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
3 weeks agosmb: client: use kvzalloc() for megabyte buffer in simple fallocate
Fredric Cover [Sun, 12 Jul 2026 02:54:02 +0000 (19:54 -0700)] 
smb: client: use kvzalloc() for megabyte buffer in simple fallocate

Currently in smb3_simple_fallocate_range(), a 1 MB buffer is allocated
using kzalloc(). Under heavy memory fragmentation, a contiguous 1 MB block
of physical memory (an order-8 allocation) may not be available,
causing the allocation to fail.

This failure was observed during xfstests generic/013 on a 4GB RAM
test machine running fsstress:

fsstress: page allocation failure: order:8,
mode:0x40dc0(GFP_KERNEL|__GFP_ZERO|__GFP_COMP),
nodemask=(null),cpuset=/,mems_allowed=0

Call Trace:
 <TASK>
 dump_stack_lvl+0x5d/0x80
 warn_alloc+0x163/0x190
 __alloc_pages_slowpath.constprop.0+0x71b/0x12f0
 __alloc_frozen_pages_noprof+0x2f6/0x340
 alloc_pages_mpol+0xb6/0x170
 ___kmalloc_large_node+0xb3/0xd0
 __kmalloc_large_noprof+0x1e/0xc0
 smb3_simple_falloc.isra.0+0x62b/0x960
 cifs_fallocate+0xed/0x180
 vfs_fallocate+0x165/0x3c0
 __x64_sys_fallocate+0x48/0xa0
 do_syscall_64+0xe1/0x640
 entry_SYSCALL_64_after_hwframe+0x76/0x7e
 </TASK>

Node 0 Normal: 3375*4kB ... 7*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB

Since this scratch buffer does not require physically contiguous memory,
switch the allocation to kvzalloc(). This retains the performance
benefits of kmalloc() under normal conditions, while gracefully falling
back to virtually contiguous memory when physical allocation fails.

Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
Cc: stable@vger.kernel.org
Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com>
Tested-by: Fredric Cover <fredric.cover.lkernel@gmail.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
3 weeks agoALSA: usb-audio: Add delay quirk for iBasso DC-Elite
Lianqin Hu [Mon, 13 Jul 2026 12:35:50 +0000 (12:35 +0000)] 
ALSA: usb-audio: Add delay quirk for iBasso DC-Elite

Audio control requests that sets sampling frequency sometimes fail on
this card. Adding delay between control messages eliminates that problem.

usb 1-1: New USB device found, idVendor=2fc6, idProduct=f0b5
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: iBasso DC-Elite
usb 1-1: Manufacturer: iBasso
usb 1-1: SerialNumber: CTUA171130B

Signed-off-by: Lianqin Hu <hulianqin@vivo.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/TYUPR06MB6217D8FF419F24378196FCEFD2FA2@TYUPR06MB6217.apcprd06.prod.outlook.com
3 weeks agoALSA: hda: conexant: Remove mic bias threshold override
Zhang Heng [Mon, 13 Jul 2026 10:03:29 +0000 (18:03 +0800)] 
ALSA: hda: conexant: Remove mic bias threshold override

Remove the mic bias current comparator threshold override (NID 0x1c,
verb 0x320, value 0x010) from Conexant codec driver.

This override was originally intended to support volume up/down controls on
headsets with inline remote controls, but it causes microphone detection
failures on some headsets with impedance less than 1k ohm.

After consulting with the vendor's engineers, it was confirmed that this
setting is board-specific and should be handled by BIOS/firmware rather
than the generic codec driver, especially since inline remote support
is not currently implemented.

Fixes: 7aeb25908648 ("ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140")
Cc: stable@vger.kernel.org
Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
Link: https://patch.msgid.link/20260713100329.306892-1-zhangheng@kylinos.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
3 weeks agoMerge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Linus Torvalds [Mon, 13 Jul 2026 14:47:55 +0000 (07:47 -0700)] 
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull rdma fixes from Jason Gunthorpe:
 "More bug fixes, many found by tools:

   - Protect from a possible DOS with certain RMPP traffic patterns

   - Correct mac address comparison so CMA works properly on IB

   - Some crashes in irdma around memory registration

   - Uninitialized value in erdma and mana

   - Wrong order setting up a QP in SIW allowed a network packet to
     reach an unready QP struct

   - Catch math overflows in hns and irdma"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  RDMA/irdma: Prevent overflows in memory contiguity checks
  RDMA/siw: publish QP after initialization
  RDMA/hns: Fix potential integer overflow in mhop hem cleanup
  RDMA/core: Fix memory leak in __ib_create_cq() on invalid cqe
  RDMA/mana_ib: initialize err for empty send WR lists
  RDMA/erdma: initialize ret for empty receive WR lists
  RDMA/irdma: Prevent user-triggered null deref on QP create
  RDMA/irdma: Prevent rereg_mr for non-mem regions
  RDMA/cma: Fix hardware address comparison length in netevent callback
  RDMa/mlx5: Avoid frame overflow warning
  IB/mad: Drop unmatched RMPP responses before reassembly

3 weeks agoBluetooth: mgmt: Translate HCI reason in Device Disconnected event
Mikhail Gavrilov [Fri, 10 Jul 2026 09:47:31 +0000 (14:47 +0500)] 
Bluetooth: mgmt: Translate HCI reason in Device Disconnected event

MGMT_EV_DEVICE_DISCONNECTED carries a reason field which is defined to
be one of MGMT_DEV_DISCONN_* (0x00..0x05). hci_disconn_complete_evt()
converts the HCI error with hci_to_mgmt_reason(), but two other paths
pass the raw HCI error straight through:

  hci_cs_disconnect()   -> cp->reason
  mgmt_connect_failed() -> status

The latter is reached whenever the adapter is powered off or suspended:
hci_disconnect_all_sync() aborts every link with
HCI_ERROR_REMOTE_POWER_OFF, hci_disconnect_sync() deliberately does not
wait for HCI_EV_DISCONN_COMPLETE for that reason, so that
hci_abort_conn_sync() finishes the connection off through
hci_conn_failed() instead.

As a result userspace sees an out of range reason:

  @ MGMT Event: Device Disconnected (0x000c) plen 8
        BR/EDR Address: 8C:A9:6F:2C:51:46
        Reason: Reserved (0x15)

  bluetoothd: btd_bearer_disconnected() Unknown disconnection value: 21
  bluetoothd: device_disconnected() Unknown disconnection value: 21

Export hci_to_mgmt_reason() and use it in both places, so that a power
off is reported as MGMT_DEV_DISCONN_REMOTE rather than as the raw
HCI_ERROR_REMOTE_POWER_OFF (0x15).

Fixes: d47da6bd4cfa ("Bluetooth: hci_core: Fix sending MGMT_EV_CONNECT_FAILED")
Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agoBluetooth: hci_qca: Clear memdump state on invalid dump size
Ruoyu Wang [Thu, 9 Jul 2026 06:22:50 +0000 (14:22 +0800)] 
Bluetooth: hci_qca: Clear memdump state on invalid dump size

qca_controller_memdump() allocates qca->qca_memdump before processing
the first dump packet. For a sequence-zero packet it then disables IBS,
marks memdump collection active, and reads the advertised dump size.

If the controller reports a zero dump size, the error path frees the
local qca_memdump object and returns without clearing qca->qca_memdump
or undoing the collection state. A later memdump work item initializes
its local pointer from qca->qca_memdump and skips allocation when that
pointer is non-NULL, so it can operate on freed memory. The stale
collection and IBS-disabled flags can also leave waiters or later
transmit handling blocked behind an aborted dump.

Clear the saved pointer and memdump state before returning from the
invalid-size path, matching the cleanup used when hci_devcd_init() fails.

A static analysis checker reported the stale memdump state, and manual
source review confirmed the invalid-size failure path.

Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support")
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agoBluetooth: hci_sync: hold hdev->lock for hci_conn_params lookups
Pauli Virtanen [Fri, 10 Jul 2026 08:23:43 +0000 (11:23 +0300)] 
Bluetooth: hci_sync: hold hdev->lock for hci_conn_params lookups

hci_conn_params_lookup requires hdev->lock be held, otherwise the list
iteration or param access is not safe.

Hold hdev->lock for params lookups in hci_sync.

Fixes: c530569adc19 ("Bluetooth: hci_core: Introduce HCI_CONN_FLAG_PAST")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agoBluetooth: mgmt: hold reference for hci_conn in mgmt_pending_cmds
Pauli Virtanen [Fri, 10 Jul 2026 08:23:42 +0000 (11:23 +0300)] 
Bluetooth: mgmt: hold reference for hci_conn in mgmt_pending_cmds

Dereferencing RCU-protected pointers outside critical sections is
invalid and may lead to UAF.  Use of hci_conn in hci_sync callbacks also
needs to hold refcount to avoid UAF.

Take appropriate locks for hci_conn lookups, and take refcount for
hci_conn pointers stored in mgmt_pending_cmd so that the pointer stays
valid.

When accessing conn->state, ensure hdev->lock is held to avoid data
race.

Fixes: 7b445e220db9 ("Bluetooth: MGMT: Fix holding hci_conn reference while command is queued")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agoBluetooth: mgmt: fix locking in unpair_device/disconnect_sync
Pauli Virtanen [Fri, 10 Jul 2026 08:23:41 +0000 (11:23 +0300)] 
Bluetooth: mgmt: fix locking in unpair_device/disconnect_sync

Dereferencing RCU-protected pointers outside critical sections is
invalid and may lead to UAF.

Take hdev->lock for hci_conn lookup and hci_abort_conn().  Don't use RCU
to ensure the conn is fully initialized at this point.

Fixes: 227a0cdf4a028 ("Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agoBluetooth: hci_sync: extend conn_hash lookup critical sections
Pauli Virtanen [Fri, 10 Jul 2026 08:23:40 +0000 (11:23 +0300)] 
Bluetooth: hci_sync: extend conn_hash lookup critical sections

Using RCU-protected pointers outside the critical sections without
refcount is incorrect and may result to UAF.

Extend critical section to cover both hci_conn_hash lookup and use of
the returned conn.

Add surrounding rcu_read_lock() also when return value is not used, in
preparation for RCU lockdep requirement to hci_lookup_le_connect().

This avoids concurrent deletion of the conn before we are done
dereferencing it.

Also, make sure to hold hdev->lock when accessing hdev->accept_list.

Fixes: 6d0417e4e1cf ("Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agoBluetooth: btrtl: validate firmware patch bounds
Laxman Acharya Padhya [Fri, 10 Jul 2026 17:25:03 +0000 (23:10 +0545)] 
Bluetooth: btrtl: validate firmware patch bounds

rtlbt_parse_firmware() copies patch_length - 4 bytes before appending the
firmware version. A malformed firmware patch shorter than the version field
can make this subtraction underflow and turn the copy into an oversized
read and write during Bluetooth setup.

The existing patch_offset + patch_length check can also wrap on 32-bit
architectures. Validate the patch length and range without arithmetic
overflow before allocating or copying the patch.

Fixes: db33c77dddc2 ("Bluetooth: btrtl: Create separate module for Realtek BT driver")
Cc: stable@vger.kernel.org
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agoBluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update
Cen Zhang [Tue, 7 Jul 2026 04:15:18 +0000 (12:15 +0800)] 
Bluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update

MGMT_OP_LOAD_CONN_PARAM queues conn_update_sync() when a single parameter
update changes an existing LE central connection. The queued work currently
stores a borrowed hci_conn_params entry from hdev->le_conn_params. A later
LOAD_CONN_PARAM request can clear disabled parameters and free that entry
before hci_cmd_sync_work() runs the queued callback.

Do not keep the borrowed hci_conn_params pointer in queued work. Queue the
hci_conn instead and hold a reference until the queued callback completes.
When the work runs, revalidate that the connection is still present, look
up the current hci_conn_params entry, and cancel the update if userspace
removed that entry while the work was pending.

Copy the interval values from the current params entry under hdev->lock,
then drop the lock and keep using hci_le_conn_update_sync() to issue the
update.

Validation reproduced this kernel report:
BUG: KASAN: slab-use-after-free in conn_update_sync+0x2a/0xf0 [bluetooth]
Read of size 1 at addr ffff88810c697126 by task kworker/u17:0/377
Workqueue: hci0 hci_cmd_sync_work [bluetooth]

Call Trace:
 <TASK>
 dump_stack_lvl+0x66/0xa0
 print_report+0xce/0x5f0
 kasan_report+0xe0/0x110
 conn_update_sync+0x2a/0xf0 [bluetooth]
 hci_cmd_sync_work+0x187/0x210 [bluetooth]
 process_one_work+0x4fd/0xbc0
 worker_thread+0x2d8/0x570
 kthread+0x1ad/0x1f0
 ret_from_fork+0x3c9/0x540
 ret_from_fork_asm+0x1a/0x30

Allocated by task 466:
 hci_conn_params_add+0xa6/0x240 [bluetooth]
 load_conn_param+0x4e1/0x850 [bluetooth]
 hci_sock_sendmsg+0x96b/0xf80 [bluetooth]

Freed by task 474:
 kfree+0x313/0x590
 hci_conn_params_clear_disabled+0x9b/0xc0 [bluetooth]
 load_conn_param+0x4bf/0x850 [bluetooth]
 hci_sock_sendmsg+0x96b/0xf80 [bluetooth]

Fixes: 0ece498c27d8c ("Bluetooth: MGMT: Make MGMT_OP_LOAD_CONN_PARAM update existing connection")
Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Assisted-by: Codex:gpt-5.5
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agoBluetooth: qca: fix NVM tag length underflow in TLV parser
Xiang Mei [Sat, 4 Jul 2026 23:10:30 +0000 (16:10 -0700)] 
Bluetooth: qca: fix NVM tag length underflow in TLV parser

In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is
"while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed
int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a
size_t (12), so "length" is converted to size_t and any firmware-supplied
"length" < 12 makes the subtraction wrap to a huge value. The loop body
then reads a 12-byte struct tlv_type_nvm past the end of the short
vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).

Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both
operands are non-negative, so it no longer underflows and a "length" too
small for one record correctly skips the loop.

  BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421)
  Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52
  Workqueue: hci0 hci_power_on
  Call Trace:
   ...
   kasan_report (mm/kasan/report.c:595)
   qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617)
   qca_uart_setup (drivers/bluetooth/btqca.c:948)
   qca_setup (drivers/bluetooth/hci_qca.c:2029)
   hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438)
   hci_dev_open_sync (net/bluetooth/hci_sync.c:5227)
   hci_power_on (net/bluetooth/hci_core.c:920)
   process_one_work (kernel/workqueue.c:3322)
   worker_thread (kernel/workqueue.c:3486)
   kthread (kernel/kthread.c:436)
   ret_from_fork (arch/x86/kernel/process.c:158)
   ret_from_fork_asm (arch/x86/entry/entry_64.S:245)

Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Reported-by: Weiming Shi <bestswngs@gmail.com>
Reviewed-by: Johan Hovold <johan@kernel.org>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
3 weeks agowifi: carl9170: fix buffer overflow in rx_stream failover path
Tristan Madani [Tue, 21 Apr 2026 13:49:28 +0000 (13:49 +0000)] 
wifi: carl9170: fix buffer overflow in rx_stream failover path

The failover continuation in carl9170_rx_stream() copies the full tlen
from the second USB transfer instead of capping at rx_failover_missing
bytes. When both transfers are near maximum size, the total exceeds the
65535-byte failover SKB, triggering skb_over_panic.

Limit the copy size to the missing byte count.

Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Acked-by: Christian Lamparter <chunkeey@gmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac
Link: https://patch.msgid.link/20260421134929.325662-4-tristmd@gmail.com
[Fix checkpatch CHECK:PARENTHESIS_ALIGNMENT]
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
3 weeks agowifi: carl9170: fix OOB read from off-by-two in TX status handler
Tristan Madani [Tue, 21 Apr 2026 13:49:27 +0000 (13:49 +0000)] 
wifi: carl9170: fix OOB read from off-by-two in TX status handler

The bounds check in carl9170_tx_process_status() uses
`i > ((cmd->hdr.len / 2) + 1)` which is off by two, allowing
2 extra iterations past valid _tx_status entries when the firmware-
controlled hdr.ext exceeds hdr.len/2. Fix by using the correct
comparison `i >= (cmd->hdr.len / 2)`.

Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Acked-by: Christian Lamparter <chunkeey@gmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac
Link: https://patch.msgid.link/20260421134929.325662-3-tristmd@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
3 weeks agowifi: carl9170: bound memcpy length in cmd callback to prevent OOB read
Tristan Madani [Tue, 21 Apr 2026 13:49:26 +0000 (13:49 +0000)] 
wifi: carl9170: bound memcpy length in cmd callback to prevent OOB read

When the firmware sends a command response with a length mismatch,
carl9170_cmd_callback() logs the mismatch and calls carl9170_restart()
but then falls through to memcpy(ar->readbuf, buffer + 4, len - 4).
Since len comes from the firmware and can exceed ar->readlen, this
copies more data than the readbuf was allocated for.

Bound the memcpy to min(len - 4, ar->readlen) so that the response
is still completed -- avoiding repeated restarts from queued garbage --
while preventing an overread past the response buffer.

Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Acked-by: Christian Lamparter <chunkeey@gmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac
Link: https://patch.msgid.link/20260421134929.325662-2-tristmd@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
3 weeks agowifi: ath6kl: fix OOB read from firmware IE lengths in connect event
Tristan Madani [Tue, 21 Apr 2026 13:50:08 +0000 (13:50 +0000)] 
wifi: ath6kl: fix OOB read from firmware IE lengths in connect event

The firmware-controlled beacon_ie_len, assoc_req_len, and assoc_resp_len
fields in ath6kl_wmi_connect_event_rx() are not validated against the
buffer length. Their sum (up to 765) can exceed the actual WMI event
data, causing out-of-bounds reads during IE parsing and state corruption
of wmi->is_wmm_enabled.

Add a check that the total IE length fits within the buffer.

Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20260421135009.348084-3-tristmd@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
3 weeks agowifi: ath6kl: fix OOB read from firmware num_msg in TX complete handler
Tristan Madani [Thu, 25 Jun 2026 23:29:07 +0000 (23:29 +0000)] 
wifi: ath6kl: fix OOB read from firmware num_msg in TX complete handler

The firmware-controlled num_msg field (u8, 0-255) drives the loop in
ath6kl_wmi_tx_complete_event_rx() without validation against the buffer
length. This allows out-of-bounds reads of up to 1020 bytes past the
WMI event buffer when the firmware sends an inflated num_msg.

Add a check that the buffer is large enough to hold the fixed struct
and the num_msg variable-length entries.

Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Link: https://patch.msgid.link/20260625232907.3620746-1-tristmd@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
3 weeks agowifi: ath6kl: fix OOB access from firmware ADDBA window size
Tristan Madani [Thu, 2 Jul 2026 00:50:20 +0000 (00:50 +0000)] 
wifi: ath6kl: fix OOB access from firmware ADDBA window size

aggr_recv_addba_req_evt() logs a debug message when the firmware-supplied
win_sz is outside [AGGR_WIN_SZ_MIN, AGGR_WIN_SZ_MAX] but does not
return. The out-of-range win_sz is then used in TID_WINDOW_SZ() to
compute a kzalloc size and stored in rxtid->hold_q_sz, leading to
zero-size or overflowed allocations and subsequent out-of-bounds access.

Clean up any previously active aggregation session for the TID first,
then return early when win_sz is out of the valid range, instead of
proceeding with a broken allocation size.

Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
Cc: stable@vger.kernel.org
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Link: https://patch.msgid.link/20260702005020.708717-1-tristmd@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
3 weeks agowifi: ath12k: fix NULL pointer dereference in rhash table destroy
Jose Ignacio Tornos Martinez [Mon, 15 Jun 2026 11:21:03 +0000 (13:21 +0200)] 
wifi: ath12k: fix NULL pointer dereference in rhash table destroy

When unbinding the ath12k driver, kernel NULL pointer dereferences
occur in irq_work_sync() called from rhashtable_destroy().

Two hash tables are affected:
1. ath12k_link_sta hash table in ath12k_base
2. ath12k_dp_link_peer hash table in ath12k_dp

The issue happens because the destroy functions are called unconditionally
in cleanup paths, but the hash tables are only initialized late in their
respective init functions. If the device was never fully started or if the
init functions failed before initializing the hash tables, the pointers
will be NULL. The issues are always reproducible from a VM because the MSI
addressing initialization is failing.

Call trace for ath12k_link_sta_rhash_tbl_destroy:
 RIP: irq_work_sync+0x1e/0x70
 rhashtable_destroy+0x12/0x60
 ath12k_link_sta_rhash_tbl_destroy+0x19/0x40 [ath12k]
 ath12k_core_stop+0xe/0x80 [ath12k]
 ath12k_core_hw_group_cleanup+0x6b/0xb0 [ath12k]
 ath12k_pci_remove+0x60/0x110 [ath12k]

Call trace for ath12k_dp_link_peer_rhash_tbl_destroy:
 RIP: irq_work_sync+0x1e/0x70
 rhashtable_destroy+0x12/0x60
 ath12k_dp_link_peer_rhash_tbl_destroy+0x29/0x50 [ath12k]
 ath12k_dp_cmn_device_deinit+0x21/0x140 [ath12k]
 ath12k_core_hw_group_cleanup+0x6b/0xb0 [ath12k]
 ath12k_pci_remove+0x60/0x110 [ath12k]

Fix this by adding NULL checks before calling rhashtable_destroy() in
both destroy functions.

The NULL check approach was chosen because the rhashtable pointer
serves as the initialization state indicator. The init can fail at
various points, leaving some components uninitialized. Checking the
pointer directly is simpler than adding separate state flags that
would need synchronization.

Fixes: 57ccca410237 ("wifi: ath12k: Add hash table for ath12k_link_sta in ath12k_base")
Fixes: a88cf5f71adf ("wifi: ath12k: Add hash table for ath12k_dp_link_peer")
Cc: stable@vger.kernel.org
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20260615112103.601982-1-jtornosm@redhat.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
3 weeks agowifi: ath12k: Fix low MLO RX throughput on WCN7850
Yingying Tang [Wed, 10 Jun 2026 05:33:15 +0000 (22:33 -0700)] 
wifi: ath12k: Fix low MLO RX throughput on WCN7850

Commit [1] introduced a regression causing severely degraded MLO RX
throughput on WCN7850.

On WCN7850, there is only a single ar instance, but MLO uses two
link IDs. ath12k_dp_peer->hw_links[] is indexed using ar->hw_link_id,
which causes both MLO link IDs to be stored at the same index.

As a result, an incorrect link ID is assigned to MSDUs in
ath12k_dp_rx_deliver_msdu(), leading to severe MLO RX throughput loss.

Different chipsets identify the per-MSDU link differently:

  - On QCN9274 / IPQ5332, the host owns multiple ar instances and the
    per-MSDU hw_link_id from the RX descriptor maps cleanly through
    dp_peer->hw_links[hw_link_id] to the IEEE link_id.

  - On single-ar chipsets like WCN7850 / QCC2072, there is only one ar
    instance for both MLO links, so dp_peer->hw_links[] has just one
    valid slot and cannot be used to distinguish the two links. To
    resolve the link, walk dp_peer->link_peers[] and match by
    rxcb->peer_id, which on the link_peer side identifies the link
    peer for the MSDU.

Add a new hw_op set_rx_link_id() so each chipset resolves the link
on the RX fast path using whatever signal it actually has, and let
the op itself decide whether to populate rx_status::link_valid and
rx_status::link_id:

  QCN9274 / IPQ5332 : always derive link_id from
                      dp_peer->hw_links[rxcb->hw_link_id] and set
                      link_valid.
  WCN7850 / QCC2072 : walk the link_peers[] of dp_peer to find the
                      link_peer whose peer_id matches rxcb->peer_id,
                      and set link_valid only when a match is found.
                      Otherwise leave link_valid clear so that
                      mac80211 can fall back to its own link
                      resolution path (via addr2 / deflink).

For WCN7850 / QCC2072, walking dp_peer->link_peers[] is bounded by
the number of links actually populated, so introduce a link_peers_map
bitmap (unsigned long) in struct ath12k_dp_peer that tracks populated
slots and use for_each_set_bit() to iterate. Non-MLO clients hit one
slot, current MLO clients hit two; the full ATH12K_NUM_MAX_LINKS
array is never scanned. The bitmap is maintained with WRITE_ONCE() on
the write side (under dp_hw->peer_lock) paired with READ_ONCE() on
both the lockless RX read side and the write-side RMW for KCSAN
correctness.

Also guard the dp_peer dereference in ath12k_mac_peer_cleanup_all()
with a NULL check, since peer->dp_peer can be NULL for self-peers or
peers not yet fully assigned, the pre-existing rcu_assign_pointer()
call there had the same latent issue.

This restores the correct link ID on WCN7850 without changing the
QCN9274 / IPQ5332 data path, which keeps its O(1) hw_links[]
indexing.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3

Fixes: 11157e0910fd ("wifi: ath12k: Use ath12k_dp_peer in per packet Tx & Rx paths") # [1]
Signed-off-by: Yingying Tang <yingying.tang@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260610053315.2249912-1-yingying.tang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
3 weeks agoKVM: x86: Fix null pointer deref due to dummy array in trace_kvm_inj_exception()
Daniel Paziyski [Fri, 10 Jul 2026 13:40:54 +0000 (15:40 +0200)] 
KVM: x86: Fix null pointer deref due to dummy array in trace_kvm_inj_exception()

The trace_kvm_inj_exception tracepoint takes as arguments the exception
vector, whether the exception has an error code (and subsequently, the
error code), and whether it is being reinjected.  Because '0' is a valid
error code, KVM uses __print_symbolic() to format the error code as a
string to avoid printing the error code entirely if the exception doesn't
have an error code (see commit 21d4c575eb4a ("KVM: x86: Print error code
in exception injection tracepoint iff valid").

KVM's abuse of __print_symbolic() was all fine and dandy, until commit
754e38d2d1ae ("tracing: Use explicit array size instead of sentinel
elements in symbol printing") reworked the printing to avoid terminating
the arrays with NULL/0 values, and missed KVM's clever use of not-quite
empty array of symbols.

  BUG: kernel NULL pointer dereference, address: 0000000000000000
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: Oops: 0000 [#1] SMP
  CPU: 20 UID: 0 PID: 791 Comm: less Not tainted 7.2.0-rc2 #401 PREEMPT
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:strlen+0x0/0x20
  Call Trace:
   <TASK>
   trace_seq_puts+0x18/0x80
   trace_print_symbols_seq+0x68/0xa0
   trace_raw_output_kvm_inj_exception+0x64/0xf0 [kvm]
   s_show+0x47/0x110
   seq_read_iter+0x2a5/0x4c0
   seq_read+0xfd/0x130
   vfs_read+0xb6/0x330
   ? vfs_write+0x2f2/0x3f0
   ksys_read+0x61/0xd0
   do_syscall_64+0xb7/0x570
   entry_SYSCALL_64_after_hwframe+0x4b/0x53
  RIP: 0033:0x7ff283714862
   </TASK>

Simply drop the dummy array entirely, so that __print_symbolic() generates
a truly empty array.

Signed-off-by: Daniel Paziyski <danielpaziyski@gmail.com>
Fixes: 754e38d2d1ae ("tracing: Use explicit array size instead of sentinel elements in symbol printing")
Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Link: https://patch.msgid.link/20260710134055.16432-1-danielpaziyski@gmail.com
[sean: massage changelog, add splat, add Fixes, cc stable]
Signed-off-by: Sean Christopherson <seanjc@google.com>
3 weeks agoRISC-V: KVM: Zicbo[m|z|p] block sizes should be always present in ONE_REG
Anup Patel [Mon, 6 Jul 2026 18:15:22 +0000 (23:45 +0530)] 
RISC-V: KVM: Zicbo[m|z|p] block sizes should be always present in ONE_REG

All config and core registers of the KVM RISC-V ONE_REG interface are
expected to be always available to the KVM user-space and the KVM
get-reg-list selftest assumes these registers to be as base registers.

Currently, the Zicbo[m|z|p] block size config registers are only
available when corresponding ISA extension is present on the host
which breaks the above expectation. In fact, KVM get-reg-list selftest
fails when any of the Zicbo[m|z|p] ISA extension is not present on
host. To address this issue, drop the ISA extension checks from
kvm_riscv_vcpu_get/set_reg_config() and copy_config_reg_indices()
functions.

Fixes: 031f9efafc08 ("KVM: riscv: Add KVM_GET_REG_LIST API support")
Fixes: a044ef71043e ("RISC-V: KVM: use ENOENT in *_one_reg() when extension is unavailable")
Fixes: 48e2febcda74 ("RISC-V: KVM: Provide UAPI for Zicbop block size")
Fixes: cf05b059d59f ("RISC-V: KVM: Introduce common kvm_riscv_isa_check_host()")
Signed-off-by: Anup Patel <anup.patel@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260706181522.2003922-1-anup.patel@oss.qualcomm.com
Signed-off-by: Anup Patel <anup@brainfault.org>
3 weeks agoriscv: kvm: Skip TLB flush when G-stage PTE becomes valid with Svvptc
Dylan.Wu [Wed, 1 Jul 2026 07:52:39 +0000 (03:52 -0400)] 
riscv: kvm: Skip TLB flush when G-stage PTE becomes valid with Svvptc

The gstage_tlb_flush() in the kvm_riscv_gstage_set_pte() is not needed
when an invalid G-stage PTE becomes valid and Svvptc extension is available
because new valid PTEs become visible to the page-table walker within a
bounded time.

Assisted-by: YuanSheng: deepseek-v4-pro
Co-developed-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Dylan.Wu <fredwudi0305@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260701075239.95542-1-fredwudi0305@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
3 weeks agoKVM: riscv: PMU: Bound counter mask scan to BITS_PER_LONG
Shengwen Cheng [Fri, 26 Jun 2026 05:40:51 +0000 (13:40 +0800)] 
KVM: riscv: PMU: Bound counter mask scan to BITS_PER_LONG

The PMU SBI handler passes the guest argument registers directly to
the PMU start/stop helpers:

kvm_riscv_vcpu_pmu_ctr_start(vcpu, cp->a0, cp->a1, cp->a2, ...)
kvm_riscv_vcpu_pmu_ctr_stop(vcpu, cp->a0, cp->a1, cp->a2, ...)

which map to:

unsigned long ctr_base
unsigned long ctr_mask
unsigned long flags

Thus cp->a1 is a single unsigned long ctr_mask, not a bitmap array
sized for RISCV_MAX_COUNTERS.

On RV32, RISCV_MAX_COUNTERS is 64 while BITS_PER_LONG is 32.  Using
for_each_set_bit() with RISCV_MAX_COUNTERS can therefore make
find_next_bit() access bits beyond the storage of ctr_mask on RV32.

Limit the scan to BITS_PER_LONG. The requested counter range is already
validated by kvm_pmu_validate_counter_mask(), so this preserves RV64
behavior and avoids an out-of-bounds bitmap read on RV32.

Fixes: 0cb74b65d2e5 ("RISC-V: KVM: Implement perf support without sampling")
Signed-off-by: Shengwen Cheng <shengwen1997.tw@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260626054051.3360865-1-shengwen1997.tw@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
3 weeks agoASoC: fsl_sai: Fix spurious BCLK on resume by clearing BYP
Chancel Liu [Fri, 10 Jul 2026 07:08:35 +0000 (16:08 +0900)] 
ASoC: fsl_sai: Fix spurious BCLK on resume by clearing BYP

When the BCLK divider ratio is 1:1, fsl_sai_set_bclk() enables bypass
mode by setting BYP, but never clears the bit. The BYP=1 value remains
in the regcache, and is restored by regcache_sync() on the next runtime
resume.

Since BYP=1 combined with BCD=1 immediately outputs the ungated MCLK
as BCLK without waiting for BCE/TE/RE to be enabled, the clock is
driven prematurely before the stream is fully configured, causing
noise on some codecs.

Fix this by clearing BYP and BCI in fsl_sai_hw_free() taking into
account sync mode and the opposite stream's state, so that the regcache
holds BYP=0 before runtime suspend and regcache_sync() on resume will
not restore bypass mode prematurely.

Fixes: a50b7926d015 ("ASoC: fsl_sai: implement 1:1 bclk:mclk ratio support")
Cc: stable@vger.kernel.org
Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
Reviewed-by: Shengjiu Wang <shengjiu.wang@gmail.com>
Link: https://patch.msgid.link/20260710070835.3749817-1-chancel.liu@oss.nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
3 weeks agofirewire: net: Fix fragmented datagram reassembly
Ruoyu Wang [Tue, 7 Jul 2026 15:04:54 +0000 (23:04 +0800)] 
firewire: net: Fix fragmented datagram reassembly

fwnet_frag_new() keeps a sorted list of received fragments for a partial
datagram. When a new fragment is adjacent to an existing fragment, the
code checks whether the new fragment also closes the gap to the next or
previous list entry.

Those neighbor lookups currently assume that the current fragment always
has a real next or previous fragment. At a list edge, the next or
previous entry is the list head, not a struct fwnet_fragment_info.

The gap checks also compare against the old edge of the current fragment
instead of the edge after adding the new fragment. As a result, a
fragment that bridges two existing ranges may leave two adjacent ranges
unmerged, so fwnet_pd_is_complete() can miss a complete datagram.

Check for the list head before looking up the neighboring fragment, and
compare the neighbor against the new fragment's far edge when deciding
whether to merge all three ranges.

This issue was found by a static analysis checker and confirmed by
manual source review.

Fixes: c76acec6d551 ("firewire: add IPv4 support")
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Link: https://lore.kernel.org/r/20260707150454.2265951-1-ruoyuw560@gmail.com
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
3 weeks agopmdomain: mediatek: Fix possible nullptr KP in HWV cleanup/on-check
AngeloGioacchino Del Regno [Thu, 9 Jul 2026 08:46:32 +0000 (10:46 +0200)] 
pmdomain: mediatek: Fix possible nullptr KP in HWV cleanup/on-check

Should probe fail for HW_VOTER type power domains, this driver was
unconditionally trying to perform cleanup for DIRECT_CTL domains,
but only after checking if the target domain is powered on... with
the DIRECT_CTL scpsys_domain_is_on() code again.

And there's more: the scpsys_domain_is_on() function is also being
unconditionally used in the probe path, for any power domain that
has flag MTK_SCPD_KEEP_DEFAULT_OFF!

This bug was never experienced by anyone because the HWV domains
never failed probe, and because none of those is declared with the
aforementioned flag - but it's still something critical.

In order to fix this, add a check for MTCMOS Type and, based on
that, call the correct functions for an "is on" check, and also
do the same for the cleanup path, calling the correct functions
for the "power off" action.

For the latter, since there's a call to pm_genpd_remove() right
before calling power_off, be cautious and add a variation of the
power off functions (with a _internal suffix) for those to get a
pointer to scpsys_domain instead of one to generic_pm_domain as,
even if that's still working, this is way too much fragile and
would break at some point.

Fixes: 88914db077b6 ("pmdomain: mediatek: Add support for Hardware Voter power domains")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
3 weeks agoMerge branches 'for-next/scmi/fixes' and 'for-next/ffa/fixes'
Sudeep Holla [Mon, 13 Jul 2026 10:38:34 +0000 (11:38 +0100)] 
Merge branches 'for-next/scmi/fixes' and 'for-next/ffa/fixes'

* for-next/scmi/fixes:
  firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
  firmware: arm_scmi: Use 64-bit division for clock rate rounding
  firmware: arm_scmi: Grammar s/may needed/may be needed/

* for-next/ffa/fixes:
  firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
  firmware: arm_ffa: Respect firmware advertised RX/TX buffer size limits

Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
3 weeks agoALSA: hda/realtek: Fix speakers on Legion Pro 7 16ARX8H with codec SSID 17aa:38a7
Damien Laine [Sun, 12 Jul 2026 21:37:08 +0000 (23:37 +0200)] 
ALSA: hda/realtek: Fix speakers on Legion Pro 7 16ARX8H with codec SSID 17aa:38a7

Some units of the Lenovo Legion Pro 7 16ARX8H (82WS) report codec
subsystem ID 17aa:38a7 instead of 17aa:38a8. Since only 38a8 has a
codec SSID quirk, these machines fall through to the PCI SSID match
17aa:386f (Legion Pro 7i 16IAX7) and get ALC287_FIXUP_CS35L41_I2C_2,
which probes the Cirrus amplifiers of the Intel variant. The TI
TAS2781 amplifier (ACPI TIAS2781:00) present on this AMD variant is
never bound and the internal speakers remain silent.

Add a codec SSID quirk for 17aa:38a7 pointing to
ALC287_FIXUP_TAS2781_I2C, mirroring the existing 38a8 entry.

Tested on a Legion Pro 7 16ARX8H (82WS, BIOS LPCN62WW): with the codec
SSID overridden to 17aa:38a8 via the HDA patch loader, the TAS2781
amplifier binds and the internal speakers work.

Cc: <stable@vger.kernel.org>
Signed-off-by: Damien Laine <damien.laine@gmail.com>
Link: https://patch.msgid.link/20260712213708.1835469-1-damien.laine@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
3 weeks agoALSA: hda/realtek: Fix speakers on MECHREVO WUJIE Series
Chen Bowen [Fri, 10 Jul 2026 13:34:09 +0000 (21:34 +0800)] 
ALSA: hda/realtek: Fix speakers on MECHREVO WUJIE Series

The internal speakers on the MECHREVO WUJIE Series are silent,
while the headphone output works correctly.

The BIOS reports NID 0x1b on the Realtek ALC233 codec as
unconnected with pin configuration 0x411111f0. However, the pin
is connected to an internal speaker.

Overriding NID 0x1b with 0x90170150 makes the HDA generic parser
detect both 0x14 and 0x1b as speaker outputs and restores internal
speaker playback.

Add a pin configuration fixup for the affected PCI SSID c011:1d05.

Tested on a MECHREVO WUJIE Series laptop with board
WUJIE Series-Lark4-LNL and firmware EM_LNL326_V1.0.23.

Signed-off-by: Chen Bowen <hicbowen@gmail.com>
Link: https://patch.msgid.link/20260710133409.16641-1-hicbowen@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
3 weeks agoALSA: hda: cs35l56: Fail if wmfw file is missing
Richard Fitzgerald [Thu, 9 Jul 2026 16:12:06 +0000 (17:12 +0100)] 
ALSA: hda: cs35l56: Fail if wmfw file is missing

Fail cs35l56_hda_fw_load() and log an error if it didn't find a wmfw file
and the BIOS didn't patch the firmware already. Also remove a section of
code from cs35l56_hda_request_firmware_files() that attempted to find a
.bin if a .wmfw was not found.

The CS35L56 ROM can only provide default audio in SoundWire mode. A wmfw
is needed to enable I2S audio. Also none of the customer-specific .bin
files are compatible with the ROM firmware. So a .wmfw file is always
required.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260709161211.686498-1-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
3 weeks agoALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
Takashi Iwai [Thu, 9 Jul 2026 09:56:06 +0000 (11:56 +0200)] 
ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC

Salvador reported that the recent fix for applying the DSD quirk to
Musical Fidelity devices broke for his M6s DAC model (2772:0502).

Although this is basically a firmware bug, the model in question is
fairly old, and no further firmware update can be expected, so it'd be
better to address in the driver side.

As an ad hoc workaround, skip the DSD quirk for this device by adding
an empty quirk entry of 2772:0502; this essentially skips the later
DSD quirk entry by the match with the vendor 2772.

Fixes: da3a7efff64e ("ALSA: usb-audio: Update for native DSD support quirks")
Reported-by: Salvador Blaya <tiniebla6@gmail.com>
Closes: https://lore.kernel.org/CAOdyq+qFaqCh=tK_wNnA64hv5pQuA1Y09ANxQ=xK8yR-t4mf9Q@mail.gmail.com
Tested-by: Salvador Blaya <tiniebla6@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260709095614.1418838-1-tiwai@suse.de
3 weeks agoUSB: serial: ftdi_sio: add support for E+H FXA291
Tim Pambor [Sat, 11 Jul 2026 17:36:30 +0000 (17:36 +0000)] 
USB: serial: ftdi_sio: add support for E+H FXA291

The Commubox FXA291 by Endress+Hauser AG is a USB serial converter
based on FT232B which is used to communicate with field devices.

It enumerates using the FTDI vendor ID and a custom PID.

usb 1-9: New USB device found, idVendor=0403, idProduct=e510, bcdDevice= 4.00
usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-9: Product: FXA291
usb 1-9: Manufacturer: Endress+Hauser
usb 1-9: SerialNumber: 00000000
ftdi_sio 1-9:1.0: FTDI USB Serial Device converter detected
usb 1-9: Detected FT232B
usb 1-9: FTDI USB Serial Device converter now attached to ttyUSB0

Signed-off-by: Tim Pambor <timpambor@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
3 weeks agopowerpc/spufs: fix out-of-bounds access in spufs_mem_mmap_access()
Junrui Luo [Mon, 1 Jun 2026 07:50:00 +0000 (15:50 +0800)] 
powerpc/spufs: fix out-of-bounds access in spufs_mem_mmap_access()

spufs_mem_mmap_access() computes the local store offset as
address - vma->vm_start, but bounds-checks it against vma->vm_end
instead of the local store size. On 64-bit, offset is always well
below vma->vm_end, so the clamp never fires and len stays unbounded
against the LS_SIZE buffer returned by ctx->ops->get_ls().

Reject offsets at or beyond LS_SIZE and clamp len to the remaining
space, mirroring the guard already used by spufs_mem_mmap_fault() and
spufs_ps_fault().

Fixes: a352894d0705 ("spufs: use new vm_ops->access to allow local state access from gdb")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/SYBPR01MB7881EE775E8B51C09F5A29E7AF152@SYBPR01MB7881.ausprd01.prod.outlook.com
3 weeks agoUSB: serial: keyspan_pda: fix data loss on receive throttling
Johan Hovold [Wed, 8 Jul 2026 14:31:35 +0000 (16:31 +0200)] 
USB: serial: keyspan_pda: fix data loss on receive throttling

Killing the interrupt-in urb when the line disciple requests throttling
may lead to data loss if an ongoing transfer is cancelled.

Instead set a flag to prevent the completion handler from resubmitting
the urb until the port is unthrottled.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
3 weeks agoMerge v7.2-rc3 into drm-misc-fixes
Maarten Lankhorst [Mon, 13 Jul 2026 09:32:29 +0000 (11:32 +0200)] 
Merge v7.2-rc3 into drm-misc-fixes

Forward from rc1 to rc3 to track upstream closer again.

Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
3 weeks agoerofs: hide "cache_strategy=" for plain filesystems
Gao Xiang [Mon, 13 Jul 2026 08:35:29 +0000 (16:35 +0800)] 
erofs: hide "cache_strategy=" for plain filesystems

"cache_strategy=" is meaningless and confusing on unencoded EROFS
filesystems; gate it on compressed images only since it's now possible
after commit 7cef3c834194 ("erofs: separate plain and compressed
filesystems formally").

Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
3 weeks agoaccel/ivpu: Fix wrong register read in LNL failure diagnostics
Karol Wachowski [Fri, 10 Jul 2026 10:13:31 +0000 (12:13 +0200)] 
accel/ivpu: Fix wrong register read in LNL failure diagnostics

diagnose_failure_lnl() read VPU_HW_BTRS_MTL_INTERRUPT_STAT instead of
VPU_HW_BTRS_LNL_INTERRUPT_STAT, which on LNL and newer parts is a
different register with a different bit layout, so failure diagnostics
decoded the wrong register and reported a bogus error cause.
Read the LNL interrupt status register instead.

Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
Reviewed-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Link: https://patch.msgid.link/20260710101331.1899505-1-karol.wachowski@linux.intel.com
3 weeks agoKVM: riscv: SBI FWFT: Apply LOCK flag only on successful set
SeungJu Cheon [Wed, 24 Jun 2026 13:02:38 +0000 (22:02 +0900)] 
KVM: riscv: SBI FWFT: Apply LOCK flag only on successful set

kvm_sbi_fwft_set() applies the caller's flags to conf->flags before
invoking the set() callback. If the callback returns an error, the LOCK
bit persists and the feature becomes permanently locked without its value
ever being changed.

Move the flags assignment after the callback so LOCK takes effect only
on success.

Fixes: 6b72fd170592 ("RISC-V: KVM: add support for FWFT SBI extension")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260624130238.524706-1-suunj1331@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
3 weeks agoRISC-V: KVM: Avoid redundant page-table allocations in ioremap topup
Fangyu Yu [Wed, 10 Jun 2026 09:39:22 +0000 (17:39 +0800)] 
RISC-V: KVM: Avoid redundant page-table allocations in ioremap topup

kvm_riscv_mmu_ioremap() currently tops up its on-stack page-table
cache via kvm_mmu_topup_memory_cache(), which allocates up to
KVM_ARCH_NR_OBJS_PER_MEMORY_CACHE (32) objects per topup.

ioremap only consumes non-leaf page-table pages, at most
pgd_levels - 1 (1 to 4) per call, and for contiguous mappings
within the same huge page the non-leaf pages are allocated once
and reused by subsequent pages. Topping up to 32 objects therefore
triggers many unnecessary GFP_KERNEL_ACCOUNT allocations on every
call, all of which are freed when the function returns. In hot
paths (such as vCPU migration), this creates avoidable allocator
churn and wastes CPU cycles.

Use __kvm_mmu_topup_memory_cache() with a capacity of pgd_levels so
the on-stack cache is sized to the maximum demand of a single
mapping. This removes the redundant allocations and reduces per-call
overhead without changing behavior.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20260610093922.51617-1-fangyu.yu@linux.alibaba.com
Signed-off-by: Anup Patel <anup@brainfault.org>
3 weeks agoata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning
Rosen Penev [Sun, 12 Jul 2026 21:37:28 +0000 (14:37 -0700)] 
ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning

The hand-rolled bit-scanning loop in the NCQ completion path has an
infinite loop bug.  When tag_mask has only high bits set (e.g.
0x80000000), the inner while loop left-shifts tag_mask until it
overflows to 0.  At that point !(0 & 1) is always true and 0 <<= 1
stays 0, causing an infinite loop in hardirq context with a spinlock
held.

Replace the open-coded bit-scanning with __ffs() which correctly
finds the least significant set bit and is bounded by the width of
the argument.

Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
3 weeks agoata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending interrupts
Rosen Penev [Sun, 12 Jul 2026 21:37:27 +0000 (14:37 -0700)] 
ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending interrupts

clear_interrupt_bit() ignores the bit argument and performs a
read-write-back of the entire INTPR register.  If INTPR uses standard
Write-1-to-Clear semantics, this clears every pending interrupt bit,
not just the intended one.  Coalesced interrupts (e.g. DMAT + NEWFP)
would be cleared together, silently losing the second event.

Write only the specific bit to clear so that other pending interrupts
are preserved.

Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
3 weeks agoata: sata_dwc_460ex: use platform_get_irq()
Rosen Penev [Sun, 12 Jul 2026 21:37:25 +0000 (14:37 -0700)] 
ata: sata_dwc_460ex: use platform_get_irq()

Replace irq_of_parse_and_map() with platform_get_irq() in both
sata_dwc_dma_init_old() and sata_dwc_probe(). This is the preferred
way to obtain IRQs for platform devices and provides better error
reporting.  Remove the now-unnecessary #include <linux/of_irq.h>.

irq_of_parse_and_map() requires irq_dispose_mapping(), which is missing.

Also fix unused variable when CONFIG_SATA_DWC_OLD_DMA is disabled.

Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
3 weeks agoata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is registered
Rosen Penev [Sun, 12 Jul 2026 21:37:26 +0000 (14:37 -0700)] 
ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is registered

sata_dwc_enable_interrupts() is called before platform_get_irq() and
ata_host_activate(), leaving the SATA controller's interrupt mask
enabled without a registered handler.  If a later step fails (irq
request, phy init, etc.) or if the controller asserts an interrupt
during probe, the irq line may fire with no handler, causing a
spurious interrupt storm.

Move sata_dwc_enable_interrupts() after ata_host_activate() so that
interrupts are only unmasked once the handler is registered and the
core is fully initialized.

Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
3 weeks agousb: gadget: printer: fix infinite loop in printer_read()
Melbin K Mathew [Thu, 9 Jul 2026 20:56:22 +0000 (21:56 +0100)] 
usb: gadget: printer: fix infinite loop in printer_read()

printer_read() uses the same variable for the requested copy size and
the number of bytes actually copied to user space. copy_to_user()
returns the number of bytes not copied, so when it fails to copy
anything, the computed copied length becomes zero.

In that case len, buf, current_rx_bytes and current_rx_buf are left
unchanged. If RX data is available and the user buffer remains
unwritable, the read loop can repeat indefinitely.

Track the copied length separately and return -EFAULT, or the number of
bytes already copied, if an iteration makes no progress.

Fixes: b185f01a9ab7 ("usb: gadget: printer: factor out f_printer")
Cc: stable <stable@kernel.org>
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Melbin K Mathew <mlbnkm1@gmail.com>
Link: https://patch.msgid.link/20260709205622.55700-1-mlbnkm1@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agousb: gadget: f_midi: cancel pending IN work before freeing the midi object
Fan Wu [Thu, 9 Jul 2026 15:07:17 +0000 (15:07 +0000)] 
usb: gadget: f_midi: cancel pending IN work before freeing the midi object

The f_midi driver embeds a work item (midi->work) whose handler,
f_midi_in_work(), dereferences the enclosing struct f_midi through
container_of().  This work is armed from two sites: f_midi_complete(),
on a normal IN-endpoint completion, and f_midi_in_trigger(), on an ALSA
rawmidi output-stream start.

Neither f_midi_disable() nor f_midi_unbind() cancels midi->work.
f_midi_disable() only disables the endpoints and drains the in_req_fifo;
it does not synchronize the work item, and the sound card is released
asynchronously to the final free of the midi object.

The midi object is reference-counted (midi->free_ref) and is freed in
f_midi_free() only once both the usb_function reference and the rawmidi
private_data reference have been dropped.  In f_midi_unbind(),
f_midi_disable() runs before the sound card is released, so while the
USB endpoints are already disabled the rawmidi device is still usable by
an open substream.  A concurrent userspace write on such a substream can
reach f_midi_in_trigger() and queue midi->work again after
f_midi_disable() has returned.  A work item armed this way may still be
pending when the last reference drops and f_midi_free() proceeds to
kfree(midi), letting f_midi_in_work() dereference the struct after it
has been freed, a use-after-free.

For this reason cancelling midi->work in f_midi_disable() would not be
sufficient: the ALSA trigger path can rearm the work after disable()
returns.  Cancelling at the refcount-zero free site is the boundary
after which neither arming source can survive, because by then both
references that keep the midi object alive have been dropped: the USB
endpoints are already disabled and the rawmidi device has been released.

Fix this by calling cancel_work_sync(&midi->work) in the refcount-zero
block of f_midi_free(), before the embedded work_struct is freed along
with the rest of the structure.  opts->lock is a sleeping mutex, so
calling cancel_work_sync() under it is permitted, and the handler takes
midi->transmit_lock rather than opts->lock, so no self-deadlock can
occur while it waits for a running instance of the work to finish.

This issue was found by an in-house static analysis tool.

Fixes: 8653d71ce3763 ("usb/gadget: f_midi: Replace tasklet with work")
Cc: stable <stable@kernel.org>
Assisted-by: Codex:gpt-5.5
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260709150717.399083-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agousb: gadget: udc: bdc: free IRQ and drain func_wake_notify before teardown
Fan Wu [Thu, 9 Jul 2026 02:09:04 +0000 (02:09 +0000)] 
usb: gadget: udc: bdc: free IRQ and drain func_wake_notify before teardown

The Broadcom BDC UDC driver registers its IRQ handler with
devm_request_irq() in bdc_udc_init(), so the IRQ is released by devm
only after bdc_remove() returns.  devm releases resources in reverse
LIFO order, but bdc_remove() runs bdc_udc_exit() and bdc_hw_exit() ->
bdc_mem_free() manually before returning: bdc_udc_exit() tears down
individual endpoint objects via bdc_free_ep(), while bdc_hw_exit() ->
bdc_mem_free() frees and NULLs the DMA-coherent status-report ring
(bdc->srr.sr_bds) and kfree()s bdc->bdc_ep_array.  Both happen while
the IRQ handler (bdc_udc_interrupt, requested with IRQF_SHARED)
remains deliverable in the window up to the post-remove devm
free_irq().

On receipt of a shared interrupt in that window, bdc_udc_interrupt()
dereferences bdc->srr.sr_bds[bdc->srr.dqp_index] (NULL or freed DMA)
and dispatches sr_handler callbacks that index into bdc_ep_array,
causing a NULL-deref or use-after-free.

The same window affects the delayed_work bdc->func_wake_notify, which is
armed from the IRQ handler via bdc_sr_uspc() -> handle_link_state_change()
-> schedule_delayed_work() and may self-rearm from its own callback
bdc_func_wake_timer().  No cancel exists anywhere in the driver, so a
queued work item that fires after bdc_remove() returns and the bdc
structure is devm-freed dereferences freed memory.

Replace devm_request_irq() with request_irq() and add an explicit
free_irq(bdc->irq, bdc) in bdc_remove().  Clear BDC_GIE before
free_irq() to stop the device from asserting interrupts, then
free_irq() drains any in-flight handler, then cancel_delayed_work_sync()
drains the func_wake_notify delayed work.  This ordering ensures the
IRQ handler and delayed work cannot interfere with the subsequent
endpoint and DMA teardown in bdc_udc_exit() and bdc_hw_exit().  Wire the
matching free_irq() into the bdc_udc_init() error path so the IRQ is
released on probe failure, and route the bdc_init_ep() failure through
err0 instead of returning directly.

This issue was found by an in-house static analysis tool.

Fixes: efed421a94e6 ("usb: gadget: Add UDC driver for Broadcom USB3.0 device controller IP BDC")
Cc: stable <stable@kernel.org>
Assisted-by: Codex:gpt-5.5
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260709020904.502611-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agousb: typec: ucsi: Fix race condition and ordering in port unregistration
Andrei Kuchynski [Tue, 7 Jul 2026 14:17:36 +0000 (14:17 +0000)] 
usb: typec: ucsi: Fix race condition and ordering in port unregistration

A synchronization issue exists during port unregistration where pending
partner work items can race against workqueue destruction, leading to
use-after-free conditions:

  cros_ec_ucsi cros_ec_ucsi.3.auto: error -ETIMEDOUT: PPM init failed
  BUG: kernel NULL pointer dereference, address: 0000000000000000
  RIP: 0010:__queue_work+0x83/0x4a0
  Call Trace:
    <IRQ>
    __cfi_delayed_work_timer_fn+0x10/0x10
    run_timer_softirq+0x3b6/0xbd0
    sched_clock_cpu+0xc/0x110
    irq_exit_rcu+0x18d/0x330
    fred_sysvec_apic_timer_interrupt+0x5e/0x80

Fix this by ensuring strict ordering and proper serialization during
teardown:

1. Move ucsi_unregister_partner() to the beginning of the teardown
sequence and protect it under the connector mutex lock.
2. Ensure all pending partner tasks are explicitly flushed and finished
before the workqueue is destroyed.
3. Switch from mod_delayed_work() to a cancel_delayed_work() and
queue_delayed_work() sequence. This guarantees that items currently marked
as pending won't be scheduled an additional time, preventing a double
release of resources which leads to the following crash:

  Oops: general protection fault, probably for non-canonical address
    0xdead000000000122: 0000 [#1] SMP NOPTI
  Workqueue: cros_ec_ucsi.3.auto-con2 ucsi_poll_worker
  RIP: 0010:ucsi_poll_worker+0x65/0x1e0
  Call Trace:
  <TASK>
    process_scheduled_works+0x218/0x6d0
    worker_thread+0x188/0x3f0
    __cfi_worker_thread+0x10/0x10
    kthread+0x226/0x2a0

To ensure these rules are applied identically across both the normal
teardown and the ucsi_init() error paths, consolidate the cleanup logic
into a new helper, ucsi_unregister_port().

Cc: stable <stable@kernel.org>
Fixes: b9aa02ca39a4 ("usb: typec: ucsi: Add polling mechanism for partner tasks like alt mode checking")
Fixes: b13abcb7ddd8 ("usb: typec: ucsi: Fix NULL pointer access")
Fixes: fac4b8633fd6 ("usb: ucsi: Ensure connector delayed work items are flushed")
Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
Link: https://patch.msgid.link/20260707141736.1635698-1-akuchynski@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agousb: gadget: f_ncm: validate datagram bounds in ncm_unwrap_ntb()
Sonali Pradhan [Fri, 3 Jul 2026 08:37:24 +0000 (08:37 +0000)] 
usb: gadget: f_ncm: validate datagram bounds in ncm_unwrap_ntb()

When unpacking host-supplied NTBs, ncm_unwrap_ntb() checks datagram length
against frame_max but does not verify that the datagram fits within the
declared block length. Additionally, when decoding multiple NTBs from a
single socket buffer, subsequent block lengths are not checked against the
actual remaining buffer data.

With these checks missing, a malicious USB host can specify datagram
offsets and lengths that point beyond the block, or supply secondary NTB
headers declaring lengths larger than the buffer. skb_put_data() then
copies adjacent kernel memory from skb_shared_info into the network skb.

Fix this by verifying that sufficient buffer space remains for the NTB
header before parsing, handling zero-length block declarations, ensuring
that block lengths never exceed the remaining buffer space, and verifying
that each datagram payload stays strictly within the block boundary.

Fixes: 427694cfaafa ("usb: gadget: ncm: Handle decoding of multiple NTB's in unwrap call")
Fixes: 2b74b0a04d3e ("USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb()")
Cc: stable <stable@kernel.org>
Assisted-by: Jetski:Gemini-2.5-Pro
Signed-off-by: Sonali Pradhan <sonalipradhan@google.com>
Link: https://patch.msgid.link/20260703083725.1903850-1-sonalipradhan@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agoUSB: gadget: fsl-udc: drop misleading unbind sanity check
Johan Hovold [Thu, 2 Jul 2026 14:15:36 +0000 (16:15 +0200)] 
USB: gadget: fsl-udc: drop misleading unbind sanity check

The UDC pointer is set on successful probe and will never be NULL when
the driver is later unbound so drop the misleading sanity check (and
confused error message).

Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260702141536.90887-5-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agoUSB: gadget: fsl-udc: fix dev_printk() device
Johan Hovold [Thu, 2 Jul 2026 14:15:35 +0000 (16:15 +0200)] 
USB: gadget: fsl-udc: fix dev_printk() device

A change replacing custom printk() macros with dev_printk() incorrectly
used the gadget struct device instead of the controller struct device
(including for messages printed before the gadget device name has been
initialised).

Switch to using the controller platform device with dev_printk() so that
the controller device and driver names are included in log messages as
expected.

Fixes: 6025f20f16c2 ("usb: gadget: fsl-udc: Replace custom log wrappers by dev_{err,warn,dbg,vdbg}")
Cc: stable <stable@kernel.org>
Cc: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://patch.msgid.link/20260702141536.90887-4-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agoUSB: gadget: snps-udc: fix device name leak on probe failure
Johan Hovold [Thu, 2 Jul 2026 14:15:34 +0000 (16:15 +0200)] 
USB: gadget: snps-udc: fix device name leak on probe failure

The gadget device name is set by UDC core when registering the gadget
and must not be set before to avoid leaking the name in intermediate
error paths (e.g. when detecting an older chip revision).

Fixes: 12ad0fcaf2fb ("usb: gadget: amd5536udc: let udc-core manage gadget->dev")
Cc: stable <stable@kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260702141536.90887-3-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agoUSB: gadget: fsl-udc: fix device name leak on probe failure
Johan Hovold [Thu, 2 Jul 2026 14:15:33 +0000 (16:15 +0200)] 
USB: gadget: fsl-udc: fix device name leak on probe failure

The gadget device name is set by UDC core when registering the gadget
and must not be set before to avoid leaking the name in intermediate
error paths (e.g. on dma pool creation failure).

Fixes: eab35c4e6d95 ("usb: gadget: fsl_udc_core: let udc-core manage gadget->dev")
Cc: stable <stable@kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260702141536.90887-2-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agousb: xhci-pci: Limit VIA VL805 DMA addressing to 36 bits
Xincheng Zhang [Tue, 30 Jun 2026 01:26:48 +0000 (09:26 +0800)] 
usb: xhci-pci: Limit VIA VL805 DMA addressing to 36 bits

The VIA VL805/806 xHCI controller advertises AC64, but fails to handle
DMA addresses at or above 0x1000000000. On systems with large amounts of
RAM, this can cause USB device failures when the controller is given DMA
addresses beyond its usable address width.

Do not use XHCI_NO_64BIT_SUPPORT for this controller. That quirk clears
the cached AC64 capability and limits DMA to 32 bits, causing unnecessary
bouncing for addresses between 4GiB and 64GiB and hiding the controller's
real AC64 capability from code that may need to distinguish register
access width from usable DMA address width.

Track the usable DMA address width separately from the AC64 capability.
Initialize the generic xhci->dma_mask_bits field to 64 and let PCI quirks
reduce it for controllers with narrower DMA support. Set VIA VL805/806 to
36 bits so the DMA API only hands it addresses in the range it can handle
while keeping HCCPARAMS1.AC64 visible.

Cc: stable <stable@kernel.org>
Signed-off-by: Xincheng Zhang <zhangxincheng@ultrarisc.com>
Link: https://patch.msgid.link/20260630-xhci-via-dma-fix-v3-1-690dcb8cf75a@ultrarisc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3 weeks agousb: gadget: uvc: clamp SEND_RESPONSE length to the response buffer
Muhammad Bilal [Mon, 29 Jun 2026 19:50:04 +0000 (00:50 +0500)] 
usb: gadget: uvc: clamp SEND_RESPONSE length to the response buffer

uvc_send_response() builds the UVC control response from a user-supplied
struct uvc_request_data:

req->length = min_t(unsigned int, uvc->event_length, data->length);
...
memcpy(req->buf, data->data, req->length);

req->length is clamped to uvc->event_length, which is taken from the
host control request wLength (up to UVC_MAX_REQUEST_SIZE, 64), and to
data->length, which comes from the UVCIOC_SEND_RESPONSE ioctl and is
only checked for being negative.  The source buffer data->data is only
60 bytes, so a response with uvc->event_length and data->length both
greater than 60 makes memcpy() read past the end of data->data.

Clamp req->length to sizeof(data->data) as well.

Fixes: a5eaaa1f33e7 ("usb: gadget: uvc: use capped length value")
Cc: stable <stable@kernel.org>
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260629195004.148405-1-meatuni001@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>