]> www.infradead.org Git - users/hch/xfstests-dev.git/commitdiff
idmapped-mounts: Add open with O_TMPFILE operation in setgid test v2022.05.08
authorYang Xu <xuyang2018.jy@fujitsu.com>
Sat, 7 May 2022 16:01:27 +0000 (00:01 +0800)
committerZorro Lang <zlang@kernel.org>
Sat, 7 May 2022 15:08:34 +0000 (23:08 +0800)
Since we can create temp file by using O_TMPFILE flag and filesystem driver also
has this api, we should also check this operation whether strip S_ISGID.

Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
Signed-off-by: Zorro Lang <zlang@kernel.org>
src/idmapped-mounts/idmapped-mounts.c

index 592a15d5a73fcd93641aceb538f3a943edd9a553..f3873e5289c428821c59c64b118bc57a92e925fa 100644 (file)
@@ -51,6 +51,7 @@
 #define FILE1_RENAME "file1_rename"
 #define FILE2 "file2"
 #define FILE2_RENAME "file2_rename"
+#define FILE3 "file3"
 #define DIR1 "dir1"
 #define DIR2 "dir2"
 #define DIR3 "dir3"
@@ -340,6 +341,24 @@ out:
        return fret;
 }
 
+static bool openat_tmpfile_supported(int dirfd)
+{
+       int fd = -1;
+
+       fd = openat(dirfd, ".", O_TMPFILE | O_RDWR, S_IXGRP | S_ISGID);
+       if (fd == -1) {
+               if (errno == ENOTSUP)
+                       return false;
+               else
+                       return log_errno(false, "failure: create");
+       }
+
+       if (close(fd))
+               log_stderr("failure: close");
+
+       return true;
+}
+
 /* __expected_uid_gid - check whether file is owned by the provided uid and gid */
 static bool __expected_uid_gid(int dfd, const char *path, int flags,
                               uid_t expected_uid, gid_t expected_gid, bool log)
@@ -7844,7 +7863,9 @@ static int setgid_create(void)
 {
        int fret = -1;
        int file1_fd = -EBADF;
+       int tmpfile_fd = -EBADF;
        pid_t pid;
+       bool supported = false;
 
        if (!caps_supported())
                return 0;
@@ -7869,6 +7890,8 @@ static int setgid_create(void)
                goto out;
        }
 
+       supported = openat_tmpfile_supported(t_dir1_fd);
+
        pid = fork();
        if (pid < 0) {
                log_stderr("failure: fork");
@@ -7932,6 +7955,24 @@ static int setgid_create(void)
                if (unlinkat(t_dir1_fd, CHRDEV1, 0))
                        die("failure: delete");
 
+               /* create tmpfile via filesystem tmpfile api */
+               if (supported) {
+                       tmpfile_fd = openat(t_dir1_fd, ".", O_TMPFILE | O_RDWR, S_IXGRP | S_ISGID);
+                       if (tmpfile_fd < 0)
+                               die("failure: create");
+                       /* link the temporary file into the filesystem, making it permanent */
+                       if (linkat(tmpfile_fd, "", t_dir1_fd, FILE3, AT_EMPTY_PATH))
+                               die("failure: linkat");
+                       if (close(tmpfile_fd))
+                               die("failure: close");
+                       if (!is_setgid(t_dir1_fd, FILE3, 0))
+                               die("failure: is_setgid");
+                       if (!expected_uid_gid(t_dir1_fd, FILE3, 0, 0, 0))
+                               die("failure: check ownership");
+                       if (unlinkat(t_dir1_fd, FILE3, 0))
+                               die("failure: delete");
+               }
+
                exit(EXIT_SUCCESS);
        }
        if (wait_for_pid(pid))
@@ -8021,6 +8062,24 @@ static int setgid_create(void)
                if (unlinkat(t_dir1_fd, CHRDEV1, 0))
                        die("failure: delete");
 
+               /* create tmpfile via filesystem tmpfile api */
+               if (supported) {
+                       tmpfile_fd = openat(t_dir1_fd, ".", O_TMPFILE | O_RDWR, S_IXGRP | S_ISGID);
+                       if (tmpfile_fd < 0)
+                               die("failure: create");
+                       /* link the temporary file into the filesystem, making it permanent */
+                       if (linkat(tmpfile_fd, "", t_dir1_fd, FILE3, AT_EMPTY_PATH))
+                               die("failure: linkat");
+                       if (close(tmpfile_fd))
+                               die("failure: close");
+                       if (is_setgid(t_dir1_fd, FILE3, 0))
+                               die("failure: is_setgid");
+                       if (!expected_uid_gid(t_dir1_fd, FILE3, 0, 0, 0))
+                               die("failure: check ownership");
+                       if (unlinkat(t_dir1_fd, FILE3, 0))
+                               die("failure: delete");
+               }
+
                exit(EXIT_SUCCESS);
        }
        if (wait_for_pid(pid))
@@ -8042,6 +8101,9 @@ static int setgid_create_idmapped(void)
                .attr_set = MOUNT_ATTR_IDMAP,
        };
        pid_t pid;
+       int tmpfile_fd = -EBADF;
+       bool supported = false;
+       char path[PATH_MAX];
 
        if (!caps_supported())
                return 0;
@@ -8089,6 +8151,8 @@ static int setgid_create_idmapped(void)
                goto out;
        }
 
+       supported = openat_tmpfile_supported(open_tree_fd);
+
        pid = fork();
        if (pid < 0) {
                log_stderr("failure: fork");
@@ -8171,6 +8235,25 @@ static int setgid_create_idmapped(void)
                if (unlinkat(open_tree_fd, CHRDEV1, 0))
                        die("failure: delete");
 
+               /* create tmpfile via filesystem tmpfile api */
+               if (supported) {
+                       tmpfile_fd = openat(open_tree_fd, ".", O_TMPFILE | O_RDWR, S_IXGRP | S_ISGID);
+                       if (tmpfile_fd < 0)
+                               die("failure: create");
+                       /* link the temporary file into the filesystem, making it permanent */
+                       snprintf(path, PATH_MAX,  "/proc/self/fd/%d", tmpfile_fd);
+                       if (linkat(AT_FDCWD, path, open_tree_fd, FILE3, AT_SYMLINK_FOLLOW))
+                               die("failure: linkat");
+                       if (close(tmpfile_fd))
+                               die("failure: close");
+                       if (is_setgid(open_tree_fd, FILE3, 0))
+                               die("failure: is_setgid");
+                       if (!expected_uid_gid(open_tree_fd, FILE3, 0, 10000, 10000))
+                               die("failure: check ownership");
+                       if (unlinkat(open_tree_fd, FILE3, 0))
+                               die("failure: delete");
+               }
+
                exit(EXIT_SUCCESS);
        }
        if (wait_for_pid(pid))
@@ -8194,6 +8277,9 @@ static int setgid_create_idmapped_in_userns(void)
                .attr_set = MOUNT_ATTR_IDMAP,
        };
        pid_t pid;
+       int tmpfile_fd = -EBADF;
+       bool supported = false;
+       char path[PATH_MAX];
 
        if (!caps_supported())
                return 0;
@@ -8241,6 +8327,8 @@ static int setgid_create_idmapped_in_userns(void)
                goto out;
        }
 
+       supported = openat_tmpfile_supported(open_tree_fd);
+
        pid = fork();
        if (pid < 0) {
                log_stderr("failure: fork");
@@ -8307,6 +8395,25 @@ static int setgid_create_idmapped_in_userns(void)
                if (unlinkat(open_tree_fd, CHRDEV1, 0))
                        die("failure: delete");
 
+               /* create tmpfile via filesystem tmpfile api */
+               if (supported) {
+                       tmpfile_fd = openat(open_tree_fd, ".", O_TMPFILE | O_RDWR, S_IXGRP | S_ISGID);
+                       if (tmpfile_fd < 0)
+                               die("failure: create");
+                       /* link the temporary file into the filesystem, making it permanent */
+                       snprintf(path, PATH_MAX,  "/proc/self/fd/%d", tmpfile_fd);
+                       if (linkat(AT_FDCWD, path, open_tree_fd, FILE3, AT_SYMLINK_FOLLOW))
+                               die("failure: linkat");
+                       if (close(tmpfile_fd))
+                               die("failure: close");
+                       if (!is_setgid(open_tree_fd, FILE3, 0))
+                               die("failure: is_setgid");
+                       if (!expected_uid_gid(open_tree_fd, FILE3, 0, 0, 0))
+                               die("failure: check ownership");
+                       if (unlinkat(open_tree_fd, FILE3, 0))
+                               die("failure: delete");
+               }
+
                exit(EXIT_SUCCESS);
        }
        if (wait_for_pid(pid))
@@ -8415,6 +8522,25 @@ static int setgid_create_idmapped_in_userns(void)
                if (unlinkat(open_tree_fd, CHRDEV1, 0))
                        die("failure: delete");
 
+               /* create tmpfile via filesystem tmpfile api */
+               if (supported) {
+                       tmpfile_fd = openat(open_tree_fd, ".", O_TMPFILE | O_RDWR, S_IXGRP | S_ISGID);
+                       if (tmpfile_fd < 0)
+                               die("failure: create");
+                       /* link the temporary file into the filesystem, making it permanent */
+                       snprintf(path, PATH_MAX,  "/proc/self/fd/%d", tmpfile_fd);
+                       if (linkat(AT_FDCWD, path, open_tree_fd, FILE3, AT_SYMLINK_FOLLOW))
+                               die("failure: linkat");
+                       if (close(tmpfile_fd))
+                               die("failure: close");
+                       if (is_setgid(open_tree_fd, FILE3, 0))
+                               die("failure: is_setgid");
+                       if (!expected_uid_gid(open_tree_fd, FILE3, 0, 0, 1000))
+                               die("failure: check ownership");
+                       if (unlinkat(open_tree_fd, FILE3, 0))
+                               die("failure: delete");
+               }
+
                exit(EXIT_SUCCESS);
        }
        if (wait_for_pid(pid))
@@ -8511,6 +8637,25 @@ static int setgid_create_idmapped_in_userns(void)
                if (unlinkat(open_tree_fd, CHRDEV1, 0))
                        die("failure: delete");
 
+               /* create tmpfile via filesystem tmpfile api */
+               if (supported) {
+                       tmpfile_fd = openat(open_tree_fd, ".", O_TMPFILE | O_RDWR, S_IXGRP | S_ISGID);
+                       if (tmpfile_fd < 0)
+                               die("failure: create");
+                       /* link the temporary file into the filesystem, making it permanent */
+                       snprintf(path, PATH_MAX,  "/proc/self/fd/%d", tmpfile_fd);
+                       if (linkat(AT_FDCWD, path, open_tree_fd, FILE3, AT_SYMLINK_FOLLOW))
+                               die("failure: linkat");
+                       if (close(tmpfile_fd))
+                               die("failure: close");
+                       if (is_setgid(open_tree_fd, FILE3, 0))
+                               die("failure: is_setgid");
+                       if (!expected_uid_gid(open_tree_fd, FILE3, 0, 0, 0))
+                               die("failure: check ownership");
+                       if (unlinkat(open_tree_fd, FILE3, 0))
+                               die("failure: delete");
+               }
+
                exit(EXIT_SUCCESS);
        }
        if (wait_for_pid(pid))