Luís Henriques
2023-May-22 10:25 UTC
[Ocfs2-devel] [PATCH] ocfs2: fix use-after-free when unmounting read-only filesystem
It's trivial to trigger a use-after-free bug in the ocfs2 quotas code using fstest generic/452. After mounting a filesystem as read-only, quotas are suspended and ocfs2_mem_dqinfo is freed through ->ocfs2_local_free_info(). When unmounting the filesystem, an UAF access to the oinfo will eventually cause a crash. Cc: <stable at vger.kernel.org> Signed-off-by: Lu?s Henriques <lhenriques at suse.de> --- fs/ocfs2/super.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 0b0e6a132101..988d1c076861 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -952,8 +952,10 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb) for (type = 0; type < OCFS2_MAXQUOTAS; type++) { if (!sb_has_quota_loaded(sb, type)) continue; - oinfo = sb_dqinfo(sb, type)->dqi_priv; - cancel_delayed_work_sync(&oinfo->dqi_sync_work); + if (!sb_has_quota_suspended(sb, type)) { + oinfo = sb_dqinfo(sb, type)->dqi_priv; + cancel_delayed_work_sync(&oinfo->dqi_sync_work); + } inode = igrab(sb->s_dquot.files[type]); /* Turn off quotas. This will remove all dquot structures from * memory and so they will be automatically synced to global
Joseph Qi
2023-May-22 12:01 UTC
[Ocfs2-devel] [PATCH] ocfs2: fix use-after-free when unmounting read-only filesystem
On 5/22/23 6:25 PM, Lu?s Henriques wrote:> It's trivial to trigger a use-after-free bug in the ocfs2 quotas code using > fstest generic/452. After mounting a filesystem as read-only, quotas aregeneric/452 is for testing ext4 mounted with dax and ro. But ocfs2 doesn't support dax yet.> suspended and ocfs2_mem_dqinfo is freed through ->ocfs2_local_free_info(). When > unmounting the filesystem, an UAF access to the oinfo will eventually cause a > crash.In ocfs2_fill_super(), it won't enable quota if is a readonly mount. Do you mean remount as readonly? Thanks, Joseph> > Cc: <stable at vger.kernel.org> > Signed-off-by: Lu?s Henriques <lhenriques at suse.de> > --- > fs/ocfs2/super.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c > index 0b0e6a132101..988d1c076861 100644 > --- a/fs/ocfs2/super.c > +++ b/fs/ocfs2/super.c > @@ -952,8 +952,10 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb) > for (type = 0; type < OCFS2_MAXQUOTAS; type++) { > if (!sb_has_quota_loaded(sb, type)) > continue; > - oinfo = sb_dqinfo(sb, type)->dqi_priv; > - cancel_delayed_work_sync(&oinfo->dqi_sync_work); > + if (!sb_has_quota_suspended(sb, type)) { > + oinfo = sb_dqinfo(sb, type)->dqi_priv; > + cancel_delayed_work_sync(&oinfo->dqi_sync_work); > + } > inode = igrab(sb->s_dquot.files[type]); > /* Turn off quotas. This will remove all dquot structures from > * memory and so they will be automatically synced to global