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