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