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: father mqns cannot be accessed from newinstance 20 * 21 * Mount mqueue fs 22 * Create a posix mq -->mq1 23 * unshare 24 * In unshared process: 25 * Mount newinstance mqueuefs 26 * Check that mq1 is not readable from new ns 27 28 ***************************************************************************/ 29 30 #ifndef _GNU_SOURCE 31 #define _GNU_SOURCE 32 #endif 33 #include <sys/wait.h> 34 #include <errno.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 #include "mqns.h" 40 #include "mqns_helper.h" 41 42 char *TCID = "posixmq_namespace_01"; 43 int TST_TOTAL = 1; 44 45 int p1[2]; 46 int p2[2]; 47 48 int check_mqueue(void *vtest) 49 { 50 char buf[30]; 51 mqd_t mqd; 52 53 (void) vtest; 54 55 close(p1[1]); 56 close(p2[0]); 57 58 if (read(p1[0], buf, strlen("go") + 1) < 0) { 59 printf("read(p1[0], ...) failed: %s\n", strerror(errno)); 60 exit(1); 61 } 62 mqd = ltp_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDONLY); 63 if (mqd == -1) { 64 if (write(p2[1], "notfnd", strlen("notfnd") + 1) < 0) { 65 perror("write(p2[1], ...) failed"); 66 exit(1); 67 } 68 } else { 69 if (write(p2[1], "exists", strlen("exists") + 1) < 0) { 70 perror("write(p2[1], \"exists\", 7) failed"); 71 exit(1); 72 } else if (mq_close(mqd) < 0) { 73 perror("mq_close(mqd) failed"); 74 exit(1); 75 } 76 } 77 78 exit(0); 79 } 80 81 static void setup(void) 82 { 83 tst_require_root(); 84 check_mqns(); 85 } 86 87 int main(int argc, char *argv[]) 88 { 89 int r; 90 mqd_t mqd; 91 char buf[30]; 92 int use_clone = T_UNSHARE; 93 94 setup(); 95 96 if (argc == 2 && strcmp(argv[1], "-clone") == 0) { 97 tst_resm(TINFO, 98 "Testing posix mq namespaces through clone(2)."); 99 use_clone = T_CLONE; 100 } else 101 tst_resm(TINFO, 102 "Testing posix mq namespaces through unshare(2)."); 103 104 if (pipe(p1) == -1 || pipe(p2) == -1) { 105 tst_brkm(TBROK | TERRNO, NULL, "pipe failed"); 106 } 107 108 mqd = ltp_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDWR | O_CREAT | O_EXCL, 109 0777, NULL); 110 if (mqd == -1) { 111 perror("mq_open"); 112 tst_brkm(TFAIL, NULL, "mq_open failed"); 113 } 114 115 tst_resm(TINFO, "Checking namespaces isolation from parent to child"); 116 /* fire off the test */ 117 r = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_mqueue, NULL); 118 if (r < 0) { 119 tst_resm(TFAIL, "failed clone/unshare"); 120 mq_close(mqd); 121 ltp_syscall(__NR_mq_unlink, NOSLASH_MQ1); 122 tst_exit(); 123 } 124 125 close(p1[0]); 126 close(p2[1]); 127 if (write(p1[1], "go", strlen("go") + 1) < 0) 128 tst_resm(TBROK | TERRNO, "write(p1[1], \"go\", ...) failed"); 129 else if (read(p2[0], buf, 7) < 0) 130 tst_resm(TBROK | TERRNO, "read(p2[0], buf, ...) failed"); 131 else { 132 if (!strcmp(buf, "exists")) { 133 tst_resm(TFAIL, "child process found mqueue"); 134 } else if (!strcmp(buf, "notfnd")) { 135 tst_resm(TPASS, "child process didn't find mqueue"); 136 } else { 137 tst_resm(TFAIL, "UNKNOWN RESULT"); 138 } 139 } 140 141 /* destroy the mqueue */ 142 if (mq_close(mqd) == -1) { 143 tst_brkm(TBROK | TERRNO, NULL, "mq_close failed"); 144 } 145 ltp_syscall(__NR_mq_unlink, NOSLASH_MQ1); 146 147 tst_exit(); 148 } 149