]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pull-tar: Insist on foreign UID when copying
authorDaanDeMeyer <daan.j.demeyer@gmail.com>
Fri, 26 Dec 2025 20:58:04 +0000 (21:58 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 2 Jan 2026 14:21:53 +0000 (15:21 +0100)
If we're doing foreign UID range copying, we're going to be joining
a private user namespace before doing the copy. copy_tree() insists
on keeping all UIDs/GIDs the same when copying. Hence, all the
UIDs/GIDs of the files we're copying should be in the private UID
range, which means they need to be owned by the foreign UID range
and we always need to call mountfsd_mount_directory_fd(). So there's
no point in having a fallback path if the source directory is not
foreign UID range owned, we'd simply fail to copy it later. Hence,
insist on the source directory being foreign UID range owned.

src/import/pull-tar.c

index 25b07b1192f382c22f8734825628c604f4dc7380..5171f8e2dfbebc714bd29b2a6fa5eea640de2d6a 100644 (file)
@@ -288,12 +288,15 @@ static int tar_pull_make_local_copy(TarPull *p) {
                                 if (fstat(directory_fd, &st) < 0)
                                         return log_error_errno(errno, "Failed to stat '%s': %m", p->final_path);
 
-                                if (uid_is_foreign(st.st_uid)) {
-                                        r = mountfsd_mount_directory_fd(directory_fd, p->userns_fd, DISSECT_IMAGE_FOREIGN_UID, &p->tree_fd);
-                                        if (r < 0)
-                                                return r;
-                                } else
-                                        p->tree_fd = TAKE_FD(directory_fd);
+                                if (!uid_is_foreign(st.st_uid))
+                                        return log_error_errno(
+                                                        SYNTHETIC_ERRNO(EINVAL),
+                                                        "Image tree '%s' is not owned by the foreign UID range, refusing.",
+                                                        p->final_path);
+
+                                r = mountfsd_mount_directory_fd(directory_fd, p->userns_fd, DISSECT_IMAGE_FOREIGN_UID, &p->tree_fd);
+                                if (r < 0)
+                                        return r;
                         }
 
                         _cleanup_close_ int directory_fd = -EBADF;