All of lore.kernel.org
 help / color / mirror / Atom feed
From: syzbot <syzbot+e008db2ac01e282550ee@syzkaller.appspotmail.com>
To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com
Subject: Forwarded: [PATCH] mm/workingset: fix crash from corrupted shadow entries in lru_gen
Date: Sun, 07 Dec 2025 21:14:48 -0800	[thread overview]
Message-ID: <69365ec8.a70a0220.38f243.0086.GAE@google.com> (raw)
In-Reply-To: <693540fe.a70a0220.38f243.004c.GAE@google.com>

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] mm/workingset: fix crash from corrupted shadow entries in lru_gen
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master

Syzbot reported crashes in lru_gen_test_recent() and subsequent NULL
pointer dereferences in the page cache code:

  Oops: general protection fault in lru_gen_test_recent+0xfc/0x370
  KASAN: probably user-memory-access in range [0x0000000000004e00-0x0000000000004e07]

And later:

  BUG: kernel NULL pointer dereference, address: 0000000000000000
  #PF: supervisor instruction fetch in kernel mode
  RIP: 0010:0x0
  Call Trace:
   filemap_read_folio+0xc8/0x2a0

The root cause is that unpack_shadow() can extract an invalid node ID
from a corrupted shadow entry, causing NODE_DATA(nid) to return NULL for
pgdat. When this NULL pgdat is passed to mem_cgroup_lruvec(), it leads
to crashes when dereferencing memcg->nodeinfo.

Even if we detect and return early from lru_gen_test_recent(), the
corrupted state propagates through the call chain, eventually causing
crashes in the page cache code when trying to use the corrupted folio.

Fix this by:
1. Checking if pgdat is NULL in lru_gen_test_recent() and setting
   *lruvec to NULL to signal the corruption to the caller.
2. Adding a NULL check for lruvec in lru_gen_refault() to catch
   corrupted shadow entries and skip processing before the corruption
   can propagate further into the page cache code.

Reported-by: syzbot+e008db2ac01e282550ee@syzkaller.appspot.com
Link: https://syzkaller.appspot.com/bug?extid=e008db2ac01e282550ee
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
---
 mm/workingset.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/mm/workingset.c b/mm/workingset.c
index e9f05634747a..364434168b4c 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -270,7 +270,15 @@ static bool lru_gen_test_recent(void *shadow, struct lruvec **lruvec,
 	struct pglist_data *pgdat;
 
 	unpack_shadow(shadow, &memcg_id, &pgdat, token, workingset);
-
+	/*
+	 * If pgdat is NULL, the shadow entry contains an invalid node ID.
+	 * Set lruvec to NULL so caller can detect and skip processing.
+	 */
+	if (unlikely(!pgdat)) {
+	        *lruvec = NULL;
+		pr_warn("lru_gen_test_recent: Detected corrupted shadow (NULL pgdat), setting lruvec=NULL\n");
+		return false;
+	}
 	memcg = mem_cgroup_from_id(memcg_id);
 	*lruvec = mem_cgroup_lruvec(memcg, pgdat);
 
@@ -294,9 +302,11 @@ static void lru_gen_refault(struct folio *folio, void *shadow)
 	rcu_read_lock();
 
 	recent = lru_gen_test_recent(shadow, &lruvec, &token, &workingset);
-	if (lruvec != folio_lruvec(folio))
+	if (!lruvec || lruvec != folio_lruvec(folio)) {
+		if(!lruvec)
+			pr_warn("lru_gen_refault: Skipping corrupted entry (lruvec=NULL)\n");
 		goto unlock;
-
+	}
 	mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + type, delta);
 
 	if (!recent)
-- 
2.43.0


  parent reply	other threads:[~2025-12-08  5:14 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-07  8:55 [syzbot] [mm?] general protection fault in lru_gen_test_recent (2) syzbot
2025-12-07 12:44 ` Forwarded: [PATCH] mm/workingset: fix NULL pointer dereference in lru_gen_test_recent syzbot
2025-12-07 14:35 ` syzbot
2025-12-07 15:05 ` syzbot
2025-12-07 15:31 ` syzbot
2025-12-07 15:38 ` syzbot
2025-12-07 16:07 ` syzbot
2025-12-08  2:31 ` Forwarded: [PATCH] mm/workingset: fix NULL pointer dereference in lru_gen_test_recent() syzbot
2025-12-08  2:47 ` syzbot
2025-12-08  3:56 ` Forwarded: [PATCH] mm/workingset: add debug for corrupted shadow entry investigation syzbot
2025-12-08  4:49 ` Forwarded: [PATCH] mm/workingset: fix crash from corrupted shadow entries in lru_gen syzbot
2025-12-08  5:14 ` syzbot [this message]
2025-12-09  5:35 ` Forwarded: [PATCH] mm/workingset: add debug instrumentation for MGLRU shadow corruption syzbot
2025-12-09  5:44 ` Forwarded: [PATCH] mm/workingset: debug MGLRU shadow corruption leading to NULL deref syzbot
2025-12-09  6:28 ` Forwarded: [PATCH] mm/workingset: fix NULL deref from invalid node ID in shadow syzbot
2025-12-23  9:38 ` Forwarded: [PATCH] for test syzbot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=69365ec8.a70a0220.38f243.0086.GAE@google.com \
    --to=syzbot+e008db2ac01e282550ee@syzkaller.appspotmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=syzkaller-bugs@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.