Commit 3d85d6c8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'vfs-6.14-rc5.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs fixes from Christian Brauner:

 - Use __readahead_folio() in fuse again to fix a UAF issue
   when using splice

 - Remove d_op->d_delete method from pidfs

 - Remove d_op->d_delete method from nsfs

 - Simplify iomap_dio_bio_iter()

 - Fix a UAF in ovl_dentry_update_reval

 - Fix a miscalulated file range for filemap_fdatawrite_range_kick()

 - Don't skip skip dirty page in folio_unmap_invalidate()

* tag 'vfs-6.14-rc5.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  iomap: Minor code simplification in iomap_dio_bio_iter()
  nsfs: remove d_op->d_delete
  pidfs: remove d_op->d_delete
  mm/truncate: don't skip dirty page in folio_unmap_invalidate()
  mm/filemap: fix miscalculated file range for filemap_fdatawrite_range_kick()
  fuse: don't truncate cached, mutated symlink
  ovl: fix UAF in ovl_dentry_update_reval by moving dput() in ovl_link_up
  fuse: revert back to __readahead_folio() for readahead
parents 2a1944bf b5799106
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -838,6 +838,12 @@ static int fuse_check_folio(struct folio *folio)
	return 0;
}

/*
 * Attempt to steal a page from the splice() pipe and move it into the
 * pagecache. If successful, the pointer in @pagep will be updated. The
 * folio that was originally in @pagep will lose a reference and the new
 * folio returned in @pagep will carry a reference.
 */
static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
{
	int err;
+1 −1
Original line number Diff line number Diff line
@@ -1636,7 +1636,7 @@ static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
		goto out_err;

	if (fc->cache_symlinks)
		return page_get_link(dentry, inode, callback);
		return page_get_link_raw(dentry, inode, callback);

	err = -ECHILD;
	if (!dentry)
+11 −2
Original line number Diff line number Diff line
@@ -955,8 +955,10 @@ static void fuse_readpages_end(struct fuse_mount *fm, struct fuse_args *args,
		fuse_invalidate_atime(inode);
	}

	for (i = 0; i < ap->num_folios; i++)
	for (i = 0; i < ap->num_folios; i++) {
		folio_end_read(ap->folios[i], !err);
		folio_put(ap->folios[i]);
	}
	if (ia->ff)
		fuse_file_put(ia->ff, false);

@@ -1048,7 +1050,14 @@ static void fuse_readahead(struct readahead_control *rac)
		ap = &ia->ap;

		while (ap->num_folios < cur_pages) {
			folio = readahead_folio(rac);
			/*
			 * This returns a folio with a ref held on it.
			 * The ref needs to be held until the request is
			 * completed, since the splice case (see
			 * fuse_try_move_page()) drops the ref after it's
			 * replaced in the page cache.
			 */
			folio = __readahead_folio(rac);
			ap->folios[ap->num_folios] = folio;
			ap->descs[ap->num_folios].length = folio_size(folio);
			ap->num_folios++;
+3 −5
Original line number Diff line number Diff line
@@ -427,12 +427,10 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
			bio_put(bio);
			goto zero_tail;
		}
		if (dio->flags & IOMAP_DIO_WRITE) {
		if (dio->flags & IOMAP_DIO_WRITE)
			task_io_account_write(n);
		} else {
			if (dio->flags & IOMAP_DIO_DIRTY)
		else if (dio->flags & IOMAP_DIO_DIRTY)
			bio_set_pages_dirty(bio);
		}

		dio->size += n;
		copied += n;
+19 −5
Original line number Diff line number Diff line
@@ -5356,10 +5356,9 @@ const char *vfs_get_link(struct dentry *dentry, struct delayed_call *done)
EXPORT_SYMBOL(vfs_get_link);

/* get the link contents into pagecache */
const char *page_get_link(struct dentry *dentry, struct inode *inode,
static char *__page_get_link(struct dentry *dentry, struct inode *inode,
			     struct delayed_call *callback)
{
	char *kaddr;
	struct page *page;
	struct address_space *mapping = inode->i_mapping;

@@ -5378,7 +5377,22 @@ const char *page_get_link(struct dentry *dentry, struct inode *inode,
	}
	set_delayed_call(callback, page_put_link, page);
	BUG_ON(mapping_gfp_mask(mapping) & __GFP_HIGHMEM);
	kaddr = page_address(page);
	return page_address(page);
}

const char *page_get_link_raw(struct dentry *dentry, struct inode *inode,
			      struct delayed_call *callback)
{
	return __page_get_link(dentry, inode, callback);
}
EXPORT_SYMBOL_GPL(page_get_link_raw);

const char *page_get_link(struct dentry *dentry, struct inode *inode,
					struct delayed_call *callback)
{
	char *kaddr = __page_get_link(dentry, inode, callback);

	if (!IS_ERR(kaddr))
		nd_terminate_link(kaddr, inode->i_size, PAGE_SIZE - 1);
	return kaddr;
}
Loading