1 /* *************************************************************************
2 * Copyright (c) International Business Machines Corp., 2009
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 * the GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 * Author: Veerendra C <vechandr@in.ibm.com>
17 *
18 * Test Assertion:
19 * This testcase verifies the Shared Memory isoloation in 2 containers.
20 * It tries to create/access a Shared Memory created with the same KEY.
21 *
22 * Description:
23 * Create 2 'containers' with the below flag value
24 * Flag = clone, clone(CLONE_NEWIPC), or unshare(CLONE_NEWIPC)
25 * In Cont1, create Shared Memory segment with key 124426L
26 * In Cont2, try to access the MQ created in Cont1.
27 * PASS :
28 * If flag = None and the shmem seg is accessible in Cont2.
29 * If flag = unshare/clone and the shmem seg is not accessible in Cont2.
30 * If shmem seg is not accessible in Cont2,
31 * creates new shmem with same key to double check isloation in IPCNS.
32 *
33 * FAIL :
34 * If flag = none and the shmem seg is not accessible.
35 * If flag = unshare/clone and shmem seg is accessible in Cont2.
36 * If the new shmem seg creation Fails.
37 ***************************************************************************/
38
39 #define _GNU_SOURCE 1
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <string.h>
44 #include <sys/ipc.h>
45 #include <sys/shm.h>
46 #include <libclone.h>
47 #include "test.h"
48 #include "safe_macros.h"
49 #include "ipcns_helper.h"
50
51 #define TESTKEY 124426L
52 #define UNSHARESTR "unshare"
53 #define CLONESTR "clone"
54 #define NONESTR "none"
55
56 char *TCID = "shmem_2nstest";
57 int TST_TOTAL = 1;
58 int p2[2];
59 int p1[2];
60
61 /*
62 * check_shmem1() does not read -- it writes to check_shmem2() when it's done.
63 */
check_shmem1(void * vtest)64 int check_shmem1(void *vtest)
65 {
66 int id1;
67
68 (void) vtest;
69
70 close(p1[0]);
71
72 /* first create the key */
73 id1 = shmget(TESTKEY, 100, IPC_CREAT);
74 if (id1 == -1)
75 tst_brkm(TFAIL | TERRNO, NULL, "shmget failed");
76
77 tst_resm(TINFO, "Cont1: Able to create shared mem segment");
78 write(p1[1], "done", 5);
79 tst_exit();
80 }
81
82 /*
83 * check_shmem2() reads from check_shmem1() and writes to main() when it's done.
84 */
check_shmem2(void * vtest)85 int check_shmem2(void *vtest)
86 {
87 char buf[3];
88 int id2;
89
90 (void) vtest;
91
92 close(p1[1]);
93 close(p2[0]);
94
95 read(p1[0], buf, 3);
96 /* Trying to access shmem, if not existing create new shmem */
97 id2 = shmget(TESTKEY, 100, 0);
98 if (id2 == -1) {
99 id2 = shmget(TESTKEY, 100, IPC_CREAT);
100 if (id2 == -1)
101 tst_resm(TFAIL | TERRNO, "shmget failed");
102 else
103 tst_resm(TINFO,
104 "Cont2: Able to allocate shmem seg with "
105 "the same key");
106 write(p2[1], "notfnd", 7);
107 } else
108 write(p2[1], "exists", 7);
109
110 tst_exit();
111 }
112
setup(void)113 static void setup(void)
114 {
115 tst_require_root();
116 check_newipc();
117 }
118
main(int argc,char * argv[])119 int main(int argc, char *argv[])
120 {
121 int ret, use_clone = T_NONE;
122 char *tsttype = NONESTR;
123 char buf[7];
124 int id;
125
126 setup();
127
128 if (argc != 2) {
129 tst_resm(TINFO, "Usage: %s <clone| unshare| none>", argv[0]);
130 tst_resm(TINFO, " where clone, unshare, or fork specifies"
131 " unshare method.");
132 tst_exit();
133 }
134
135 /* Using PIPE's to sync between containers and Parent */
136 SAFE_PIPE(NULL, p1);
137 SAFE_PIPE(NULL, p2);
138
139 if (strcmp(argv[1], "clone") == 0) {
140 use_clone = T_CLONE;
141 tsttype = CLONESTR;
142 } else if (strcmp(argv[1], "unshare") == 0) {
143 use_clone = T_UNSHARE;
144 tsttype = UNSHARESTR;
145 }
146
147 tst_resm(TINFO, "Shared Memory namespace test : %s", tsttype);
148
149 /* Create 2 containers */
150 ret =
151 do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem1, NULL);
152 if (ret < 0)
153 tst_brkm(TFAIL, NULL, "clone/unshare failed");
154
155 ret =
156 do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem2, NULL);
157 if (ret < 0)
158 tst_brkm(TFAIL, NULL, "clone/unshare failed");
159
160 close(p2[1]);
161 read(p2[0], buf, 7);
162
163 if (strcmp(buf, "exists") == 0) {
164 if (use_clone == T_NONE)
165 tst_resm(TPASS,
166 "Plain cloned process able to access shmem "
167 "segment created");
168 else
169 tst_resm(TFAIL,
170 "%s : In namespace2 found the shmem segment "
171 "created in Namespace1", tsttype);
172 } else {
173 if (use_clone == T_NONE)
174 tst_resm(TFAIL,
175 "Plain cloned process didn't find shmem seg");
176 else
177 tst_resm(TPASS,
178 "%s : In namespace2 unable to access the shmem seg "
179 "created in Namespace1", tsttype);
180 }
181 /* destroy the key */
182
183 id = shmget(TESTKEY, 100, 0);
184 shmctl(id, IPC_RMID, NULL);
185
186 tst_exit();
187 }
188