<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/fs, branch v6.1.178</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>cifs: fix lock ordering while disabling multichannel</title>
<updated>2026-07-24T13:55:18+00:00</updated>
<author>
<name>Shyam Prasad N</name>
<email>sprasad@microsoft.com</email>
</author>
<published>2023-11-14T04:58:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=c2a0dc9fd31edd30be60c496c1fd9e14a0911a95'/>
<id>c2a0dc9fd31edd30be60c496c1fd9e14a0911a95</id>
<content type='text'>
commit 5eef12c4e3230f2025dc46ad8c4a3bc19978e5d7 upstream.

The code to handle the case of server disabling multichannel
was picking iface_lock with chan_lock held. This goes against
the lock ordering rules, as iface_lock is a higher order lock
(even if it isn't so obvious).

This change fixes the lock ordering by doing the following in
that order for each secondary channel:
1. store iface and server pointers in local variable
2. remove references to iface and server in channels
3. unlock chan_lock
4. lock iface_lock
5. dec ref count for iface
6. unlock iface_lock
7. dec ref count for server
8. lock chan_lock again

Since this function can only be called in smb2_reconnect, and
that cannot be called by two parallel processes, we should not
have races due to dropping chan_lock between steps 3 and 8.

Fixes: ee1d21794e55 ("cifs: handle when server stops supporting multichannel")
Reported-by: Paulo Alcantara &lt;pc@manguebit.com&gt;
Signed-off-by: Shyam Prasad N &lt;sprasad@microsoft.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 5eef12c4e3230f2025dc46ad8c4a3bc19978e5d7 upstream.

The code to handle the case of server disabling multichannel
was picking iface_lock with chan_lock held. This goes against
the lock ordering rules, as iface_lock is a higher order lock
(even if it isn't so obvious).

This change fixes the lock ordering by doing the following in
that order for each secondary channel:
1. store iface and server pointers in local variable
2. remove references to iface and server in channels
3. unlock chan_lock
4. lock iface_lock
5. dec ref count for iface
6. unlock iface_lock
7. dec ref count for server
8. lock chan_lock again

Since this function can only be called in smb2_reconnect, and
that cannot be called by two parallel processes, we should not
have races due to dropping chan_lock between steps 3 and 8.

Fixes: ee1d21794e55 ("cifs: handle when server stops supporting multichannel")
Reported-by: Paulo Alcantara &lt;pc@manguebit.com&gt;
Signed-off-by: Shyam Prasad N &lt;sprasad@microsoft.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>writeback: drop now-unnecessary rcu_barrier() in cgroup_writeback_umount()</title>
<updated>2026-07-24T13:55:18+00:00</updated>
<author>
<name>Baokun Li</name>
<email>libaokun@linux.alibaba.com</email>
</author>
<published>2026-05-21T09:50:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=b360aa7208f03734b72b065afae23579460cf096'/>
<id>b360aa7208f03734b72b065afae23579460cf096</id>
<content type='text'>
commit e90a6d668e26e00a72df2d09c173b563468f09c9 upstream.

Commit e1b849cfa6b6 ("writeback: Avoid contention on wb-&gt;list_lock when
switching inodes") replaced the queue_rcu_work() based scheduling of
inode wb switches with a plain queue_work().  Since then no switcher
goes through call_rcu(), so rcu_barrier() in cgroup_writeback_umount()
has no callbacks of its own to wait for.  It still drains unrelated
call_rcu() callbacks from other subsystems on busy systems, which
incidentally slows umount down; drop it.

Fixes: e1b849cfa6b6 ("writeback: Avoid contention on wb-&gt;list_lock when switching inodes")
Reviewed-by: Jan Kara &lt;jack@suse.cz&gt;
Signed-off-by: Baokun Li &lt;libaokun@linux.alibaba.com&gt;
Link: https://patch.msgid.link/20260521095016.2791354-3-libaokun@linux.alibaba.com
Acked-by: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Christian Brauner (Amutable) &lt;brauner@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit e90a6d668e26e00a72df2d09c173b563468f09c9 upstream.

Commit e1b849cfa6b6 ("writeback: Avoid contention on wb-&gt;list_lock when
switching inodes") replaced the queue_rcu_work() based scheduling of
inode wb switches with a plain queue_work().  Since then no switcher
goes through call_rcu(), so rcu_barrier() in cgroup_writeback_umount()
has no callbacks of its own to wait for.  It still drains unrelated
call_rcu() callbacks from other subsystems on busy systems, which
incidentally slows umount down; drop it.

Fixes: e1b849cfa6b6 ("writeback: Avoid contention on wb-&gt;list_lock when switching inodes")
Reviewed-by: Jan Kara &lt;jack@suse.cz&gt;
Signed-off-by: Baokun Li &lt;libaokun@linux.alibaba.com&gt;
Link: https://patch.msgid.link/20260521095016.2791354-3-libaokun@linux.alibaba.com
Acked-by: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Christian Brauner (Amutable) &lt;brauner@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>writeback: Fix use after free in inode_switch_wbs_work_fn()</title>
<updated>2026-07-24T13:55:18+00:00</updated>
<author>
<name>Jan Kara</name>
<email>jack@suse.cz</email>
</author>
<published>2026-04-13T09:36:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=382cf81cae89e58d22b4bdc38891cd4d0b9ba921'/>
<id>382cf81cae89e58d22b4bdc38891cd4d0b9ba921</id>
<content type='text'>
commit 6689f01d6740cf358932b3e97ee968c6099800d9 upstream.

inode_switch_wbs_work_fn() has a loop like:

  wb_get(new_wb);
  while (1) {
    list = llist_del_all(&amp;new_wb-&gt;switch_wbs_ctxs);
    /* Nothing to do? */
    if (!list)
      break;
    ... process the items ...
  }

Now adding of items to the list looks like:

wb_queue_isw()
  if (llist_add(&amp;isw-&gt;list, &amp;wb-&gt;switch_wbs_ctxs))
    queue_work(isw_wq, &amp;wb-&gt;switch_work);

Because inode_switch_wbs_work_fn() loops when processing isw items, it
can happen that wb-&gt;switch_work is pending while wb-&gt;switch_wbs_ctxs is
empty. This is a problem because in that case wb can get freed (no isw
items -&gt; no wb reference) while the work is still pending causing
use-after-free issues.

We cannot just fix this by cancelling work when freeing wb because that
could still trigger problematic 0 -&gt; 1 transitions on wb refcount due to
wb_get() in inode_switch_wbs_work_fn(). It could be all handled with
more careful code but that seems unnecessarily complex so let's avoid
that until it is proven that the looping actually brings practical
benefit. Just remove the loop from inode_switch_wbs_work_fn() instead.
That way when wb_queue_isw() queues work, we are guaranteed we have
added the first item to wb-&gt;switch_wbs_ctxs and nobody is going to
remove it (and drop the wb reference it holds) until the queued work
runs.

Fixes: e1b849cfa6b6 ("writeback: Avoid contention on wb-&gt;list_lock when switching inodes")
CC: stable@vger.kernel.org
Signed-off-by: Jan Kara &lt;jack@suse.cz&gt;
Link: https://patch.msgid.link/20260413093618.17244-2-jack@suse.cz
Acked-by: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Christian Brauner &lt;brauner@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 6689f01d6740cf358932b3e97ee968c6099800d9 upstream.

inode_switch_wbs_work_fn() has a loop like:

  wb_get(new_wb);
  while (1) {
    list = llist_del_all(&amp;new_wb-&gt;switch_wbs_ctxs);
    /* Nothing to do? */
    if (!list)
      break;
    ... process the items ...
  }

Now adding of items to the list looks like:

wb_queue_isw()
  if (llist_add(&amp;isw-&gt;list, &amp;wb-&gt;switch_wbs_ctxs))
    queue_work(isw_wq, &amp;wb-&gt;switch_work);

Because inode_switch_wbs_work_fn() loops when processing isw items, it
can happen that wb-&gt;switch_work is pending while wb-&gt;switch_wbs_ctxs is
empty. This is a problem because in that case wb can get freed (no isw
items -&gt; no wb reference) while the work is still pending causing
use-after-free issues.

We cannot just fix this by cancelling work when freeing wb because that
could still trigger problematic 0 -&gt; 1 transitions on wb refcount due to
wb_get() in inode_switch_wbs_work_fn(). It could be all handled with
more careful code but that seems unnecessarily complex so let's avoid
that until it is proven that the looping actually brings practical
benefit. Just remove the loop from inode_switch_wbs_work_fn() instead.
That way when wb_queue_isw() queues work, we are guaranteed we have
added the first item to wb-&gt;switch_wbs_ctxs and nobody is going to
remove it (and drop the wb reference it holds) until the queued work
runs.

Fixes: e1b849cfa6b6 ("writeback: Avoid contention on wb-&gt;list_lock when switching inodes")
CC: stable@vger.kernel.org
Signed-off-by: Jan Kara &lt;jack@suse.cz&gt;
Link: https://patch.msgid.link/20260413093618.17244-2-jack@suse.cz
Acked-by: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Christian Brauner &lt;brauner@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>btrfs: fix incorrect buffered IO fallback for append direct writes</title>
<updated>2026-07-24T13:55:17+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-07-20T20:19:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=10b1abc1d0c8ae25c2b9ac465515717c68ffff05'/>
<id>10b1abc1d0c8ae25c2b9ac465515717c68ffff05</id>
<content type='text'>
[ Upstream commit ff66fe6662330226b3f486014c375538d91c44aa ]

[BUG]
With the previous bug of short direct writes fixed, test case
generic/362 (*) still fails with the following error with nodatasum
mount option:

# generic/362  0s ... - output mismatch (see /home/adam/xfstests/results//generic/362.out.bad)
# - output mismatch (see /home/adam/xfstests/results//generic/362.out.bad)
#    --- tests/generic/362.out	2024-08-24 15:31:37.200000000 +0930
#    +++ /home/adam/xfstests/results//generic/362.out.bad	2026-05-27 10:13:09.072485767 +0930
#    @@ -1,2 +1,3 @@
#     QA output created by 362
#    +Wrong file size after first write, got 8192 expected 4096
#     Silence is golden
#    ...

*: If the test case has been executed before with default data checksum,
the failure will not reproduce. Need the following fix to make it
reliably reproducible:
https://lore.kernel.org/linux-btrfs/20260528111659.87113-1-wqu@suse.com/

[CAUSE]
Inside btrfs_dio_iomap_begin() for a direct write, we increase the isize
if it's beyond the current isize.

But if the direct io finished short, we do not revert the isize to the
previous value nor to the short write end.

Then if we need to fall back to buffered writes, and the write has
IOCB_APPEND flag, then the buffered write will be positioned at the
incorrect isize.

The call chain looks like this:

 btrfs_direct_write(pos=0, length=4K)
 |- __iomap_dio_rw()
 |  |- iomap_iter()
 |  |  |- btrfs_dio_iomap_begin()
 |  |     |- btrfs_get_blocks_direct_write()
 |  |        |- i_size_write()
 |  |           Which updates the isize to the write end (4K).
 |  |
 |  |- iomap_dio_iter()
 |  |  Failed with -EFAULT on the first page.
 |  |
 |  |- iomap_iter()
 |  |  |- btrfs_dio_iomap_end()
 |  |     Detects a short write, return -ENOTBLK
 |  |- if (ret == -ENOTBLK) { ret = 0;}
 |     Which resets the return value.
 |
 |- ret = iomap_dio_complet()
 |  Which returns 0.
 |
 |- btrfs_buffered_write(iocb, from);
    |- generic_write_checks()
       |- iocb-&gt;ki_pos = i_size_read()
          Which is still the new size (4K), other than the original
	  isize 0.

[FIX]
Introduce the following btrfs_dio_data members:

- old_isize

- updated_isize
  If the direct write has enlarged the isize.

Then if we got a short write, and btrfs_dio_data::updated_isize is set,
revert to the correct isize based on old_isize and current file
position.

And here we call i_size_write() without holding an extent lock, which is
a very special case that we're safe to do:

 - Only a single writer can be enlarging isize
   Enlarging isize will take the exclusive inode lock.

 - Buffered readers need to wait for the OE we're holding
   Buffered readers will lock extent and wait for OE of the folio range.
   Sometimes we can skip the OE wait, but since all page cache is
   invalidated, the OE wait can not be skipped.

But I do not think this is the most elegant solution, nor covers all
cases. E.g. if the bio is submitted but IO failed, we are unable to do
the revert.

I believe the more elegant one would be extend the EXTENT_DIO_LOCKED
lifespan for direct writes, so that we can update the isize when a
write beyond EOF finished successfully.

However that change is too huge for a small bug fix.
So only implement the minimal partial fix for now.

[REASON FOR NO FIXES TAG]
The bug is again very old, before commit f85781fb505e ("btrfs: switch to
iomap for direct IO") we are already increasing isize without a
proper rollback for short writes.

Thus only a CC to stable.

CC: stable@vger.kernel.org # 5.15+
Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit ff66fe6662330226b3f486014c375538d91c44aa ]

[BUG]
With the previous bug of short direct writes fixed, test case
generic/362 (*) still fails with the following error with nodatasum
mount option:

# generic/362  0s ... - output mismatch (see /home/adam/xfstests/results//generic/362.out.bad)
# - output mismatch (see /home/adam/xfstests/results//generic/362.out.bad)
#    --- tests/generic/362.out	2024-08-24 15:31:37.200000000 +0930
#    +++ /home/adam/xfstests/results//generic/362.out.bad	2026-05-27 10:13:09.072485767 +0930
#    @@ -1,2 +1,3 @@
#     QA output created by 362
#    +Wrong file size after first write, got 8192 expected 4096
#     Silence is golden
#    ...

*: If the test case has been executed before with default data checksum,
the failure will not reproduce. Need the following fix to make it
reliably reproducible:
https://lore.kernel.org/linux-btrfs/20260528111659.87113-1-wqu@suse.com/

[CAUSE]
Inside btrfs_dio_iomap_begin() for a direct write, we increase the isize
if it's beyond the current isize.

But if the direct io finished short, we do not revert the isize to the
previous value nor to the short write end.

Then if we need to fall back to buffered writes, and the write has
IOCB_APPEND flag, then the buffered write will be positioned at the
incorrect isize.

The call chain looks like this:

 btrfs_direct_write(pos=0, length=4K)
 |- __iomap_dio_rw()
 |  |- iomap_iter()
 |  |  |- btrfs_dio_iomap_begin()
 |  |     |- btrfs_get_blocks_direct_write()
 |  |        |- i_size_write()
 |  |           Which updates the isize to the write end (4K).
 |  |
 |  |- iomap_dio_iter()
 |  |  Failed with -EFAULT on the first page.
 |  |
 |  |- iomap_iter()
 |  |  |- btrfs_dio_iomap_end()
 |  |     Detects a short write, return -ENOTBLK
 |  |- if (ret == -ENOTBLK) { ret = 0;}
 |     Which resets the return value.
 |
 |- ret = iomap_dio_complet()
 |  Which returns 0.
 |
 |- btrfs_buffered_write(iocb, from);
    |- generic_write_checks()
       |- iocb-&gt;ki_pos = i_size_read()
          Which is still the new size (4K), other than the original
	  isize 0.

[FIX]
Introduce the following btrfs_dio_data members:

- old_isize

- updated_isize
  If the direct write has enlarged the isize.

Then if we got a short write, and btrfs_dio_data::updated_isize is set,
revert to the correct isize based on old_isize and current file
position.

And here we call i_size_write() without holding an extent lock, which is
a very special case that we're safe to do:

 - Only a single writer can be enlarging isize
   Enlarging isize will take the exclusive inode lock.

 - Buffered readers need to wait for the OE we're holding
   Buffered readers will lock extent and wait for OE of the folio range.
   Sometimes we can skip the OE wait, but since all page cache is
   invalidated, the OE wait can not be skipped.

But I do not think this is the most elegant solution, nor covers all
cases. E.g. if the bio is submitted but IO failed, we are unable to do
the revert.

I believe the more elegant one would be extend the EXTENT_DIO_LOCKED
lifespan for direct writes, so that we can update the isize when a
write beyond EOF finished successfully.

However that change is too huge for a small bug fix.
So only implement the minimal partial fix for now.

[REASON FOR NO FIXES TAG]
The bug is again very old, before commit f85781fb505e ("btrfs: switch to
iomap for direct IO") we are already increasing isize without a
proper rollback for short writes.

Thus only a CC to stable.

CC: stable@vger.kernel.org # 5.15+
Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>btrfs: fix false IO failure after falling back to buffered write</title>
<updated>2026-07-24T13:55:17+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-07-20T18:08:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=22c739df6534cedadd526f52f27f6b0f028585e2'/>
<id>22c739df6534cedadd526f52f27f6b0f028585e2</id>
<content type='text'>
[ Upstream commit 66ff4d366e7eb4d31813d2acabf3af512ce03aa5 ]

[BUG]
The test case generic/362 will fail with "nodatasum" mount option (*):

 MOUNT_OPTIONS -- -o nodatasum /dev/mapper/test-scratch1 /mnt/scratch

# generic/362  0s ... - output mismatch (see /home/adam/xfstests/results//generic/362.out.bad)
#    --- tests/generic/362.out	2024-08-24 15:31:37.200000000 +0930
#    +++ /home/adam/xfstests/results//generic/362.out.bad	2026-05-27 10:21:17.574771567 +0930
#    @@ -1,2 +1,3 @@
#     QA output created by 362
#    +First write failed: Input/output error
#     Silence is golden
#    ...

*: If the test case has been executed before with default data checksum,
the failure will not reproduce. Need the following fix to make it
reliably reproducible:
https://lore.kernel.org/linux-btrfs/20260528111659.87113-1-wqu@suse.com/

[CAUSE]
Inside __iomap_dio_rw(), the -EFAULT/-ENOTBLK error is not directly returned.
Thus we never got an error pointer from __iomap_dio_rw().

The call chain looks like this:

 btrfs_direct_write()
 |- btrfs_dio_write()
 |-  __iomap_dio_rw()
 |  |- iomap_iter()
 |  |  |- btrfs_dio_iomap_begin()
 |  |     Now an ordered extent is allocated for the 4K write.
 |  |
 |  |- iomi.status = iomap_dio_iter()
 |  |  Where iomap_dio_iter() returned -EFAULT.
 |  |
 |  |- ret = iomap_iter()
 |  |  |- btrfs_dio_iomap_end()
 |  |  |  |- btrfs_finish_ordered_extent(uptodate = false)
 |  |  |  |  |- can_finish_ordered_extent()
 |  |  |  |     |- btrfs_mark_ordered_extent_error()
 |  |  |  |        |- mapping_set_error()
 |  |  |  |           Now the address space is marked error.
 |  |  |  | return -ENOTBLK
 |  |  |- return -ENOTBLK
 |  |- if (ret == -ENOTBLK) { ret = 0; }
 |     Now the return value is reset to 0.
 |     Thus no error pointer will be returned.
 |
 |- ret = iomap_dio_complete()
 |  Since no byte is submitted, @ret is 0.
 |
 |- Fallback to buffered IO
 |  And the buffered write finished without error
 |
 |- filemap_fdatawait_range()
    |- filemap_check_errors()
       The previous error is recorded, thus an error is returned

However the buffered write is properly submitted and finished, the error
is from the btrfs_finish_ordered_extent() call with @uptodate = false.

[FIX]
When a short dio write happened, any range that is submitted will have
btrfs_extract_ordered_extent() to be called, thus the submitted range
will always have an OE just covering the submitted range.

The remaining OE range is never submitted, thus they should be treated
as truncated, not an error. So that we can properly reclaim and not
insert an unnecessary file extent item, without marking the mapping as
error.

Extract a helper, btrfs_mark_ordered_extent_truncated(), and utilize
that helper to mark the direct IO ordered extent as truncated, so it
won't cause failure for the later buffered fallback.

[REASON FOR NO FIXES TAG]
The bug itself is pretty old, at commit f85781fb505e ("btrfs: switch to
iomap for direct IO") we're already passing @uptodate=false finishing
the OE.
But at that time OE with IOERR won't call mapping_set_error(), so it's
not exposed.
Later commit d61bec08b904 ("btrfs: mark ordered extent and inode with
error if we fail to finish") finally exposed the bug, but that commit
is doing a correct job, not the root cause.

Anyway the bug is very old, dating back to 5.1x days, thus only CC to
stable.

CC: stable@vger.kernel.org # 5.15+
Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 66ff4d366e7eb4d31813d2acabf3af512ce03aa5 ]

[BUG]
The test case generic/362 will fail with "nodatasum" mount option (*):

 MOUNT_OPTIONS -- -o nodatasum /dev/mapper/test-scratch1 /mnt/scratch

# generic/362  0s ... - output mismatch (see /home/adam/xfstests/results//generic/362.out.bad)
#    --- tests/generic/362.out	2024-08-24 15:31:37.200000000 +0930
#    +++ /home/adam/xfstests/results//generic/362.out.bad	2026-05-27 10:21:17.574771567 +0930
#    @@ -1,2 +1,3 @@
#     QA output created by 362
#    +First write failed: Input/output error
#     Silence is golden
#    ...

*: If the test case has been executed before with default data checksum,
the failure will not reproduce. Need the following fix to make it
reliably reproducible:
https://lore.kernel.org/linux-btrfs/20260528111659.87113-1-wqu@suse.com/

[CAUSE]
Inside __iomap_dio_rw(), the -EFAULT/-ENOTBLK error is not directly returned.
Thus we never got an error pointer from __iomap_dio_rw().

The call chain looks like this:

 btrfs_direct_write()
 |- btrfs_dio_write()
 |-  __iomap_dio_rw()
 |  |- iomap_iter()
 |  |  |- btrfs_dio_iomap_begin()
 |  |     Now an ordered extent is allocated for the 4K write.
 |  |
 |  |- iomi.status = iomap_dio_iter()
 |  |  Where iomap_dio_iter() returned -EFAULT.
 |  |
 |  |- ret = iomap_iter()
 |  |  |- btrfs_dio_iomap_end()
 |  |  |  |- btrfs_finish_ordered_extent(uptodate = false)
 |  |  |  |  |- can_finish_ordered_extent()
 |  |  |  |     |- btrfs_mark_ordered_extent_error()
 |  |  |  |        |- mapping_set_error()
 |  |  |  |           Now the address space is marked error.
 |  |  |  | return -ENOTBLK
 |  |  |- return -ENOTBLK
 |  |- if (ret == -ENOTBLK) { ret = 0; }
 |     Now the return value is reset to 0.
 |     Thus no error pointer will be returned.
 |
 |- ret = iomap_dio_complete()
 |  Since no byte is submitted, @ret is 0.
 |
 |- Fallback to buffered IO
 |  And the buffered write finished without error
 |
 |- filemap_fdatawait_range()
    |- filemap_check_errors()
       The previous error is recorded, thus an error is returned

However the buffered write is properly submitted and finished, the error
is from the btrfs_finish_ordered_extent() call with @uptodate = false.

[FIX]
When a short dio write happened, any range that is submitted will have
btrfs_extract_ordered_extent() to be called, thus the submitted range
will always have an OE just covering the submitted range.

The remaining OE range is never submitted, thus they should be treated
as truncated, not an error. So that we can properly reclaim and not
insert an unnecessary file extent item, without marking the mapping as
error.

Extract a helper, btrfs_mark_ordered_extent_truncated(), and utilize
that helper to mark the direct IO ordered extent as truncated, so it
won't cause failure for the later buffered fallback.

[REASON FOR NO FIXES TAG]
The bug itself is pretty old, at commit f85781fb505e ("btrfs: switch to
iomap for direct IO") we're already passing @uptodate=false finishing
the OE.
But at that time OE with IOERR won't call mapping_set_error(), so it's
not exposed.
Later commit d61bec08b904 ("btrfs: mark ordered extent and inode with
error if we fail to finish") finally exposed the bug, but that commit
is doing a correct job, not the root cause.

Anyway the bug is very old, dating back to 5.1x days, thus only CC to
stable.

CC: stable@vger.kernel.org # 5.15+
Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>btrfs: check and set EXTENT_DELALLOC_NEW before clearing EXTENT_DELALLOC</title>
<updated>2026-07-24T13:55:17+00:00</updated>
<author>
<name>Qu Wenruo</name>
<email>wqu@suse.com</email>
</author>
<published>2026-07-20T20:18:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=c3bee98891ad2eb02f4fbd39b82b9918d0aa7a42'/>
<id>c3bee98891ad2eb02f4fbd39b82b9918d0aa7a42</id>
<content type='text'>
[ Upstream commit 95ee2231896d5f2a31760411429075a99d6045a7 ]

[WARNING]
When running test cases with injected errors or shutdown, e.g.
generic/388 or generic/475, there is a chance that the following kernel
warning is triggered:

  BTRFS info (device dm-2): first mount of filesystem d8a19a28-3232-4809-b0df-38df83e71bff
  BTRFS info (device dm-2): using crc32c checksum algorithm
  BTRFS info (device dm-2): checking UUID tree
  BTRFS info (device dm-2): turning on async discard
  BTRFS info (device dm-2): enabling free space tree
  BTRFS critical (device dm-2 state E): emergency shutdown
  ------------[ cut here ]------------
  WARNING: extent_io.c:1742 at extent_writepage_io+0x437/0x520 [btrfs], CPU#2: kworker/u43:2/651591
  CPU: 2 UID: 0 PID: 651591 Comm: kworker/u43:2 Tainted: G        W  OE       7.0.0-rc6-custom+ #365 PREEMPT(full)  5804053f02137e627472d94b5128cc9fcb110e88
  RIP: 0010:extent_writepage_io+0x437/0x520 [btrfs]
  Call Trace:
   &lt;TASK&gt;
   extent_write_cache_pages+0x2a5/0x820 [btrfs 70299925d0856939e93b17d480651713b3cbba58]
   btrfs_writepages+0x74/0x130 [btrfs 70299925d0856939e93b17d480651713b3cbba58]
   do_writepages+0xd0/0x160
   __writeback_single_inode+0x42/0x340
   writeback_sb_inodes+0x22d/0x580
   wb_writeback+0xc6/0x360
   wb_workfn+0xbd/0x470
   process_one_work+0x198/0x3b0
   worker_thread+0x1c8/0x330
   kthread+0xee/0x120
   ret_from_fork+0x2a6/0x330
   ret_from_fork_asm+0x11/0x20
   &lt;/TASK&gt;
  ---[ end trace 0000000000000000 ]---
  BTRFS error (device dm-2 state E): root 5 ino 259 folio 1323008 is marked dirty without notifying the fs
  BTRFS error (device dm-2 state E): failed to submit blocks, root=5 inode=259 folio=1323008 submit_bitmap=0: -117
  BTRFS info (device dm-2 state E): last unmount of filesystem d8a19a28-3232-4809-b0df-38df83e71bff

[CAUSE]
Inside btrfs we have the following pattern in several locations, for
example inside btrfs_dirty_folio():

	btrfs_clear_extent_bit(&amp;inode-&gt;io_tree, start_pos, end_of_last_block,
			       EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
			       cached);

	ret = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
					extra_bits, cached);
	if (ret)
		return ret;

However btrfs_set_extent_delalloc() can return IO errors other than -ENOMEM
through the following callchain:

 btrfs_set_extent_delalloc()
 \- btrfs_find_new_delalloc_bytes()
    \- btrfs_get_extent()
       \- btrfs_lookup_file_extent()
          \- btrfs_search_slot()

When such IO error happened, the previous btrfs_clear_extent_bit() has
cleared the EXTENT_DELALLOC for the range, and we're expecting
btrfs_set_extent_delalloc() to re-set EXTENT_DELALLOC.

But since btrfs_set_extent_delalloc() failed before
btrfs_set_extent_bit(), EXTENT_DELALLOC flag is no longer present.

And if the folio range is dirty before entering
btrfs_set_extent_delalloc(), we got a dirty folio but no EXTENT_DELALLOC
flag now.

Then we hit the folio writeback:

  extent_writepage()
  |- writepage_delalloc()
  |  No ordered extent is created, as there is no EXTENT_DELALLOC set
  |  for the folio range.
  |  This also means the folio has no ordered flag set.
  |
  |- extent_writepage_io()
     \- if (unlikely(!folio_test_ordered(folio))
        Now we hit the warning.

[FIX]
Introduce a new helper, btrfs_reset_extent_delalloc() to replace the
currently open-coded btrfs_clear_extent_bit() +
btrfs_set_extent_delalloc() combination.

Instead of calling btrfs_clear_extent_bit() first, update
EXTENT_DELALLOC_NEW first, as that part can fail due to metadata IO,
meanwhile btrfs_clear_extent_bit() and btrfs_set_extent_bit() won't
return any error but retry memory allocation until succeeded.

This allows us to fail early without clearing EXTENT_DELALLOC bit, so
even if that new btrfs_reset_extent_delalloc() failed before touching
EXTENT_DELALLOC, the existing dirty range will still have their old
EXTENT_DELALLOC flag present, thus avoid the warning.

CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 95ee2231896d5f2a31760411429075a99d6045a7 ]

[WARNING]
When running test cases with injected errors or shutdown, e.g.
generic/388 or generic/475, there is a chance that the following kernel
warning is triggered:

  BTRFS info (device dm-2): first mount of filesystem d8a19a28-3232-4809-b0df-38df83e71bff
  BTRFS info (device dm-2): using crc32c checksum algorithm
  BTRFS info (device dm-2): checking UUID tree
  BTRFS info (device dm-2): turning on async discard
  BTRFS info (device dm-2): enabling free space tree
  BTRFS critical (device dm-2 state E): emergency shutdown
  ------------[ cut here ]------------
  WARNING: extent_io.c:1742 at extent_writepage_io+0x437/0x520 [btrfs], CPU#2: kworker/u43:2/651591
  CPU: 2 UID: 0 PID: 651591 Comm: kworker/u43:2 Tainted: G        W  OE       7.0.0-rc6-custom+ #365 PREEMPT(full)  5804053f02137e627472d94b5128cc9fcb110e88
  RIP: 0010:extent_writepage_io+0x437/0x520 [btrfs]
  Call Trace:
   &lt;TASK&gt;
   extent_write_cache_pages+0x2a5/0x820 [btrfs 70299925d0856939e93b17d480651713b3cbba58]
   btrfs_writepages+0x74/0x130 [btrfs 70299925d0856939e93b17d480651713b3cbba58]
   do_writepages+0xd0/0x160
   __writeback_single_inode+0x42/0x340
   writeback_sb_inodes+0x22d/0x580
   wb_writeback+0xc6/0x360
   wb_workfn+0xbd/0x470
   process_one_work+0x198/0x3b0
   worker_thread+0x1c8/0x330
   kthread+0xee/0x120
   ret_from_fork+0x2a6/0x330
   ret_from_fork_asm+0x11/0x20
   &lt;/TASK&gt;
  ---[ end trace 0000000000000000 ]---
  BTRFS error (device dm-2 state E): root 5 ino 259 folio 1323008 is marked dirty without notifying the fs
  BTRFS error (device dm-2 state E): failed to submit blocks, root=5 inode=259 folio=1323008 submit_bitmap=0: -117
  BTRFS info (device dm-2 state E): last unmount of filesystem d8a19a28-3232-4809-b0df-38df83e71bff

[CAUSE]
Inside btrfs we have the following pattern in several locations, for
example inside btrfs_dirty_folio():

	btrfs_clear_extent_bit(&amp;inode-&gt;io_tree, start_pos, end_of_last_block,
			       EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
			       cached);

	ret = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
					extra_bits, cached);
	if (ret)
		return ret;

However btrfs_set_extent_delalloc() can return IO errors other than -ENOMEM
through the following callchain:

 btrfs_set_extent_delalloc()
 \- btrfs_find_new_delalloc_bytes()
    \- btrfs_get_extent()
       \- btrfs_lookup_file_extent()
          \- btrfs_search_slot()

When such IO error happened, the previous btrfs_clear_extent_bit() has
cleared the EXTENT_DELALLOC for the range, and we're expecting
btrfs_set_extent_delalloc() to re-set EXTENT_DELALLOC.

But since btrfs_set_extent_delalloc() failed before
btrfs_set_extent_bit(), EXTENT_DELALLOC flag is no longer present.

And if the folio range is dirty before entering
btrfs_set_extent_delalloc(), we got a dirty folio but no EXTENT_DELALLOC
flag now.

Then we hit the folio writeback:

  extent_writepage()
  |- writepage_delalloc()
  |  No ordered extent is created, as there is no EXTENT_DELALLOC set
  |  for the folio range.
  |  This also means the folio has no ordered flag set.
  |
  |- extent_writepage_io()
     \- if (unlikely(!folio_test_ordered(folio))
        Now we hit the warning.

[FIX]
Introduce a new helper, btrfs_reset_extent_delalloc() to replace the
currently open-coded btrfs_clear_extent_bit() +
btrfs_set_extent_delalloc() combination.

Instead of calling btrfs_clear_extent_bit() first, update
EXTENT_DELALLOC_NEW first, as that part can fail due to metadata IO,
meanwhile btrfs_clear_extent_bit() and btrfs_set_extent_bit() won't
return any error but retry memory allocation until succeeded.

This allows us to fail early without clearing EXTENT_DELALLOC bit, so
even if that new btrfs_reset_extent_delalloc() failed before touching
EXTENT_DELALLOC, the existing dirty range will still have their old
EXTENT_DELALLOC flag present, thus avoid the warning.

CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length</title>
<updated>2026-07-24T13:55:16+00:00</updated>
<author>
<name>Tristan Madani</name>
<email>tristan@talencesecurity.com</email>
</author>
<published>2026-07-18T11:20:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=671c3fcc2ad31c1311ea6414382a2d95104ae1b9'/>
<id>671c3fcc2ad31c1311ea6414382a2d95104ae1b9</id>
<content type='text'>
[ Upstream commit 966cb76fb2857a4242cab6ea2ea17acf818a3da7 ]

check_and_correct_requested_length() compares (off + len) against
node_size using u32 arithmetic.  When the caller passes a large len
value (e.g. from an underflowed subtraction in hfs_brec_remove()),
off + len can wrap past 2^32 and produce a small result, causing the
bounds check to pass when it should fail.

For example, with off=14 and len=0xFFFFFFF2 (underflowed from
data_off - keyoffset - size in hfs_brec_remove), off + len wraps to 6,
which is less than a typical node_size of 512, so the check passes and
the subsequent memmove reads ~4GB past the node buffer.

Fix this by widening the addition to u64 before comparing against
node_size.  This prevents the u32 wrap while keeping the logic
straightforward.

Reported-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6df204b70bf3261691c5
Tested-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com
Reported-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e76bf3d19b85350571ac
Tested-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com
Fixes: a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani &lt;tristan@talencesecurity.com&gt;
Reviewed-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Signed-off-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Link: https://lore.kernel.org/r/20260505111300.3592757-2-tristmd@gmail.com
Signed-off-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 966cb76fb2857a4242cab6ea2ea17acf818a3da7 ]

check_and_correct_requested_length() compares (off + len) against
node_size using u32 arithmetic.  When the caller passes a large len
value (e.g. from an underflowed subtraction in hfs_brec_remove()),
off + len can wrap past 2^32 and produce a small result, causing the
bounds check to pass when it should fail.

For example, with off=14 and len=0xFFFFFFF2 (underflowed from
data_off - keyoffset - size in hfs_brec_remove), off + len wraps to 6,
which is less than a typical node_size of 512, so the check passes and
the subsequent memmove reads ~4GB past the node buffer.

Fix this by widening the addition to u64 before comparing against
node_size.  This prevents the u32 wrap while keeping the logic
straightforward.

Reported-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6df204b70bf3261691c5
Tested-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com
Reported-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e76bf3d19b85350571ac
Tested-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com
Fixes: a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani &lt;tristan@talencesecurity.com&gt;
Reviewed-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Signed-off-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Link: https://lore.kernel.org/r/20260505111300.3592757-2-tristmd@gmail.com
Signed-off-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>hfs/hfsplus: prevent getting negative values of offset/length</title>
<updated>2026-07-24T13:55:16+00:00</updated>
<author>
<name>Viacheslav Dubeyko</name>
<email>slava@dubeyko.com</email>
</author>
<published>2026-07-18T11:20:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=4f7d2876b230e47918b7629c57a665ec7a196cd7'/>
<id>4f7d2876b230e47918b7629c57a665ec7a196cd7</id>
<content type='text'>
[ Upstream commit 00c14a09a70e10ae18eb3707d0059291425c04bd ]

The syzbot reported KASAN out-of-bounds issue in
hfs_bnode_move():

[   45.588165][ T9821] hfs: dst 14, src 65536, len -65536
[   45.588895][ T9821] ==================================================================
[   45.590114][ T9821] BUG: KASAN: out-of-bounds in hfs_bnode_move+0xfd/0x140
[   45.591127][ T9821] Read of size 18446744073709486080 at addr ffff888035935400 by task repro/9821
[   45.592207][ T9821]
[   45.592420][ T9821] CPU: 0 UID: 0 PID: 9821 Comm: repro Not tainted 6.16.0-rc7-dirty #42 PREEMPT(full)
[   45.592428][ T9821] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   45.592431][ T9821] Call Trace:
[   45.592434][ T9821]  &lt;TASK&gt;
[   45.592437][ T9821]  dump_stack_lvl+0x1c1/0x2a0
[   45.592446][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
[   45.592454][ T9821]  ? __pfx_dump_stack_lvl+0x10/0x10
[   45.592461][ T9821]  ? rcu_is_watching+0x15/0xb0
[   45.592469][ T9821]  ? lock_release+0x4b/0x3e0
[   45.592476][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
[   45.592483][ T9821]  ? __virt_addr_valid+0x4a5/0x5c0
[   45.592491][ T9821]  print_report+0x17e/0x7c0
[   45.592497][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
[   45.592504][ T9821]  ? __virt_addr_valid+0x4a5/0x5c0
[   45.592511][ T9821]  ? __phys_addr+0xd3/0x180
[   45.592519][ T9821]  ? hfs_bnode_move+0xfd/0x140
[   45.592526][ T9821]  kasan_report+0x147/0x180
[   45.592531][ T9821]  ? _printk+0xcf/0x120
[   45.592537][ T9821]  ? hfs_bnode_move+0xfd/0x140
[   45.592544][ T9821]  ? hfs_bnode_move+0xfd/0x140
[   45.592552][ T9821]  kasan_check_range+0x2b0/0x2c0
[   45.592557][ T9821]  ? hfs_bnode_move+0xfd/0x140
[   45.592565][ T9821]  __asan_memmove+0x29/0x70
[   45.592572][ T9821]  hfs_bnode_move+0xfd/0x140
[   45.592580][ T9821]  hfs_brec_remove+0x473/0x560
[   45.592589][ T9821]  hfs_cat_move+0x6fb/0x960
[   45.592598][ T9821]  ? __pfx_hfs_cat_move+0x10/0x10
[   45.592607][ T9821]  ? seqcount_lockdep_reader_access+0x122/0x1c0
[   45.592614][ T9821]  ? lockdep_hardirqs_on+0x9c/0x150
[   45.592631][ T9821]  ? __lock_acquire+0xaec/0xd80
[   45.592641][ T9821]  hfs_rename+0x1dc/0x2d0
[   45.592649][ T9821]  ? __pfx_hfs_rename+0x10/0x10
[   45.592657][ T9821]  vfs_rename+0xac6/0xed0
[   45.592664][ T9821]  ? __pfx_vfs_rename+0x10/0x10
[   45.592670][ T9821]  ? d_alloc+0x144/0x190
[   45.592677][ T9821]  ? bpf_lsm_path_rename+0x9/0x20
[   45.592683][ T9821]  ? security_path_rename+0x17d/0x490
[   45.592691][ T9821]  do_renameat2+0x890/0xc50
[   45.592699][ T9821]  ? __pfx_do_renameat2+0x10/0x10
[   45.592707][ T9821]  ? getname_flags+0x1e5/0x540
[   45.592714][ T9821]  __x64_sys_rename+0x82/0x90
[   45.592720][ T9821]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   45.592725][ T9821]  do_syscall_64+0xf3/0x3a0
[   45.592741][ T9821]  ? exc_page_fault+0x9f/0xf0
[   45.592748][ T9821]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   45.592754][ T9821] RIP: 0033:0x7f7f73fe3fc9
[   45.592760][ T9821] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 48
[   45.592765][ T9821] RSP: 002b:00007ffc7e116cf8 EFLAGS: 00000283 ORIG_RAX: 0000000000000052
[   45.592772][ T9821] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7f73fe3fc9
[   45.592776][ T9821] RDX: 0000200000000871 RSI: 0000200000000780 RDI: 00002000000003c0
[   45.592781][ T9821] RBP: 00007ffc7e116d00 R08: 0000000000000000 R09: 00007ffc7e116d30
[   45.592784][ T9821] R10: fffffffffffffff0 R11: 0000000000000283 R12: 00005557e81f8250
[   45.592788][ T9821] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[   45.592795][ T9821]  &lt;/TASK&gt;
[   45.592797][ T9821]
[   45.619721][ T9821] The buggy address belongs to the physical page:
[   45.620300][ T9821] page: refcount:1 mapcount:1 mapping:0000000000000000 index:0x559a88174 pfn:0x35935
[   45.621150][ T9821] memcg:ffff88810a1d5b00
[   45.621531][ T9821] anon flags: 0xfff60000020838(uptodate|dirty|lru|owner_2|swapbacked|node=0|zone=1|lastcpupid=0x7ff)
[   45.622496][ T9821] raw: 00fff60000020838 ffffea0000d64d88 ffff888021753e10 ffff888029da0771
[   45.623260][ T9821] raw: 0000000559a88174 0000000000000000 0000000100000000 ffff88810a1d5b00
[   45.624030][ T9821] page dumped because: kasan: bad access detected
[   45.624602][ T9821] page_owner tracks the page as allocated
[   45.625115][ T9821] page last allocated via order 0, migratetype Movable, gfp_mask 0x140dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO0
[   45.626685][ T9821]  post_alloc_hook+0x240/0x2a0
[   45.627127][ T9821]  get_page_from_freelist+0x2101/0x21e0
[   45.627628][ T9821]  __alloc_frozen_pages_noprof+0x274/0x380
[   45.628154][ T9821]  alloc_pages_mpol+0x241/0x4b0
[   45.628593][ T9821]  vma_alloc_folio_noprof+0xe4/0x210
[   45.629066][ T9821]  folio_prealloc+0x30/0x180
[   45.629487][ T9821]  __handle_mm_fault+0x34bd/0x5640
[   45.629957][ T9821]  handle_mm_fault+0x40e/0x8e0
[   45.630392][ T9821]  do_user_addr_fault+0xa81/0x1390
[   45.630862][ T9821]  exc_page_fault+0x76/0xf0
[   45.631273][ T9821]  asm_exc_page_fault+0x26/0x30
[   45.631712][ T9821] page last free pid 5269 tgid 5269 stack trace:
[   45.632281][ T9821]  free_unref_folios+0xc73/0x14c0
[   45.632740][ T9821]  folios_put_refs+0x55b/0x640
[   45.633177][ T9821]  free_pages_and_swap_cache+0x26d/0x510
[   45.633685][ T9821]  tlb_flush_mmu+0x3a0/0x680
[   45.634105][ T9821]  tlb_finish_mmu+0xd4/0x200
[   45.634525][ T9821]  exit_mmap+0x44c/0xb70
[   45.634914][ T9821]  __mmput+0x118/0x420
[   45.635286][ T9821]  exit_mm+0x1da/0x2c0
[   45.635659][ T9821]  do_exit+0x652/0x2330
[   45.636039][ T9821]  do_group_exit+0x21c/0x2d0
[   45.636457][ T9821]  __x64_sys_exit_group+0x3f/0x40
[   45.636915][ T9821]  x64_sys_call+0x21ba/0x21c0
[   45.637342][ T9821]  do_syscall_64+0xf3/0x3a0
[   45.637756][ T9821]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   45.638290][ T9821] page has been migrated, last migrate reason: numa_misplaced
[   45.638956][ T9821]
[   45.639173][ T9821] Memory state around the buggy address:
[   45.639677][ T9821]  ffff888035935300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.640397][ T9821]  ffff888035935380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.641117][ T9821] &gt;ffff888035935400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.641837][ T9821]                    ^
[   45.642207][ T9821]  ffff888035935480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.642929][ T9821]  ffff888035935500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.643650][ T9821] ==================================================================

This commit [1] fixes the issue if an offset inside of b-tree node
or length of the request is bigger than b-tree node. However,
this fix is still not ready for negative values
of the offset or length. Moreover, negative values of
the offset or length doesn't make sense for b-tree's
operations. Because we could try to access the memory address
outside of the beginning of memory page's addresses range.
Also, using of negative values make logic very complicated,
unpredictable, and we could access the wrong item(s)
in the b-tree node.

This patch changes b-tree interface by means of converting
signed integer arguments of offset and length on u32 type.
Such conversion has goal to prevent of using negative values
unintentionally or by mistake in b-tree operations.

[1] 'commit a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")'

Signed-off-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
cc: John Paul Adrian Glaubitz &lt;glaubitz@physik.fu-berlin.de&gt;
cc: Yangtao Li &lt;frank.li@vivo.com&gt;
cc: linux-fsdevel@vger.kernel.org
Link: https://lore.kernel.org/r/20251002200020.2578311-1-slava@dubeyko.com
Signed-off-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Stable-dep-of: 966cb76fb285 ("hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length")
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 00c14a09a70e10ae18eb3707d0059291425c04bd ]

The syzbot reported KASAN out-of-bounds issue in
hfs_bnode_move():

[   45.588165][ T9821] hfs: dst 14, src 65536, len -65536
[   45.588895][ T9821] ==================================================================
[   45.590114][ T9821] BUG: KASAN: out-of-bounds in hfs_bnode_move+0xfd/0x140
[   45.591127][ T9821] Read of size 18446744073709486080 at addr ffff888035935400 by task repro/9821
[   45.592207][ T9821]
[   45.592420][ T9821] CPU: 0 UID: 0 PID: 9821 Comm: repro Not tainted 6.16.0-rc7-dirty #42 PREEMPT(full)
[   45.592428][ T9821] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   45.592431][ T9821] Call Trace:
[   45.592434][ T9821]  &lt;TASK&gt;
[   45.592437][ T9821]  dump_stack_lvl+0x1c1/0x2a0
[   45.592446][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
[   45.592454][ T9821]  ? __pfx_dump_stack_lvl+0x10/0x10
[   45.592461][ T9821]  ? rcu_is_watching+0x15/0xb0
[   45.592469][ T9821]  ? lock_release+0x4b/0x3e0
[   45.592476][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
[   45.592483][ T9821]  ? __virt_addr_valid+0x4a5/0x5c0
[   45.592491][ T9821]  print_report+0x17e/0x7c0
[   45.592497][ T9821]  ? __virt_addr_valid+0x1c8/0x5c0
[   45.592504][ T9821]  ? __virt_addr_valid+0x4a5/0x5c0
[   45.592511][ T9821]  ? __phys_addr+0xd3/0x180
[   45.592519][ T9821]  ? hfs_bnode_move+0xfd/0x140
[   45.592526][ T9821]  kasan_report+0x147/0x180
[   45.592531][ T9821]  ? _printk+0xcf/0x120
[   45.592537][ T9821]  ? hfs_bnode_move+0xfd/0x140
[   45.592544][ T9821]  ? hfs_bnode_move+0xfd/0x140
[   45.592552][ T9821]  kasan_check_range+0x2b0/0x2c0
[   45.592557][ T9821]  ? hfs_bnode_move+0xfd/0x140
[   45.592565][ T9821]  __asan_memmove+0x29/0x70
[   45.592572][ T9821]  hfs_bnode_move+0xfd/0x140
[   45.592580][ T9821]  hfs_brec_remove+0x473/0x560
[   45.592589][ T9821]  hfs_cat_move+0x6fb/0x960
[   45.592598][ T9821]  ? __pfx_hfs_cat_move+0x10/0x10
[   45.592607][ T9821]  ? seqcount_lockdep_reader_access+0x122/0x1c0
[   45.592614][ T9821]  ? lockdep_hardirqs_on+0x9c/0x150
[   45.592631][ T9821]  ? __lock_acquire+0xaec/0xd80
[   45.592641][ T9821]  hfs_rename+0x1dc/0x2d0
[   45.592649][ T9821]  ? __pfx_hfs_rename+0x10/0x10
[   45.592657][ T9821]  vfs_rename+0xac6/0xed0
[   45.592664][ T9821]  ? __pfx_vfs_rename+0x10/0x10
[   45.592670][ T9821]  ? d_alloc+0x144/0x190
[   45.592677][ T9821]  ? bpf_lsm_path_rename+0x9/0x20
[   45.592683][ T9821]  ? security_path_rename+0x17d/0x490
[   45.592691][ T9821]  do_renameat2+0x890/0xc50
[   45.592699][ T9821]  ? __pfx_do_renameat2+0x10/0x10
[   45.592707][ T9821]  ? getname_flags+0x1e5/0x540
[   45.592714][ T9821]  __x64_sys_rename+0x82/0x90
[   45.592720][ T9821]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   45.592725][ T9821]  do_syscall_64+0xf3/0x3a0
[   45.592741][ T9821]  ? exc_page_fault+0x9f/0xf0
[   45.592748][ T9821]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   45.592754][ T9821] RIP: 0033:0x7f7f73fe3fc9
[   45.592760][ T9821] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 48
[   45.592765][ T9821] RSP: 002b:00007ffc7e116cf8 EFLAGS: 00000283 ORIG_RAX: 0000000000000052
[   45.592772][ T9821] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7f73fe3fc9
[   45.592776][ T9821] RDX: 0000200000000871 RSI: 0000200000000780 RDI: 00002000000003c0
[   45.592781][ T9821] RBP: 00007ffc7e116d00 R08: 0000000000000000 R09: 00007ffc7e116d30
[   45.592784][ T9821] R10: fffffffffffffff0 R11: 0000000000000283 R12: 00005557e81f8250
[   45.592788][ T9821] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[   45.592795][ T9821]  &lt;/TASK&gt;
[   45.592797][ T9821]
[   45.619721][ T9821] The buggy address belongs to the physical page:
[   45.620300][ T9821] page: refcount:1 mapcount:1 mapping:0000000000000000 index:0x559a88174 pfn:0x35935
[   45.621150][ T9821] memcg:ffff88810a1d5b00
[   45.621531][ T9821] anon flags: 0xfff60000020838(uptodate|dirty|lru|owner_2|swapbacked|node=0|zone=1|lastcpupid=0x7ff)
[   45.622496][ T9821] raw: 00fff60000020838 ffffea0000d64d88 ffff888021753e10 ffff888029da0771
[   45.623260][ T9821] raw: 0000000559a88174 0000000000000000 0000000100000000 ffff88810a1d5b00
[   45.624030][ T9821] page dumped because: kasan: bad access detected
[   45.624602][ T9821] page_owner tracks the page as allocated
[   45.625115][ T9821] page last allocated via order 0, migratetype Movable, gfp_mask 0x140dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO0
[   45.626685][ T9821]  post_alloc_hook+0x240/0x2a0
[   45.627127][ T9821]  get_page_from_freelist+0x2101/0x21e0
[   45.627628][ T9821]  __alloc_frozen_pages_noprof+0x274/0x380
[   45.628154][ T9821]  alloc_pages_mpol+0x241/0x4b0
[   45.628593][ T9821]  vma_alloc_folio_noprof+0xe4/0x210
[   45.629066][ T9821]  folio_prealloc+0x30/0x180
[   45.629487][ T9821]  __handle_mm_fault+0x34bd/0x5640
[   45.629957][ T9821]  handle_mm_fault+0x40e/0x8e0
[   45.630392][ T9821]  do_user_addr_fault+0xa81/0x1390
[   45.630862][ T9821]  exc_page_fault+0x76/0xf0
[   45.631273][ T9821]  asm_exc_page_fault+0x26/0x30
[   45.631712][ T9821] page last free pid 5269 tgid 5269 stack trace:
[   45.632281][ T9821]  free_unref_folios+0xc73/0x14c0
[   45.632740][ T9821]  folios_put_refs+0x55b/0x640
[   45.633177][ T9821]  free_pages_and_swap_cache+0x26d/0x510
[   45.633685][ T9821]  tlb_flush_mmu+0x3a0/0x680
[   45.634105][ T9821]  tlb_finish_mmu+0xd4/0x200
[   45.634525][ T9821]  exit_mmap+0x44c/0xb70
[   45.634914][ T9821]  __mmput+0x118/0x420
[   45.635286][ T9821]  exit_mm+0x1da/0x2c0
[   45.635659][ T9821]  do_exit+0x652/0x2330
[   45.636039][ T9821]  do_group_exit+0x21c/0x2d0
[   45.636457][ T9821]  __x64_sys_exit_group+0x3f/0x40
[   45.636915][ T9821]  x64_sys_call+0x21ba/0x21c0
[   45.637342][ T9821]  do_syscall_64+0xf3/0x3a0
[   45.637756][ T9821]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   45.638290][ T9821] page has been migrated, last migrate reason: numa_misplaced
[   45.638956][ T9821]
[   45.639173][ T9821] Memory state around the buggy address:
[   45.639677][ T9821]  ffff888035935300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.640397][ T9821]  ffff888035935380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.641117][ T9821] &gt;ffff888035935400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.641837][ T9821]                    ^
[   45.642207][ T9821]  ffff888035935480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.642929][ T9821]  ffff888035935500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   45.643650][ T9821] ==================================================================

This commit [1] fixes the issue if an offset inside of b-tree node
or length of the request is bigger than b-tree node. However,
this fix is still not ready for negative values
of the offset or length. Moreover, negative values of
the offset or length doesn't make sense for b-tree's
operations. Because we could try to access the memory address
outside of the beginning of memory page's addresses range.
Also, using of negative values make logic very complicated,
unpredictable, and we could access the wrong item(s)
in the b-tree node.

This patch changes b-tree interface by means of converting
signed integer arguments of offset and length on u32 type.
Such conversion has goal to prevent of using negative values
unintentionally or by mistake in b-tree operations.

[1] 'commit a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")'

Signed-off-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
cc: John Paul Adrian Glaubitz &lt;glaubitz@physik.fu-berlin.de&gt;
cc: Yangtao Li &lt;frank.li@vivo.com&gt;
cc: linux-fsdevel@vger.kernel.org
Link: https://lore.kernel.org/r/20251002200020.2578311-1-slava@dubeyko.com
Signed-off-by: Viacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Stable-dep-of: 966cb76fb285 ("hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length")
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>proc: protect ptrace_may_access() with exec_update_lock (part 1)</title>
<updated>2026-07-24T13:55:16+00:00</updated>
<author>
<name>Jann Horn</name>
<email>jannh@google.com</email>
</author>
<published>2026-07-17T15:00:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=bb43679356f1f2a4c6b1c88aec4f021e5b5c74e9'/>
<id>bb43679356f1f2a4c6b1c88aec4f021e5b5c74e9</id>
<content type='text'>
[ Upstream commit 6650527444dadc63d84aa939d14ecba4fadb2f69 ]

Fix the easy cases where procfs currently calls ptrace_may_access() without
exec_update_lock protection, where the fix is to simply add the extra lock
or use mm_access():

 - do_task_stat(): grab exec_update_lock
 - proc_pid_wchan(): grab exec_update_lock
 - proc_map_files_lookup(): use mm_access() instead of get_task_mm()
 - proc_map_files_readdir(): use mm_access() instead of get_task_mm()
 - proc_ns_get_link(): grab exec_update_lock
 - proc_ns_readlink(): grab exec_update_lock

Fixes: f83ce3e6b02d ("proc: avoid information leaks to non-privileged processes")
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn &lt;jannh@google.com&gt;
Link: https://patch.msgid.link/20260518-procfs-lockfix-part1-v1-1-5c3d20e0ac33@google.com
Signed-off-by: Christian Brauner (Amutable) &lt;brauner@kernel.org&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 6650527444dadc63d84aa939d14ecba4fadb2f69 ]

Fix the easy cases where procfs currently calls ptrace_may_access() without
exec_update_lock protection, where the fix is to simply add the extra lock
or use mm_access():

 - do_task_stat(): grab exec_update_lock
 - proc_pid_wchan(): grab exec_update_lock
 - proc_map_files_lookup(): use mm_access() instead of get_task_mm()
 - proc_map_files_readdir(): use mm_access() instead of get_task_mm()
 - proc_ns_get_link(): grab exec_update_lock
 - proc_ns_readlink(): grab exec_update_lock

Fixes: f83ce3e6b02d ("proc: avoid information leaks to non-privileged processes")
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn &lt;jannh@google.com&gt;
Link: https://patch.msgid.link/20260518-procfs-lockfix-part1-v1-1-5c3d20e0ac33@google.com
Signed-off-by: Christian Brauner (Amutable) &lt;brauner@kernel.org&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>seqlock: Change do_task_stat() to use scoped_seqlock_read()</title>
<updated>2026-07-24T13:55:16+00:00</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2026-07-17T15:00:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=63d51c539c43a127b802ab2b9f22268ff16fba2f'/>
<id>63d51c539c43a127b802ab2b9f22268ff16fba2f</id>
<content type='text'>
[ Upstream commit b76f72bea2c601afec81829ea427fc0d20f83216 ]

To simplify the code and make it more readable.

[peterz: change to new interface]
Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Stable-dep-of: 6650527444da ("proc: protect ptrace_may_access() with exec_update_lock (part 1)")
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit b76f72bea2c601afec81829ea427fc0d20f83216 ]

To simplify the code and make it more readable.

[peterz: change to new interface]
Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Stable-dep-of: 6650527444da ("proc: protect ptrace_may_access() with exec_update_lock (part 1)")
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
