From 88dbb8ea9c4c666972bb2a7434235bbfb93b1a8d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 9 Jul 2024 12:57:04 +0200 Subject: [PATCH] 5.4-stable patches added patches: nilfs2-fix-incorrect-inode-allocation-from-reserved-inodes.patch --- ...node-allocation-from-reserved-inodes.patch | 148 ++++++++++++++++++ queue-5.4/series | 1 + 2 files changed, 149 insertions(+) create mode 100644 queue-5.4/nilfs2-fix-incorrect-inode-allocation-from-reserved-inodes.patch diff --git a/queue-5.4/nilfs2-fix-incorrect-inode-allocation-from-reserved-inodes.patch b/queue-5.4/nilfs2-fix-incorrect-inode-allocation-from-reserved-inodes.patch new file mode 100644 index 00000000000..3e63845e0e0 --- /dev/null +++ b/queue-5.4/nilfs2-fix-incorrect-inode-allocation-from-reserved-inodes.patch @@ -0,0 +1,148 @@ +From 93aef9eda1cea9e84ab2453fcceb8addad0e46f1 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Sun, 23 Jun 2024 14:11:35 +0900 +Subject: nilfs2: fix incorrect inode allocation from reserved inodes + +From: Ryusuke Konishi + +commit 93aef9eda1cea9e84ab2453fcceb8addad0e46f1 upstream. + +If the bitmap block that manages the inode allocation status is corrupted, +nilfs_ifile_create_inode() may allocate a new inode from the reserved +inode area where it should not be allocated. + +Previous fix commit d325dc6eb763 ("nilfs2: fix use-after-free bug of +struct nilfs_root"), fixed the problem that reserved inodes with inode +numbers less than NILFS_USER_INO (=11) were incorrectly reallocated due to +bitmap corruption, but since the start number of non-reserved inodes is +read from the super block and may change, in which case inode allocation +may occur from the extended reserved inode area. + +If that happens, access to that inode will cause an IO error, causing the +file system to degrade to an error state. + +Fix this potential issue by adding a wraparound option to the common +metadata object allocation routine and by modifying +nilfs_ifile_create_inode() to disable the option so that it only allocates +inodes with inode numbers greater than or equal to the inode number read +in "nilfs->ns_first_ino", regardless of the bitmap status of reserved +inodes. + +Link: https://lkml.kernel.org/r/20240623051135.4180-4-konishi.ryusuke@gmail.com +Signed-off-by: Ryusuke Konishi +Cc: Hillf Danton +Cc: Jan Kara +Cc: Matthew Wilcox (Oracle) +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/nilfs2/alloc.c | 18 ++++++++++++++---- + fs/nilfs2/alloc.h | 4 ++-- + fs/nilfs2/dat.c | 2 +- + fs/nilfs2/ifile.c | 7 ++----- + 4 files changed, 19 insertions(+), 12 deletions(-) + +--- a/fs/nilfs2/alloc.c ++++ b/fs/nilfs2/alloc.c +@@ -377,11 +377,12 @@ void *nilfs_palloc_block_get_entry(const + * @target: offset number of an entry in the group (start point) + * @bsize: size in bits + * @lock: spin lock protecting @bitmap ++ * @wrap: whether to wrap around + */ + static int nilfs_palloc_find_available_slot(unsigned char *bitmap, + unsigned long target, + unsigned int bsize, +- spinlock_t *lock) ++ spinlock_t *lock, bool wrap) + { + int pos, end = bsize; + +@@ -397,6 +398,8 @@ static int nilfs_palloc_find_available_s + + end = target; + } ++ if (!wrap) ++ return -ENOSPC; + + /* wrap around */ + for (pos = 0; pos < end; pos++) { +@@ -495,9 +498,10 @@ int nilfs_palloc_count_max_entries(struc + * nilfs_palloc_prepare_alloc_entry - prepare to allocate a persistent object + * @inode: inode of metadata file using this allocator + * @req: nilfs_palloc_req structure exchanged for the allocation ++ * @wrap: whether to wrap around + */ + int nilfs_palloc_prepare_alloc_entry(struct inode *inode, +- struct nilfs_palloc_req *req) ++ struct nilfs_palloc_req *req, bool wrap) + { + struct buffer_head *desc_bh, *bitmap_bh; + struct nilfs_palloc_group_desc *desc; +@@ -516,7 +520,7 @@ int nilfs_palloc_prepare_alloc_entry(str + entries_per_group = nilfs_palloc_entries_per_group(inode); + + for (i = 0; i < ngroups; i += n) { +- if (group >= ngroups) { ++ if (group >= ngroups && wrap) { + /* wrap around */ + group = 0; + maxgroup = nilfs_palloc_group(inode, req->pr_entry_nr, +@@ -541,7 +545,13 @@ int nilfs_palloc_prepare_alloc_entry(str + bitmap = bitmap_kaddr + bh_offset(bitmap_bh); + pos = nilfs_palloc_find_available_slot( + bitmap, group_offset, +- entries_per_group, lock); ++ entries_per_group, lock, wrap); ++ /* ++ * Since the search for a free slot in the ++ * second and subsequent bitmap blocks always ++ * starts from the beginning, the wrap flag ++ * only has an effect on the first search. ++ */ + if (pos >= 0) { + /* found a free entry */ + nilfs_palloc_group_desc_add_entries( +--- a/fs/nilfs2/alloc.h ++++ b/fs/nilfs2/alloc.h +@@ -50,8 +50,8 @@ struct nilfs_palloc_req { + struct buffer_head *pr_entry_bh; + }; + +-int nilfs_palloc_prepare_alloc_entry(struct inode *, +- struct nilfs_palloc_req *); ++int nilfs_palloc_prepare_alloc_entry(struct inode *inode, ++ struct nilfs_palloc_req *req, bool wrap); + void nilfs_palloc_commit_alloc_entry(struct inode *, + struct nilfs_palloc_req *); + void nilfs_palloc_abort_alloc_entry(struct inode *, struct nilfs_palloc_req *); +--- a/fs/nilfs2/dat.c ++++ b/fs/nilfs2/dat.c +@@ -75,7 +75,7 @@ int nilfs_dat_prepare_alloc(struct inode + { + int ret; + +- ret = nilfs_palloc_prepare_alloc_entry(dat, req); ++ ret = nilfs_palloc_prepare_alloc_entry(dat, req, true); + if (ret < 0) + return ret; + +--- a/fs/nilfs2/ifile.c ++++ b/fs/nilfs2/ifile.c +@@ -55,13 +55,10 @@ int nilfs_ifile_create_inode(struct inod + struct nilfs_palloc_req req; + int ret; + +- req.pr_entry_nr = 0; /* +- * 0 says find free inode from beginning +- * of a group. dull code!! +- */ ++ req.pr_entry_nr = NILFS_FIRST_INO(ifile->i_sb); + req.pr_entry_bh = NULL; + +- ret = nilfs_palloc_prepare_alloc_entry(ifile, &req); ++ ret = nilfs_palloc_prepare_alloc_entry(ifile, &req, false); + if (!ret) { + ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1, + &req.pr_entry_bh); diff --git a/queue-5.4/series b/queue-5.4/series index 9d2fc237510..9ae8beb3868 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -44,3 +44,4 @@ media-dw2102-fix-a-potential-buffer-overflow.patch i2c-pnx-fix-potential-deadlock-warning-from-del_time.patch alsa-hda-realtek-enable-headset-mic-of-jp-ik-leap-w5.patch nvme-multipath-find-numa-path-only-for-online-numa-n.patch +nilfs2-fix-incorrect-inode-allocation-from-reserved-inodes.patch -- 2.47.3