Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull vfs fixes from Christian Brauner:
"fuse:

- Prevent opening of non-regular backing files.

Fuse doesn't support non-regular files anyway.

- Check whether copy_file_range() returns a larger size than
requested.

- Prevent overflow in copy_file_range() as fuse currently only
supports 32-bit sized copies.

- Cache the blocksize value if the server returned a new value as
inode->i_blkbits isn't modified directly anymore.

- Fix i_blkbits handling for iomap partial writes.

By default i_blkbits is set to PAGE_SIZE which causes iomap to mark
the whole folio as uptodate even on a partial write. But fuseblk
filesystems support choosing a blocksize smaller than PAGE_SIZE
risking data corruption. Simply enforce PAGE_SIZE as blocksize for
fuseblk's internal inode for now.

- Prevent out-of-bounds acces in fuse_dev_write() when the number of
bytes to be retrieved is truncated to the fc->max_pages limit.

virtiofs:

- Fix page faults for DAX page addresses.

Misc:

- Tighten file handle decoding from userns.

Check that the decoded dentry itself has a valid idmapping in the
user namespace.

- Fix mount-notify selftests.

- Fix some indentation errors.

- Add an FMODE_ flag to indicate IOCB_HAS_METADATA availability.

This will be moved to an FOP_* flag with a bit more rework needed
for that to happen not suitable for a fix.

- Don't silently ignore metadata for sync read/write.

- Don't pointlessly log warning when reading coredump sysctls"

* tag 'vfs-6.17-rc6.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
fuse: virtio_fs: fix page fault for DAX page address
selftests/fs/mount-notify: Fix compilation failure.
fhandle: use more consistent rules for decoding file handle from userns
fuse: Block access to folio overlimit
fuse: fix fuseblk i_blkbits for iomap partial writes
fuse: reflect cached blocksize if blocksize was changed
fuse: prevent overflow in copy_file_range return value
fuse: check if copy_file_range() returns larger than requested size
fuse: do not allow mapping a non-regular backing file
coredump: don't pointlessly check and spew warnings
fs: fix indentation style
block: don't silently ignore metadata for sync read/write
fs: add a FMODE_ flag to indicate IOCB_HAS_METADATA availability
Please enter a commit message to explain why this merge is necessary,
especially if it merges an updated upstream into a topic branch.

+86 -31
+8 -5
block/fops.c
··· 7 7 #include <linux/init.h> 8 8 #include <linux/mm.h> 9 9 #include <linux/blkdev.h> 10 + #include <linux/blk-integrity.h> 10 11 #include <linux/buffer_head.h> 11 12 #include <linux/mpage.h> 12 13 #include <linux/uio.h> ··· 55 54 struct bio bio; 56 55 ssize_t ret; 57 56 58 - WARN_ON_ONCE(iocb->ki_flags & IOCB_HAS_METADATA); 59 57 if (nr_pages <= DIO_INLINE_BIO_VECS) 60 58 vecs = inline_vecs; 61 59 else { ··· 131 131 if (bio->bi_status && !dio->bio.bi_status) 132 132 dio->bio.bi_status = bio->bi_status; 133 133 134 - if (!is_sync && (dio->iocb->ki_flags & IOCB_HAS_METADATA)) 134 + if (bio_integrity(bio)) 135 135 bio_integrity_unmap_user(bio); 136 136 137 137 if (atomic_dec_and_test(&dio->ref)) { ··· 233 233 } 234 234 bio->bi_opf |= REQ_NOWAIT; 235 235 } 236 - if (!is_sync && (iocb->ki_flags & IOCB_HAS_METADATA)) { 236 + if (iocb->ki_flags & IOCB_HAS_METADATA) { 237 237 ret = bio_integrity_map_iter(bio, iocb->private); 238 238 if (unlikely(ret)) 239 239 goto fail; ··· 301 301 ret = blk_status_to_errno(bio->bi_status); 302 302 } 303 303 304 - if (iocb->ki_flags & IOCB_HAS_METADATA) 304 + if (bio_integrity(bio)) 305 305 bio_integrity_unmap_user(bio); 306 306 307 307 iocb->ki_complete(iocb, ret); ··· 422 422 } 423 423 424 424 nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1); 425 - if (likely(nr_pages <= BIO_MAX_VECS)) { 425 + if (likely(nr_pages <= BIO_MAX_VECS && 426 + !(iocb->ki_flags & IOCB_HAS_METADATA))) { 426 427 if (is_sync_kiocb(iocb)) 427 428 return __blkdev_direct_IO_simple(iocb, iter, bdev, 428 429 nr_pages); ··· 688 687 689 688 if (bdev_can_atomic_write(bdev)) 690 689 filp->f_mode |= FMODE_CAN_ATOMIC_WRITE; 690 + if (blk_get_integrity(bdev->bd_disk)) 691 + filp->f_mode |= FMODE_HAS_METADATA; 691 692 692 693 ret = bdev_open(bdev, mode, filp->private_data, NULL, filp); 693 694 if (ret)
+4
fs/coredump.c
··· 1466 1466 ssize_t retval; 1467 1467 char old_core_pattern[CORENAME_MAX_SIZE]; 1468 1468 1469 + if (write) 1470 + return proc_dostring(table, write, buffer, lenp, ppos); 1471 + 1469 1472 retval = strscpy(old_core_pattern, core_pattern, CORENAME_MAX_SIZE); 1470 1473 1471 1474 error = proc_dostring(table, write, buffer, lenp, ppos); 1472 1475 if (error) 1473 1476 return error; 1477 + 1474 1478 if (!check_coredump_socket()) { 1475 1479 strscpy(core_pattern, old_core_pattern, retval + 1); 1476 1480 return -EINVAL;
+1 -1
fs/exec.c
··· 2048 2048 { 2049 2049 int error = proc_dointvec_minmax(table, write, buffer, lenp, ppos); 2050 2050 2051 - if (!error) 2051 + if (!error && !write) 2052 2052 validate_coredump_safety(); 2053 2053 return error; 2054 2054 }
+8
fs/fhandle.c
··· 208 208 return 1; 209 209 210 210 /* 211 + * Verify that the decoded dentry itself has a valid id mapping. 212 + * In case the decoded dentry is the mountfd root itself, this 213 + * verifies that the mountfd inode itself has a valid id mapping. 214 + */ 215 + if (!privileged_wrt_inode_uidgid(user_ns, idmap, d_inode(dentry))) 216 + return 0; 217 + 218 + /* 211 219 * It's racy as we're not taking rename_lock but we're able to ignore 212 220 * permissions and we just need an approximation whether we were able 213 221 * to follow a path to the file.
+1 -1
fs/fuse/dev.c
··· 1893 1893 1894 1894 index = outarg->offset >> PAGE_SHIFT; 1895 1895 1896 - while (num) { 1896 + while (num && ap->num_folios < num_pages) { 1897 1897 struct folio *folio; 1898 1898 unsigned int folio_offset; 1899 1899 unsigned int nr_bytes;
+2 -1
fs/fuse/dir.c
··· 1199 1199 if (attr->blksize != 0) 1200 1200 blkbits = ilog2(attr->blksize); 1201 1201 else 1202 - blkbits = inode->i_sb->s_blocksize_bits; 1202 + blkbits = fc->blkbits; 1203 1203 1204 1204 stat->blksize = 1 << blkbits; 1205 1205 } ··· 1377 1377 generic_fillattr(idmap, request_mask, inode, stat); 1378 1378 stat->mode = fi->orig_i_mode; 1379 1379 stat->ino = fi->orig_ino; 1380 + stat->blksize = 1 << fi->cached_i_blkbits; 1380 1381 if (test_bit(FUSE_I_BTIME, &fi->state)) { 1381 1382 stat->btime = fi->i_btime; 1382 1383 stat->result_mask |= STATX_BTIME;
+4 -1
fs/fuse/file.c
··· 2960 2960 .nodeid_out = ff_out->nodeid, 2961 2961 .fh_out = ff_out->fh, 2962 2962 .off_out = pos_out, 2963 - .len = len, 2963 + .len = min_t(size_t, len, UINT_MAX & PAGE_MASK), 2964 2964 .flags = flags 2965 2965 }; 2966 2966 struct fuse_write_out outarg; ··· 3026 3026 fc->no_copy_file_range = 1; 3027 3027 err = -EOPNOTSUPP; 3028 3028 } 3029 + if (!err && outarg.size > len) 3030 + err = -EIO; 3031 + 3029 3032 if (err) 3030 3033 goto out; 3031 3034
+14
fs/fuse/fuse_i.h
··· 210 210 /** Reference to backing file in passthrough mode */ 211 211 struct fuse_backing *fb; 212 212 #endif 213 + 214 + /* 215 + * The underlying inode->i_blkbits value will not be modified, 216 + * so preserve the blocksize specified by the server. 217 + */ 218 + u8 cached_i_blkbits; 213 219 }; 214 220 215 221 /** FUSE inode state bits */ ··· 975 969 /* Request timeout (in jiffies). 0 = no timeout */ 976 970 unsigned int req_timeout; 977 971 } timeout; 972 + 973 + /* 974 + * This is a workaround until fuse uses iomap for reads. 975 + * For fuseblk servers, this represents the blocksize passed in at 976 + * mount time and for regular fuse servers, this is equivalent to 977 + * inode->i_blkbits. 978 + */ 979 + u8 blkbits; 978 980 }; 979 981 980 982 /*
+16
fs/fuse/inode.c
··· 289 289 } 290 290 } 291 291 292 + if (attr->blksize) 293 + fi->cached_i_blkbits = ilog2(attr->blksize); 294 + else 295 + fi->cached_i_blkbits = fc->blkbits; 296 + 292 297 /* 293 298 * Don't set the sticky bit in i_mode, unless we want the VFS 294 299 * to check permissions. This prevents failures due to the ··· 1810 1805 err = -EINVAL; 1811 1806 if (!sb_set_blocksize(sb, ctx->blksize)) 1812 1807 goto err; 1808 + /* 1809 + * This is a workaround until fuse hooks into iomap for reads. 1810 + * Use PAGE_SIZE for the blocksize else if the writeback cache 1811 + * is enabled, buffered writes go through iomap and a read may 1812 + * overwrite partially written data if blocksize < PAGE_SIZE 1813 + */ 1814 + fc->blkbits = sb->s_blocksize_bits; 1815 + if (ctx->blksize != PAGE_SIZE && 1816 + !sb_set_blocksize(sb, PAGE_SIZE)) 1817 + goto err; 1813 1818 #endif 1814 1819 } else { 1815 1820 sb->s_blocksize = PAGE_SIZE; 1816 1821 sb->s_blocksize_bits = PAGE_SHIFT; 1822 + fc->blkbits = sb->s_blocksize_bits; 1817 1823 } 1818 1824 1819 1825 sb->s_subtype = ctx->subtype;
+5
fs/fuse/passthrough.c
··· 237 237 if (!file) 238 238 goto out; 239 239 240 + /* read/write/splice/mmap passthrough only relevant for regular files */ 241 + res = d_is_dir(file->f_path.dentry) ? -EISDIR : -EINVAL; 242 + if (!d_is_reg(file->f_path.dentry)) 243 + goto out_fput; 244 + 240 245 backing_sb = file_inode(file)->i_sb; 241 246 res = -ELOOP; 242 247 if (backing_sb->s_stack_depth >= fc->max_stack_depth)
+1 -1
fs/fuse/virtio_fs.c
··· 1016 1016 if (kaddr) 1017 1017 *kaddr = fs->window_kaddr + offset; 1018 1018 if (pfn) 1019 - *pfn = fs->window_phys_addr + offset; 1019 + *pfn = PHYS_PFN(fs->window_phys_addr + offset); 1020 1020 return nr_pages > max_nr_pages ? max_nr_pages : nr_pages; 1021 1021 } 1022 1022
+1 -1
fs/namespace.c
··· 2455 2455 return ERR_PTR(-EINVAL); 2456 2456 } 2457 2457 2458 - if (!ns_capable(old_mnt->mnt_ns->user_ns, CAP_SYS_ADMIN)) 2458 + if (!ns_capable(old_mnt->mnt_ns->user_ns, CAP_SYS_ADMIN)) 2459 2459 return ERR_PTR(-EPERM); 2460 2460 2461 2461 if (__has_locked_children(old_mnt, path->dentry))
+2 -1
include/linux/fs.h
··· 149 149 /* Expect random access pattern */ 150 150 #define FMODE_RANDOM ((__force fmode_t)(1 << 12)) 151 151 152 - /* FMODE_* bit 13 */ 152 + /* Supports IOCB_HAS_METADATA */ 153 + #define FMODE_HAS_METADATA ((__force fmode_t)(1 << 13)) 153 154 154 155 /* File is opened with O_PATH; almost nothing can be done with it */ 155 156 #define FMODE_PATH ((__force fmode_t)(1 << 14))
+3
io_uring/rw.c
··· 886 886 if (req->flags & REQ_F_HAS_METADATA) { 887 887 struct io_async_rw *io = req->async_data; 888 888 889 + if (!(file->f_mode & FMODE_HAS_METADATA)) 890 + return -EINVAL; 891 + 889 892 /* 890 893 * We have a union of meta fields with wpq used for buffered-io 891 894 * in io_async_rw, so fail it here.
+8 -9
tools/testing/selftests/filesystems/mount-notify/mount-notify_test.c
··· 2 2 // Copyright (c) 2025 Miklos Szeredi <miklos@szeredi.hu> 3 3 4 4 #define _GNU_SOURCE 5 + 6 + // Needed for linux/fanotify.h 7 + typedef struct { 8 + int val[2]; 9 + } __kernel_fsid_t; 10 + #define __kernel_fsid_t __kernel_fsid_t 11 + 5 12 #include <fcntl.h> 6 13 #include <sched.h> 7 14 #include <stdio.h> ··· 17 10 #include <sys/mount.h> 18 11 #include <unistd.h> 19 12 #include <sys/syscall.h> 13 + #include <sys/fanotify.h> 20 14 21 15 #include "../../kselftest_harness.h" 22 16 #include "../statmount/statmount.h" 23 17 #include "../utils.h" 24 - 25 - // Needed for linux/fanotify.h 26 - #ifndef __kernel_fsid_t 27 - typedef struct { 28 - int val[2]; 29 - } __kernel_fsid_t; 30 - #endif 31 - 32 - #include <sys/fanotify.h> 33 18 34 19 static const char root_mntpoint_templ[] = "/tmp/mount-notify_test_root.XXXXXX"; 35 20
+8 -10
tools/testing/selftests/filesystems/mount-notify/mount-notify_test_ns.c
··· 2 2 // Copyright (c) 2025 Miklos Szeredi <miklos@szeredi.hu> 3 3 4 4 #define _GNU_SOURCE 5 + 6 + // Needed for linux/fanotify.h 7 + typedef struct { 8 + int val[2]; 9 + } __kernel_fsid_t; 10 + #define __kernel_fsid_t __kernel_fsid_t 11 + 5 12 #include <fcntl.h> 6 13 #include <sched.h> 7 14 #include <stdio.h> ··· 17 10 #include <sys/mount.h> 18 11 #include <unistd.h> 19 12 #include <sys/syscall.h> 13 + #include <sys/fanotify.h> 20 14 21 15 #include "../../kselftest_harness.h" 22 - #include "../../pidfd/pidfd.h" 23 16 #include "../statmount/statmount.h" 24 17 #include "../utils.h" 25 - 26 - // Needed for linux/fanotify.h 27 - #ifndef __kernel_fsid_t 28 - typedef struct { 29 - int val[2]; 30 - } __kernel_fsid_t; 31 - #endif 32 - 33 - #include <sys/fanotify.h> 34 18 35 19 static const char root_mntpoint_templ[] = "/tmp/mount-notify_test_root.XXXXXX"; 36 20