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 * If a user ID has no mapping inside the namespace, user ID and group 17 * ID will be the value defined in the file /proc/sys/kernel/overflowuid(65534) 18 * and /proc/sys/kernel/overflowgid(65534). A child process has a full set 19 * of permitted and effective capabilities, even though the program was 20 * run from an unprivileged account. 21 */ 22 23#define _GNU_SOURCE 24#include <sys/wait.h> 25#include <assert.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <unistd.h> 29#include <string.h> 30#include <errno.h> 31#include "userns_helper.h" 32#include "test.h" 33#include "config.h" 34#if HAVE_SYS_CAPABILITY_H 35#include <sys/capability.h> 36#endif 37 38#define OVERFLOWUIDPATH "/proc/sys/kernel/overflowuid" 39#define OVERFLOWGIDPATH "/proc/sys/kernel/overflowgid" 40 41char *TCID = "user_namespace1"; 42int TST_TOTAL = 1; 43 44static long overflowuid; 45static long overflowgid; 46 47/* 48 * child_fn1() - Inside a new user namespace 49 */ 50static int child_fn1(void *arg LTP_ATTRIBUTE_UNUSED) 51{ 52 int exit_val = 0; 53 int uid, gid; 54#ifdef HAVE_LIBCAP 55 cap_t caps; 56 int i, last_cap; 57 cap_flag_value_t flag_val; 58#endif 59 60 uid = geteuid(); 61 gid = getegid(); 62 63 tst_resm(TINFO, "USERNS test is running in a new user namespace."); 64 65 if (uid != overflowuid || gid != overflowgid) { 66 printf("Got unexpected result of uid=%d gid=%d\n", uid, gid); 67 exit_val = 1; 68 } 69 70#ifdef HAVE_LIBCAP 71 caps = cap_get_proc(); 72 SAFE_FILE_SCANF(NULL, "/proc/sys/kernel/cap_last_cap", "%d", &last_cap); 73 for (i = 0; i <= last_cap; i++) { 74 cap_get_flag(caps, i, CAP_EFFECTIVE, &flag_val); 75 if (flag_val == 0) 76 break; 77 cap_get_flag(caps, i, CAP_PERMITTED, &flag_val); 78 if (flag_val == 0) 79 break; 80 } 81 82 if (flag_val == 0) { 83 printf("unexpected effective/permitted caps at %d\n", i); 84 exit_val = 1; 85 } 86#else 87 printf("System is missing libcap.\n"); 88#endif 89 return exit_val; 90} 91 92static void setup(void) 93{ 94 check_newuser(); 95 SAFE_FILE_SCANF(NULL, OVERFLOWUIDPATH, "%ld", &overflowuid); 96 SAFE_FILE_SCANF(NULL, OVERFLOWGIDPATH, "%ld", &overflowgid); 97} 98 99int main(int argc, char *argv[]) 100{ 101 int lc; 102 103 tst_parse_opts(argc, argv, NULL, NULL); 104 setup(); 105 106 for (lc = 0; TEST_LOOPING(lc); lc++) { 107 TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWUSER, 108 child_fn1, NULL)); 109 110 if (TEST_RETURN == -1) 111 tst_brkm(TFAIL | TTERRNO, NULL, "clone failed"); 112 tst_record_childstatus(NULL, -1); 113 } 114 tst_exit(); 115} 116