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