Re: [PATCH] gfs2: fix null-ptr-deref in gfs2_quota_hold during unmount
Deepanshu Kartikey <[email protected]> Sat, 25 Jul 2026 07:27:14 +0530
| Newsgroups | dev.linux.lists.gfs2,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CADhLXY60Ly=EUQLZos4gwrhC1247xsDCiEBRPoXaZW9U9q4GAg@mail.gmail.com> |
On Tue, Jun 30, 2026 at 9:44=E2=80=AFAM Deepanshu Kartikey <[email protected]> wrote: > > gfs2_quota_cleanup() frees sd_quota_bitmap early in gfs2_put_super() > before the iput() calls that can trigger inode eviction. When an unlinked > inode is evicted during unmount, it goes through: > > gfs2_evict_inode() -> gfs2_dinode_dealloc() -> gfs2_quota_hold() > -> qdsb_get() -> slot_get() -> find_first_zero_bit(sd_quota_bitmap) > > If sd_quota_bitmap has already been freed by gfs2_quota_cleanup(), this > results in a null pointer dereference: > > KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] > _find_first_zero_bit+0x29/0xb0 lib/find_bit.c:149 > slot_get fs/gfs2/quota.c:355 > qdsb_get+0x133/0x340 fs/gfs2/quota.c:522 > gfs2_quota_hold+0x191/0x5c0 fs/gfs2/quota.c:606 > gfs2_dinode_dealloc+0x176/0x3f0 fs/gfs2/inode.c:488 > gfs2_evict_inode+0x11cd/0x1400 fs/gfs2/super.c:1479 > gfs2_put_super+0x300/0x860 fs/gfs2/super.c:618 > > The same problem exists in both paths through gfs2_put_super(): the > direct gfs2_quota_cleanup() call in the read-only branch, and indirectly > via gfs2_make_fs_ro() in the read-write branch. > > Fix this by removing gfs2_quota_cleanup() from gfs2_make_fs_ro() and > moving it to after all the iput() calls in gfs2_put_super(), ensuring > sd_quota_bitmap remains valid for the entire duration of inode eviction. > Restore an explicit gfs2_quota_cleanup() call in gfs2_reconfigure() after > gfs2_make_fs_ro() to preserve the remount-ro cleanup behaviour. > > Reported-by: [email protected] > Closes: https://syzkaller.appspot.com/bug?extid=3Dcb79de2cc8b76fbf474f > Signed-off-by: Deepanshu Kartikey <[email protected]> > --- > fs/gfs2/ops_fstype.c | 1 + > fs/gfs2/super.c | 5 ++--- > 2 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c > index 9b9e70f14d25..56bc966531f2 100644 > --- a/fs/gfs2/ops_fstype.c > +++ b/fs/gfs2/ops_fstype.c > @@ -1592,6 +1592,7 @@ static int gfs2_reconfigure(struct fs_context *fc) > if ((sb->s_flags ^ fc->sb_flags) & SB_RDONLY) { > if (fc->sb_flags & SB_RDONLY) { > gfs2_make_fs_ro(sdp); > + gfs2_quota_cleanup(sdp); > } else { > error =3D gfs2_make_fs_rw(sdp); > if (error) > diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c > index 4d854556b529..e13c9f9efe6c 100644 > --- a/fs/gfs2/super.c > +++ b/fs/gfs2/super.c > @@ -565,7 +565,6 @@ void gfs2_make_fs_ro(struct gfs2_sbd *sdp) > HZ * 5); > gfs2_assert_warn(sdp, gfs2_log_is_empty(sdp)); > } > - gfs2_quota_cleanup(sdp); > } > > /** > @@ -604,8 +603,6 @@ static void gfs2_put_super(struct super_block *sb) > else { > if (gfs2_withdrawn(sdp)) > gfs2_destroy_threads(sdp); > - > - gfs2_quota_cleanup(sdp); > } > > /* At this point, we're through modifying the disk */ > @@ -637,6 +634,8 @@ static void gfs2_put_super(struct super_block *sb) > gfs2_glock_dq_uninit(&sdp->sd_live_gh); > gfs2_clear_rgrpd(sdp); > gfs2_jindex_free(sdp); > + > + gfs2_quota_cleanup(sdp); > /* Take apart glock structures and buffer lists */ > gfs2_gl_hash_clear(sdp); > iput(sdp->sd_inode); > -- > 2.43.0 > Hi Agruenba, Gentle reminder. Please let me know the status of this patch Thanks Deepanshu