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