selftests/landlock: Do not allocate memory in fixture data
authorMickaël Salaün <mic@digikod.net>
Sat, 11 May 2024 17:14:40 +0000 (19:14 +0200)
committerMickaël Salaün <mic@digikod.net>
Sat, 11 May 2024 17:18:44 +0000 (19:18 +0200)
Do not allocate self->dir_path in the test process because this would
not be visible in the FIXTURE_TEARDOWN() process when relying on
fork()/clone3() instead of vfork().

This change is required for a following commit removing vfork() call to
not break the layout3_fs.* test cases.

Cc: Günther Noack <gnoack@google.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20240511171445.904356-6-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
tools/testing/selftests/landlock/fs_test.c

index 46b9eff..1e2cffd 100644 (file)
@@ -9,6 +9,7 @@
 
 #define _GNU_SOURCE
 #include <fcntl.h>
+#include <libgen.h>
 #include <linux/landlock.h>
 #include <linux/magic.h>
 #include <sched.h>
@@ -4624,7 +4625,6 @@ FIXTURE(layout3_fs)
 {
        bool has_created_dir;
        bool has_created_file;
-       char *dir_path;
        bool skip_test;
 };
 
@@ -4683,11 +4683,24 @@ FIXTURE_VARIANT_ADD(layout3_fs, hostfs) {
        .cwd_fs_magic = HOSTFS_SUPER_MAGIC,
 };
 
+static char *dirname_alloc(const char *path)
+{
+       char *dup;
+
+       if (!path)
+               return NULL;
+
+       dup = strdup(path);
+       if (!dup)
+               return NULL;
+
+       return dirname(dup);
+}
+
 FIXTURE_SETUP(layout3_fs)
 {
        struct stat statbuf;
-       const char *slash;
-       size_t dir_len;
+       char *dir_path = dirname_alloc(variant->file_path);
 
        if (!supports_filesystem(variant->mnt.type) ||
            !cwd_matches_fs(variant->cwd_fs_magic)) {
@@ -4697,25 +4710,15 @@ FIXTURE_SETUP(layout3_fs)
 
        _metadata->teardown_parent = true;
 
-       slash = strrchr(variant->file_path, '/');
-       ASSERT_NE(slash, NULL);
-       dir_len = (size_t)slash - (size_t)variant->file_path;
-       ASSERT_LT(0, dir_len);
-       self->dir_path = malloc(dir_len + 1);
-       self->dir_path[dir_len] = '\0';
-       strncpy(self->dir_path, variant->file_path, dir_len);
-
        prepare_layout_opt(_metadata, &variant->mnt);
 
        /* Creates directory when required. */
-       if (stat(self->dir_path, &statbuf)) {
+       if (stat(dir_path, &statbuf)) {
                set_cap(_metadata, CAP_DAC_OVERRIDE);
-               EXPECT_EQ(0, mkdir(self->dir_path, 0700))
+               EXPECT_EQ(0, mkdir(dir_path, 0700))
                {
                        TH_LOG("Failed to create directory \"%s\": %s",
-                              self->dir_path, strerror(errno));
-                       free(self->dir_path);
-                       self->dir_path = NULL;
+                              dir_path, strerror(errno));
                }
                self->has_created_dir = true;
                clear_cap(_metadata, CAP_DAC_OVERRIDE);
@@ -4736,6 +4739,8 @@ FIXTURE_SETUP(layout3_fs)
                self->has_created_file = true;
                clear_cap(_metadata, CAP_DAC_OVERRIDE);
        }
+
+       free(dir_path);
 }
 
 FIXTURE_TEARDOWN(layout3_fs)
@@ -4754,16 +4759,17 @@ FIXTURE_TEARDOWN(layout3_fs)
        }
 
        if (self->has_created_dir) {
+               char *dir_path = dirname_alloc(variant->file_path);
+
                set_cap(_metadata, CAP_DAC_OVERRIDE);
                /*
                 * Don't check for error because the directory might already
                 * have been removed (cf. release_inode test).
                 */
-               rmdir(self->dir_path);
+               rmdir(dir_path);
                clear_cap(_metadata, CAP_DAC_OVERRIDE);
+               free(dir_path);
        }
-       free(self->dir_path);
-       self->dir_path = NULL;
 
        cleanup_layout(_metadata);
 }
@@ -4830,7 +4836,10 @@ TEST_F_FORK(layout3_fs, tag_inode_dir_mnt)
 
 TEST_F_FORK(layout3_fs, tag_inode_dir_child)
 {
-       layer3_fs_tag_inode(_metadata, self, variant, self->dir_path);
+       char *dir_path = dirname_alloc(variant->file_path);
+
+       layer3_fs_tag_inode(_metadata, self, variant, dir_path);
+       free(dir_path);
 }
 
 TEST_F_FORK(layout3_fs, tag_inode_file)
@@ -4857,9 +4866,13 @@ TEST_F_FORK(layout3_fs, release_inodes)
        if (self->has_created_file)
                EXPECT_EQ(0, remove_path(variant->file_path));
 
-       if (self->has_created_dir)
+       if (self->has_created_dir) {
+               char *dir_path = dirname_alloc(variant->file_path);
+
                /* Don't check for error because of cgroup specificities. */
-               remove_path(self->dir_path);
+               remove_path(dir_path);
+               free(dir_path);
+       }
 
        ruleset_fd =
                create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_DIR, layer1);