[PATCH] gfs2: Fix slab-use-after-free in gfs2_qd_dispose

Deepanshu Kartikey <[email protected]>
Newsgroups dev.linux.lists.gfs2,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
In gfs2_qd_dispose(), the quota data (qd) is removed from qd_list and
qd_hlist, but not removed from the LRU list before call_rcu() is
invoked to free the object.

This can lead to a use-after-free when the shrinker (gfs2_qd_shrink_scan)
runs concurrently with filesystem unmount. The shrinker attempts to walk
the LRU list via list_lru_shrink_walk(), accessing quota data that has
already been freed by the RCU callback (gfs2_qd_dealloc).

Fix this by calling list_lru_del_obj() to remove the quota data from
the LRU list before scheduling the RCU callback.

Fixes: faada74a90563 ("gfs2: Factor out duplicate quota data disposal code")
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=046b605f01802054bff0
Signed-off-by: Deepanshu Kartikey <[email protected]>
---
Note: Only compile-tested. No reproducer available from syzbot.
---
 fs/gfs2/quota.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index b1692f12a602..85b0b5105b4b 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -125,6 +125,8 @@ static void gfs2_qd_dispose(struct gfs2_quota_data *qd)
 	hlist_bl_del_rcu(&qd->qd_hlist);
 	spin_unlock_bucket(qd->qd_hash);
 
+	list_lru_del_obj(&gfs2_qd_lru, &qd->qd_lru);
+
 	if (!gfs2_withdrawn(sdp)) {
 		gfs2_assert_warn(sdp, !qd->qd_change);
 		gfs2_assert_warn(sdp, !qd->qd_slot_ref);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.