xref: /netbsd-src/tests/rump/rumpkern/t_lwproc.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: t_lwproc.c,v 1.3 2010/09/07 17:09:28 pooka Exp $	*/
2 
3 /*
4  * Copyright (c) 2010 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 
33 #include <rump/rump.h>
34 #include <rump/rump_syscalls.h>
35 
36 #include <atf-c.h>
37 #include <err.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <util.h>
44 
45 #include "../../h_macros.h"
46 
47 ATF_TC(makelwp);
48 ATF_TC_HEAD(makelwp, tc)
49 {
50 
51 	atf_tc_set_md_var(tc, "descr", "tests that lwps can be attached to "
52 	    "processes");
53 }
54 
55 ATF_TC_BODY(makelwp, tc)
56 {
57 	struct lwp *l;
58 	pid_t pid;
59 
60 	rump_init();
61 	RZ(rump_pub_lwproc_newlwp(0));
62 	ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(37), ESRCH);
63 	l = rump_pub_lwproc_curlwp();
64 
65 	RZ(rump_pub_lwproc_newproc());
66 	ATF_REQUIRE(rump_pub_lwproc_curlwp() != l);
67 	l = rump_pub_lwproc_curlwp();
68 
69 	RZ(rump_pub_lwproc_newlwp(rump_sys_getpid()));
70 	ATF_REQUIRE(rump_pub_lwproc_curlwp() != l);
71 
72 	pid = rump_sys_getpid();
73 	ATF_REQUIRE(pid != -1 && pid != 0);
74 }
75 
76 ATF_TC(proccreds);
77 ATF_TC_HEAD(proccreds, tc)
78 {
79 
80 	atf_tc_set_md_var(tc, "descr", "check that procs have different creds");
81 }
82 
83 ATF_TC_BODY(proccreds, tc)
84 {
85 	struct lwp *l1, *l2;
86 
87 	rump_init();
88 	RZ(rump_pub_lwproc_newproc());
89 	l1 = rump_pub_lwproc_curlwp();
90 
91 	RZ(rump_pub_lwproc_newproc());
92 	l2 = rump_pub_lwproc_curlwp();
93 
94 	RL(rump_sys_setuid(22));
95 	ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
96 
97 	rump_pub_lwproc_switch(l1);
98 	ATF_REQUIRE_EQ(rump_sys_getuid(), 0); /* from parent, proc0 */
99 	RL(rump_sys_setuid(11));
100 	ATF_REQUIRE_EQ(rump_sys_getuid(), 11);
101 
102 	rump_pub_lwproc_switch(l2);
103 	ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
104 	rump_pub_lwproc_newlwp(rump_sys_getpid());
105 	ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
106 }
107 
108 
109 ATF_TC(inherit);
110 ATF_TC_HEAD(inherit, tc)
111 {
112 
113 	atf_tc_set_md_var(tc, "descr", "new processes inherit creds from "
114 	    "parents");
115 }
116 
117 ATF_TC_BODY(inherit, tc)
118 {
119 
120 	rump_init();
121 
122 	RZ(rump_pub_lwproc_newproc());
123 	RL(rump_sys_setuid(66));
124 	ATF_REQUIRE_EQ(rump_sys_getuid(), 66);
125 
126 	RZ(rump_pub_lwproc_newproc());
127 	ATF_REQUIRE_EQ(rump_sys_getuid(), 66);
128 
129 	/* release lwp and proc */
130 	rump_pub_lwproc_releaselwp();
131 	ATF_REQUIRE_EQ(rump_sys_getuid(), 0);
132 }
133 
134 ATF_TC(lwps);
135 ATF_TC_HEAD(lwps, tc)
136 {
137 
138 	atf_tc_set_md_var(tc, "descr", "proc can hold many lwps and is "
139 	    "automatically g/c'd when the last one exits");
140 }
141 
142 #define LOOPS 128
143 ATF_TC_BODY(lwps, tc)
144 {
145 	struct lwp *l[LOOPS];
146 	pid_t mypid;
147 	struct lwp *l_orig;
148 	int i;
149 
150 	rump_init();
151 
152 	RZ(rump_pub_lwproc_newproc());
153 	mypid = rump_sys_getpid();
154 	RL(rump_sys_setuid(375));
155 
156 	l_orig = rump_pub_lwproc_curlwp();
157 	for (i = 0; i < LOOPS; i++) {
158 		mypid = rump_sys_getpid();
159 		ATF_REQUIRE(mypid != -1 && mypid != 0);
160 		RZ(rump_pub_lwproc_newlwp(mypid));
161 		l[i] = rump_pub_lwproc_curlwp();
162 		ATF_REQUIRE_EQ(rump_sys_getuid(), 375);
163 	}
164 
165 	rump_pub_lwproc_switch(l_orig);
166 	rump_pub_lwproc_releaselwp();
167 	for (i = 0; i < LOOPS; i++) {
168 		rump_pub_lwproc_switch(l[i]);
169 		ATF_REQUIRE_EQ(rump_sys_getpid(), mypid);
170 		ATF_REQUIRE_EQ(rump_sys_getuid(), 375);
171 		rump_pub_lwproc_releaselwp();
172 		ATF_REQUIRE_EQ(rump_sys_getpid(), 0);
173 		ATF_REQUIRE_EQ(rump_sys_getuid(), 0);
174 	}
175 
176 	ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(mypid), ESRCH);
177 }
178 
179 ATF_TC(nolwprelease);
180 ATF_TC_HEAD(nolwprelease, tc)
181 {
182 
183 	atf_tc_set_md_var(tc, "descr", "check that lwp context is required "
184 	    "for lwproc_releaselwp()");
185 }
186 
187 ATF_TC_BODY(nolwprelease, tc)
188 {
189 	int status;
190 
191 	switch (fork()) {
192 	case 0:
193 		rump_init();
194 		rump_pub_lwproc_releaselwp();
195 		atf_tc_fail("survived");
196 		break;
197 	case -1:
198 		atf_tc_fail_errno("fork");
199 		break;
200 	default:
201 		wait(&status);
202 		ATF_REQUIRE(WIFSIGNALED(status));
203 		ATF_REQUIRE_EQ(WTERMSIG(status), SIGABRT);
204 
205 	}
206 }
207 
208 ATF_TC(nolwp);
209 ATF_TC_HEAD(nolwp, tc)
210 {
211 
212 	atf_tc_set_md_var(tc, "descr", "check that curlwp for an implicit "
213 	    "context is NULL");
214 }
215 
216 ATF_TC_BODY(nolwp, tc)
217 {
218 
219 	rump_init();
220 	ATF_REQUIRE_EQ(rump_pub_lwproc_curlwp(), NULL);
221 }
222 
223 ATF_TC(nullswitch);
224 ATF_TC_HEAD(nullswitch, tc)
225 {
226 
227 	atf_tc_set_md_var(tc, "descr", "check that switching to NULL marks "
228 	    "current lwp as not running");
229 }
230 
231 ATF_TC_BODY(nullswitch, tc)
232 {
233 	struct lwp *l;
234 
235 	rump_init();
236 	RZ(rump_pub_lwproc_newlwp(0));
237 	l = rump_pub_lwproc_curlwp();
238 	rump_pub_lwproc_switch(NULL);
239 	/* if remains LP_RUNNING, next call will panic */
240 	rump_pub_lwproc_switch(l);
241 }
242 
243 ATF_TP_ADD_TCS(tp)
244 {
245 
246 	ATF_TP_ADD_TC(tp, makelwp);
247 	ATF_TP_ADD_TC(tp, proccreds);
248 	ATF_TP_ADD_TC(tp, inherit);
249 	ATF_TP_ADD_TC(tp, lwps);
250 	ATF_TP_ADD_TC(tp, nolwprelease);
251 	ATF_TP_ADD_TC(tp, nolwp);
252 	ATF_TP_ADD_TC(tp, nullswitch);
253 
254 	return atf_no_error();
255 }
256