From: Bob Peterson <rpete...@redhat.com>

[ Upstream commit d5bf630f355d8c532bef2347cf90e8ae60a5f1bd ]

Before this patch, function signal_our_withdraw referenced the journal
inode immediately. But corrupt file systems may have some invalid
journals, in which case our attempt to read it in will withdraw and the
resulting signal_our_withdraw would dereference the NULL value.

This patch adds a check to signal_our_withdraw so that if the journal
has not yet been initialized, it simply returns and does the old-style
withdraw.

Thanks, Andy Price, for his analysis.

Reported-by: syzbot+50a8a9cf8127f2c6f...@syzkaller.appspotmail.com
Fixes: 601ef0d52e96 ("gfs2: Force withdraw to replay journals and wait for it 
to finish")
Signed-off-by: Bob Peterson <rpete...@redhat.com>
Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 fs/gfs2/util.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 8d3c670c990f..dc4985429cf2 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -119,17 +119,22 @@ void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh)
 static void signal_our_withdraw(struct gfs2_sbd *sdp)
 {
        struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl;
-       struct inode *inode = sdp->sd_jdesc->jd_inode;
-       struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_glock *i_gl = ip->i_gl;
-       u64 no_formal_ino = ip->i_no_formal_ino;
+       struct inode *inode;
+       struct gfs2_inode *ip;
+       struct gfs2_glock *i_gl;
+       u64 no_formal_ino;
        int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
        int ret = 0;
        int tries;
 
-       if (test_bit(SDF_NORECOVERY, &sdp->sd_flags))
+       if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) || !sdp->sd_jdesc)
                return;
 
+       inode = sdp->sd_jdesc->jd_inode;
+       ip = GFS2_I(inode);
+       i_gl = ip->i_gl;
+       no_formal_ino = ip->i_no_formal_ino;
+
        /* Prevent any glock dq until withdraw recovery is complete */
        set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags);
        /*
-- 
2.30.1



Reply via email to