diff --git a/contrib/capsicum-test/capability-fd.cc b/contrib/capsicum-test/capability-fd.cc index 6c470cff3418..a454d54aa86a 100644 --- a/contrib/capsicum-test/capability-fd.cc +++ b/contrib/capsicum-test/capability-fd.cc @@ -1085,8 +1085,6 @@ TEST(Capability, SyscallAt) { cap_rights_init(&r_no_mkdir, CAP_READ, CAP_LOOKUP, CAP_UNLINKAT, CAP_MKFIFOAT); cap_rights_t r_no_mkfifo; cap_rights_init(&r_no_mkfifo, CAP_READ, CAP_LOOKUP, CAP_UNLINKAT, CAP_MKDIRAT); - cap_rights_t r_no_mknod; - cap_rights_init(&r_no_mknod, CAP_READ, CAP_LOOKUP, CAP_UNLINKAT, CAP_MKDIRAT); cap_rights_t r_create; cap_rights_init(&r_create, CAP_READ, CAP_LOOKUP, CAP_CREATE); cap_rights_t r_bind; @@ -1106,9 +1104,6 @@ TEST(Capability, SyscallAt) { int cap_dfd_no_mkfifo = dup(dfd); EXPECT_OK(cap_dfd_no_mkfifo); EXPECT_OK(cap_rights_limit(cap_dfd_no_mkfifo, &r_no_mkfifo)); - int cap_dfd_no_mknod = dup(dfd); - EXPECT_OK(cap_dfd_no_mknod); - EXPECT_OK(cap_rights_limit(cap_dfd_no_mknod, &r_no_mknod)); int cap_dfd_create = dup(dfd); EXPECT_OK(cap_dfd_create); EXPECT_OK(cap_rights_limit(cap_dfd_create, &r_create)); @@ -1148,24 +1143,7 @@ TEST(Capability, SyscallAt) { unlink(TmpFile("cap_at_topdir/cap_socket")); #endif - if (getuid() == 0) { - // Need CAP_MKNODAT to mknodat(2) a device - EXPECT_NOTCAPABLE(mknodat(cap_dfd_no_mknod, "cap_device", S_IFCHR|0755, makedev(99, 123))); - unlink(TmpFile("cap_at_topdir/cap_device")); - EXPECT_OK(mknodat(cap_dfd_all, "cap_device", S_IFCHR|0755, makedev(99, 123))); - unlink(TmpFile("cap_at_topdir/cap_device")); - - // Need CAP_MKFIFOAT to mknodat(2) for a FIFO. - EXPECT_NOTCAPABLE(mknodat(cap_dfd_no_mkfifo, "cap_fifo", S_IFIFO|0755, 0)); - unlink(TmpFile("cap_at_topdir/cap_fifo")); - EXPECT_OK(mknodat(cap_dfd_all, "cap_fifo", S_IFIFO|0755, 0)); - unlink(TmpFile("cap_at_topdir/cap_fifo")); - } else { - TEST_SKIPPED("requires root (partial)"); - } - close(cap_dfd_all); - close(cap_dfd_no_mknod); close(cap_dfd_no_mkfifo); close(cap_dfd_no_mkdir); close(cap_dfd_no_unlink); @@ -1177,7 +1155,53 @@ TEST(Capability, SyscallAt) { rmdir(TmpFile("cap_at_topdir")); } -FORK_TEST_ON(Capability, ExtendedAttributes, TmpFile("cap_extattr")) { +TEST(Capability, SyscallAtIfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); + int rc = mkdir(TmpFile("cap_at_topdir"), 0755); + EXPECT_OK(rc); + if (rc < 0 && errno != EEXIST) return; + + cap_rights_t r_all; + cap_rights_init(&r_all, CAP_READ, CAP_LOOKUP, CAP_MKNODAT, CAP_UNLINKAT, CAP_MKDIRAT, CAP_MKFIFOAT); + cap_rights_t r_no_mkfifo; + cap_rights_init(&r_no_mkfifo, CAP_READ, CAP_LOOKUP, CAP_UNLINKAT, CAP_MKDIRAT); + cap_rights_t r_no_mknod; + cap_rights_init(&r_no_mknod, CAP_READ, CAP_LOOKUP, CAP_UNLINKAT, CAP_MKDIRAT); + + int dfd = open(TmpFile("cap_at_topdir"), O_RDONLY); + EXPECT_OK(dfd); + int cap_dfd_all = dup(dfd); + EXPECT_OK(cap_dfd_all); + EXPECT_OK(cap_rights_limit(cap_dfd_all, &r_all)); + int cap_dfd_no_mkfifo = dup(dfd); + EXPECT_OK(cap_dfd_no_mkfifo); + EXPECT_OK(cap_rights_limit(cap_dfd_no_mkfifo, &r_no_mkfifo)); + int cap_dfd_no_mknod = dup(dfd); + EXPECT_OK(cap_dfd_no_mknod); + EXPECT_OK(cap_rights_limit(cap_dfd_no_mknod, &r_no_mknod)); + + // Need CAP_MKNODAT to mknodat(2) a device + EXPECT_NOTCAPABLE(mknodat(cap_dfd_no_mknod, "cap_device", S_IFCHR|0755, makedev(99, 123))); + unlink(TmpFile("cap_at_topdir/cap_device")); + EXPECT_OK(mknodat(cap_dfd_all, "cap_device", S_IFCHR|0755, makedev(99, 123))); + unlink(TmpFile("cap_at_topdir/cap_device")); + + // Need CAP_MKFIFOAT to mknodat(2) for a FIFO. + EXPECT_NOTCAPABLE(mknodat(cap_dfd_no_mkfifo, "cap_fifo", S_IFIFO|0755, 0)); + unlink(TmpFile("cap_at_topdir/cap_fifo")); + EXPECT_OK(mknodat(cap_dfd_all, "cap_fifo", S_IFIFO|0755, 0)); + unlink(TmpFile("cap_at_topdir/cap_fifo")); + + close(cap_dfd_all); + close(cap_dfd_no_mknod); + close(cap_dfd_no_mkfifo); + close(dfd); + + // Tidy up. + rmdir(TmpFile("cap_at_topdir")); +} + +FORK_TEST_ON(Capability, ExtendedAttributesIfAvailable, TmpFile("cap_extattr")) { int fd = open(TmpFile("cap_extattr"), O_RDONLY|O_CREAT, 0644); EXPECT_OK(fd); @@ -1185,9 +1209,8 @@ FORK_TEST_ON(Capability, ExtendedAttributes, TmpFile("cap_extattr")) { int rc = fgetxattr_(fd, "user.capsicumtest", buffer, sizeof(buffer)); if (rc < 0 && errno == ENOTSUP) { // Need user_xattr mount option for non-root users on Linux - TEST_SKIPPED("/tmp doesn't support extended attributes"); close(fd); - return; + GTEST_SKIP() << "/tmp doesn't support extended attributes"; } cap_rights_t r_rws; @@ -1278,8 +1301,8 @@ TEST(Capability, PipeUnseekable) { close(fds[1]); } -TEST(Capability, NoBypassDAC) { - REQUIRE_ROOT(); +TEST(Capability, NoBypassDACIfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); int fd = open(TmpFile("cap_root_owned"), O_RDONLY|O_CREAT, 0644); EXPECT_OK(fd); cap_rights_t rights; @@ -1289,7 +1312,10 @@ TEST(Capability, NoBypassDAC) { pid_t child = fork(); if (child == 0) { // Child: change uid to a lesser being - setuid(other_uid); + ASSERT_NE(0u, other_uid) << "other_uid not initialized correctly, " + "please pass the -u flag."; + EXPECT_EQ(0, setuid(other_uid)); + EXPECT_EQ(other_uid, getuid()); // Attempt to fchmod the file, and fail. // Having CAP_FCHMOD doesn't bypass the need to comply with DAC policy. int rc = fchmod(fd, 0666); diff --git a/contrib/capsicum-test/capsicum-test-main.cc b/contrib/capsicum-test/capsicum-test-main.cc index 524631ebf5bd..d0f955270fd4 100644 --- a/contrib/capsicum-test/capsicum-test-main.cc +++ b/contrib/capsicum-test/capsicum-test-main.cc @@ -84,24 +84,30 @@ private: std::string capsicum_test_bindir; +// Adds a directory to $PATH. +static void AddDirectoryToPath(const char *dir) { + char *new_path, *old_path; + + old_path = getenv("PATH"); + assert(old_path); + + assert(asprintf(&new_path, "%s:%s", dir, old_path) > 0); + assert(setenv("PATH", new_path, 1) == 0); +} + int main(int argc, char* argv[]) { // Set up the test program path, so capsicum-test can find programs, like // mini-me* when executed from an absolute path. - { - char *new_path, *old_path, *program_name; + char *program_name; - program_name = strdup(argv[0]); - assert(program_name); - capsicum_test_bindir = std::string(dirname(program_name)); - free(program_name); + // Copy argv[0], so dirname can do an in-place manipulation of the buffer's + // contents. + program_name = strdup(argv[0]); + assert(program_name); + capsicum_test_bindir = std::string(dirname(program_name)); + free(program_name); - old_path = getenv("PATH"); - assert(old_path); - - assert(asprintf(&new_path, "%s:%s", capsicum_test_bindir.c_str(), - old_path) > 0); - assert(setenv("PATH", new_path, 1) == 0); - } + AddDirectoryToPath(capsicum_test_bindir.c_str()); ::testing::InitGoogleTest(&argc, argv); for (int ii = 1; ii < argc; ii++) { @@ -150,7 +156,5 @@ int main(int argc, char* argv[]) { #endif testing::AddGlobalTestEnvironment(new SetupEnvironment()); - int rc = RUN_ALL_TESTS(); - ShowSkippedTests(std::cerr); - return rc; + return RUN_ALL_TESTS(); } diff --git a/contrib/capsicum-test/capsicum-test.cc b/contrib/capsicum-test/capsicum-test.cc index 24b096ed877c..6adb222ec055 100644 --- a/contrib/capsicum-test/capsicum-test.cc +++ b/contrib/capsicum-test/capsicum-test.cc @@ -76,27 +76,3 @@ char ProcessState(int pid) { } #endif } - -typedef std::vector TestList; -typedef std::map SkippedTestMap; -static SkippedTestMap skipped_tests; -void TestSkipped(const char *testcase, const char *test, const std::string& reason) { - if (skipped_tests.find(reason) == skipped_tests.end()) { - skipped_tests[reason] = new TestList; - } - std::string testname(testcase); - testname += "."; - testname += test; - skipped_tests[reason]->push_back(testname); -} - -void ShowSkippedTests(std::ostream& os) { - for (SkippedTestMap::iterator skiplist = skipped_tests.begin(); - skiplist != skipped_tests.end(); ++skiplist) { - os << "Following tests were skipped because: " << skiplist->first << std::endl; - for (size_t ii = 0; ii < skiplist->second->size(); ++ii) { - const std::string& testname((*skiplist->second)[ii]); - os << " " << testname << std::endl; - } - } -} diff --git a/contrib/capsicum-test/capsicum-test.h b/contrib/capsicum-test/capsicum-test.h index 821100c48167..808840f4280e 100644 --- a/contrib/capsicum-test/capsicum-test.h +++ b/contrib/capsicum-test/capsicum-test.h @@ -10,6 +10,7 @@ #include #include +#include #include "gtest/gtest.h" @@ -75,7 +76,7 @@ const char *TmpFile(const char *pathname); } \ } else if (pid > 0) { \ int rc, status; \ - int remaining_us = 10000000; \ + int remaining_us = 30000000; \ while (remaining_us > 0) { \ status = 0; \ rc = waitpid(pid, &status, WNOHANG); \ @@ -169,12 +170,14 @@ const char *TmpFile(const char *pathname); } else { \ EXPECT_SYSCALL_FAIL(E_NO_TRAVERSE_CAPABILITY, result); \ } \ + if (result >= 0) { close(result); } \ } while (0) #else #define EXPECT_OPENAT_FAIL_TRAVERSAL(fd, path, flags) \ do { \ const int result = openat((fd), (path), (flags)); \ EXPECT_SYSCALL_FAIL(E_NO_TRAVERSE_CAPABILITY, result); \ + if (result >= 0) { close(result); } \ } while (0) #endif @@ -241,21 +244,10 @@ char ProcessState(int pid); #define EXPECT_PID_ZOMBIE(pid) EXPECT_PID_REACHES_STATES(pid, 'Z', 'Z'); #define EXPECT_PID_GONE(pid) EXPECT_PID_REACHES_STATES(pid, '\0', '\0'); -void ShowSkippedTests(std::ostream& os); -void TestSkipped(const char *testcase, const char *test, const std::string& reason); -#define TEST_SKIPPED(reason) \ - do { \ - const ::testing::TestInfo* const info = ::testing::UnitTest::GetInstance()->current_test_info(); \ - std::cerr << "Skipping " << info->test_case_name() << "::" << info->name() << " because: " << reason << std::endl; \ - TestSkipped(info->test_case_name(), info->name(), reason); \ - GTEST_SKIP(); \ - } while (0) - // Mark a test that can only be run as root. -#define REQUIRE_ROOT() \ - if (getuid() != 0) { \ - TEST_SKIPPED("requires root"); \ - return; \ - } +#define GTEST_SKIP_IF_NOT_ROOT() \ + if (getuid() != 0) { GTEST_SKIP() << "requires root"; } + +extern std::string capsicum_test_bindir; #endif // CAPSICUM_TEST_H diff --git a/contrib/capsicum-test/fexecve.cc b/contrib/capsicum-test/fexecve.cc index 2212e9fd955e..86df2af06388 100644 --- a/contrib/capsicum-test/fexecve.cc +++ b/contrib/capsicum-test/fexecve.cc @@ -1,6 +1,6 @@ #include -#include #include +#include #include #include #include @@ -126,10 +126,9 @@ FORK_TEST_F(Fexecve, ExecutePermissionCheck) { } } -FORK_TEST_F(Fexecve, SetuidIgnored) { +FORK_TEST_F(Fexecve, SetuidIgnoredIfNonRoot) { if (geteuid() == 0) { - TEST_SKIPPED("requires non-root"); - return; + GTEST_SKIP() << "requires non-root"; } int fd = open(exec_prog_setuid_.c_str(), O_RDONLY); EXPECT_OK(fd); @@ -173,7 +172,7 @@ class Execveat : public Execve { }; TEST_F(Execveat, NoUpwardTraversal) { - char *abspath = realpath(exec_prog_, NULL); + char *abspath = realpath(exec_prog_.c_str(), NULL); char cwd[1024]; getcwd(cwd, sizeof(cwd)); @@ -193,7 +192,7 @@ TEST_F(Execveat, NoUpwardTraversal) { char buffer[1024] = "../"; strcat(buffer, ++p); strcat(buffer, "/"); - strcat(buffer, exec_prog_); + strcat(buffer, exec_prog_.c_str()); EXPECT_SYSCALL_FAIL(E_NO_TRAVERSE_CAPABILITY, execveat(dfd, buffer, argv_pass_, null_envp, 0)); exit(HasFailure() ? 99 : 123); diff --git a/contrib/capsicum-test/linux.cc b/contrib/capsicum-test/linux.cc index dee1f99897f6..81ba06c5e588 100644 --- a/contrib/capsicum-test/linux.cc +++ b/contrib/capsicum-test/linux.cc @@ -104,10 +104,9 @@ TEST(Linux, TimerFD) { close(fd); } -FORK_TEST(Linux, SignalFD) { +FORK_TEST(Linux, SignalFDIfSingleThreaded) { if (force_mt) { - TEST_SKIPPED("multi-threaded run clashes with signals"); - return; + GTEST_SKIP() << "multi-threaded run clashes with signals"; } pid_t me = getpid(); sigset_t mask; @@ -372,8 +371,8 @@ TEST(Linux, fstatat) { // fanotify support may not be available at compile-time #ifdef __NR_fanotify_init -TEST(Linux, fanotify) { - REQUIRE_ROOT(); +TEST(Linux, FanotifyIfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); int fa_fd = fanotify_init(FAN_CLASS_NOTIF, O_RDWR); EXPECT_OK(fa_fd); if (fa_fd < 0) return; // May not be enabled @@ -577,7 +576,7 @@ TEST(Linux, inotify) { unlink(TmpFile("cap_inotify")); } -TEST(Linux, ArchChange) { +TEST(Linux, ArchChangeIfAvailable) { const char* prog_candidates[] = {"./mini-me.32", "./mini-me.x32", "./mini-me.64"}; const char* progs[] = {NULL, NULL, NULL}; char* argv_pass[] = {(char*)"to-come", (char*)"--capmode", NULL}; @@ -593,8 +592,7 @@ TEST(Linux, ArchChange) { } } if (count == 0) { - TEST_SKIPPED("no different-architecture programs available"); - return; + GTEST_SKIP() << "no different-architecture programs available"; } for (int ii = 0; ii < count; ii++) { @@ -617,8 +615,8 @@ TEST(Linux, ArchChange) { } } -FORK_TEST(Linux, Namespace) { - REQUIRE_ROOT(); +FORK_TEST(Linux, NamespaceIfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); pid_t me = getpid_(); // Create a new UTS namespace. @@ -758,9 +756,9 @@ static int ChildFunc(void *arg) { #define STACK_SIZE (1024 * 1024) static char child_stack[STACK_SIZE]; -// TODO(drysdale): fork into a user namespace first so REQUIRE_ROOT can be removed. -TEST(Linux, PidNamespacePdFork) { - REQUIRE_ROOT(); +// TODO(drysdale): fork into a user namespace first so GTEST_SKIP_IF_NOT_ROOT can be removed. +TEST(Linux, PidNamespacePdForkIfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); // Pass process descriptors in both directions across a PID namespace boundary. // pdfork() off a child before we start, holding its process descriptor in a global // variable that's accessible to children. @@ -871,8 +869,8 @@ int NSInit(void *data) { return 0; } -TEST(Linux, DeadNSInit) { - REQUIRE_ROOT(); +TEST(Linux, DeadNSInitIfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); // Prepare sockets to communicate with child process. EXPECT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, shared_sock_fds)); @@ -916,8 +914,8 @@ TEST(Linux, DeadNSInit) { } } -TEST(Linux, DeadNSInit2) { - REQUIRE_ROOT(); +TEST(Linux, DeadNSInit2IfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); // Prepare sockets to communicate with child process. EXPECT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, shared_sock_fds)); @@ -1188,7 +1186,7 @@ TEST(Linux, AIO) { #ifndef KCMP_FILE #define KCMP_FILE 0 #endif -TEST(Linux, Kcmp) { +TEST(Linux, KcmpIfAvailable) { // This requires CONFIG_CHECKPOINT_RESTORE in kernel config. int fd = open("/etc/passwd", O_RDONLY); EXPECT_OK(fd); @@ -1197,8 +1195,7 @@ TEST(Linux, Kcmp) { errno = 0; int rc = syscall(__NR_kcmp, parent, parent, KCMP_FILE, fd, fd); if (rc == -1 && errno == ENOSYS) { - TEST_SKIPPED("kcmp(2) gives -ENOSYS"); - return; + GTEST_SKIP() << "kcmp(2) gives -ENOSYS"; } pid_t child = fork(); @@ -1362,8 +1359,8 @@ TEST(Linux, InvalidRightsSyscall) { unlink(TmpFile("cap_invalid_rights")); } -FORK_TEST_ON(Linux, OpenByHandleAt, TmpFile("cap_openbyhandle_testfile")) { - REQUIRE_ROOT(); +FORK_TEST_ON(Linux, OpenByHandleAtIfRoot, TmpFile("cap_openbyhandle_testfile")) { + GTEST_SKIP_IF_NOT_ROOT(); int dir = open(tmpdir.c_str(), O_RDONLY); EXPECT_OK(dir); int fd = openat(dir, "cap_openbyhandle_testfile", O_RDWR|O_CREAT, 0644); @@ -1380,8 +1377,9 @@ FORK_TEST_ON(Linux, OpenByHandleAt, TmpFile("cap_openbyhandle_testfile")) { fd = open_by_handle_at(dir, fhandle, O_RDONLY); EXPECT_OK(fd); char buffer[200]; - EXPECT_OK(read(fd, buffer, 199)); - EXPECT_EQ(std::string(message), std::string(buffer)); + ssize_t len = read(fd, buffer, 199); + EXPECT_OK(len); + EXPECT_EQ(std::string(message), std::string(buffer, len)); close(fd); // Cannot issue open_by_handle_at after entering capability mode. @@ -1423,11 +1421,10 @@ int memfd_create_(const char *name, unsigned int flags) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) #include // Requires 3.17 kernel -TEST(Linux, MemFDDeathTest) { +TEST(Linux, MemFDDeathTestIfAvailable) { int memfd = memfd_create_("capsicum-test", MFD_ALLOW_SEALING); if (memfd == -1 && errno == ENOSYS) { - TEST_SKIPPED("memfd_create(2) gives -ENOSYS"); - return; + GTEST_SKIP() << "memfd_create(2) gives -ENOSYS"; } const int LEN = 16; EXPECT_OK(ftruncate(memfd, LEN)); diff --git a/contrib/capsicum-test/makefile b/contrib/capsicum-test/makefile index c92caeb3bc10..7b95e1927927 100644 --- a/contrib/capsicum-test/makefile +++ b/contrib/capsicum-test/makefile @@ -1,7 +1,7 @@ all: capsicum-test smoketest mini-me mini-me.noexec mini-me.setuid $(EXTRA_PROGS) OBJECTS=capsicum-test-main.o capsicum-test.o capability-fd.o fexecve.o procdesc.o capmode.o fcntl.o ioctl.o openat.o sysctl.o select.o mqueue.o socket.o sctp.o capability-fd-pair.o linux.o overhead.o rename.o -GTEST_DIR=gtest-1.8.1 +GTEST_DIR=gtest-1.10.0 GTEST_INCS=-I$(GTEST_DIR)/include -I$(GTEST_DIR) GTEST_FLAGS=-DGTEST_USE_OWN_TR1_TUPLE=1 -DGTEST_HAS_TR1_TUPLE=1 CXXFLAGS+=$(ARCHFLAG) -Wall -g $(GTEST_INCS) $(GTEST_FLAGS) --std=c++11 @@ -28,7 +28,7 @@ smoketest: $(SMOKETEST_OBJECTS) $(LOCAL_LIBS) test: capsicum-test mini-me mini-me.noexec mini-me.setuid $(EXTRA_PROGS) ./capsicum-test gtest-all.o: - $(CXX) $(ARCHFLAG) -I$(GTEST_DIR)/include -I$(GTEST_DIR) $(GTEST_FLAGS) -c ${GTEST_DIR}/src/gtest-all.cc + $(CXX) $(CXXFLAGS) $(ARCHFLAG) -I$(GTEST_DIR)/include -I$(GTEST_DIR) $(GTEST_FLAGS) -c ${GTEST_DIR}/src/gtest-all.cc libgtest.a: gtest-all.o $(AR) -rv libgtest.a gtest-all.o diff --git a/contrib/capsicum-test/mqueue.cc b/contrib/capsicum-test/mqueue.cc index 42478c760020..f2f3daeb1db8 100644 --- a/contrib/capsicum-test/mqueue.cc +++ b/contrib/capsicum-test/mqueue.cc @@ -28,14 +28,13 @@ void seen_it_done_it(int) { invoked = true; } -FORK_TEST_ON_MQ(PosixMqueue, CapMode, "/cap_mq") { +FORK_TEST_ON_MQ(PosixMqueue, CapModeIfMqOpenAvailable, "/cap_mq") { int mq = mq_open_("/cap_mq", O_RDWR|O_CREAT, 0644, NULL); // On FreeBSD, turn on message queue support with: // - 'kldload mqueuefs' // - 'options P1003_1B_MQUEUE' in kernel build config. if (mq < 0 && errno == ENOSYS) { - TEST_SKIPPED("mq_open -> -ENOSYS"); - return; + GTEST_SKIP() << "mq_open -> -ENOSYS"; } EXPECT_OK(mq); cap_rights_t r_read; diff --git a/contrib/capsicum-test/procdesc.cc b/contrib/capsicum-test/procdesc.cc index 94c0dc5d774d..11274ce9e866 100644 --- a/contrib/capsicum-test/procdesc.cc +++ b/contrib/capsicum-test/procdesc.cc @@ -519,8 +519,8 @@ TEST_F(PipePdfork, CloseLast) { signal(SIGCHLD, original); } -FORK_TEST(Pdfork, OtherUser) { - REQUIRE_ROOT(); +FORK_TEST(Pdfork, OtherUserIfRoot) { + GTEST_SKIP_IF_NOT_ROOT(); int pd; pid_t pid = pdfork(&pd, 0); EXPECT_OK(pid); @@ -531,7 +531,10 @@ FORK_TEST(Pdfork, OtherUser) { usleep(100); // Now that the second process has been pdfork()ed, change euid. - setuid(other_uid); + ASSERT_NE(0u, other_uid) << "other_uid not initialized correctly, " + "please pass the -u flag."; + EXPECT_EQ(0, setuid(other_uid)); + EXPECT_EQ(other_uid, getuid()); if (verbose) fprintf(stderr, "uid=%d euid=%d\n", getuid(), geteuid()); // Fail to kill child with normal PID operation.