[PATCH] gfs2: Fix use-after-free in glockfd iterator

Shuangpeng Bai <[email protected]>
Newsgroups dev.linux.lists.gfs2,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
gfs2_glockfd_seq_stop() drops the file and task references held by
the iterator, but leaves both pointers unchanged. seq_file can invoke the
iterator again after stop, for example after a bounded read followed by a
rewind.

The next start then drops the stale task reference again in
gfs2_glockfd_next_task(), and can similarly drop the stale file reference
in gfs2_glockfd_next_file(). A duplicate task put can queue the task_struct
for RCU freeing before fget_task_next() uses it.

Clear both pointers when releasing their references so later iterator
callbacks cannot put them again.

Fixes: 4480c27ca3ea ("gfs2: Add glockfd debugfs file")
Cc: [email protected]
Signed-off-by: Shuangpeng Bai <[email protected]>
---
 fs/gfs2/glock.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index b8a144d3a73b..283c5701dc1a 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -2734,10 +2734,14 @@ static void gfs2_glockfd_seq_stop(struct seq_file *seq, void *iter_ptr)
 {
 	struct gfs2_glockfd_iter *i = seq->private;
 
-	if (i->file)
+	if (i->file) {
 		fput(i->file);
-	if (i->task)
+		i->file = NULL;
+	}
+	if (i->task) {
 		put_task_struct(i->task);
+		i->task = NULL;
+	}
 }
 
 static void gfs2_glockfd_seq_show_flock(struct seq_file *seq,
-- 
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.