xref: /aosp_15_r20/external/ltp/testcases/kernel/containers/mqns/mqns_01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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