Merge pull request #26153 from DaanDeMeyer/repart-remove-userns

mkfs-util: Remove user namespace owner => root mapping
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2023-01-23 21:46:55 +01:00
committed by GitHub
4 changed files with 59 additions and 109 deletions
+2 -49
View 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);