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 c59d53d6d3f3490f976ca179ddfe02e69265ae4d..2dd6340de6b4efddc406f0c235701c15cf02f650 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 49eeb2ad8dbd8e074c6240417693f23fb328afa8..27c1d5ebcd91c8c296dc6676307f66bfdf4ab78d 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 69a829912a05eb8a3e21ed701d1030e31c0148bc..0765b3a8d6d600d7b9f83182d401d9f80c03476c 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 f5ed71f1910d09769c845c2d062d99ee0449437c..9fe47112c586f152662af38a9a7f90957cb96cf8 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 680f568b77f2cbefc3eacb2517f276041f229b1e..7b6e97828e552d4da90046ddfcd4a55723e522bb 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 0b9b7e25b69ad592642f8533bee9ccfe95ce9626..aa70e371bb54ab5d9c8dd8923b6ecf9693ee914d 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 c844cd5cda620b2809a397cdd6f4315ab6a1bfe2..1e8c44c7b61492eabf00c777831e457a7a6e579c 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 349b8aad1159f404103bd2057a1e64e9bf309f18..114a5a1a62302e32dd74d1679ff423a2d57c3c6b 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 d9fc94c869657fcfbd7aca1d5f5abc9fae2fb9d8..94df3cb957e9d547d192e8732c0cf23ef2b5ce5d 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 d8b4ab78bef076bd50d49b87dea5060fd8c1686a..9a084bdb892694bc562f514b55212d167cbac12f 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 e9115b4d8b635b846e5c9ad6ce229605323723a5..a4569b96ef06c54ce7aa795d039541c90a38284f 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 c8cad33bf250ea110de37bd1407f5a43ec5e38f2..52a7652fcff6394b96ace1f3b0ed72250ee5e669 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 727f99d333b304b3db0711953a3d91ece18a28eb..83e45eb6c095a36baaf749927628e6052fe900e6 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 4d0fb2fba7e208ae9455459afe11e277321d9f74..3f0ec87d5db4e290c62e2ffa6391a431a00dd36a 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 5eb708bff1c791debd6cfc5322583b2ae53f6437..cfb5ca41e30de1a4e073750096f5b51a2ec137d2 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 37effc1b134eea061f2c350c1d68b4436b65a4dd..f657a77314f8667fa019a01e10c84ea270024adc 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 d2ef1d69839bec308648dd1133ba8fb7240043cd..ac4ad746c770569cc07669f50474031e8820a4cc 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 c6333204d45130eb022f6db460eea34a1f6e91db..079ea1d09d85e60bd87fbbe66e1b2f551705c56d 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 88dc393c2bca38c0fa1b3fae579f7cfe4931223c..2892a45023af6d3eb941623d4fed04841ab07e02 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 ebbdb3c42e9f74613b003014c0baf44c842bb756..580b4e246aecd5f07d542943ba68fc4ed5961660 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