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 "ipcns_helper.h"
49
50 #define TESTKEY 124426L
51 #define UNSHARESTR "unshare"
52 #define CLONESTR "clone"
53 #define NONESTR "none"
54
55 char *TCID = "shmem_2nstest";
56 int TST_TOTAL = 1;
57 int p2[2];
58 int p1[2];
59
60 /*
61 * check_shmem1() does not read -- it writes to check_shmem2() when it's done.
62 */
check_shmem1(void * vtest)63 int check_shmem1(void *vtest)
64 {
65 int id1;
66
67 (void) vtest;
68
69 close(p1[0]);
70
71 /* first create the key */
72 id1 = shmget(TESTKEY, 100, IPC_CREAT);
73 if (id1 == -1)
74 tst_brkm(TFAIL | TERRNO, NULL, "shmget failed");
75
76 tst_resm(TINFO, "Cont1: Able to create shared mem segment");
77 write(p1[1], "done", 5);
78 tst_exit();
79 }
80
81 /*
82 * check_shmem2() reads from check_shmem1() and writes to main() when it's done.
83 */
check_shmem2(void * vtest)84 int check_shmem2(void *vtest)
85 {
86 char buf[3];
87 int id2;
88
89 (void) vtest;
90
91 close(p1[1]);
92 close(p2[0]);
93
94 read(p1[0], buf, 3);
95 /* Trying to access shmem, if not existing create new shmem */
96 id2 = shmget(TESTKEY, 100, 0);
97 if (id2 == -1) {
98 id2 = shmget(TESTKEY, 100, IPC_CREAT);
99 if (id2 == -1)
100 tst_resm(TFAIL | TERRNO, "shmget failed");
101 else
102 tst_resm(TINFO,
103 "Cont2: Able to allocate shmem seg with "
104 "the same key");
105 write(p2[1], "notfnd", 7);
106 } else
107 write(p2[1], "exists", 7);
108
109 tst_exit();
110 }
111
setup(void)112 static void setup(void)
113 {
114 tst_require_root();
115 check_newipc();
116 }
117
main(int argc,char * argv[])118 int main(int argc, char *argv[])
119 {
120 int ret, use_clone = T_NONE;
121 char *tsttype = NONESTR;
122 char buf[7];
123 int id;
124
125 setup();
126
127 if (argc != 2) {
128 tst_resm(TINFO, "Usage: %s <clone| unshare| none>", argv[0]);
129 tst_resm(TINFO, " where clone, unshare, or fork specifies"
130 " unshare method.");
131 tst_exit();
132 }
133
134 /* Using PIPE's to sync between containers and Parent */
135 if (pipe(p1) == -1)
136 tst_brkm(TBROK | TERRNO, NULL, "pipe1 error");
137 if (pipe(p2) == -1)
138 tst_brkm(TBROK | TERRNO, NULL, "pipe2 error");
139
140 if (strcmp(argv[1], "clone") == 0) {
141 use_clone = T_CLONE;
142 tsttype = CLONESTR;
143 } else if (strcmp(argv[1], "unshare") == 0) {
144 use_clone = T_UNSHARE;
145 tsttype = UNSHARESTR;
146 }
147
148 tst_resm(TINFO, "Shared Memory namespace test : %s", tsttype);
149
150 /* Create 2 containers */
151 ret =
152 do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem1, NULL);
153 if (ret < 0)
154 tst_brkm(TFAIL, NULL, "clone/unshare failed");
155
156 ret =
157 do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmem2, NULL);
158 if (ret < 0)
159 tst_brkm(TFAIL, NULL, "clone/unshare failed");
160
161 close(p2[1]);
162 read(p2[0], buf, 7);
163
164 if (strcmp(buf, "exists") == 0) {
165 if (use_clone == T_NONE)
166 tst_resm(TPASS,
167 "Plain cloned process able to access shmem "
168 "segment created");
169 else
170 tst_resm(TFAIL,
171 "%s : In namespace2 found the shmem segment "
172 "created in Namespace1", tsttype);
173 } else {
174 if (use_clone == T_NONE)
175 tst_resm(TFAIL,
176 "Plain cloned process didn't find shmem seg");
177 else
178 tst_resm(TPASS,
179 "%s : In namespace2 unable to access the shmem seg "
180 "created in Namespace1", tsttype);
181 }
182 /* destroy the key */
183
184 id = shmget(TESTKEY, 100, 0);
185 shmctl(id, IPC_RMID, NULL);
186
187 tst_exit();
188 }
189