}
int detach_mount_namespace_harder(uid_t target_uid, gid_t target_gid) {
+ uid_t from_uid;
+ gid_t from_gid;
int r;
/* Tried detach_mount_namespace() first. If that doesn't work due to permissions, opens up an
if (r != -EPERM)
return r;
+ from_uid = getuid();
+ from_gid = getgid();
+
if (unshare(CLONE_NEWUSER) < 0)
return log_debug_errno(errno, "Failed to acquire user namespace: %m");
r = write_string_filef("/proc/self/uid_map", 0,
- UID_FMT " " UID_FMT " 1\n", target_uid, getuid());
+ UID_FMT " " UID_FMT " 1\n", target_uid, from_uid);
if (r < 0)
return log_debug_errno(r, "Failed to write uid map: %m");
return log_debug_errno(r, "Failed to write setgroups file: %m");
r = write_string_filef("/proc/self/gid_map", 0,
- GID_FMT " " GID_FMT " 1\n", target_gid, getgid());
+ GID_FMT " " GID_FMT " 1\n", target_gid, from_gid);
if (r < 0)
return log_debug_errno(r, "Failed to write gid map: %m");
assert_se(wait_for_terminate_and_check("ns-kernellogs", pid, WAIT_LOG) == EXIT_SUCCESS);
}
+TEST(detach_mount_namespace_harder) {
+ _cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
+ _cleanup_close_pair_ int p[2] = EBADF_PAIR;
+ char x = 0;
+ int r;
+
+ ASSERT_OK_ERRNO(pipe2(p, O_CLOEXEC));
+
+ ASSERT_OK(r = pidref_safe_fork("(child)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_LOG, &pid));
+ if (r == 0) {
+ p[0] = safe_close(p[0]);
+
+ ASSERT_OK(detach_mount_namespace_harder(0, 0));
+
+ ASSERT_OK_EQ_ERRNO(write(p[1], &(const char[]) { 'x' }, 1), 1);
+ freeze();
+ }
+
+ p[1] = safe_close(p[1]);
+ ASSERT_OK_EQ_ERRNO(read(p[0], &x, 1), 1);
+ ASSERT_EQ(x, 'x');
+}
+
static int intro(void) {
if (!have_namespaces())
return log_tests_skipped("Don't have namespace support");