__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: 57a304cfd4 ("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>
[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 095be159f3 ("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: 095be159f3 ("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>
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 f86f7a75e2 ("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 f86f7a75e2.
CC: Jeff Layton <jlayton@kernel.org>
Link: https://lore.kernel.org/all/20260629-btrfs-skip-logging-v1-1-4e3a28c1acaf@kernel.org/
Fixes: f86f7a75e2 ("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>
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 84cda1a608 ("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: 84cda1a608 ("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>
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>
Commit a6908f88c9 ("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: a6908f88c9 ("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>
[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 3eaf5f082c ("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: 3eaf5f082c ("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>
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: cc68a8a5a4 ("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>
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>
- 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.
-----BEGIN PGP SIGNATURE-----
iIQEABYKACwWIQTfIjM1kS57o3GsC/uxYfJx3gVYGQUCalVWkg4cdGpAa2VybmVs
Lm9yZwAKCRCxYfJx3gVYGet9AQD3/qE93E+PctxXa+rmRfSSjIzqqv9NUZa4THjs
YOUqSAEApVSLPkhg3xHF61q9l+FuocLLY378Uf6LYGWet1SghAQ=
=1Gp+
-----END PGP SIGNATURE-----
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
- 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.
-----BEGIN PGP SIGNATURE-----
iIQEABYKACwWIQTfIjM1kS57o3GsC/uxYfJx3gVYGQUCalVWgw4cdGpAa2VybmVs
Lm9yZwAKCRCxYfJx3gVYGTmUAP0QHX7Ae/g7yMPEB4slURpnSj/wE7hRCI5jTmay
2iIEJgD/RAhpwUUAp4Abozt0mjQMWh9UyEVjOxPCVNKaNh1XfwU=
=EBCm
-----END PGP SIGNATURE-----
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
- 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.
-----BEGIN PGP SIGNATURE-----
iIoEABYKADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCalVLJxQccm9zdGVkdEBn
b29kbWlzLm9yZwAKCRAp5XQQmuv6qirUAP9pqYHgcHkaJpLXJYNXAAkd45qzo0RD
17QgHysPOwnYlwEAlnudrPPBLnSLnjw+0NgOolMJKu38h2vIjcVEbmuZaAE=
=BGaW
-----END PGP SIGNATURE-----
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
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: 750e76b4f9 ("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 14a2012a49)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
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>
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: 021d23428b ("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>
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>
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: c41bf4326c ("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>
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>
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>
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: 27655b9bb9 ("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
Applies the same treatment as commit 7cf6dd467e ("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: 086b9f27f0 ("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
Issues reported with v7.2-rc:
- Fix a UAF when unlocking a filesystem
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEKLLlsBKG3yQ88j7+M2qzM29mf5cFAmpUTYQACgkQM2qzM29m
f5fluA//Ttq+/8JVZnAwxCYyMTM+ix8S1qYAP9eXxB4OwHVjVGdm/aAHbm6fmnuw
IiMdJw0ZB2RQEFrD+jLJxWipYil/oHYUhUsS1sxSLTE9RMeAVnD4SbGEO1Hg2imV
zISIpM7kNkh7NcJkKgzb8mCh04C6TSLwUsq36sOf6H6JlWJsQjM9j6t343pET3NY
IDxjCIz/C7wfPRHsg+ycsXCvbrF3tE27Grq2HX0/0tPIo8JoqR3sCgIWz00UN3NT
QE0FfPU0fUmn0TW6WupMmibC/cSBjUkEayEIWOuRdo2HfjdHFJKKVEJhbPfueHZU
NiTTyMaIC2bKXclAZR9CEggyZmdfJTBMkmQSIvMKr2XWYKcLFTrVfcXpU3iuYgLq
R97keupMX5YrBA1HZa+pWozuBdBxYD4ykJFFYy3hF+84X8JY4om3g40mtIG1P52/
lc61qZGqMGddkPPL7pGVxJ0l6husKeCd3T/vo1HupeRg1swOB0VzCYK9NNo1tBO4
yf7ZdqOE2r7crmYpIE2woNdXs9fGpkpZriLq8iWvlVWIuHHfjYolk0a62QIO/GV1
Tgvu442+gJYcf+QLOZIf+YRA1LvNxXyENR/ZKXDhQ85h/nTEULKL5Ne9Fqq2qOTk
5YCNE6/XkB5sGNA/aF06RPDnUjuBNX7PTEMt5a+t2ikB5nkq/YY=
=NRRN
-----END PGP SIGNATURE-----
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
Commit 53b7c271f0 ("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: 53b7c271f0 ("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>
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>
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>
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>
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: 966a3cb7c7 ("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>
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: 99cd0a6eeb ("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>
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: 966a3cb7c7 ("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>
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
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: 7aeb259086 ("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>
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
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRRRCHOFoQz/8F5bUaFwuHvBreFYQUCalTdtwAKCRCFwuHvBreF
YQ44AP47MlX9CTlu5GtEVmjeQzIuYVAp0pNIDbU0XSqZa3BSQgD/Z7X3Ib8HIr7+
pnGCDpwqkXHHiHKsgIgjRIwSZFxWkws=
=G+7p
-----END PGP SIGNATURE-----
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
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: d47da6bd4c ("Bluetooth: hci_core: Fix sending MGMT_EV_CONNECT_FAILED")
Fixes: 182ee45da0 ("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>
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: 06d3fdfcdf ("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>
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: c530569adc ("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>
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: 7b445e220d ("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>
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: 227a0cdf4a ("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>
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: 6d0417e4e1 ("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>
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: db33c77ddd ("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>
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: 0ece498c27 ("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>
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: 2e4edfa1e2 ("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>
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: a84fab3cbf ("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>
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: a84fab3cbf ("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>
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: a84fab3cbf ("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>
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: bdcd817079 ("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>
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: bdcd817079 ("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>
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: bdcd817079 ("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>
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: 57ccca4102 ("wifi: ath12k: Add hash table for ath12k_link_sta in ath12k_base")
Fixes: a88cf5f71a ("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>