1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd., 2015 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation; either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 11 * the GNU General Public License for more details. 12 */ 13 14 /* 15 * Verify that: 16 * The user ID and group ID, which are inside a container, can be modified 17 * by its parent process. 18 */ 19 20 #define _GNU_SOURCE 21 #include <sys/wait.h> 22 #include <assert.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <unistd.h> 26 #include <string.h> 27 #include <errno.h> 28 #include "userns_helper.h" 29 #include "test.h" 30 31 char *TCID = "user_namespace2"; 32 int TST_TOTAL = 1; 33 34 static void cleanup(void) 35 { 36 tst_rmdir(); 37 } 38 39 /* 40 * child_fn1() - Inside a new user namespace 41 */ 42 static int child_fn1(void) 43 { 44 int exit_val; 45 int uid, gid; 46 47 TST_SAFE_CHECKPOINT_WAIT(NULL, 0); 48 uid = geteuid(); 49 gid = getegid(); 50 51 if (uid == 100 && gid == 100) { 52 printf("Got expected uid and gid.\n"); 53 exit_val = 0; 54 } else { 55 printf("Got unexpected result of uid=%d gid=%d\n", uid, gid); 56 exit_val = 1; 57 } 58 59 return exit_val; 60 } 61 62 static void setup(void) 63 { 64 check_newuser(); 65 tst_tmpdir(); 66 TST_CHECKPOINT_INIT(NULL); 67 } 68 69 int main(int argc, char *argv[]) 70 { 71 int lc; 72 int childpid; 73 int parentuid; 74 int parentgid; 75 char path[BUFSIZ]; 76 char content[BUFSIZ]; 77 int fd; 78 79 tst_parse_opts(argc, argv, NULL, NULL); 80 setup(); 81 82 for (lc = 0; TEST_LOOPING(lc); lc++) { 83 tst_count = 0; 84 childpid = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, 85 (void *)child_fn1, NULL); 86 87 if (childpid < 0) 88 tst_brkm(TFAIL | TERRNO, cleanup, "clone failed"); 89 90 parentuid = geteuid(); 91 parentgid = getegid(); 92 sprintf(path, "/proc/%d/uid_map", childpid); 93 sprintf(content, "100 %d 1", parentuid); 94 fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); 95 SAFE_WRITE(cleanup, 1, fd, content, strlen(content)); 96 SAFE_CLOSE(cleanup, fd); 97 98 if (access("/proc/self/setgroups", F_OK) == 0) { 99 sprintf(path, "/proc/%d/setgroups", childpid); 100 fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); 101 SAFE_WRITE(cleanup, 1, fd, "deny", 4); 102 SAFE_CLOSE(cleanup, fd); 103 } 104 105 sprintf(path, "/proc/%d/gid_map", childpid); 106 sprintf(content, "100 %d 1", parentgid); 107 fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); 108 SAFE_WRITE(cleanup, 1, fd, content, strlen(content)); 109 SAFE_CLOSE(cleanup, fd); 110 111 TST_SAFE_CHECKPOINT_WAKE(cleanup, 0); 112 113 tst_record_childstatus(cleanup, childpid); 114 } 115 cleanup(); 116 tst_exit(); 117 } 118