[lvc-project] [PATCH] gfs2: lock glock before dumping consistency errors

Alexey Nepomnyashih sdl at nppct.ru
Tue Jun 9 23:56:50 MSK 2026


gfs2_dump_glock() walks the glock holder list and dump_holder()
dereferences holder fields, including the owner pid. The holder list is
protected by gl->gl_lockref.lock, but the consistency error paths call
gfs2_dump_glock() without taking that lock.

This can race with holder removal or reinitialization and make
dump_holder() operate on a stale holder.

  Thread 1                         Thread 2
  --------                         --------
  gfs2_consist_inode_i()
    gfs2_dump_glock()
      gh = first holder
                                   gfs2_glock_dq_uninit(gh)
                                     gfs2_glock_dq(gh)
                                       spin_lock(&gl->gl_lockref.lock)
                                       list_del_init(&gh->gh_list)
                                       spin_unlock(&gl->gl_lockref.lock)
                                     gfs2_holder_uninit(gh)
                                       put_pid(gh->gh_owner_pid)
                                       gfs2_holder_mark_uninitialized(gh)
      dump_holder(gh)
        pid_is_meaningful(gh)
        pid_nr(gh->gh_owner_pid)

Depending on where the stale holder is dereferenced, this can show up as
a fault in pid_is_meaningful() or as a KASAN report in pid_nr().

Reuse the existing locked glock dump wrapper for the consistency dumps.

Reported-by: syzbot+7efd59a5a532c57037e6 at syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7efd59a5a532c57037e6
Fixes: a739765cd8e6 ("gfs2: dump glocks from gfs2_consist_OBJ_i")
Cc: stable at vger.kernel.org
Signed-off-by: Alexey Nepomnyashih <sdl at nppct.ru>
---
 fs/gfs2/glock.c | 6 +++---
 fs/gfs2/glock.h | 2 ++
 fs/gfs2/util.c  | 4 ++--
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index b8a144d3a73b..548ce5f8866f 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -2100,7 +2100,7 @@ void gfs2_glock_thaw(struct gfs2_sbd *sdp)
 	glock_hash_walk(thaw_glock, sdp);
 }
 
-static void dump_glock(struct seq_file *seq, struct gfs2_glock *gl, bool fsid)
+void gfs2_dump_glock_locked(struct seq_file *seq, struct gfs2_glock *gl, bool fsid)
 {
 	spin_lock(&gl->gl_lockref.lock);
 	gfs2_dump_glock(seq, gl, fsid);
@@ -2109,7 +2109,7 @@ static void dump_glock(struct seq_file *seq, struct gfs2_glock *gl, bool fsid)
 
 static void dump_glock_func(struct gfs2_glock *gl)
 {
-	dump_glock(NULL, gl, true);
+	gfs2_dump_glock_locked(NULL, gl, true);
 }
 
 static void withdraw_glock(struct gfs2_glock *gl)
@@ -2537,7 +2537,7 @@ static void gfs2_glock_seq_stop(struct seq_file *seq, void *iter_ptr)
 
 static int gfs2_glock_seq_show(struct seq_file *seq, void *iter_ptr)
 {
-	dump_glock(seq, iter_ptr, false);
+	gfs2_dump_glock_locked(seq, iter_ptr, false);
 	return 0;
 }
 
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 6341ac9b863f..f58c532d193a 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -217,6 +217,8 @@ int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs);
 void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs);
 void gfs2_dump_glock(struct seq_file *seq, struct gfs2_glock *gl,
 			    bool fsid);
+void gfs2_dump_glock_locked(struct seq_file *seq, struct gfs2_glock *gl,
+			    bool fsid);
 #define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) {		\
 			gfs2_dump_glock(NULL, gl, true);	\
 			BUG(); } } while(0)
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 83b8bb6446e5..3417d1553b13 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -342,7 +342,7 @@ void gfs2_consist_inode_i(struct gfs2_inode *ip,
 		(unsigned long long)ip->i_no_formal_ino,
 		(unsigned long long)ip->i_no_addr,
 		function, file, line);
-	gfs2_dump_glock(NULL, ip->i_gl, 1);
+	gfs2_dump_glock_locked(NULL, ip->i_gl, true);
 	gfs2_withdraw(sdp);
 }
 
@@ -364,7 +364,7 @@ void gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd,
 		"function = %s, file = %s, line = %u\n",
 		(unsigned long long)rgd->rd_addr,
 		function, file, line);
-	gfs2_dump_glock(NULL, rgd->rd_gl, 1);
+	gfs2_dump_glock_locked(NULL, rgd->rd_gl, true);
 	gfs2_withdraw(sdp);
 }
 
-- 
2.43.0




More information about the lvc-project mailing list