]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Revert "repart: Ensure files end up owned by root in generated filesystems"
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 23 Jan 2023 13:47:00 +0000 (14:47 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 23 Jan 2023 15:33:03 +0000 (16:33 +0100)
This reverts commit e59678b2cf42e4206ddabc959d3cf9a5a865ecdc.

We also modify the repart integration tests to make them pass with the
changes in this commit. In short, we have to make sure every file is
owned by the user executing repart. We use tee instead of cat since it
makes that easier. This also has the benefit of improving debugability
as seeing the config file contents on stdout makes it easier to know
which test is failing.

src/partition/repart.c
src/shared/mkfs-util.c
test/units/testsuite-58.sh

index 12ed0b02f5617dd66cd3e14aba3af9ef278cc18c..c95b1d601df300bf049b5866e02f9d107fcd48e1 100644 (file)
@@ -3745,7 +3745,6 @@ static int context_copy_blocks(Context *context) {
 }
 
 static int do_copy_files(Partition *p, const char *root, const Set *denylist) {
-
         int r;
 
         assert(p);
@@ -3794,14 +3793,14 @@ static int do_copy_files(Partition *p, const char *root, const Set *denylist) {
                                 r = copy_tree_at(
                                                 sfd, ".",
                                                 pfd, fn,
-                                                getuid(), getgid(),
+                                                UID_INVALID, GID_INVALID,
                                                 COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN,
                                                 denylist);
                         } else
                                 r = copy_tree_at(
                                                 sfd, ".",
                                                 tfd, ".",
-                                                getuid(), getgid(),
+                                                UID_INVALID, GID_INVALID,
                                                 COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN,
                                                 denylist);
                         if (r < 0)
@@ -3856,7 +3855,7 @@ static int do_make_directories(Partition *p, const char *root) {
 
         STRV_FOREACH(d, p->make_directories) {
 
-                r = mkdir_p_root(root, *d, getuid(), getgid(), 0755);
+                r = mkdir_p_root(root, *d, UID_INVALID, GID_INVALID, 0755);
                 if (r < 0)
                         return log_error_errno(r, "Failed to create directory '%s' in file system: %m", *d);
         }
index 11ae92290d71eeca9a514f5712ca0205fac2a3b4..d64ef0d47a0b60e3193aab3dad7147a595172d5e 100644 (file)
@@ -98,41 +98,11 @@ static int mangle_fat_label(const char *s, char **ret) {
         return 0;
 }
 
-static int setup_userns(uid_t uid, gid_t gid) {
-        int r;
-
-       /* mkfs programs tend to keep ownership intact when bootstrapping themselves from a root directory.
-        * However, we'd like for the files to be owned by root instead, so we fork off a user namespace and
-        * inside of it, map the uid/gid of the root directory to root in the user namespace. mkfs programs
-        * will pick up on this and the files will be owned by root in the generated filesystem. */
-
-        r = write_string_filef("/proc/self/uid_map", WRITE_STRING_FILE_DISABLE_BUFFER,
-                                UID_FMT " " UID_FMT " " UID_FMT, 0u, uid, 1u);
-        if (r < 0)
-                return log_error_errno(r,
-                                       "Failed to write mapping for "UID_FMT" to /proc/self/uid_map: %m",
-                                       uid);
-
-        r = write_string_file("/proc/self/setgroups", "deny", WRITE_STRING_FILE_DISABLE_BUFFER);
-        if (r < 0)
-                return log_error_errno(r, "Failed to write 'deny' to /proc/self/setgroups: %m");
-
-        r = write_string_filef("/proc/self/gid_map", WRITE_STRING_FILE_DISABLE_BUFFER,
-                                GID_FMT " " GID_FMT " " GID_FMT, 0u, gid, 1u);
-        if (r < 0)
-                return log_error_errno(r,
-                                       "Failed to write mapping for "GID_FMT" to /proc/self/gid_map: %m",
-                                       gid);
-
-        return 0;
-}
-
 static int do_mcopy(const char *node, const char *root) {
         _cleanup_free_ char *mcopy = NULL;
         _cleanup_strv_free_ char **argv = NULL;
         _cleanup_close_ int rfd = -EBADF;
         _cleanup_free_ DirectoryEntries *de = NULL;
-        struct stat st;
         int r;
 
         assert(node);
@@ -182,17 +152,10 @@ static int do_mcopy(const char *node, const char *root) {
         if (strv_extend(&argv, "::") < 0)
                 return log_oom();
 
-        if (fstat(rfd, &st) < 0)
-                return log_error_errno(errno, "Failed to stat '%s': %m", root);
-
-        r = safe_fork("(mcopy)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_NEW_USERNS|FORK_CLOSE_ALL_FDS, NULL);
+        r = safe_fork("(mcopy)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS, NULL);
         if (r < 0)
                 return r;
         if (r == 0) {
-                r = setup_userns(st.st_uid, st.st_gid);
-                if (r < 0)
-                        _exit(EXIT_FAILURE);
-
                 /* Avoid failures caused by mismatch in expectations between mkfs.vfat and mcopy by disabling
                  * the stricter mcopy checks using MTOOLS_SKIP_CHECK. */
                 execve(mcopy, argv, STRV_MAKE("MTOOLS_SKIP_CHECK=1"));
@@ -308,7 +271,6 @@ int make_filesystem(
         _cleanup_strv_free_ char **argv = NULL;
         _cleanup_(unlink_and_freep) char *protofile = NULL;
         char vol_id[CONST_MAX(SD_ID128_UUID_STRING_MAX, 8U + 1U)] = {};
-        struct stat st;
         int r;
 
         assert(node);
@@ -527,21 +489,12 @@ int make_filesystem(
         if (extra_mkfs_args && strv_extend_strv(&argv, extra_mkfs_args, false) < 0)
                 return log_oom();
 
-        if (root && stat(root, &st) < 0)
-                return log_error_errno(errno, "Failed to stat %s: %m", root);
-
-        r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS|(root ? FORK_NEW_USERNS : 0), NULL);
+        r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS, NULL);
         if (r < 0)
                 return r;
         if (r == 0) {
                 /* Child */
 
-                if (root) {
-                        r = setup_userns(st.st_uid, st.st_gid);
-                        if (r < 0)
-                                _exit(EXIT_FAILURE);
-                }
-
                 execvp(mkfs, argv);
 
                 log_error_errno(errno, "Failed to execute %s: %m", mkfs);
index cf1007f69aff85339aca09ef600995c1d1d1ce76..e83df97067ac650a01e4be0f0a8ede341309e487 100755 (executable)
@@ -119,21 +119,21 @@ last-lba: 2097118"
 
     # 2. Testing with root, root2, home, and swap
 
-    cat >"$defs/root.conf" <<EOF
+    runas testuser tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root
 EOF
 
     ln -s root.conf "$defs/root2.conf"
 
-    cat >"$defs/home.conf" <<EOF
+    runas testuser tee "$defs/home.conf" <<EOF
 [Partition]
 Type=home
 Label=home-first
 Label=home-always-too-long-xxxxxxxxxxxxxx-%v
 EOF
 
-    cat >"$defs/swap.conf" <<EOF
+    runas testuser tee "$defs/swap.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=64M
@@ -194,13 +194,13 @@ $imgs/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5
 
     # 3. Testing with root, root2, home, swap, and another partition
 
-    cat >"$defs/swap.conf" <<EOF
+    runas testuser tee "$defs/swap.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=64M
 EOF
 
-    cat >"$defs/extra.conf" <<EOF
+    runas testuser tee "$defs/extra.conf" <<EOF
 [Partition]
 Type=linux-generic
 Label=custom_label
@@ -255,7 +255,7 @@ $imgs/zzz5 : start=     1908696, size=     2285568, type=0FC63DAF-8483-4772-8E79
 
     dd if=/dev/urandom of="$imgs/block-copy" bs=4096 count=10240
 
-    cat >"$defs/extra2.conf" <<EOF
+    runas testuser tee "$defs/extra2.conf" <<EOF
 [Partition]
 Type=linux-generic
 Label=block-copy
@@ -288,7 +288,7 @@ $imgs/zzz6 : start=     4194264, size=     2097152, type=0FC63DAF-8483-4772-8E79
 
     # 6. Testing Format=/Encrypt=/CopyFiles=
 
-    cat >"$defs/extra3.conf" <<EOF
+    runas testuser tee "$defs/extra3.conf" <<EOF
 [Partition]
 Type=linux-generic
 Label=luks-format-copy
@@ -350,21 +350,21 @@ test_dropin() {
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
 
-    cat >"$defs/root.conf" <<EOF
+    runas testuser tee "$defs/root.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=64M
 UUID=837c3d67-21b3-478e-be82-7e7f83bf96d3
 EOF
 
-    mkdir -p "$defs/root.conf.d"
-    cat >"$defs/root.conf.d/override1.conf" <<EOF
+    runas testuser mkdir -p "$defs/root.conf.d"
+    runas testuser tee "$defs/root.conf.d/override1.conf" <<EOF
 [Partition]
 Label=label1
 SizeMaxBytes=32M
 EOF
 
-    cat >"$defs/root.conf.d/override2.conf" <<EOF
+    runas testuser tee "$defs/root.conf.d/override2.conf" <<EOF
 [Partition]
 Label=label2
 EOF
@@ -408,9 +408,9 @@ test_multiple_definitions() {
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
 
-    mkdir -p "$defs/1"
+    runas testuser mkdir -p "$defs/1"
 
-    cat >"$defs/1/root1.conf" <<EOF
+    runas testuser tee "$defs/1/root1.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=32M
@@ -418,9 +418,9 @@ UUID=7b93d1f2-595d-4ce3-b0b9-837fbd9e63b0
 Label=label1
 EOF
 
-    mkdir -p "$defs/2"
+    runas testuser mkdir -p "$defs/2"
 
-    cat >"$defs/2/root2.conf" <<EOF
+    runas testuser tee "$defs/2/root2.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=32M
@@ -481,14 +481,14 @@ test_copy_blocks() {
 
     # First, create a disk image and verify its in order
 
-    cat >"$defs/esp.conf" <<EOF
+    runas testuser tee "$defs/esp.conf" <<EOF
 [Partition]
 Type=esp
 SizeMinBytes=10M
 Format=vfat
 EOF
 
-    cat >"$defs/usr.conf" <<EOF
+    runas testuser tee "$defs/usr.conf" <<EOF
 [Partition]
 Type=usr-${architecture}
 SizeMinBytes=10M
@@ -496,7 +496,7 @@ Format=ext4
 ReadOnly=yes
 EOF
 
-    cat >"$defs/root.conf" <<EOF
+    runas testuser tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 SizeMinBytes=10M
@@ -523,20 +523,20 @@ EOF
 
     # Then, create another image with CopyBlocks=auto
 
-    cat >"$defs/esp.conf" <<EOF
+    runas testuser tee "$defs/esp.conf" <<EOF
 [Partition]
 Type=esp
 CopyBlocks=auto
 EOF
 
-    cat >"$defs/usr.conf" <<EOF
+    runas testuser tee "$defs/usr.conf" <<EOF
 [Partition]
 Type=usr-${architecture}
 ReadOnly=yes
 CopyBlocks=auto
 EOF
 
-    cat >"$defs/root.conf" <<EOF
+    runas testuser tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 CopyBlocks=auto
@@ -563,7 +563,7 @@ test_unaligned_partition() {
 
     # Operate on an image with unaligned partition.
 
-    cat >"$defs/root.conf" <<EOF
+    runas testuser tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 EOF
@@ -598,7 +598,7 @@ test_issue_21817() {
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
 
-    cat >"$defs/test.conf" <<EOF
+    runas testuser tee "$defs/test.conf" <<EOF
 [Partition]
 Type=root
 EOF
@@ -634,14 +634,14 @@ test_issue_24553() {
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
 
-    cat >"$defs/root.conf" <<EOF
+    runas testuser tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root
 SizeMinBytes=10G
 SizeMaxBytes=120G
 EOF
 
-    cat >"$imgs/partscript" <<EOF
+    runas testuser tee "$imgs/partscript" <<EOF
 label: gpt
 label-id: C9FFE979-A415-C449-B729-78C7AA664B10
 unit: sectors
@@ -679,7 +679,7 @@ EOF
     assert_in "$imgs/zzz2 : start=      524328, size=    24641456, type=${root_guid}, uuid=${root_uuid}, name=\"root-${architecture}\"" "$output"
 
     # 3. Multiple partitions with Priority= (small disk)
-    cat >"$defs/root.conf" <<EOF
+    runas testuser tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root
 SizeMinBytes=10G
@@ -687,7 +687,7 @@ SizeMaxBytes=120G
 Priority=100
 EOF
 
-    cat >"$defs/usr.conf" <<EOF
+    runas testuser tee "$defs/usr.conf" <<EOF
 [Partition]
 Type=usr
 SizeMinBytes=10M
@@ -734,7 +734,7 @@ test_zero_uuid() {
 
     # Test image with zero UUID.
 
-    cat >"$defs/root.conf" <<EOF
+    runas testuser tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 UUID=null
@@ -760,7 +760,7 @@ test_verity() {
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
 
-    cat >"$defs/verity-data.conf" <<EOF
+    runas testuser tee "$defs/verity-data.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 CopyFiles=${defs}
@@ -768,14 +768,14 @@ Verity=data
 VerityMatchKey=root
 EOF
 
-    cat >"$defs/verity-hash.conf" <<EOF
+    runas testuser tee "$defs/verity-hash.conf" <<EOF
 [Partition]
 Type=root-${architecture}-verity
 Verity=hash
 VerityMatchKey=root
 EOF
 
-    cat >"$defs/verity-sig.conf" <<EOF
+    runas testuser tee "$defs/verity-sig.conf" <<EOF
 [Partition]
 Type=root-${architecture}-verity-sig
 Verity=signature
@@ -783,7 +783,7 @@ VerityMatchKey=root
 EOF
 
     # Unfortunately OpenSSL insists on reading some config file, hence provide one with mostly placeholder contents
-    cat >> "$defs/verity.openssl.cnf" <<EOF
+    runas testuser tee > "$defs/verity.openssl.cnf" <<EOF
 [ req ]
 prompt = no
 distinguished_name = req_distinguished_name
@@ -843,17 +843,17 @@ test_issue_24786() {
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs' '$root'" RETURN
 
-    touch "$root/abc"
-    mkdir "$root/usr"
-    touch "$root/usr/def"
+    runas testuser touch "$root/abc"
+    runas testuser mkdir "$root/usr"
+    runas testuser touch "$root/usr/def"
 
-    cat >"$defs/00-root.conf" <<EOF
+    runas testuser tee "$defs/00-root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 CopyFiles=/
 EOF
 
-    cat >"$defs/10-usr.conf" <<EOF
+    runas testuser tee "$defs/10-usr.conf" <<EOF
 [Partition]
 Type=usr-${architecture}
 CopyFiles=/usr:/
@@ -906,7 +906,7 @@ test_minimize() {
             continue
         fi
 
-        cat >"$defs/root-$format.conf" <<EOF
+        tee "$defs/root-$format.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 Format=${format}
@@ -916,7 +916,7 @@ EOF
     done
 
     if ! command -v mksquashfs >/dev/null; then
-        cat >"$defs/root-squashfs.conf" <<EOF
+        tee "$defs/root-squashfs.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 Format=squashfs
@@ -955,19 +955,19 @@ test_sector() {
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
 
-    cat > "$defs/a.conf" <<EOF
+    tee "$defs/a.conf" <<EOF
 [Partition]
 Type=root
 SizeMaxBytes=15M
 SizeMinBytes=15M
 EOF
-    cat > "$defs/b.conf" <<EOF
+    tee "$defs/b.conf" <<EOF
 [Partition]
 Type=linux-generic
 Weight=250
 EOF
 
-    cat > "$defs/c.conf" <<EOF
+    tee "$defs/c.conf" <<EOF
 [Partition]
 Type=linux-generic
 Weight=750