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 with the same name in both parent and isolated/forked child,
12 * then check namespace isolation.
13 */
14
15 #include "tst_test.h"
16 #include "lapi/sched.h"
17 #include "tst_safe_posix_ipc.h"
18
19 #define MQNAME "/MQ1"
20
21 static mqd_t mqd;
22 static char *str_op;
23
create_message_queue(void)24 static int create_message_queue(void)
25 {
26 return mq_open(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
27 }
28
shared_child(void)29 static void shared_child(void)
30 {
31 mqd_t mqd1 = -1;
32
33 TST_EXP_FAIL(mqd1 = create_message_queue(), EEXIST);
34
35 if (mqd1 != -1) {
36 SAFE_MQ_CLOSE(mqd1);
37 SAFE_MQ_UNLINK(MQNAME);
38 }
39 }
40
isolated_child(void)41 static void isolated_child(void)
42 {
43 mqd_t mqd1 = -1;
44
45 TST_EXP_POSITIVE(mqd1 = create_message_queue());
46
47 if (mqd1 != -1) {
48 SAFE_MQ_CLOSE(mqd1);
49 SAFE_MQ_UNLINK(MQNAME);
50 }
51 }
52
run(void)53 static void run(void)
54 {
55 const struct tst_clone_args clone_args = {
56 .flags = CLONE_NEWIPC,
57 .exit_signal = SIGCHLD,
58 };
59
60 tst_res(TINFO, "Checking namespaces isolation from parent to child");
61
62 if (str_op && !strcmp(str_op, "clone")) {
63 tst_res(TINFO, "Spawning isolated process");
64
65 if (!SAFE_CLONE(&clone_args)) {
66 isolated_child();
67 return;
68 }
69 } else if (str_op && !strcmp(str_op, "unshare")) {
70 tst_res(TINFO, "Spawning unshared process");
71
72 if (!SAFE_FORK()) {
73 SAFE_UNSHARE(CLONE_NEWIPC);
74 isolated_child();
75 return;
76 }
77 } else {
78 tst_res(TINFO, "Spawning plain process");
79
80 if (!SAFE_FORK()) {
81 shared_child();
82 return;
83 }
84 }
85 }
86
setup(void)87 static void setup(void)
88 {
89 mqd = SAFE_MQ_OPEN(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
90 }
91
cleanup(void)92 static void cleanup(void)
93 {
94 if (mqd != -1) {
95 SAFE_MQ_CLOSE(mqd);
96 SAFE_MQ_UNLINK(MQNAME);
97 }
98 }
99
100 static struct tst_test test = {
101 .test_all = run,
102 .setup = setup,
103 .cleanup = cleanup,
104 .needs_root = 1,
105 .forks_child = 1,
106 .options = (struct tst_option[]) {
107 { "m:", &str_op, "Child process isolation <clone|unshare>" },
108 {},
109 },
110 .needs_kconfigs = (const char *[]) {
111 "CONFIG_USER_NS",
112 NULL
113 },
114 };
115