54 lines · cpp
1// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s2 3// The test models how sandbox2 unshares user namespace after clone:4// https://github.com/google/sandboxed-api/blob/c95837a6c131fbdf820db352a97d54fcbcbde6c0/sandboxed_api/sandbox2/forkserver.cc#L2495// which works only in single-threaded processes.6 7#include "../test.h"8#include <errno.h>9#include <sched.h>10#include <sys/types.h>11#include <sys/wait.h>12#ifdef __linux__13# include <linux/version.h>14#endif15 16#if __PPC64__ && RHEL_MAJOR == 7 && RHEL_MINOR == 917# define PPC64_RHEL7_9 118#endif19 20#ifndef PPC64_RHEL7_921static int cloned(void *arg) {22 // Unshare can fail for other reasons, e.g. no permissions,23 // so check only the error we are interested in:24 // if the process is multi-threaded unshare must return EINVAL.25 if (unshare(CLONE_NEWUSER) && errno == EINVAL) {26 fprintf(stderr, "unshare failed: %d\n", errno);27 exit(1);28 }29 exit(0);30 return 0;31}32#endif33 34int main() {35#ifndef PPC64_RHEL7_936 char stack[64 << 10] __attribute__((aligned(64)));37 int pid = clone(cloned, stack + sizeof(stack), SIGCHLD, 0);38 if (pid == -1) {39 fprintf(stderr, "failed to clone: %d\n", errno);40 exit(1);41 }42 int status = 0;43 while (wait(&status) != pid) {44 }45 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {46 fprintf(stderr, "child failed: %d\n", status);47 exit(1);48 }49#endif50 fprintf(stderr, "DONE\n");51}52 53// CHECK: DONE54