summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux
diff options
context:
space:
mode:
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r--test/syscalls/linux/BUILD2
-rw-r--r--test/syscalls/linux/fork.cc31
2 files changed, 33 insertions, 0 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD
index 3c61c48ef..e7f5ea998 100644
--- a/test/syscalls/linux/BUILD
+++ b/test/syscalls/linux/BUILD
@@ -732,7 +732,9 @@ cc_binary(
srcs = ["fork.cc"],
linkstatic = 1,
deps = [
+ "//test/util:capability_util",
"//test/util:logging",
+ "//test/util:memory_util",
"//test/util:test_main",
"//test/util:test_util",
"//test/util:thread_util",
diff --git a/test/syscalls/linux/fork.cc b/test/syscalls/linux/fork.cc
index 1bff5e50f..73ac885b5 100644
--- a/test/syscalls/linux/fork.cc
+++ b/test/syscalls/linux/fork.cc
@@ -21,11 +21,14 @@
#include <sys/types.h>
#include <unistd.h>
#include <atomic>
+#include <cstdlib>
#include "gtest/gtest.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
+#include "test/util/capability_util.h"
#include "test/util/logging.h"
+#include "test/util/memory_util.h"
#include "test/util/test_util.h"
#include "test/util/thread_util.h"
@@ -393,6 +396,34 @@ TEST_F(ForkTest, Affinity) {
EXPECT_THAT(Wait(child), SyscallSucceedsWithValue(0));
}
+TEST(CloneTest, NewUserNamespacePermitsAllOtherNamespaces) {
+ // "If CLONE_NEWUSER is specified along with other CLONE_NEW* flags in a
+ // single clone(2) or unshare(2) call, the user namespace is guaranteed to be
+ // created first, giving the child (clone(2)) or caller (unshare(2))
+ // privileges over the remaining namespaces created by the call. Thus, it is
+ // possible for an unprivileged caller to specify this combination of flags."
+ // - user_namespaces(7)
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanCreateUserNamespace()));
+ Mapping child_stack = ASSERT_NO_ERRNO_AND_VALUE(
+ MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE));
+ int child_pid;
+ // We only test with CLONE_NEWIPC, CLONE_NEWNET, and CLONE_NEWUTS since these
+ // namespaces were implemented in Linux before user namespaces.
+ ASSERT_THAT(
+ child_pid = clone(
+ +[](void*) { return 0; },
+ reinterpret_cast<void*>(child_stack.addr() + kPageSize),
+ CLONE_NEWUSER | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWUTS | SIGCHLD,
+ /* arg = */ nullptr),
+ SyscallSucceeds());
+
+ int status;
+ ASSERT_THAT(waitpid(child_pid, &status, 0),
+ SyscallSucceedsWithValue(child_pid));
+ EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
+ << "status = " << status;
+}
+
#ifdef __x86_64__
// Clone with CLONE_SETTLS and a non-canonical TLS address is rejected.
TEST(CloneTest, NonCanonicalTLS) {