1 /* 2 * Copyright (c) International Business Machines Corp., 2009 3 * Copyright (c) Nadia Derbey, 2009 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 * 17 * Author: Nadia Derbey <Nadia.Derbey (at) bull.net> 18 * 19 * Check mqns isolation: child mqns cannot be accessed from father 20 * 21 * Mount mqueue fs 22 * unshare 23 * In unshared process: 24 * Mount newinstance mqueuefs 25 * Create a posix mq -->mq1 26 * Check that mq1 is not readable from father 27 * 28 * Changelog: 29 * Dec 16: accomodate new mqns semantics (Serge Hallyn) 30 31 ***************************************************************************/ 32 33 #ifndef _GNU_SOURCE 34 #define _GNU_SOURCE 35 #endif 36 #include <sys/wait.h> 37 #include <errno.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 #include "mqns.h" 43 #include "mqns_helper.h" 44 45 char *TCID = "posixmq_namespace_02"; 46 int TST_TOTAL = 1; 47 48 int p1[2]; 49 int p2[2]; 50 51 int check_mqueue(void *vtest) 52 { 53 char buf[30]; 54 mqd_t mqd; 55 56 (void) vtest; 57 58 close(p1[1]); 59 close(p2[0]); 60 61 if (read(p1[0], buf, 3) < 0) { 62 perror("read(p1[0], ..) failed"); 63 exit(1); 64 } else { 65 66 mqd = 67 ltp_syscall(__NR_mq_open, NOSLASH_MQ1, 68 O_RDWR | O_CREAT | O_EXCL, 0777, NULL); 69 if (mqd == -1) { 70 if (write(p2[1], "mqfail", strlen("mqfail") + 1) < 0) { 71 perror("write(p2[1], \"mqfail\", ..) failed"); 72 exit(1); 73 } 74 } else { 75 76 if (write(p2[1], "mqopen", strlen("mqopen") + 1) < 0) { 77 perror("write(p2[1], \"mqopen\", ..) failed"); 78 exit(1); 79 } else { 80 81 if (read(p1[0], buf, 5) < 0) { 82 perror("read(p1[0], ..) failed"); 83 exit(1); 84 } else { 85 86 /* destroy the mqueue */ 87 if (mq_close(mqd) < 0) { 88 perror("mq_close(mqd) failed"); 89 exit(1); 90 } else if (ltp_syscall(__NR_mq_unlink, 91 NOSLASH_MQ1) < 0) { 92 perror("mq_unlink(" NOSLASH_MQ1 93 ") failed"); 94 exit(1); 95 } else if (write(p2[1], "done", 96 strlen("done") + 1) 97 < 0) { 98 perror("write(p2[1], " 99 "\"done\", ..) failed"); 100 exit(1); 101 } 102 103 } 104 105 } 106 107 } 108 109 } 110 exit(0); 111 112 } 113 114 static void setup(void) 115 { 116 tst_require_root(); 117 check_mqns(); 118 } 119 120 int main(int argc, char *argv[]) 121 { 122 int r; 123 mqd_t mqd; 124 char buf[30]; 125 int use_clone = T_UNSHARE; 126 127 setup(); 128 129 if (argc == 2 && strcmp(argv[1], "-clone") == 0) { 130 tst_resm(TINFO, 131 "Testing posix mq namespaces through clone(2)."); 132 use_clone = T_CLONE; 133 } else 134 tst_resm(TINFO, 135 "Testing posix mq namespaces through unshare(2)."); 136 137 if (pipe(p1) == -1 || pipe(p2) == -1) { 138 tst_brkm(TBROK | TERRNO, NULL, "pipe"); 139 } 140 141 /* fire off the test */ 142 r = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_mqueue, NULL); 143 if (r < 0) { 144 tst_brkm(TFAIL, NULL, "failed clone/unshare"); 145 } 146 147 tst_resm(TINFO, "Checking namespaces isolation (child to parent)"); 148 149 close(p1[0]); 150 close(p2[1]); 151 if (write(p1[1], "go", strlen("go") + 1) < 0) { 152 tst_brkm(TBROK, NULL, "write(p1[1], \"go\", ..) failed"); 153 } 154 155 if (read(p2[0], buf, 7) < 0) { 156 tst_resm(TBROK | TERRNO, "read(p2[0], ..) failed"); 157 } else if (!strcmp(buf, "mqfail")) { 158 tst_resm(TFAIL, "child process could not create mqueue"); 159 umount(DEV_MQUEUE); 160 } else if (strcmp(buf, "mqopen")) { 161 tst_resm(TFAIL, "child process could not create mqueue"); 162 umount(DEV_MQUEUE); 163 } else { 164 mqd = ltp_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDONLY); 165 if (mqd == -1) { 166 tst_resm(TPASS, 167 "Parent process can't see the mqueue"); 168 } else { 169 tst_resm(TFAIL | TERRNO, 170 "Parent process found mqueue"); 171 mq_close(mqd); 172 } 173 if (write(p1[1], "cont", 5) < 0) { 174 tst_resm(TBROK | TERRNO, "write(p1[1], ..) failed"); 175 } 176 read(p2[0], buf, 7); 177 } 178 179 tst_exit(); 180 } 181