mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2026 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 35 participants
  • 24177 discussions
[PATCH] [OLK-5.10] fuse: re-lock request before replacing page cache folio
by Lu Chentao 24 Jul '26

24 Jul '26
mainline inclusion from mainline-v7.2-rc1 commit a078484921052d0badd827fcc2770b5cfc1d4120 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16108 CVE: CVE-2026-53388 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- fuse_try_move_folio() unlocks the request on entry but does not re-lock it on the success path. This means fuse_chan_abort() can end the request and free the fuse_io_args (eg fuse_readpages_end()) while the subsequent copy chain logic after fuse_try_move_folio() accesses the fuse_io_args, leading to use-after-free issues. Fix this by calling lock_request() before replace_page_cache_folio(). This ensures the request is locked on the success path which will prevent the fuse_io_args from being freed while the later copying logic runs, and also ensures that the ap->folios[i]->mapping is never null since ap->folios[i] will always point to the newfolio after replace_page_cache_folio(). Fixes: ce534fb05292 ("fuse: allow splice to move pages") Cc: stable(a)vger.kernel.org Reported-by: Lei Lu <llfamsec(a)gmail.com> Signed-off-by: Joanne Koong <joannelkoong(a)gmail.com> Signed-off-by: Miklos Szeredi <mszeredi(a)redhat.com> Conflicts: fs/fuse/dev.c [Conflicts due to context] Signed-off-by: Lu Chentao <luchentao1(a)huawei.com> --- fs/fuse/dev.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 0c4487e4b867..1a12515fd8ea 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1186,10 +1186,14 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage))) goto out_fallback_unlock; if (WARN_ON(PageMlocked(oldpage))) goto out_fallback_unlock; + err = lock_request(cs->req); + if (err) + goto out_fallback_unlock; + err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); if (err) { unlock_page(newpage); goto out_put_old; } @@ -1203,24 +1207,11 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) * Release while we have extra ref on stolen page. Otherwise * anon_pipe_buf_release() might think the page can be reused. */ pipe_buf_release(cs->pipe, buf); - err = 0; - spin_lock(&cs->req->waitq.lock); - if (test_bit(FR_ABORTED, &cs->req->flags)) - err = -ENOENT; - else - *pagep = newpage; - spin_unlock(&cs->req->waitq.lock); - - if (err) { - unlock_page(newpage); - put_page(newpage); - goto out_put_old; - } - + *pagep = newpage; unlock_page(oldpage); /* Drop ref for ap->pages[] array */ put_page(oldpage); cs->len = 0; -- 2.52.0
1 2
0 0
[PATCH] [OLK-6.6] fuse: re-lock request before replacing page cache folio
by Lu Chentao 24 Jul '26

24 Jul '26
From: Joanne Koong <joannelkoong(a)gmail.com> stable inclusion from stable-v6.6.144 commit 030fe3e9d8abdee303dd7e9e42f45082d382a407 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16108 CVE: CVE-2026-53388 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- [ Upstream commit a078484921052d0badd827fcc2770b5cfc1d4120 ] fuse_try_move_folio() unlocks the request on entry but does not re-lock it on the success path. This means fuse_chan_abort() can end the request and free the fuse_io_args (eg fuse_readpages_end()) while the subsequent copy chain logic after fuse_try_move_folio() accesses the fuse_io_args, leading to use-after-free issues. Fix this by calling lock_request() before replace_page_cache_folio(). This ensures the request is locked on the success path which will prevent the fuse_io_args from being freed while the later copying logic runs, and also ensures that the ap->folios[i]->mapping is never null since ap->folios[i] will always point to the newfolio after replace_page_cache_folio(). Fixes: ce534fb05292 ("fuse: allow splice to move pages") Cc: stable(a)vger.kernel.org Reported-by: Lei Lu <llfamsec(a)gmail.com> Signed-off-by: Joanne Koong <joannelkoong(a)gmail.com> Signed-off-by: Miklos Szeredi <mszeredi(a)redhat.com> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Lu Chentao <luchentao1(a)huawei.com> --- fs/fuse/dev.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 75c067522c98..f197909aee8d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -928,10 +928,14 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) folio_test_writeback(oldfolio))) goto out_fallback_unlock; if (WARN_ON(folio_test_mlocked(oldfolio))) goto out_fallback_unlock; + err = lock_request(cs->req); + if (err) + goto out_fallback_unlock; + replace_page_cache_folio(oldfolio, newfolio); folio_get(newfolio); if (!(buf->flags & PIPE_BUF_FLAG_LRU)) @@ -941,24 +945,11 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) * Release while we have extra ref on stolen page. Otherwise * anon_pipe_buf_release() might think the page can be reused. */ pipe_buf_release(cs->pipe, buf); - err = 0; - spin_lock(&cs->req->waitq.lock); - if (test_bit(FR_ABORTED, &cs->req->flags)) - err = -ENOENT; - else - *pagep = &newfolio->page; - spin_unlock(&cs->req->waitq.lock); - - if (err) { - folio_unlock(newfolio); - folio_put(newfolio); - goto out_put_old; - } - + *pagep = &newfolio->page; folio_unlock(oldfolio); /* Drop ref for ap->pages[] array */ folio_put(oldfolio); cs->len = 0; -- 2.52.0
1 5
0 0
[PATCH openEuler-1.0-LTS v2] xfs: resample the data fork mapping after cycling ILOCK
by Zizhi Wo 24 Jul '26

24 Jul '26
From: "Darrick J. Wong" <djwong(a)kernel.org> stable inclusion from stable-v6.12.96 commit e705d81a7193dd19e69b8e2bad4696d78a4ea075 category: bugfix bugzilla: NA CVE: CVE-2026-64600 Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit… -------------------------------- commit 2f4acd0fcd862e22eab45690ec2c08c80b6ef2e7 upstream. xfs_reflink_fill_{cow_hole,delalloc} are both presented with an inode, a data fork mapping, and a cow fork mapping. Unfortunately, these two helpers cycle the ILOCK to grab a transaction, which means that the mappings are stale as soon as we reacquire the ILOCK. Currently we refresh the cow fork mapping by re-calling xfs_find_trim_cow_extent, but we don't refresh the data fork mapping beforehand, which means that the xfs_bmap_trim_cow in that function queries the refcount btree about the wrong physical blocks and returns an inaccurate value in *shared. If *shared is now false, the directio write proceeds with a stale data fork mapping. Fix this by querying the data fork mapping if the sequence counter changes across the ILOCK cycle. Cc: hch(a)lst.de Cc: stable(a)vger.kernel.org # v4.11 Fixes: 3c68d44a2b49a0 ("xfs: allocate direct I/O COW blocks in iomap_begin") Signed-off-by: "Darrick J. Wong" <djwong(a)kernel.org> Reviewed-by: Christoph Hellwig <hch(a)lst.de> Reviewed-by: Carlos Maiolino <cmaiolino(a)redhat.com> Signed-off-by: Carlos Maiolino <cem(a)kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Conflicts: fs/xfs/xfs_reflink.c [In this version, the logic of xfs_reflink_fill_cow_hole/delalloc is all contained within xfs_reflink_allocate_cow(), adapt it directly.] Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com> --- fs/xfs/xfs_reflink.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 6622652a85a8..c0f5990b4a9f 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -404,10 +404,11 @@ xfs_reflink_allocate_cow( { struct xfs_mount *mp = ip->i_mount; xfs_fileoff_t offset_fsb = imap->br_startoff; xfs_filblks_t count_fsb = imap->br_blockcount; struct xfs_trans *tp; + unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); int nimaps, error = 0; bool found; xfs_filblks_t resaligned; xfs_extlen_t resblks = 0; @@ -434,10 +435,26 @@ xfs_reflink_allocate_cow( error = xfs_qm_dqattach_locked(ip, false); if (error) goto out_trans_cancel; + /* + * The data fork mapping may have changed while we dropped the ILOCK + * (a racing O_DIRECT writer under IOLOCK_SHARED can complete a full + * CoW cycle including xfs_reflink_end_cow(), which remaps this offset + * and drops the refcount of the old shared block). Re-read it so the + * shared-status recheck below and the caller's in-place iomap both + * operate on the current mapping rather than a stale physical block. + */ + if (seq_before != READ_ONCE(ip->i_df.if_seq)) { + nimaps = 1; + error = xfs_bmapi_read(ip, imap->br_startoff, + imap->br_blockcount, imap, &nimaps, 0); + if (error) + goto out_trans_cancel; + } + /* * Check for an overlapping extent again now that we dropped the ilock. */ error = xfs_find_trim_cow_extent(ip, imap, shared, &found); if (error || !*shared) -- 2.52.0
2 1
0 0
[PATCH openEuler-1.0-LTS] security/keys: fix missed RCU read section on lookup
by Yi Yang 24 Jul '26

24 Jul '26
From: Linus Torvalds <torvalds(a)linux-foundation.org> mainline inclusion from mainline-v7.1-rc6 commit 43a1e3744548e6fd85873e6fb43e293eb4010694 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16340 CVE: CVE-2026-64015 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- Nicholas Carlini reports that the keyring code calls assoc_array_find() in find_key_to_update() without holding the RCU read lock, while the assoc_array_gc() code really is designed around removing the node from the tree and then freeing it after an RCU grace-period. The regular key handling doesn't see this because holding the keyring semaphore hides any lifetime issues, but the persistent key handling uses a different model. Instead of extending the keyring locking, just do the simple RCU locking that the assoc_array was designed for. Reported-by: Nicholas Carlini <npc(a)anthropic.com> Cc: David Howells <dhowells(a)redhat.com> Cc: Jarkko Sakkinen <jarkko(a)kernel.org> Cc: Paul Moore <paul(a)paul-moore.com> Cc: James Morris James Morris <jmorris(a)namei.org> Cc: Serge E. Hallyn <serge(a)hallyn.com> Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org> Signed-off-by: Yi Yang <yiyang13(a)huawei.com> --- security/keys/keyring.c | 1 + 1 file changed, 1 insertion(+) diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 0f414a114729..45dd804aad2f 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -1064,6 +1064,7 @@ key_ref_t find_key_to_update(key_ref_t keyring_ref, kenter("{%d},{%s,%s}", keyring->serial, index_key->type->name, index_key->description); + guard(rcu)(); object = assoc_array_find(&keyring->keys, &keyring_assoc_array_ops, index_key); -- 2.25.1
2 1
0 0
[PATCH openEuler-1.0-LTS] xfs: resample the data fork mapping after cycling ILOCK
by Zizhi Wo 24 Jul '26

24 Jul '26
From: "Darrick J. Wong" <djwong(a)kernel.org> stable inclusion from stable-v6.12.96 commit e705d81a7193dd19e69b8e2bad4696d78a4ea075 category: bugfix bugzilla: NA CVE: CVE-2026-64600 Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit… -------------------------------- commit 2f4acd0fcd862e22eab45690ec2c08c80b6ef2e7 upstream. xfs_reflink_fill_{cow_hole,delalloc} are both presented with an inode, a data fork mapping, and a cow fork mapping. Unfortunately, these two helpers cycle the ILOCK to grab a transaction, which means that the mappings are stale as soon as we reacquire the ILOCK. Currently we refresh the cow fork mapping by re-calling xfs_find_trim_cow_extent, but we don't refresh the data fork mapping beforehand, which means that the xfs_bmap_trim_cow in that function queries the refcount btree about the wrong physical blocks and returns an inaccurate value in *shared. If *shared is now false, the directio write proceeds with a stale data fork mapping. Fix this by querying the data fork mapping if the sequence counter changes across the ILOCK cycle. Cc: hch(a)lst.de Cc: stable(a)vger.kernel.org # v4.11 Fixes: 3c68d44a2b49a0 ("xfs: allocate direct I/O COW blocks in iomap_begin") Signed-off-by: "Darrick J. Wong" <djwong(a)kernel.org> Reviewed-by: Christoph Hellwig <hch(a)lst.de> Reviewed-by: Carlos Maiolino <cmaiolino(a)redhat.com> Signed-off-by: Carlos Maiolino <cem(a)kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Conflicts: fs/xfs/xfs_reflink.c [In this version, the logic of xfs_reflink_fill_cow_hole/delalloc is all contained within xfs_reflink_allocate_cow(), adapt it directly.] Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com> --- fs/xfs/xfs_reflink.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 6622652a85a8..cf4a843d66db 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -404,10 +404,11 @@ xfs_reflink_allocate_cow( { struct xfs_mount *mp = ip->i_mount; xfs_fileoff_t offset_fsb = imap->br_startoff; xfs_filblks_t count_fsb = imap->br_blockcount; struct xfs_trans *tp; + unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); int nimaps, error = 0; bool found; xfs_filblks_t resaligned; xfs_extlen_t resblks = 0; @@ -430,10 +431,26 @@ xfs_reflink_allocate_cow( xfs_ilock(ip, *lockmode); if (error) return error; + /* + * The data fork mapping may have changed while we dropped the ILOCK + * (a racing O_DIRECT writer under IOLOCK_SHARED can complete a full + * CoW cycle including xfs_reflink_end_cow(), which remaps this offset + * and drops the refcount of the old shared block). Re-read it so the + * shared-status recheck below and the caller's in-place iomap both + * operate on the current mapping rather than a stale physical block. + */ + if (seq_before != READ_ONCE(ip->i_df.if_seq)) { + nimaps = 1; + error = xfs_bmapi_read(ip, imap->br_startoff, + imap->br_blockcount, imap, &nimaps, 0); + if (error) + goto out_trans_cancel; + } + error = xfs_qm_dqattach_locked(ip, false); if (error) goto out_trans_cancel; /* -- 2.52.0
2 1
0 0
[PATCH OLK-5.10] xfs: resample the data fork mapping after cycling ILOCK
by Zizhi Wo 24 Jul '26

24 Jul '26
From: "Darrick J. Wong" <djwong(a)kernel.org> stable inclusion from stable-v6.12.96 commit e705d81a7193dd19e69b8e2bad4696d78a4ea075 category: bugfix bugzilla: NA CVE: CVE-2026-64600 Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit… -------------------------------- commit 2f4acd0fcd862e22eab45690ec2c08c80b6ef2e7 upstream. xfs_reflink_fill_{cow_hole,delalloc} are both presented with an inode, a data fork mapping, and a cow fork mapping. Unfortunately, these two helpers cycle the ILOCK to grab a transaction, which means that the mappings are stale as soon as we reacquire the ILOCK. Currently we refresh the cow fork mapping by re-calling xfs_find_trim_cow_extent, but we don't refresh the data fork mapping beforehand, which means that the xfs_bmap_trim_cow in that function queries the refcount btree about the wrong physical blocks and returns an inaccurate value in *shared. If *shared is now false, the directio write proceeds with a stale data fork mapping. Fix this by querying the data fork mapping if the sequence counter changes across the ILOCK cycle. Cc: hch(a)lst.de Cc: stable(a)vger.kernel.org # v4.11 Fixes: 3c68d44a2b49a0 ("xfs: allocate direct I/O COW blocks in iomap_begin") Signed-off-by: "Darrick J. Wong" <djwong(a)kernel.org> Reviewed-by: Christoph Hellwig <hch(a)lst.de> Reviewed-by: Carlos Maiolino <cmaiolino(a)redhat.com> Signed-off-by: Carlos Maiolino <cem(a)kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Conflicts: fs/xfs/xfs_reflink.c [In this version, the logic of xfs_reflink_fill_cow_hole/delalloc is all contained within xfs_reflink_allocate_cow(), adapt it directly.] Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com> --- fs/xfs/xfs_reflink.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 551cc92b049d..6ff06c7ab5e6 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -352,10 +352,11 @@ xfs_reflink_allocate_cow( { struct xfs_mount *mp = ip->i_mount; xfs_fileoff_t offset_fsb = imap->br_startoff; xfs_filblks_t count_fsb = imap->br_blockcount; struct xfs_trans *tp; + unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); int nimaps, error = 0; bool found; xfs_filblks_t resaligned; xfs_extlen_t resblks = 0; @@ -383,10 +384,26 @@ xfs_reflink_allocate_cow( if (error) return error; *lockmode = XFS_ILOCK_EXCL; + /* + * The data fork mapping may have changed while we dropped the ILOCK + * (a racing O_DIRECT writer under IOLOCK_SHARED can complete a full + * CoW cycle including xfs_reflink_end_cow(), which remaps this offset + * and drops the refcount of the old shared block). Re-read it so the + * shared-status recheck below and the caller's in-place iomap both + * operate on the current mapping rather than a stale physical block. + */ + if (seq_before != READ_ONCE(ip->i_df.if_seq)) { + nimaps = 1; + error = xfs_bmapi_read(ip, imap->br_startoff, + imap->br_blockcount, imap, &nimaps, 0); + if (error) + goto out_trans_cancel; + } + /* * Check for an overlapping extent again now that we dropped the ilock. */ error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); if (error || !*shared) -- 2.52.0
2 1
0 0
[PATCH OLK-6.6] xfs: resample the data fork mapping after cycling ILOCK
by Zizhi Wo 24 Jul '26

24 Jul '26
From: "Darrick J. Wong" <djwong(a)kernel.org> stable inclusion from stable-v6.12.96 commit e705d81a7193dd19e69b8e2bad4696d78a4ea075 category: bugfix bugzilla: NA CVE: CVE-2026-64600 Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit… -------------------------------- commit 2f4acd0fcd862e22eab45690ec2c08c80b6ef2e7 upstream. xfs_reflink_fill_{cow_hole,delalloc} are both presented with an inode, a data fork mapping, and a cow fork mapping. Unfortunately, these two helpers cycle the ILOCK to grab a transaction, which means that the mappings are stale as soon as we reacquire the ILOCK. Currently we refresh the cow fork mapping by re-calling xfs_find_trim_cow_extent, but we don't refresh the data fork mapping beforehand, which means that the xfs_bmap_trim_cow in that function queries the refcount btree about the wrong physical blocks and returns an inaccurate value in *shared. If *shared is now false, the directio write proceeds with a stale data fork mapping. Fix this by querying the data fork mapping if the sequence counter changes across the ILOCK cycle. Cc: hch(a)lst.de Cc: stable(a)vger.kernel.org # v4.11 Fixes: 3c68d44a2b49a0 ("xfs: allocate direct I/O COW blocks in iomap_begin") Signed-off-by: "Darrick J. Wong" <djwong(a)kernel.org> Reviewed-by: Christoph Hellwig <hch(a)lst.de> Reviewed-by: Carlos Maiolino <cmaiolino(a)redhat.com> Signed-off-by: Carlos Maiolino <cem(a)kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com> --- fs/xfs/xfs_reflink.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 3431d0d8b6f3..4b598e6841c2 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -387,10 +387,11 @@ xfs_reflink_fill_cow_hole( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; xfs_filblks_t resaligned; xfs_extlen_t resblks; + unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); int nimaps; int error; bool found; resaligned = xfs_aligned_fsb_count(imap->br_startoff, @@ -405,10 +406,26 @@ xfs_reflink_fill_cow_hole( if (error) return error; *lockmode = XFS_ILOCK_EXCL; + /* + * The data fork mapping may have changed while we dropped the ILOCK + * (a racing O_DIRECT writer under IOLOCK_SHARED can complete a full + * CoW cycle including xfs_reflink_end_cow(), which remaps this offset + * and drops the refcount of the old shared block). Re-read it so the + * shared-status recheck below and the caller's in-place iomap both + * operate on the current mapping rather than a stale physical block. + */ + if (seq_before != READ_ONCE(ip->i_df.if_seq)) { + nimaps = 1; + error = xfs_bmapi_read(ip, imap->br_startoff, + imap->br_blockcount, imap, &nimaps, 0); + if (error) + goto out_trans_cancel; + } + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); if (error || !*shared) goto out_trans_cancel; if (found) { @@ -451,20 +468,39 @@ xfs_reflink_fill_delalloc( int nimaps; int error; bool found; do { + unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); + xfs_iunlock(ip, *lockmode); *lockmode = 0; error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write, 0, 0, false, &tp); if (error) return error; *lockmode = XFS_ILOCK_EXCL; + /* + * The data fork mapping may have changed while we dropped the + * ILOCK (a racing O_DIRECT writer under IOLOCK_SHARED can + * complete a full CoW cycle including xfs_reflink_end_cow(), + * which remaps this offset and drops the refcount of the old + * shared block). Re-read it so the shared-status recheck + * below and the caller's in-place iomap both operate on the + * current mapping rather than a stale physical block. + */ + if (seq_before != READ_ONCE(ip->i_df.if_seq)) { + nimaps = 1; + error = xfs_bmapi_read(ip, imap->br_startoff, + imap->br_blockcount, imap, &nimaps, 0); + if (error) + goto out_trans_cancel; + } + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); if (error || !*shared) goto out_trans_cancel; -- 2.52.0
2 1
0 0
[PATCH] xfs: resample the data fork mapping after cycling ILOCK
by Zizhi Wo 24 Jul '26

24 Jul '26
From: "Darrick J. Wong" <djwong(a)kernel.org> commit 2f4acd0fcd862e22eab45690ec2c08c80b6ef2e7 upstream. xfs_reflink_fill_{cow_hole,delalloc} are both presented with an inode, a data fork mapping, and a cow fork mapping. Unfortunately, these two helpers cycle the ILOCK to grab a transaction, which means that the mappings are stale as soon as we reacquire the ILOCK. Currently we refresh the cow fork mapping by re-calling xfs_find_trim_cow_extent, but we don't refresh the data fork mapping beforehand, which means that the xfs_bmap_trim_cow in that function queries the refcount btree about the wrong physical blocks and returns an inaccurate value in *shared. If *shared is now false, the directio write proceeds with a stale data fork mapping. Fix this by querying the data fork mapping if the sequence counter changes across the ILOCK cycle. Cc: hch(a)lst.de Cc: stable(a)vger.kernel.org # v4.11 Fixes: 3c68d44a2b49a0 ("xfs: allocate direct I/O COW blocks in iomap_begin") Signed-off-by: "Darrick J. Wong" <djwong(a)kernel.org> Reviewed-by: Christoph Hellwig <hch(a)lst.de> Reviewed-by: Carlos Maiolino <cmaiolino(a)redhat.com> Signed-off-by: Carlos Maiolino <cem(a)kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Zizhi Wo <wozizhi(a)huaweicloud.com> --- fs/xfs/xfs_reflink.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 5bf6682e701b..4d69280e3c17 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -390,6 +390,7 @@ xfs_reflink_fill_cow_hole( struct xfs_trans *tp; xfs_filblks_t resaligned; xfs_extlen_t resblks; + unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); int nimaps; int error; bool found; @@ -408,6 +409,22 @@ xfs_reflink_fill_cow_hole( *lockmode = XFS_ILOCK_EXCL; + /* + * The data fork mapping may have changed while we dropped the ILOCK + * (a racing O_DIRECT writer under IOLOCK_SHARED can complete a full + * CoW cycle including xfs_reflink_end_cow(), which remaps this offset + * and drops the refcount of the old shared block). Re-read it so the + * shared-status recheck below and the caller's in-place iomap both + * operate on the current mapping rather than a stale physical block. + */ + if (seq_before != READ_ONCE(ip->i_df.if_seq)) { + nimaps = 1; + error = xfs_bmapi_read(ip, imap->br_startoff, + imap->br_blockcount, imap, &nimaps, 0); + if (error) + goto out_trans_cancel; + } + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); if (error || !*shared) goto out_trans_cancel; @@ -454,6 +471,8 @@ xfs_reflink_fill_delalloc( bool found; do { + unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); + xfs_iunlock(ip, *lockmode); *lockmode = 0; @@ -464,6 +483,23 @@ xfs_reflink_fill_delalloc( *lockmode = XFS_ILOCK_EXCL; + /* + * The data fork mapping may have changed while we dropped the + * ILOCK (a racing O_DIRECT writer under IOLOCK_SHARED can + * complete a full CoW cycle including xfs_reflink_end_cow(), + * which remaps this offset and drops the refcount of the old + * shared block). Re-read it so the shared-status recheck + * below and the caller's in-place iomap both operate on the + * current mapping rather than a stale physical block. + */ + if (seq_before != READ_ONCE(ip->i_df.if_seq)) { + nimaps = 1; + error = xfs_bmapi_read(ip, imap->br_startoff, + imap->br_blockcount, imap, &nimaps, 0); + if (error) + goto out_trans_cancel; + } + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); if (error || !*shared) -- 2.52.0
1 0
0 0
[PATCH openEuler-1.0-LTS] sctp: purge outqueue on stale COOKIE-ECHO handling
by Wupeng Ma 24 Jul '26

24 Jul '26
From: Xin Long <lucien.xin(a)gmail.com> stable inclusion from stable-v5.10.259 commit 84b7a319105db2f917ccdcf502bdc866082b1285 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/15640 CVE: CVE-2026-52924 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit e374b22e9b07b72a25909621464ff74096151bfb ] sctp_stream_update() is only invoked when the association is moved into COOKIE_WAIT during association setup/reconfiguration. In this path, the outbound stream scheduler state (stream->out_curr) is expected to be clean, since no user data should have been transmitted yet unless the state machine has already partially progressed. However, a corner case exists in sctp_sf_do_5_2_6_stale(): when a Stale Cookie ERROR is received, the association is rolled back from COOKIE_ECHOED to COOKIE_WAIT. In this scenario, user data may already have been queued and even bundled with the COOKIE-ECHO chunk. During the rollback, sctp_stream_update() frees the old stream table and installs a new one, but it does not invalidate stream->out_curr. As a result, out_curr may still point to a freed sctp_stream_out entry from the previous stream state. Later, SCTP scheduler dequeue paths (FCFS, RR, PRIO, etc.) rely on stream->out_curr->ext, which can lead to use-after-free once the old stream state has been released via sctp_stream_free(). This results in crashes such as (reported by Yuqi): BUG: KASAN: slab-use-after-free in sctp_sched_fcfs_dequeue+0x13a/0x140 Read of size 8 at addr ff1100004d4d3208 by task mini_poc/9312 CPU: 1 UID: 1001 PID: 9312 Comm: mini_poc Not tainted 7.1.0-rc1-00305-gbd3a4795d574 #5 PREEMPT(full) sctp_sched_fcfs_dequeue+0x13a/0x140 sctp_outq_flush+0x1603/0x33e0 sctp_do_sm+0x31c9/0x5d30 sctp_assoc_bh_rcv+0x392/0x6f0 sctp_inq_push+0x1db/0x270 sctp_rcv+0x138d/0x3c10 Fix this by fully purging the association outqueue when handling the Stale Cookie case. This ensures all pending transmit and retransmit state is dropped, and any scheduler cached pointers are invalidated, making it safe to rebuild stream state during COOKIE_WAIT restart. Updating only stream->out_curr would be insufficient, since queued and retransmittable data would still reference the old stream state and trigger later use-after-free in dequeue paths. Fixes: 5bbbbe32a431 ("sctp: introduce stream scheduler foundations") Reported-by: Yuan Tan <yuantan098(a)gmail.com> Reported-by: Yifan Wu <yifanwucs(a)gmail.com> Reported-by: Juefei Pu <tomapufckgml(a)gmail.com> Reported-by: Zhengchuan Liang <zcliangcn(a)gmail.com> Reported-by: Xin Liu <bird(a)lzu.edu.cn> Reported-by: Yuqi Xu <xuyq21(a)lenovo.com> Reported-by: Ren Wei <n05ec(a)lzu.edu.cn> Signed-off-by: Xin Long <lucien.xin(a)gmail.com> Link: https://patch.msgid.link/94318159b9052907a6cbb7256aee8b5f8dfbfccb.178051030… Signed-off-by: Jakub Kicinski <kuba(a)kernel.org> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Wupeng Ma <mawupeng1(a)huawei.com> --- net/sctp/sm_statefuns.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index bde3a8174aef..36acb188a57b 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -2530,11 +2530,7 @@ static enum sctp_disposition sctp_sf_do_5_2_6_stale( */ sctp_add_cmd_sf(commands, SCTP_CMD_DEL_NON_PRIMARY, SCTP_NULL()); - /* If we've sent any data bundled with COOKIE-ECHO we will need to - * resend - */ - sctp_add_cmd_sf(commands, SCTP_CMD_T1_RETRAN, - SCTP_TRANSPORT(asoc->peer.primary_path)); + sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); /* Cast away the const modifier, as we want to just * rerun it through as a sideffect. -- 2.43.0
2 1
0 0
[PATCH OLK-5.10] nfsd: fix posix_acl leak on SETACL decode failure
by Lai Zewei 23 Jul '26

23 Jul '26
stable inclusion from stable-v5.10.260 commit b2eb1ffd511d1b3c3e21122f97cbbccea411e277 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16117 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- nfsaclsvc_decode_setaclargs() and nfs3svc_decode_setaclargs() each call nfs_stream_decode_acl() twice, first for NFS_ACL and then for NFS_DFACL. Each successful call transfers ownership of a freshly allocated posix_acl into argp->acl_access or argp->acl_default. If the first call succeeds but the second fails, the decoder returns false and argp->acl_access is left dangling. ACLPROC2_SETACL.pc_release was wired to nfssvc_release_attrstat and ACLPROC3_SETACL.pc_release was wired to nfs3svc_release_fhandle. Both only call fh_put() and have no knowledge of the ACL fields on argp. The posix_acl_release() pairs sat at the out: labels inside nfsacld_proc_setacl() and nfsd3_proc_setacl(), but svc_process() skips pc_func when pc_decode returns false, so that cleanup is unreachable on decode failure: svc_process_common() pc_decode() /* decode_setaclargs: false */ /* pc_func skipped */ pc_release() /* fh_put only -- ACLs leaked */ The orphaned posix_acl is leaked for the lifetime of the server. Fix by adding nfsaclsvc_release_setacl() and nfs3svc_release_setacl(), which release both argp->acl_access and argp->acl_default in addition to fh_put(), and wiring them as pc_release for their respective SETACL procedures. pc_release runs on every path svc_process() takes after decode, including decode failure, so the posix_acl_release() pairs are removed from the proc functions' out: labels to keep ownership in one place. This matches the existing release_getacl() pattern used by the sibling GETACL procedures. Fixes: a257cdd0e217 ("[PATCH] NFSD: Add server support for NFSv3 ACLs.") Cc: stable(a)vger.kernel.org Assisted-by: kres:claude-opus-4-7 Signed-off-by: Jeff Layton <jlayton(a)kernel.org> Signed-off-by: Chuck Lever <chuck.lever(a)oracle.com> Conflicts: fs/nfsd/nfs2acl.c fs/nfsd/nfs3acl.c [ctx: conflicts] Signed-off-by: Lai Zewei <laizewei3(a)huawei.com> --- fs/nfsd/nfs2acl.c | 17 ++++++++++++----- fs/nfsd/nfs3acl.c | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index 6a900f770dd2..b8bf3097dfe8 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c @@ -127,10 +127,7 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp) resp->status = fh_getattr(fh, &resp->stat); out: - /* argp->acl_{access,default} may have been allocated in - nfssvc_decode_setaclargs. */ - posix_acl_release(argp->acl_access); - posix_acl_release(argp->acl_default); + /* argp->acl_{access,default} are released in nfsaclsvc_release_setacl. */ return rpc_success; out_drop_lock: @@ -368,6 +365,16 @@ static void nfsaclsvc_release_access(struct svc_rqst *rqstp) fh_put(&resp->fh); } +static void nfsaclsvc_release_setacl(struct svc_rqst *rqstp) +{ + struct nfsd3_setaclargs *argp = rqstp->rq_argp; + struct nfsd_attrstat *resp = rqstp->rq_resp; + + fh_put(&resp->fh); + posix_acl_release(argp->acl_access); + posix_acl_release(argp->acl_default); +} + struct nfsd3_voidargs { int dummy; }; #define ST 1 /* status*/ @@ -399,7 +406,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = { .pc_func = nfsacld_proc_setacl, .pc_decode = nfsaclsvc_decode_setaclargs, .pc_encode = nfsaclsvc_encode_attrstatres, - .pc_release = nfsaclsvc_release_attrstat, + .pc_release = nfsaclsvc_release_setacl, .pc_argsize = sizeof(struct nfsd3_setaclargs), .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_NOCACHE, diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 34a394e50e1d..80aa209fd046 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c @@ -114,10 +114,7 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp) out_errno: resp->status = nfserrno(error); out: - /* argp->acl_{access,default} may have been allocated in - nfs3svc_decode_setaclargs. */ - posix_acl_release(argp->acl_access); - posix_acl_release(argp->acl_default); + /* argp->acl_{access,default} are released in nfs3svc_release_setacl. */ return rpc_success; } @@ -235,6 +232,16 @@ static void nfs3svc_release_getacl(struct svc_rqst *rqstp) posix_acl_release(resp->acl_default); } +static void nfs3svc_release_setacl(struct svc_rqst *rqstp) +{ + struct nfsd3_setaclargs *argp = rqstp->rq_argp; + struct nfsd3_attrstat *resp = rqstp->rq_resp; + + fh_put(&resp->fh); + posix_acl_release(argp->acl_access); + posix_acl_release(argp->acl_default); +} + struct nfsd3_voidargs { int dummy; }; #define ST 1 /* status*/ @@ -266,7 +273,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = { .pc_func = nfsd3_proc_setacl, .pc_decode = nfs3svc_decode_setaclargs, .pc_encode = nfs3svc_encode_setaclres, - .pc_release = nfs3svc_release_fhandle, + .pc_release = nfs3svc_release_setacl, .pc_argsize = sizeof(struct nfsd3_setaclargs), .pc_ressize = sizeof(struct nfsd3_attrstat), .pc_cachetype = RC_NOCACHE, -- 2.52.0
2 1
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • 5
  • ...
  • 2418
  • Older →

HyperKitty Powered by HyperKitty