From: Greg Kroah-Hartman Date: Tue, 31 Mar 2026 13:12:15 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v6.6.131~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cdc42053409484afc97f0355f1331c5119a34f91;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: erofs-fix-bug-bad-page-state-in-z_erofs_do_read_page.patch mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch xfs-avoid-dereferencing-log-items-after-push-callbacks.patch xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch --- diff --git a/queue-6.6/erofs-fix-bug-bad-page-state-in-z_erofs_do_read_page.patch b/queue-6.6/erofs-fix-bug-bad-page-state-in-z_erofs_do_read_page.patch new file mode 100644 index 0000000000..e25ccfb584 --- /dev/null +++ b/queue-6.6/erofs-fix-bug-bad-page-state-in-z_erofs_do_read_page.patch @@ -0,0 +1,41 @@ +From hsiangkao@linux.alibaba.com Fri Mar 27 05:15:33 2026 +From: Gao Xiang +Date: Fri, 27 Mar 2026 12:15:24 +0800 +Subject: erofs: fix "BUG: Bad page state in z_erofs_do_read_page" +To: stable@vger.kernel.org, Greg Kroah-Hartman +Cc: linux-erofs@lists.ozlabs.org, Gao Xiang , syzbot+b6353e35ae2bab997538@syzkaller.appspotmail.com +Message-ID: <20260327041524.1087336-1-hsiangkao@linux.alibaba.com> + +From: Gao Xiang + +It's actually a stable-only issue from backporting 9e2f9d34dd12 +("erofs: handle overlapped pclusters out of crafted images properly") + +We missed to update `oldpage` after `pcl->compressed_bvecs[nr].page` +is updated, so that the following cmpxchg() will fail; the original +upstream commit doesn't behave like this due to new features and +refactoring. + +This backport issue only impacts some specific crafted images and +normal filesystems won't be impacted at all. + +Fixes: 1bf7e414cac3 ("erofs: handle overlapped pclusters out of crafted images properly") # 6.6.y +Closes: https://syzkaller.appspot.com/bug?extid=b6353e35ae2bab997538 +Reported-and-tested-by: syzbot+b6353e35ae2bab997538@syzkaller.appspotmail.com [1] +[1] https://lore.kernel.org/r/69c3b299.a70a0220.234938.004b.GAE@google.com +Signed-off-by: Gao Xiang +Signed-off-by: Greg Kroah-Hartman +--- + fs/erofs/zdata.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/erofs/zdata.c ++++ b/fs/erofs/zdata.c +@@ -1503,6 +1503,7 @@ repeat: + lock_page(page); + if (likely(page->mapping == mc)) { + WRITE_ONCE(pcl->compressed_bvecs[nr].page, page); ++ oldpage = page; + + /* + * The cached folio is still in managed cache but without diff --git a/queue-6.6/mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch b/queue-6.6/mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch new file mode 100644 index 0000000000..45e7568fff --- /dev/null +++ b/queue-6.6/mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch @@ -0,0 +1,59 @@ +From 1bfe9fb5ed2667fb075682408b776b5273162615 Mon Sep 17 00:00:00 2001 +From: Josh Law +Date: Sat, 21 Mar 2026 10:54:25 -0700 +Subject: mm/damon/sysfs: check contexts->nr before accessing contexts_arr[0] + +From: Josh Law + +commit 1bfe9fb5ed2667fb075682408b776b5273162615 upstream. + +Multiple sysfs command paths dereference contexts_arr[0] without first +verifying that kdamond->contexts->nr == 1. A user can set nr_contexts to +0 via sysfs while DAMON is running, causing NULL pointer dereferences. + +In more detail, the issue can be triggered by privileged users like +below. + +First, start DAMON and make contexts directory empty +(kdamond->contexts->nr == 0). + + # damo start + # cd /sys/kernel/mm/damon/admin/kdamonds/0 + # echo 0 > contexts/nr_contexts + +Then, each of below commands will cause the NULL pointer dereference. + + # echo update_schemes_stats > state + # echo update_schemes_tried_regions > state + # echo update_schemes_tried_bytes > state + # echo update_schemes_effective_quotas > state + # echo update_tuned_intervals > state + +Guard all commands (except OFF) at the entry point of +damon_sysfs_handle_cmd(). + +Link: https://lkml.kernel.org/r/20260321175427.86000-3-sj@kernel.org +Fixes: 0ac32b8affb5 ("mm/damon/sysfs: support DAMOS stats") +Signed-off-by: Josh Law +Reviewed-by: SeongJae Park +Signed-off-by: SeongJae Park +Cc: [5.18+] +Signed-off-by: Andrew Morton +Signed-off-by: SeongJae Park +Signed-off-by: Greg Kroah-Hartman +--- + mm/damon/sysfs.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/mm/damon/sysfs.c ++++ b/mm/damon/sysfs.c +@@ -1494,6 +1494,9 @@ static int damon_sysfs_handle_cmd(enum d + { + bool need_wait = true; + ++ if (cmd != DAMON_SYSFS_CMD_OFF && kdamond->contexts->nr != 1) ++ return -EINVAL; ++ + /* Handle commands that doesn't access DAMON context-internal data */ + switch (cmd) { + case DAMON_SYSFS_CMD_ON: diff --git a/queue-6.6/series b/queue-6.6/series index 40f4ecb912..a5bcf8c509 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -153,3 +153,7 @@ gfs2-fix-unlikely-race-in-gdlm_put_lock.patch libbpf-fix-wdiscarded-qualifiers-under-c23.patch xattr-switch-to-class-fd.patch nvme-fix-admin-queue-leak-on-controller-reset.patch +mm-damon-sysfs-check-contexts-nr-before-accessing-contexts_arr.patch +xfs-avoid-dereferencing-log-items-after-push-callbacks.patch +xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch +erofs-fix-bug-bad-page-state-in-z_erofs_do_read_page.patch diff --git a/queue-6.6/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch b/queue-6.6/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch new file mode 100644 index 0000000000..be4d805544 --- /dev/null +++ b/queue-6.6/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch @@ -0,0 +1,172 @@ +From 79ef34ec0554ec04bdbafafbc9836423734e1bd6 Mon Sep 17 00:00:00 2001 +From: Yuto Ohnuki +Date: Tue, 10 Mar 2026 18:38:38 +0000 +Subject: xfs: avoid dereferencing log items after push callbacks + +From: Yuto Ohnuki + +commit 79ef34ec0554ec04bdbafafbc9836423734e1bd6 upstream. + +After xfsaild_push_item() calls iop_push(), the log item may have been +freed if the AIL lock was dropped during the push. Background inode +reclaim or the dquot shrinker can free the log item while the AIL lock +is not held, and the tracepoints in the switch statement dereference +the log item after iop_push() returns. + +Fix this by capturing the log item type, flags, and LSN before calling +xfsaild_push_item(), and introducing a new xfs_ail_push_class trace +event class that takes these pre-captured values and the ailp pointer +instead of the log item pointer. + +Reported-by: syzbot+652af2b3c5569c4ab63c@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=652af2b3c5569c4ab63c +Fixes: 90c60e164012 ("xfs: xfs_iflush() is no longer necessary") +Cc: stable@vger.kernel.org # v5.9 +Signed-off-by: Yuto Ohnuki +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_trace.c | 1 + + fs/xfs/xfs_trace.h | 36 ++++++++++++++++++++++++++++++++---- + fs/xfs/xfs_trans_ail.c | 26 +++++++++++++++++++------- + 3 files changed, 52 insertions(+), 11 deletions(-) + +--- a/fs/xfs/xfs_trace.c ++++ b/fs/xfs/xfs_trace.c +@@ -22,6 +22,7 @@ + #include "xfs_trans.h" + #include "xfs_log.h" + #include "xfs_log_priv.h" ++#include "xfs_trans_priv.h" + #include "xfs_buf_item.h" + #include "xfs_quota.h" + #include "xfs_dquot_item.h" +--- a/fs/xfs/xfs_trace.h ++++ b/fs/xfs/xfs_trace.h +@@ -50,6 +50,7 @@ + #include + + struct xfs_agf; ++struct xfs_ail; + struct xfs_alloc_arg; + struct xfs_attr_list_context; + struct xfs_buf_log_item; +@@ -1332,14 +1333,41 @@ TRACE_EVENT(xfs_log_force, + DEFINE_EVENT(xfs_log_item_class, name, \ + TP_PROTO(struct xfs_log_item *lip), \ + TP_ARGS(lip)) +-DEFINE_LOG_ITEM_EVENT(xfs_ail_push); +-DEFINE_LOG_ITEM_EVENT(xfs_ail_pinned); +-DEFINE_LOG_ITEM_EVENT(xfs_ail_locked); +-DEFINE_LOG_ITEM_EVENT(xfs_ail_flushing); + DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_mark); + DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_skip); + DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_unpin); + ++DECLARE_EVENT_CLASS(xfs_ail_push_class, ++ TP_PROTO(struct xfs_ail *ailp, uint type, unsigned long flags, xfs_lsn_t lsn), ++ TP_ARGS(ailp, type, flags, lsn), ++ TP_STRUCT__entry( ++ __field(dev_t, dev) ++ __field(uint, type) ++ __field(unsigned long, flags) ++ __field(xfs_lsn_t, lsn) ++ ), ++ TP_fast_assign( ++ __entry->dev = ailp->ail_log->l_mp->m_super->s_dev; ++ __entry->type = type; ++ __entry->flags = flags; ++ __entry->lsn = lsn; ++ ), ++ TP_printk("dev %d:%d lsn %d/%d type %s flags %s", ++ MAJOR(__entry->dev), MINOR(__entry->dev), ++ CYCLE_LSN(__entry->lsn), BLOCK_LSN(__entry->lsn), ++ __print_symbolic(__entry->type, XFS_LI_TYPE_DESC), ++ __print_flags(__entry->flags, "|", XFS_LI_FLAGS)) ++) ++ ++#define DEFINE_AIL_PUSH_EVENT(name) \ ++DEFINE_EVENT(xfs_ail_push_class, name, \ ++ TP_PROTO(struct xfs_ail *ailp, uint type, unsigned long flags, xfs_lsn_t lsn), \ ++ TP_ARGS(ailp, type, flags, lsn)) ++DEFINE_AIL_PUSH_EVENT(xfs_ail_push); ++DEFINE_AIL_PUSH_EVENT(xfs_ail_pinned); ++DEFINE_AIL_PUSH_EVENT(xfs_ail_locked); ++DEFINE_AIL_PUSH_EVENT(xfs_ail_flushing); ++ + DECLARE_EVENT_CLASS(xfs_ail_class, + TP_PROTO(struct xfs_log_item *lip, xfs_lsn_t old_lsn, xfs_lsn_t new_lsn), + TP_ARGS(lip, old_lsn, new_lsn), +--- a/fs/xfs/xfs_trans_ail.c ++++ b/fs/xfs/xfs_trans_ail.c +@@ -389,6 +389,12 @@ xfsaild_resubmit_item( + return XFS_ITEM_SUCCESS; + } + ++/* ++ * Push a single log item from the AIL. ++ * ++ * @lip may have been released and freed by the time this function returns, ++ * so callers must not dereference the log item afterwards. ++ */ + static inline uint + xfsaild_push_item( + struct xfs_ail *ailp, +@@ -476,20 +482,26 @@ xfsaild_push( + + lsn = lip->li_lsn; + while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) { +- int lock_result; ++ int lock_result; ++ uint type = lip->li_type; ++ unsigned long flags = lip->li_flags; ++ xfs_lsn_t item_lsn = lip->li_lsn; + + /* + * Note that iop_push may unlock and reacquire the AIL lock. We + * rely on the AIL cursor implementation to be able to deal with + * the dropped lock. ++ * ++ * The log item may have been freed by the push, so it must not ++ * be accessed or dereferenced below this line. + */ + lock_result = xfsaild_push_item(ailp, lip); + switch (lock_result) { + case XFS_ITEM_SUCCESS: + XFS_STATS_INC(mp, xs_push_ail_success); +- trace_xfs_ail_push(lip); ++ trace_xfs_ail_push(ailp, type, flags, item_lsn); + +- ailp->ail_last_pushed_lsn = lsn; ++ ailp->ail_last_pushed_lsn = item_lsn; + break; + + case XFS_ITEM_FLUSHING: +@@ -505,22 +517,22 @@ xfsaild_push( + * AIL is being flushed. + */ + XFS_STATS_INC(mp, xs_push_ail_flushing); +- trace_xfs_ail_flushing(lip); ++ trace_xfs_ail_flushing(ailp, type, flags, item_lsn); + + flushing++; +- ailp->ail_last_pushed_lsn = lsn; ++ ailp->ail_last_pushed_lsn = item_lsn; + break; + + case XFS_ITEM_PINNED: + XFS_STATS_INC(mp, xs_push_ail_pinned); +- trace_xfs_ail_pinned(lip); ++ trace_xfs_ail_pinned(ailp, type, flags, item_lsn); + + stuck++; + ailp->ail_log_flush++; + break; + case XFS_ITEM_LOCKED: + XFS_STATS_INC(mp, xs_push_ail_locked); +- trace_xfs_ail_locked(lip); ++ trace_xfs_ail_locked(ailp, type, flags, item_lsn); + + stuck++; + break; diff --git a/queue-6.6/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch b/queue-6.6/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch new file mode 100644 index 0000000000..b2f85699e3 --- /dev/null +++ b/queue-6.6/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch @@ -0,0 +1,96 @@ +From 394d70b86fae9fe865e7e6d9540b7696f73aa9b6 Mon Sep 17 00:00:00 2001 +From: Yuto Ohnuki +Date: Tue, 10 Mar 2026 18:38:39 +0000 +Subject: xfs: save ailp before dropping the AIL lock in push callbacks + +From: Yuto Ohnuki + +commit 394d70b86fae9fe865e7e6d9540b7696f73aa9b6 upstream. + +In xfs_inode_item_push() and xfs_qm_dquot_logitem_push(), the AIL lock +is dropped to perform buffer IO. Once the cluster buffer no longer +protects the log item from reclaim, the log item may be freed by +background reclaim or the dquot shrinker. The subsequent spin_lock() +call dereferences lip->li_ailp, which is a use-after-free. + +Fix this by saving the ailp pointer in a local variable while the AIL +lock is held and the log item is guaranteed to be valid. + +Reported-by: syzbot+652af2b3c5569c4ab63c@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=652af2b3c5569c4ab63c +Fixes: 90c60e164012 ("xfs: xfs_iflush() is no longer necessary") +Cc: stable@vger.kernel.org # v5.9 +Reviewed-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Yuto Ohnuki +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_dquot_item.c | 9 +++++++-- + fs/xfs/xfs_inode_item.c | 9 +++++++-- + 2 files changed, 14 insertions(+), 4 deletions(-) + +--- a/fs/xfs/xfs_dquot_item.c ++++ b/fs/xfs/xfs_dquot_item.c +@@ -125,6 +125,7 @@ xfs_qm_dquot_logitem_push( + { + struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; + struct xfs_buf *bp = lip->li_buf; ++ struct xfs_ail *ailp = lip->li_ailp; + uint rval = XFS_ITEM_SUCCESS; + int error; + +@@ -153,7 +154,7 @@ xfs_qm_dquot_logitem_push( + goto out_unlock; + } + +- spin_unlock(&lip->li_ailp->ail_lock); ++ spin_unlock(&ailp->ail_lock); + + error = xfs_qm_dqflush(dqp, &bp); + if (!error) { +@@ -163,7 +164,11 @@ xfs_qm_dquot_logitem_push( + } else if (error == -EAGAIN) + rval = XFS_ITEM_LOCKED; + +- spin_lock(&lip->li_ailp->ail_lock); ++ /* ++ * The buffer no longer protects the log item from reclaim, so ++ * do not reference lip after this point. ++ */ ++ spin_lock(&ailp->ail_lock); + out_unlock: + xfs_dqunlock(dqp); + return rval; +--- a/fs/xfs/xfs_inode_item.c ++++ b/fs/xfs/xfs_inode_item.c +@@ -727,6 +727,7 @@ xfs_inode_item_push( + struct xfs_inode_log_item *iip = INODE_ITEM(lip); + struct xfs_inode *ip = iip->ili_inode; + struct xfs_buf *bp = lip->li_buf; ++ struct xfs_ail *ailp = lip->li_ailp; + uint rval = XFS_ITEM_SUCCESS; + int error; + +@@ -749,7 +750,7 @@ xfs_inode_item_push( + if (!xfs_buf_trylock(bp)) + return XFS_ITEM_LOCKED; + +- spin_unlock(&lip->li_ailp->ail_lock); ++ spin_unlock(&ailp->ail_lock); + + /* + * We need to hold a reference for flushing the cluster buffer as it may +@@ -773,7 +774,11 @@ xfs_inode_item_push( + rval = XFS_ITEM_LOCKED; + } + +- spin_lock(&lip->li_ailp->ail_lock); ++ /* ++ * The buffer no longer protects the log item from reclaim, so ++ * do not reference lip after this point. ++ */ ++ spin_lock(&ailp->ail_lock); + return rval; + } +