fs: add open_tree_attr()
authorChristian Brauner <brauner@kernel.org>
Tue, 28 Jan 2025 10:33:41 +0000 (11:33 +0100)
committerChristian Brauner <brauner@kernel.org>
Wed, 12 Feb 2025 11:12:28 +0000 (12:12 +0100)
Add open_tree_attr() which allow to atomically create a detached mount
tree and set mount options on it. If OPEN_TREE_CLONE is used this will
allow the creation of a detached mount with a new set of mount options
without it ever being exposed to userspace without that set of mount
options applied.

Link: https://lore.kernel.org/r/20250128-work-mnt_idmap-update-v2-v1-3-c25feb0d2eb3@kernel.org
Reviewed-by: "Seth Forshee (DigitalOcean)" <sforshee@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
20 files changed:
arch/alpha/kernel/syscalls/syscall.tbl
arch/arm/tools/syscall.tbl
arch/arm64/tools/syscall_32.tbl
arch/m68k/kernel/syscalls/syscall.tbl
arch/microblaze/kernel/syscalls/syscall.tbl
arch/mips/kernel/syscalls/syscall_n32.tbl
arch/mips/kernel/syscalls/syscall_n64.tbl
arch/mips/kernel/syscalls/syscall_o32.tbl
arch/parisc/kernel/syscalls/syscall.tbl
arch/powerpc/kernel/syscalls/syscall.tbl
arch/s390/kernel/syscalls/syscall.tbl
arch/sh/kernel/syscalls/syscall.tbl
arch/sparc/kernel/syscalls/syscall.tbl
arch/x86/entry/syscalls/syscall_32.tbl
arch/x86/entry/syscalls/syscall_64.tbl
arch/xtensa/kernel/syscalls/syscall.tbl
fs/namespace.c
include/linux/syscalls.h
include/uapi/asm-generic/unistd.h
scripts/syscall.tbl

index c59d53d..2dd6340 100644 (file)
 574    common  getxattrat                      sys_getxattrat
 575    common  listxattrat                     sys_listxattrat
 576    common  removexattrat                   sys_removexattrat
+577    common  open_tree_attr                  sys_open_tree_attr
index 49eeb2a..27c1d5e 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index 69a8299..0765b3a 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index f5ed71f..9fe4711 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index 680f568..7b6e978 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index 0b9b7e2..aa70e37 100644 (file)
 464    n32     getxattrat                      sys_getxattrat
 465    n32     listxattrat                     sys_listxattrat
 466    n32     removexattrat                   sys_removexattrat
+467    n32     open_tree_attr                  sys_open_tree_attr
index c844cd5..1e8c44c 100644 (file)
 464    n64     getxattrat                      sys_getxattrat
 465    n64     listxattrat                     sys_listxattrat
 466    n64     removexattrat                   sys_removexattrat
+467    n64     open_tree_attr                  sys_open_tree_attr
index 349b8aa..114a5a1 100644 (file)
 464    o32     getxattrat                      sys_getxattrat
 465    o32     listxattrat                     sys_listxattrat
 466    o32     removexattrat                   sys_removexattrat
+467    o32     open_tree_attr                  sys_open_tree_attr
index d9fc94c..94df3cb 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index d8b4ab7..9a084bd 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index e9115b4..a4569b9 100644 (file)
 464  common    getxattrat              sys_getxattrat                  sys_getxattrat
 465  common    listxattrat             sys_listxattrat                 sys_listxattrat
 466  common    removexattrat           sys_removexattrat               sys_removexattrat
+467  common    open_tree_attr          sys_open_tree_attr              sys_open_tree_attr
index c8cad33..52a7652 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index 727f99d..83e45eb 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index 4d0fb2f..3f0ec87 100644 (file)
 464    i386    getxattrat              sys_getxattrat
 465    i386    listxattrat             sys_listxattrat
 466    i386    removexattrat           sys_removexattrat
+467    i386    open_tree_attr          sys_open_tree_attr
index 5eb708b..cfb5ca4 100644 (file)
 464    common  getxattrat              sys_getxattrat
 465    common  listxattrat             sys_listxattrat
 466    common  removexattrat           sys_removexattrat
+467    common  open_tree_attr          sys_open_tree_attr
 
 #
 # Due to a historical design error, certain syscalls are numbered differently
index 37effc1..f657a77 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr
index d2ef1d6..ac4ad74 100644 (file)
@@ -4995,6 +4995,45 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path,
        return err;
 }
 
+SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename,
+               unsigned, flags, struct mount_attr __user *, uattr,
+               size_t, usize)
+{
+       struct file __free(fput) *file = NULL;
+       int fd;
+
+       if (!uattr && usize)
+               return -EINVAL;
+
+       file = vfs_open_tree(dfd, filename, flags);
+       if (IS_ERR(file))
+               return PTR_ERR(file);
+
+       if (uattr) {
+               int ret;
+               struct mount_kattr kattr = {
+                       .recurse = !!(flags & AT_RECURSIVE),
+               };
+
+               ret = copy_mount_setattr(uattr, usize, &kattr);
+               if (ret)
+                       return ret;
+
+               ret = do_mount_setattr(&file->f_path, &kattr);
+               if (ret)
+                       return ret;
+
+               finish_mount_kattr(&kattr);
+       }
+
+       fd = get_unused_fd_flags(flags & O_CLOEXEC);
+       if (fd < 0)
+               return fd;
+
+       fd_install(fd, no_free_ptr(file));
+       return fd;
+}
+
 int show_path(struct seq_file *m, struct dentry *root)
 {
        if (root->d_sb->s_op->show_path)
index c633320..079ea1d 100644 (file)
@@ -951,6 +951,10 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags,
 asmlinkage long sys_rseq(struct rseq __user *rseq, uint32_t rseq_len,
                         int flags, uint32_t sig);
 asmlinkage long sys_open_tree(int dfd, const char __user *path, unsigned flags);
+asmlinkage long sys_open_tree_attr(int dfd, const char __user *path,
+                                  unsigned flags,
+                                  struct mount_attr __user *uattr,
+                                  size_t usize);
 asmlinkage long sys_move_mount(int from_dfd, const char __user *from_path,
                               int to_dfd, const char __user *to_path,
                               unsigned int ms_flags);
index 88dc393..2892a45 100644 (file)
@@ -849,9 +849,11 @@ __SYSCALL(__NR_getxattrat, sys_getxattrat)
 __SYSCALL(__NR_listxattrat, sys_listxattrat)
 #define __NR_removexattrat 466
 __SYSCALL(__NR_removexattrat, sys_removexattrat)
+#define __NR_open_tree_attr 467
+__SYSCALL(__NR_open_tree_attr, sys_open_tree_attr)
 
 #undef __NR_syscalls
-#define __NR_syscalls 467
+#define __NR_syscalls 468
 
 /*
  * 32 bit systems traditionally used different
index ebbdb3c..580b4e2 100644 (file)
 464    common  getxattrat                      sys_getxattrat
 465    common  listxattrat                     sys_listxattrat
 466    common  removexattrat                   sys_removexattrat
+467    common  open_tree_attr                  sys_open_tree_attr