1
0
mirror of https://github.com/systemd/systemd synced 2026-03-15 17:44:49 +01:00

Compare commits

..

No commits in common. "802babf38c0018ab03f2a13aef0f9fc2bc219fd8" and "a8b099d663e995fcea2490e6b132c953882b0649" have entirely different histories.

View File

@ -2394,14 +2394,7 @@ static int setup_private_users_child(int unshare_ready_fd, const char *uid_map,
return 0; return 0;
} }
static int setup_private_users( static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogid, uid_t uid, gid_t gid, bool allow_setgroups) {
PrivateUsers private_users,
uid_t ouid,
gid_t ogid,
uid_t uid,
gid_t gid,
bool allow_setgroups) {
_cleanup_free_ char *uid_map = NULL, *gid_map = NULL; _cleanup_free_ char *uid_map = NULL, *gid_map = NULL;
_cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR; _cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
_cleanup_close_ int unshare_ready_fd = -EBADF; _cleanup_close_ int unshare_ready_fd = -EBADF;
@ -2420,80 +2413,63 @@ static int setup_private_users(
* For unprivileged users (i.e. without capabilities), the root to root mapping is excluded. As such, it * For unprivileged users (i.e. without capabilities), the root to root mapping is excluded. As such, it
* does not need CAP_SETUID to write the single line mapping to itself. */ * does not need CAP_SETUID to write the single line mapping to itself. */
switch (private_users) { /* Prepare the UID mappings */ if (private_users == PRIVATE_USERS_NO)
return 0;
case PRIVATE_USERS_NO: if (private_users == PRIVATE_USERS_IDENTITY) {
return 0; /* Early exit */
case PRIVATE_USERS_IDENTITY:
uid_map = strdup("0 0 65536\n"); uid_map = strdup("0 0 65536\n");
if (!uid_map) if (!uid_map)
return -ENOMEM; return -ENOMEM;
break; } else if (private_users == PRIVATE_USERS_FULL) {
case PRIVATE_USERS_FULL:
/* Map all UID/GID from original to new user namespace. /* Map all UID/GID from original to new user namespace.
* *
* Note the kernel defines the UID range between 0 and UINT32_MAX so we map all UIDs even though * Note the kernel defines the UID range between 0 and UINT32_MAX so we map all UIDs even though
* the UID range beyond INT32_MAX (e.g. i.e. the range above the signed 32-bit range) is * the UID range beyond INT32_MAX (e.g. i.e. the range above the signed 32-bit range) is
* icky. For example, setfsuid() returns the old UID as signed integer. But units can decide to * icky. For example, setfsuid() returns the old UID as signed integer. But units can decide to
* use these UIDs/GIDs so we need to map them. */ * use these UIDs/GIDs so we need to map them. */
if (asprintf(&uid_map, "0 0 " UID_FMT "\n", (uid_t) UINT32_MAX) < 0) r = asprintf(&uid_map, "0 0 " UID_FMT "\n", (uid_t) UINT32_MAX);
if (r < 0)
return -ENOMEM; return -ENOMEM;
break;
case PRIVATE_USERS_SELF:
/* Can only set up multiple mappings with CAP_SETUID. */ /* Can only set up multiple mappings with CAP_SETUID. */
if (uid_is_valid(uid) && uid != ouid && have_effective_cap(CAP_SETUID) > 0) } else if (have_effective_cap(CAP_SETUID) > 0 && uid != ouid && uid_is_valid(uid)) {
r = asprintf(&uid_map, r = asprintf(&uid_map,
UID_FMT " " UID_FMT " 1\n" /* Map $OUID → $OUID */ UID_FMT " " UID_FMT " 1\n" /* Map $OUID → $OUID */
UID_FMT " " UID_FMT " 1\n", /* Map $UID → $UID */ UID_FMT " " UID_FMT " 1\n", /* Map $UID → $UID */
ouid, ouid, uid, uid); ouid, ouid, uid, uid);
else if (r < 0)
return -ENOMEM;
} else {
r = asprintf(&uid_map, r = asprintf(&uid_map,
UID_FMT " " UID_FMT " 1\n", /* Map $OUID → $OUID */ UID_FMT " " UID_FMT " 1\n", /* Map $OUID → $OUID */
ouid, ouid); ouid, ouid);
if (r < 0) if (r < 0)
return -ENOMEM; return -ENOMEM;
break;
default:
assert_not_reached();
} }
switch (private_users) { /* Prepare the GID mappings */ if (private_users == PRIVATE_USERS_IDENTITY) {
case PRIVATE_USERS_IDENTITY:
gid_map = strdup("0 0 65536\n"); gid_map = strdup("0 0 65536\n");
if (!gid_map) if (!gid_map)
return -ENOMEM; return -ENOMEM;
break; } else if (private_users == PRIVATE_USERS_FULL) {
r = asprintf(&gid_map, "0 0 " GID_FMT "\n", (gid_t) UINT32_MAX);
case PRIVATE_USERS_FULL: if (r < 0)
if (asprintf(&gid_map, "0 0 " GID_FMT "\n", (gid_t) UINT32_MAX) < 0)
return -ENOMEM; return -ENOMEM;
break;
case PRIVATE_USERS_SELF:
/* Can only set up multiple mappings with CAP_SETGID. */ /* Can only set up multiple mappings with CAP_SETGID. */
if (gid_is_valid(gid) && gid != ogid && have_effective_cap(CAP_SETGID) > 0) } else if (have_effective_cap(CAP_SETGID) > 0 && gid != ogid && gid_is_valid(gid)) {
r = asprintf(&gid_map, r = asprintf(&gid_map,
GID_FMT " " GID_FMT " 1\n" /* Map $OGID → $OGID */ GID_FMT " " GID_FMT " 1\n" /* Map $OGID → $OGID */
GID_FMT " " GID_FMT " 1\n", /* Map $GID → $GID */ GID_FMT " " GID_FMT " 1\n", /* Map $GID → $GID */
ogid, ogid, gid, gid); ogid, ogid, gid, gid);
else if (r < 0)
return -ENOMEM;
} else {
r = asprintf(&gid_map, r = asprintf(&gid_map,
GID_FMT " " GID_FMT " 1\n", /* Map $OGID -> $OGID */ GID_FMT " " GID_FMT " 1\n", /* Map $OGID -> $OGID */
ogid, ogid); ogid, ogid);
if (r < 0) if (r < 0)
return -ENOMEM; return -ENOMEM;
break;
default:
assert_not_reached();
} }
/* Create a communication channel so that the parent can tell the child when it finished creating the user /* Create a communication channel so that the parent can tell the child when it finished creating the user
@ -3859,12 +3835,13 @@ static int apply_mount_namespace(
if (asprintf(&private_namespace_dir, "/run/user/" UID_FMT "/systemd", geteuid()) < 0) if (asprintf(&private_namespace_dir, "/run/user/" UID_FMT "/systemd", geteuid()) < 0)
return -ENOMEM; return -ENOMEM;
if (setup_os_release_symlink && if (setup_os_release_symlink) {
asprintf(&host_os_release_stage, if (asprintf(&host_os_release_stage,
"/run/user/" UID_FMT "/systemd/propagate/.os-release-stage", "/run/user/" UID_FMT "/systemd/propagate/.os-release-stage",
geteuid()) < 0) geteuid()) < 0)
return -ENOMEM; return -ENOMEM;
} }
}
if (root_image) { if (root_image) {
r = verity_settings_prepare( r = verity_settings_prepare(