1 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s 2 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#L249 5 // which works only in sigle-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 13 static int cloned(void *arg) { 14 // Unshare can fail for other reasons, e.g. no permissions, 15 // so check only the error we are interested in: 16 // if the process is multi-threaded unshare must return EINVAL. 17 if (unshare(CLONE_NEWUSER) && errno == EINVAL) { 18 fprintf(stderr, "unshare failed: %d\n", errno); 19 exit(1); 20 } 21 exit(0); 22 return 0; 23 } 24 25 int main() { 26 char stack[64 << 10] __attribute__((aligned(64))); 27 int pid = clone(cloned, stack + sizeof(stack), SIGCHLD, 0); 28 if (pid == -1) { 29 fprintf(stderr, "failed to clone: %d\n", errno); 30 exit(1); 31 } 32 int status = 0; 33 while (wait(&status) != pid) { 34 } 35 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 36 fprintf(stderr, "child failed: %d\n", status); 37 exit(1); 38 } 39 fprintf(stderr, "DONE\n"); 40 } 41 42 // CHECK: DONE 43