1 /*
2 * Copyright (c) International Business Machines Corp., 2007
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: Serge Hallyn <serue@us.ibm.com>
17 *
18 * Create shm with key 0xEAEAEA
19 * clone, clone(CLONE_NEWIPC), or unshare(CLONE_NEWIPC)
20 * In cloned process, try to get the created shm
21
22 ***************************************************************************/
23
24 #define _GNU_SOURCE 1
25 #include <sys/wait.h>
26 #include <assert.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <sys/ipc.h>
33 #include <sys/shm.h>
34 #include "test.h"
35 #include <libclone.h>
36 #include "ipcns_helper.h"
37
38 char *TCID = "sysvipc_namespace";
39 int TST_TOTAL = 1;
40 #define TESTKEY 0xEAEAEA
41
42 int p1[2];
43 int p2[2];
44
check_shmid(void * vtest)45 int check_shmid(void *vtest)
46 {
47 char buf[3];
48 int id;
49
50 (void) vtest;
51
52 close(p1[1]);
53 close(p2[0]);
54
55 read(p1[0], buf, 3);
56 id = shmget(TESTKEY, 100, 0);
57 if (id == -1) {
58 write(p2[1], "notfnd", 7);
59 } else {
60 write(p2[1], "exists", 7);
61 shmctl(id, IPC_RMID, NULL);
62 }
63
64 tst_exit();
65 }
66
setup(void)67 static void setup(void)
68 {
69 tst_require_root();
70 check_newipc();
71 }
72
73 #define UNSHARESTR "unshare"
74 #define CLONESTR "clone"
75 #define NONESTR "none"
main(int argc,char * argv[])76 int main(int argc, char *argv[])
77 {
78 int r, use_clone = T_NONE;
79 int id;
80 char *tsttype = NONESTR;
81 char buf[7];
82
83 setup();
84
85 if (argc != 2) {
86 tst_resm(TFAIL, "Usage: %s <clone|unshare|none>", argv[0]);
87 tst_brkm(TFAIL,
88 NULL,
89 " where clone, unshare, or fork specifies unshare method.");
90 }
91 if (pipe(p1) == -1) {
92 perror("pipe");
93 exit(EXIT_FAILURE);
94 }
95 if (pipe(p2) == -1) {
96 perror("pipe");
97 exit(EXIT_FAILURE);
98 }
99 tsttype = NONESTR;
100 if (strcmp(argv[1], "clone") == 0) {
101 use_clone = T_CLONE;
102 tsttype = CLONESTR;
103 } else if (strcmp(argv[1], "unshare") == 0) {
104 use_clone = T_UNSHARE;
105 tsttype = UNSHARESTR;
106 }
107
108 /* first create the key */
109 id = shmget(TESTKEY, 100, IPC_CREAT);
110 if (id == -1) {
111 perror("shmget");
112 tst_brkm(TFAIL, NULL, "shmget failed");
113 }
114
115 tst_resm(TINFO, "shmid namespaces test : %s", tsttype);
116 /* fire off the test */
117 r = do_clone_unshare_test(use_clone, CLONE_NEWIPC, check_shmid, NULL);
118 if (r < 0) {
119 tst_brkm(TFAIL, NULL, "%s failed", tsttype);
120 }
121
122 close(p1[0]);
123 close(p2[1]);
124 write(p1[1], "go", 3);
125 read(p2[0], buf, 7);
126 if (strcmp(buf, "exists") == 0) {
127 if (use_clone == T_NONE)
128 tst_resm(TPASS, "plain cloned process found shmid");
129 else
130 tst_resm(TFAIL, "%s: child process found shmid",
131 tsttype);
132 } else {
133 if (use_clone == T_NONE)
134 tst_resm(TFAIL,
135 "plain cloned process didn't find shmid");
136 else
137 tst_resm(TPASS, "%s: child process didn't find shmid",
138 tsttype);
139 }
140
141 /* destroy the key */
142 shmctl(id, IPC_RMID, NULL);
143
144 tst_exit();
145 }
146