Commit f69d00d1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ntfs3 fixes from Konstantin Komarov:

 - memory leak

 - some logic errors, NULL dereferences

 - some code was refactored

 - more sanity checks

* tag 'ntfs3_for_6.6' of https://github.com/Paragon-Software-Group/linux-ntfs3:
  fs/ntfs3: Avoid possible memory leak
  fs/ntfs3: Fix directory element type detection
  fs/ntfs3: Fix possible null-pointer dereference in hdr_find_e()
  fs/ntfs3: Fix OOB read in ntfs_init_from_boot
  fs/ntfs3: fix panic about slab-out-of-bounds caused by ntfs_list_ea()
  fs/ntfs3: Fix NULL pointer dereference on error in attr_allocate_frame()
  fs/ntfs3: Fix possible NULL-ptr-deref in ni_readpage_cmpr()
  fs/ntfs3: Do not allow to change label if volume is read-only
  fs/ntfs3: Add more info into /proc/fs/ntfs3/<dev>/volinfo
  fs/ntfs3: Refactoring and comments
  fs/ntfs3: Fix alternative boot searching
  fs/ntfs3: Allow repeated call to ntfs3_put_sbi
  fs/ntfs3: Use inode_set_ctime_to_ts instead of inode_set_ctime
  fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
  fs/ntfs3: fix deadlock in mark_as_free_ex
  fs/ntfs3: Add more attributes checks in mi_enum_attr()
  fs/ntfs3: Use kvmalloc instead of kmalloc(... __GFP_NOWARN)
  fs/ntfs3: Write immediately updated ntfs state
  fs/ntfs3: Add ckeck in ni_update_parent()
parents 7cf4bea7 e4494770
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -1736,10 +1736,8 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
			le_b = NULL;
			attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL,
					      0, NULL, &mi_b);
			if (!attr_b) {
				err = -ENOENT;
				goto out;
			}
			if (!attr_b)
				return -ENOENT;

			attr = attr_b;
			le = le_b;
+13 −2
Original line number Diff line number Diff line
@@ -52,7 +52,8 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)

	if (!attr->non_res) {
		lsize = le32_to_cpu(attr->res.data_size);
		le = kmalloc(al_aligned(lsize), GFP_NOFS | __GFP_NOWARN);
		/* attr is resident: lsize < record_size (1K or 4K) */
		le = kvmalloc(al_aligned(lsize), GFP_KERNEL);
		if (!le) {
			err = -ENOMEM;
			goto out;
@@ -80,7 +81,17 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
		if (err < 0)
			goto out;

		le = kmalloc(al_aligned(lsize), GFP_NOFS | __GFP_NOWARN);
		/* attr is nonresident.
		 * The worst case:
		 * 1T (2^40) extremely fragmented file.
		 * cluster = 4K (2^12) => 2^28 fragments
		 * 2^9 fragments per one record => 2^19 records
		 * 2^5 bytes of ATTR_LIST_ENTRY per one record => 2^24 bytes.
		 *
		 * the result is 16M bytes per attribute list.
		 * Use kvmalloc to allocate in range [several Kbytes - dozen Mbytes]
		 */
		le = kvmalloc(al_aligned(lsize), GFP_KERNEL);
		if (!le) {
			err = -ENOMEM;
			goto out;
+3 −1
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ void wnd_close(struct wnd_bitmap *wnd)
	struct rb_node *node, *next;

	kfree(wnd->free_bits);
	wnd->free_bits = NULL;
	run_close(&wnd->run);

	node = rb_first(&wnd->start_tree);
@@ -659,7 +660,8 @@ int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits)
		wnd->bits_last = wbits;

	wnd->free_bits =
		kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS | __GFP_NOWARN);
		kvmalloc_array(wnd->nwnd, sizeof(u16), GFP_KERNEL | __GFP_ZERO);

	if (!wnd->free_bits)
		return -ENOMEM;

+5 −1
Original line number Diff line number Diff line
@@ -309,6 +309,10 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni,
		return 0;
	}

	/* NTFS: symlinks are "dir + reparse" or "file + reparse" */
	if (fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT)
		dt_type = DT_LNK;
	else
		dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG;

	return !dir_emit(ctx, (s8 *)name, name_len, ino, dt_type);
+2 −2
Original line number Diff line number Diff line
@@ -745,8 +745,8 @@ static ssize_t ntfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
}

static ssize_t ntfs_file_splice_read(struct file *in, loff_t *ppos,
				     struct pipe_inode_info *pipe,
				     size_t len, unsigned int flags)
				     struct pipe_inode_info *pipe, size_t len,
				     unsigned int flags)
{
	struct inode *inode = in->f_mapping->host;
	struct ntfs_inode *ni = ntfs_i(inode);
Loading