From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ryusuke Konishi Subject: [PATCH] nilfs2: prevent WARNING in nilfs_dat_commit_end() Date: Fri, 27 Jan 2023 22:22:02 +0900 Message-ID: <20230127132202.6083-1-konishi.ryusuke@gmail.com> References: <000000000000154d2c05e9ec7df6@google.com> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Return-path: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5j29kml6zIepJZzNZLhnsejuRvqVcZnRr54YcbRqQ4s=; b=NAD/8CLetbneQ3aGVzaDGDWFro/8aJ2Y/tSZS1ISbz5SE2Vikv/Ho49ojlXLmKtdt4 yBBvYT2ZX5Pd8ja+Rct0Bifa6avxL3n8l4/5QvNAMOf+xX97YR0r41ZkDNiNRkNzUyfH FhXGHiQtte0nX6akxLxU6+B5YPEn8RKHEGNEy5AEgoRBCcssc2g/MD5MRpy+KmHWX4Yq BvxYgn6w3GisTfZnmzPjJ22aLGJ4ra8gB4uHNGxsuPhxSQArlQTNt/4JGJdR8+EiMbST 8S+LSK+RUpgHtN2rDI9Wdew1YbpTyTO/MmA6hAqIfT/lQUchyv/vO42sj0RSx7WWIkVq BWmQ== In-Reply-To: <000000000000154d2c05e9ec7df6-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> List-ID: Content-Type: text/plain; charset="us-ascii" To: Andrew Morton Cc: linux-nilfs , syzbot , syzkaller-bugs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org, LKML If nilfs2 reads a corrupted disk image and its DAT metadata file contains invalid lifetime data for a virtual block number, a kernel warning can be generated by the WARN_ON check in nilfs_dat_commit_end() and can panic if the kernel is booted with panic_on_warn. This patch avoids the issue with a sanity check that treats it as an error. Since error return is not allowed in the execution phase of nilfs_dat_commit_end(), this inserts that sanity check in nilfs_dat_prepare_end(), which prepares for nilfs_dat_commit_end(). As the error code, -EINVAL is returned to notify bmap layer of the metadata corruption. When the bmap layer sees this code, it handles the abnormal situation and replaces the return code with -EIO as it should. Link: https://lkml.kernel.org/r/000000000000154d2c05e9ec7df6-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org Signed-off-by: Ryusuke Konishi Reported-by: syzbot+cbff7a52b6f99059e67f-Pl5Pbv+GP7P466ipTTIvnc23WoclnBCfAL8bYrjMMd8@public.gmane.org Tested-by: Ryusuke Konishi --- Andrew, please add this patch to the queue. This fixes another WARN_ON hit in fs/nilfs2/dat.c for a corrupted disk image pattern. Thanks, Ryusuke Konishi fs/nilfs2/dat.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 1e7f653c1df7..9cf6ba58f585 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c @@ -158,6 +158,7 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req, int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req) { struct nilfs_dat_entry *entry; + __u64 start; sector_t blocknr; void *kaddr; int ret; @@ -169,6 +170,7 @@ int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req) kaddr = kmap_atomic(req->pr_entry_bh->b_page); entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, req->pr_entry_bh, kaddr); + start = le64_to_cpu(entry->de_start); blocknr = le64_to_cpu(entry->de_blocknr); kunmap_atomic(kaddr); @@ -179,6 +181,15 @@ int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req) return ret; } } + if (unlikely(start > nilfs_mdt_cno(dat))) { + nilfs_err(dat->i_sb, + "vblocknr = %llu has abnormal lifetime: start cno (= %llu) > current cno (= %llu)", + (unsigned long long)req->pr_entry_nr, + (unsigned long long)start, + (unsigned long long)nilfs_mdt_cno(dat)); + nilfs_dat_abort_entry(dat, req); + return -EINVAL; + } return 0; } -- 2.34.1