[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240929044749.135112-1-lizhi.xu@windriver.com>
Date: Sun, 29 Sep 2024 12:47:49 +0800
From: Lizhi Xu <lizhi.xu@...driver.com>
To: <syzbot+4d55dad3a9e8e9f7d2b5@...kaller.appspotmail.com>
CC: <jlbec@...lplan.org>, <joseph.qi@...ux.alibaba.com>,
<linux-kernel@...r.kernel.org>, <mark@...heh.com>,
<ocfs2-devel@...ts.linux.dev>, <syzkaller-bugs@...glegroups.com>
Subject: Re: [ocfs2?] KASAN: use-after-free Read in __ocfs2_flush_truncate_log
When the truncate log is initialized, it got a too big tl_used in truncate
log inode, tl_used is 64512 and tl_count is 39.
So, when the condition tl_used > tl_count holds, use the value of tl_count
to tl_used.
#syz test
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index ea9127ba3208..a309920fecd1 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6326,6 +6326,25 @@ void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb)
}
}
+void ocfs2_bh_valid(struct buffer_head *bh)
+{
+ struct ocfs2_dinode *di;
+ struct ocfs2_truncate_log *tl;
+
+ if (IS_ERR_OR_NULL(bh))
+ return;
+
+ di = (struct ocfs2_dinode *) bh->b_data;
+ tl = &di->id2.i_dealloc;
+
+ if (tl->tl_used > tl->tl_count) {
+ mlog(ML_NOTICE, "tl_used [%d] is greater than tl_count [%d], "
+ "set it to tl_count.\n", le16_to_cpu(tl->tl_used),
+ le16_to_cpu(tl->tl_count));
+ tl->tl_used = cpu_to_le16(tl->tl_count);
+ }
+}
+
int ocfs2_truncate_log_init(struct ocfs2_super *osb)
{
int status;
@@ -6339,6 +6358,8 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb)
if (status < 0)
mlog_errno(status);
+ ocfs2_bh_valid(tl_bh);
+
/* ocfs2_truncate_log_shutdown keys on the existence of
* osb->osb_tl_inode so we don't set any of the osb variables
* until we're sure all is well. */
Powered by blists - more mailing lists