t_lwproc.c revision 314817
1/* $NetBSD: t_lwproc.c,v 1.9 2017/01/13 21:30:43 christos 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#include <sys/stat.h> 33 34#include <rump/rump.h> 35#include <rump/rump_syscalls.h> 36 37#include <atf-c.h> 38#include <err.h> 39#include <errno.h> 40#include <fcntl.h> 41#include <stdio.h> 42#include <stdlib.h> 43#include <string.h> 44#include <unistd.h> 45#include <util.h> 46 47#include "h_macros.h" 48 49ATF_TC(makelwp); 50ATF_TC_HEAD(makelwp, tc) 51{ 52 53 atf_tc_set_md_var(tc, "descr", "tests that lwps can be attached to " 54 "processes"); 55} 56 57ATF_TC_BODY(makelwp, tc) 58{ 59 struct lwp *l; 60 pid_t pid; 61 62 rump_init(); 63 RZ(rump_pub_lwproc_newlwp(0)); 64 ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(37), ESRCH); 65 l = rump_pub_lwproc_curlwp(); 66 67 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 68 ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); 69 l = rump_pub_lwproc_curlwp(); 70 71 RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); 72 ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); 73 74 pid = rump_sys_getpid(); 75 ATF_REQUIRE(pid != -1 && pid != 0); 76} 77 78ATF_TC(proccreds); 79ATF_TC_HEAD(proccreds, tc) 80{ 81 82 atf_tc_set_md_var(tc, "descr", "check that procs have different creds"); 83} 84 85ATF_TC_BODY(proccreds, tc) 86{ 87 struct lwp *l1, *l2; 88 89 rump_init(); 90 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 91 l1 = rump_pub_lwproc_curlwp(); 92 RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); 93 94 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 95 l2 = rump_pub_lwproc_curlwp(); 96 97 RL(rump_sys_setuid(22)); 98 ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 99 100 rump_pub_lwproc_switch(l1); 101 ATF_REQUIRE_EQ(rump_sys_getuid(), 0); /* from parent, proc0 */ 102 RL(rump_sys_setuid(11)); 103 ATF_REQUIRE_EQ(rump_sys_getuid(), 11); 104 105 rump_pub_lwproc_switch(l2); 106 ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 107 rump_pub_lwproc_newlwp(rump_sys_getpid()); 108 ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 109} 110 111 112ATF_TC(inherit); 113ATF_TC_HEAD(inherit, tc) 114{ 115 116 atf_tc_set_md_var(tc, "descr", "new processes inherit creds from " 117 "parents"); 118} 119 120ATF_TC_BODY(inherit, tc) 121{ 122 123 rump_init(); 124 125 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 126 RL(rump_sys_setuid(66)); 127 ATF_REQUIRE_EQ(rump_sys_getuid(), 66); 128 129 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 130 ATF_REQUIRE_EQ(rump_sys_getuid(), 66); 131 132 /* release lwp and proc */ 133 rump_pub_lwproc_releaselwp(); 134 ATF_REQUIRE_EQ(rump_sys_getuid(), 0); 135} 136 137ATF_TC(lwps); 138ATF_TC_HEAD(lwps, tc) 139{ 140 141 atf_tc_set_md_var(tc, "descr", "proc can hold many lwps and is " 142 "automatically g/c'd when the last one exits"); 143} 144 145#define LOOPS 128 146ATF_TC_BODY(lwps, tc) 147{ 148 struct lwp *l[LOOPS]; 149 pid_t mypid; 150 struct lwp *l_orig; 151 int i; 152 153 rump_init(); 154 155 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 156 mypid = rump_sys_getpid(); 157 RL(rump_sys_setuid(375)); 158 159 l_orig = rump_pub_lwproc_curlwp(); 160 for (i = 0; i < LOOPS; i++) { 161 mypid = rump_sys_getpid(); 162 ATF_REQUIRE(mypid != -1 && mypid != 0); 163 RZ(rump_pub_lwproc_newlwp(mypid)); 164 l[i] = rump_pub_lwproc_curlwp(); 165 ATF_REQUIRE_EQ(rump_sys_getuid(), 375); 166 } 167 168 rump_pub_lwproc_switch(l_orig); 169 rump_pub_lwproc_releaselwp(); 170 for (i = 0; i < LOOPS; i++) { 171 rump_pub_lwproc_switch(l[i]); 172 ATF_REQUIRE_EQ(rump_sys_getpid(), mypid); 173 ATF_REQUIRE_EQ(rump_sys_getuid(), 375); 174 rump_pub_lwproc_releaselwp(); 175 ATF_REQUIRE_EQ(rump_sys_getpid(), 1); 176 ATF_REQUIRE_EQ(rump_sys_getuid(), 0); 177 } 178 179 ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(mypid), ESRCH); 180} 181 182ATF_TC(nolwprelease); 183ATF_TC_HEAD(nolwprelease, tc) 184{ 185 186 atf_tc_set_md_var(tc, "descr", "check that lwp context is required " 187 "for lwproc_releaselwp()"); 188} 189 190ATF_TC_BODY(nolwprelease, tc) 191{ 192 int status; 193 194 switch (fork()) { 195 case 0: 196 rump_init(); 197 rump_pub_lwproc_releaselwp(); 198 atf_tc_fail("survived"); 199 break; 200 case -1: 201 atf_tc_fail_errno("fork"); 202 break; 203 default: 204 wait(&status); 205 ATF_REQUIRE(WIFSIGNALED(status)); 206 ATF_REQUIRE_EQ(WTERMSIG(status), SIGABRT); 207 208 } 209} 210 211ATF_TC(nolwp); 212ATF_TC_HEAD(nolwp, tc) 213{ 214 215 atf_tc_set_md_var(tc, "descr", "check that curlwp for an implicit " 216 "context is NULL"); 217} 218 219ATF_TC_BODY(nolwp, tc) 220{ 221 222 rump_init(); 223 ATF_REQUIRE_EQ(rump_pub_lwproc_curlwp(), NULL); 224} 225 226ATF_TC(nullswitch); 227ATF_TC_HEAD(nullswitch, tc) 228{ 229 230 atf_tc_set_md_var(tc, "descr", "check that switching to NULL marks " 231 "current lwp as not running"); 232} 233 234ATF_TC_BODY(nullswitch, tc) 235{ 236 struct lwp *l; 237 238 rump_init(); 239 RZ(rump_pub_lwproc_newlwp(0)); 240 l = rump_pub_lwproc_curlwp(); 241 rump_pub_lwproc_switch(NULL); 242 /* if remains LP_RUNNING, next call will panic */ 243 rump_pub_lwproc_switch(l); 244} 245 246ATF_TC(rfork); 247ATF_TC_HEAD(rfork, tc) 248{ 249 250 atf_tc_set_md_var(tc, "descr", "check that fork shares fd's"); 251} 252 253ATF_TC_BODY(rfork, tc) 254{ 255 struct stat sb; 256 struct lwp *l, *l2; 257 int fd; 258 259 RZ(rump_init()); 260 261 ATF_REQUIRE_EQ(rump_pub_lwproc_rfork(RUMP_RFFDG|RUMP_RFCFDG), EINVAL); 262 263 RZ(rump_pub_lwproc_rfork(0)); 264 l = rump_pub_lwproc_curlwp(); 265 266 RL(fd = rump_sys_open("/file", O_RDWR | O_CREAT, 0777)); 267 268 /* ok, first check rfork(RUMP_RFCFDG) does *not* preserve fd's */ 269 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 270 ATF_REQUIRE_ERRNO(EBADF, rump_sys_write(fd, &fd, sizeof(fd)) == -1); 271 272 /* then check that rfork(0) does */ 273 rump_pub_lwproc_switch(l); 274 RZ(rump_pub_lwproc_rfork(0)); 275 ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); 276 RL(rump_sys_fstat(fd, &sb)); 277 l2 = rump_pub_lwproc_curlwp(); 278 279 /* 280 * check that the shared fd table is really shared by 281 * closing fd in parent 282 */ 283 rump_pub_lwproc_switch(l); 284 RL(rump_sys_close(fd)); 285 rump_pub_lwproc_switch(l2); 286 ATF_REQUIRE_ERRNO(EBADF, rump_sys_fstat(fd, &sb) == -1); 287 288 /* redo, this time copying the fd table instead of sharing it */ 289 rump_pub_lwproc_releaselwp(); 290 rump_pub_lwproc_switch(l); 291 RL(fd = rump_sys_open("/file", O_RDWR, 0777)); 292 RZ(rump_pub_lwproc_rfork(RUMP_RFFDG)); 293 ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); 294 RL(rump_sys_fstat(fd, &sb)); 295 l2 = rump_pub_lwproc_curlwp(); 296 297 /* check that the fd table is copied */ 298 rump_pub_lwproc_switch(l); 299 RL(rump_sys_close(fd)); 300 rump_pub_lwproc_switch(l2); 301 RL(rump_sys_fstat(fd, &sb)); 302 ATF_REQUIRE_EQ(sb.st_size, sizeof(fd)); 303} 304 305ATF_TP_ADD_TCS(tp) 306{ 307 308 ATF_TP_ADD_TC(tp, makelwp); 309 ATF_TP_ADD_TC(tp, proccreds); 310 ATF_TP_ADD_TC(tp, inherit); 311 ATF_TP_ADD_TC(tp, lwps); 312 ATF_TP_ADD_TC(tp, nolwprelease); 313 ATF_TP_ADD_TC(tp, nolwp); 314 ATF_TP_ADD_TC(tp, nullswitch); 315 ATF_TP_ADD_TC(tp, rfork); 316 317 return atf_no_error(); 318} 319