1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) International Business Machines Corp., 2009 4 * Copyright (c) Nadia Derbey, 2009 <Nadia.Derbey@bull.net> 5 * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> 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 21static mqd_t mqd; 22static char *str_op; 23 24static int create_message_queue(void) 25{ 26 return mq_open(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL); 27} 28 29static 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 41static 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 53static 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 87static void setup(void) 88{ 89 mqd = SAFE_MQ_OPEN(MQNAME, O_RDWR | O_CREAT | O_EXCL, 0777, NULL); 90} 91 92static void cleanup(void) 93{ 94 if (mqd != -1) { 95 SAFE_MQ_CLOSE(mqd); 96 SAFE_MQ_UNLINK(MQNAME); 97 } 98} 99 100static 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