Merge tag 'nilfs2-v7.2-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/nilfs2
Pull nilfs2 updates from Viacheslav Dubeyko:
"Fixes of syzbot reported issue and various small fixes in NILFS2
functionality.
- fix hung task in nilfs_transaction_begin() (Deepanshu Kartikey)
Reported by syzbot. The root cause is that user-supplied segment
numbers were not validated before nilfs_clean_segments() began
doing work; the range check on each segnum was performed deep
inside the call chain by nilfs_sufile_updatev(), which emits a
nilfs_warn() per invalid entry while still holding the segctor lock
and the sufile mi_sem.
Fix it by validating the contents of kbufs[4] in
nilfs_clean_segments() immediately after acquiring ns_segctor_sem
via nilfs_transaction_lock().
- fix a smatch warning in nilfs_mkdir() warn (Hongling Zeng)
This corrects a semantic issue related to the use of the
ERR_PTR macro that arose from a recent VFS change.
- fix a backing_dev_info reference leak (Shuangpeng Bai)
setup_bdev_super() initializes sb->s_bdev and takes a reference on
the block device backing_dev_info when assigning sb->s_bdi.
nilfs_fill_super() takes another reference to the same
backing_dev_info and stores it in sb->s_bdi again. The extra
reference is not paired with a matching bdi_put(), since
generic_shutdown_super() releases sb->s_bdi only once.
Drop the redundant bdi_get() in nilfs_fill_super(). The single
reference taken by setup_bdev_super() is enough and is released
during superblock shutdown"
* tag 'nilfs2-v7.2-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/nilfs2:
nilfs2: Fix return in nilfs_mkdir
nilfs2: fix backing_dev_info reference leak
nilfs2: reject CLEAN_SEGMENTS ioctl with out-of-range segment numbers
This commit is contained in:
commit
6f60a6033c
3 files changed
+23
-3
No files matched your search
+1
-1
@@ -258,7 +258,7 @@ out:
|
||||
else
|
||||
nilfs_transaction_abort(dir->i_sb);
|
||||
|
||||
return ERR_PTR(err);
|
||||
return err ? ERR_PTR(err) : NULL;
|
||||
|
||||
out_fail:
|
||||
drop_nlink(inode);
|
||||
|
||||
@@ -2512,12 +2512,33 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
|
||||
struct nilfs_sc_info *sci = nilfs->ns_writer;
|
||||
struct nilfs_transaction_info ti;
|
||||
int err;
|
||||
size_t i, nfreesegs = argv[4].v_nmembs;
|
||||
__u64 *segnumv = kbufs[4];
|
||||
|
||||
if (unlikely(!sci))
|
||||
return -EROFS;
|
||||
|
||||
nilfs_transaction_lock(sb, &ti, 1);
|
||||
|
||||
/*
|
||||
* Validate segment numbers under ns_segctor_sem (held for write
|
||||
* by nilfs_transaction_lock above) so the check is serialized
|
||||
* against nilfs_ioctl_resize(), which can modify ns_nsegments.
|
||||
* Rejecting bad input here, before any segment-cleaning work
|
||||
* begins, avoids the per-element diagnostic path inside
|
||||
* nilfs_sufile_updatev() that would otherwise run under this
|
||||
* same lock and stall concurrent readers.
|
||||
*/
|
||||
for (i = 0; i < nfreesegs; i++) {
|
||||
if (segnumv[i] >= nilfs->ns_nsegments) {
|
||||
nilfs_err(sb,
|
||||
"Segment number %llu to be freed is out of range",
|
||||
(unsigned long long)segnumv[i]);
|
||||
err = -EINVAL;
|
||||
goto bail_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat);
|
||||
if (unlikely(err))
|
||||
goto out_unlock;
|
||||
@@ -2558,6 +2579,7 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
|
||||
sci->sc_freesegs = NULL;
|
||||
sci->sc_nfreesegs = 0;
|
||||
nilfs_mdt_clear_shadow_map(nilfs->ns_dat);
|
||||
bail_unlock:
|
||||
nilfs_transaction_unlock(sb);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1070,8 +1070,6 @@ nilfs_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||
sb->s_time_gran = 1;
|
||||
sb->s_max_links = NILFS_LINK_MAX;
|
||||
|
||||
sb->s_bdi = bdi_get(sb->s_bdev->bd_disk->bdi);
|
||||
|
||||
err = load_nilfs(nilfs, sb);
|
||||
if (err)
|
||||
goto failed_nilfs;
|
||||
|
||||
Reference in new issue
Block a user