1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Huawei Technologies Co., Ltd., 2015
4 * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
5 */
6
7 /*\
8 * [Description]
9 *
10 * Verify that the user ID and group ID, which are inside a container,
11 * can be modified by its parent process.
12 */
13
14 #define _GNU_SOURCE
15
16 #include <stdio.h>
17 #include "common.h"
18 #include "tst_test.h"
19
20 /*
21 * child_fn1() - Inside a new user namespace
22 */
child_fn1(LTP_ATTRIBUTE_UNUSED void * arg)23 static int child_fn1(LTP_ATTRIBUTE_UNUSED void *arg)
24 {
25 int uid, gid;
26
27 TST_CHECKPOINT_WAIT(0);
28
29 uid = geteuid();
30 gid = getegid();
31
32 if (uid == 100 && gid == 100)
33 tst_res(TPASS, "got expected uid and gid");
34 else
35 tst_res(TFAIL, "got unexpected uid=%d gid=%d", uid, gid);
36
37 return 0;
38 }
39
setup(void)40 static void setup(void)
41 {
42 check_newuser();
43 }
44
run(void)45 static void run(void)
46 {
47 int childpid;
48 int parentuid;
49 int parentgid;
50 char path[BUFSIZ];
51
52 childpid = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, child_fn1, NULL);
53 if (childpid < 0)
54 tst_brk(TBROK | TTERRNO, "clone failed");
55
56 parentuid = geteuid();
57 parentgid = getegid();
58
59 sprintf(path, "/proc/%d/uid_map", childpid);
60 SAFE_FILE_PRINTF(path, "100 %d 1", parentuid);
61
62 if (access("/proc/self/setgroups", F_OK) == 0) {
63 sprintf(path, "/proc/%d/setgroups", childpid);
64 SAFE_FILE_PRINTF(path, "deny");
65 }
66
67 sprintf(path, "/proc/%d/gid_map", childpid);
68 SAFE_FILE_PRINTF(path, "100 %d 1", parentgid);
69
70 TST_CHECKPOINT_WAKE(0);
71 }
72
73 static struct tst_test test = {
74 .setup = setup,
75 .test_all = run,
76 .needs_root = 1,
77 .needs_checkpoints = 1,
78 .needs_kconfigs = (const char *[]) {
79 "CONFIG_USER_NS",
80 NULL,
81 },
82 };
83