1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) International Business Machines Corp., 2009
4 * Copyright (c) Nadia Derbey, 2009 <[email protected]>
5 * Copyright (C) 2023 SUSE LLC Andrea Cervesato <[email protected]>
6 */
7
8 /*\
9 * [Description]
10 *
11 * Create a mqueue inside the parent and check if it can be accessed from
12 * the child namespace. Isolated and unshared process can't access to parent,
13 * but plain process can.
14 */
15
16 #include "tst_test.h"
17 #include "lapi/sched.h"
18 #include "tst_safe_posix_ipc.h"
19
20 #define MQNAME "/MQ1"
21
22 static mqd_t mqd;
23 static char *str_op;
24
run(void)25 static void run(void)
26 {
27 const struct tst_clone_args clone_args = {
28 .flags = CLONE_NEWIPC,
29 .exit_signal = SIGCHLD,
30 };
31
32 tst_res(TINFO, "Checking namespaces isolation from parent to child");
33
34 if (str_op && !strcmp(str_op, "clone")) {
35 tst_res(TINFO, "Spawning isolated process");
36
37 if (!SAFE_CLONE(&clone_args)) {
38 TST_EXP_FAIL(mq_open(MQNAME, O_RDONLY), ENOENT);
39 return;
40 }
41 } else if (str_op && !strcmp(str_op, "unshare")) {
42 tst_res(TINFO, "Spawning unshared process");
43
44 if (!SAFE_FORK()) {
45 SAFE_UNSHARE(CLONE_NEWIPC);
46 TST_EXP_FAIL(mq_open(MQNAME, O_RDONLY), ENOENT);
47 return;
48 }
49 } else {
50 tst_res(TINFO, "Spawning plain process");
51
52 if (!SAFE_FORK()) {
53 TST_EXP_POSITIVE(mq_open(MQNAME, O_RDONLY));
54 return;
55 }
56 }
57 }
58
setup(void)59 static void setup(void)
60 {
61 mqd = SAFE_MQ_OPEN(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
62 }
63
cleanup(void)64 static void cleanup(void)
65 {
66 if (mqd != -1) {
67 SAFE_MQ_CLOSE(mqd);
68 SAFE_MQ_UNLINK(MQNAME);
69 }
70 }
71
72 static struct tst_test test = {
73 .test_all = run,
74 .setup = setup,
75 .cleanup = cleanup,
76 .needs_root = 1,
77 .forks_child = 1,
78 .options = (struct tst_option[]) {
79 { "m:", &str_op, "Child process isolation <clone|unshare>" },
80 {},
81 },
82 .needs_kconfigs = (const char *[]) {
83 "CONFIG_USER_NS",
84 NULL
85 },
86 };
87