1*640235e2SEnji Cooper /* $NetBSD: t_lwproc.c,v 1.7 2015/01/21 15:19:01 pooka Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper /* 457718be8SEnji Cooper * Copyright (c) 2010 The NetBSD Foundation, Inc. 557718be8SEnji Cooper * All rights reserved. 657718be8SEnji Cooper * 757718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 857718be8SEnji Cooper * modification, are permitted provided that the following conditions 957718be8SEnji Cooper * are met: 1057718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 1157718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 1257718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1357718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 1457718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 1557718be8SEnji Cooper * 1657718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 1757718be8SEnji Cooper * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 1857718be8SEnji Cooper * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1957718be8SEnji Cooper * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2057718be8SEnji Cooper * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 2157718be8SEnji Cooper * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2257718be8SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 2357718be8SEnji Cooper * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2457718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 2557718be8SEnji Cooper * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2657718be8SEnji Cooper * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 2757718be8SEnji Cooper * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2857718be8SEnji Cooper */ 2957718be8SEnji Cooper 3057718be8SEnji Cooper #include <sys/types.h> 3157718be8SEnji Cooper #include <sys/wait.h> 3257718be8SEnji Cooper 3357718be8SEnji Cooper #include <rump/rump.h> 3457718be8SEnji Cooper #include <rump/rump_syscalls.h> 3557718be8SEnji Cooper 3657718be8SEnji Cooper #include <atf-c.h> 3757718be8SEnji Cooper #include <err.h> 3857718be8SEnji Cooper #include <errno.h> 3957718be8SEnji Cooper #include <fcntl.h> 4057718be8SEnji Cooper #include <stdio.h> 4157718be8SEnji Cooper #include <stdlib.h> 4257718be8SEnji Cooper #include <string.h> 4357718be8SEnji Cooper #include <unistd.h> 4457718be8SEnji Cooper #include <util.h> 4557718be8SEnji Cooper 4657718be8SEnji Cooper #include "../../h_macros.h" 4757718be8SEnji Cooper 4857718be8SEnji Cooper ATF_TC(makelwp); 4957718be8SEnji Cooper ATF_TC_HEAD(makelwp, tc) 5057718be8SEnji Cooper { 5157718be8SEnji Cooper 5257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "tests that lwps can be attached to " 5357718be8SEnji Cooper "processes"); 5457718be8SEnji Cooper } 5557718be8SEnji Cooper 5657718be8SEnji Cooper ATF_TC_BODY(makelwp, tc) 5757718be8SEnji Cooper { 5857718be8SEnji Cooper struct lwp *l; 5957718be8SEnji Cooper pid_t pid; 6057718be8SEnji Cooper 6157718be8SEnji Cooper rump_init(); 6257718be8SEnji Cooper RZ(rump_pub_lwproc_newlwp(0)); 6357718be8SEnji Cooper ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(37), ESRCH); 6457718be8SEnji Cooper l = rump_pub_lwproc_curlwp(); 6557718be8SEnji Cooper 6657718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 6757718be8SEnji Cooper ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); 6857718be8SEnji Cooper l = rump_pub_lwproc_curlwp(); 6957718be8SEnji Cooper 7057718be8SEnji Cooper RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); 7157718be8SEnji Cooper ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); 7257718be8SEnji Cooper 7357718be8SEnji Cooper pid = rump_sys_getpid(); 7457718be8SEnji Cooper ATF_REQUIRE(pid != -1 && pid != 0); 7557718be8SEnji Cooper } 7657718be8SEnji Cooper 7757718be8SEnji Cooper ATF_TC(proccreds); 7857718be8SEnji Cooper ATF_TC_HEAD(proccreds, tc) 7957718be8SEnji Cooper { 8057718be8SEnji Cooper 8157718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that procs have different creds"); 8257718be8SEnji Cooper } 8357718be8SEnji Cooper 8457718be8SEnji Cooper ATF_TC_BODY(proccreds, tc) 8557718be8SEnji Cooper { 8657718be8SEnji Cooper struct lwp *l1, *l2; 8757718be8SEnji Cooper 8857718be8SEnji Cooper rump_init(); 8957718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 9057718be8SEnji Cooper l1 = rump_pub_lwproc_curlwp(); 91*640235e2SEnji Cooper RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); 9257718be8SEnji Cooper 9357718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 9457718be8SEnji Cooper l2 = rump_pub_lwproc_curlwp(); 9557718be8SEnji Cooper 9657718be8SEnji Cooper RL(rump_sys_setuid(22)); 9757718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 9857718be8SEnji Cooper 9957718be8SEnji Cooper rump_pub_lwproc_switch(l1); 10057718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 0); /* from parent, proc0 */ 10157718be8SEnji Cooper RL(rump_sys_setuid(11)); 10257718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 11); 10357718be8SEnji Cooper 10457718be8SEnji Cooper rump_pub_lwproc_switch(l2); 10557718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 10657718be8SEnji Cooper rump_pub_lwproc_newlwp(rump_sys_getpid()); 10757718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 10857718be8SEnji Cooper } 10957718be8SEnji Cooper 11057718be8SEnji Cooper 11157718be8SEnji Cooper ATF_TC(inherit); 11257718be8SEnji Cooper ATF_TC_HEAD(inherit, tc) 11357718be8SEnji Cooper { 11457718be8SEnji Cooper 11557718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "new processes inherit creds from " 11657718be8SEnji Cooper "parents"); 11757718be8SEnji Cooper } 11857718be8SEnji Cooper 11957718be8SEnji Cooper ATF_TC_BODY(inherit, tc) 12057718be8SEnji Cooper { 12157718be8SEnji Cooper 12257718be8SEnji Cooper rump_init(); 12357718be8SEnji Cooper 12457718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 12557718be8SEnji Cooper RL(rump_sys_setuid(66)); 12657718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 66); 12757718be8SEnji Cooper 12857718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 12957718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 66); 13057718be8SEnji Cooper 13157718be8SEnji Cooper /* release lwp and proc */ 13257718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 13357718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 0); 13457718be8SEnji Cooper } 13557718be8SEnji Cooper 13657718be8SEnji Cooper ATF_TC(lwps); 13757718be8SEnji Cooper ATF_TC_HEAD(lwps, tc) 13857718be8SEnji Cooper { 13957718be8SEnji Cooper 14057718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "proc can hold many lwps and is " 14157718be8SEnji Cooper "automatically g/c'd when the last one exits"); 14257718be8SEnji Cooper } 14357718be8SEnji Cooper 14457718be8SEnji Cooper #define LOOPS 128 14557718be8SEnji Cooper ATF_TC_BODY(lwps, tc) 14657718be8SEnji Cooper { 14757718be8SEnji Cooper struct lwp *l[LOOPS]; 14857718be8SEnji Cooper pid_t mypid; 14957718be8SEnji Cooper struct lwp *l_orig; 15057718be8SEnji Cooper int i; 15157718be8SEnji Cooper 15257718be8SEnji Cooper rump_init(); 15357718be8SEnji Cooper 15457718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 15557718be8SEnji Cooper mypid = rump_sys_getpid(); 15657718be8SEnji Cooper RL(rump_sys_setuid(375)); 15757718be8SEnji Cooper 15857718be8SEnji Cooper l_orig = rump_pub_lwproc_curlwp(); 15957718be8SEnji Cooper for (i = 0; i < LOOPS; i++) { 16057718be8SEnji Cooper mypid = rump_sys_getpid(); 16157718be8SEnji Cooper ATF_REQUIRE(mypid != -1 && mypid != 0); 16257718be8SEnji Cooper RZ(rump_pub_lwproc_newlwp(mypid)); 16357718be8SEnji Cooper l[i] = rump_pub_lwproc_curlwp(); 16457718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 375); 16557718be8SEnji Cooper } 16657718be8SEnji Cooper 16757718be8SEnji Cooper rump_pub_lwproc_switch(l_orig); 16857718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 16957718be8SEnji Cooper for (i = 0; i < LOOPS; i++) { 17057718be8SEnji Cooper rump_pub_lwproc_switch(l[i]); 17157718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getpid(), mypid); 17257718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 375); 17357718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 17457718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getpid(), 1); 17557718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 0); 17657718be8SEnji Cooper } 17757718be8SEnji Cooper 17857718be8SEnji Cooper ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(mypid), ESRCH); 17957718be8SEnji Cooper } 18057718be8SEnji Cooper 18157718be8SEnji Cooper ATF_TC(nolwprelease); 18257718be8SEnji Cooper ATF_TC_HEAD(nolwprelease, tc) 18357718be8SEnji Cooper { 18457718be8SEnji Cooper 18557718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that lwp context is required " 18657718be8SEnji Cooper "for lwproc_releaselwp()"); 18757718be8SEnji Cooper } 18857718be8SEnji Cooper 18957718be8SEnji Cooper ATF_TC_BODY(nolwprelease, tc) 19057718be8SEnji Cooper { 19157718be8SEnji Cooper int status; 19257718be8SEnji Cooper 19357718be8SEnji Cooper switch (fork()) { 19457718be8SEnji Cooper case 0: 19557718be8SEnji Cooper rump_init(); 19657718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 19757718be8SEnji Cooper atf_tc_fail("survived"); 19857718be8SEnji Cooper break; 19957718be8SEnji Cooper case -1: 20057718be8SEnji Cooper atf_tc_fail_errno("fork"); 20157718be8SEnji Cooper break; 20257718be8SEnji Cooper default: 20357718be8SEnji Cooper wait(&status); 20457718be8SEnji Cooper ATF_REQUIRE(WIFSIGNALED(status)); 20557718be8SEnji Cooper ATF_REQUIRE_EQ(WTERMSIG(status), SIGABRT); 20657718be8SEnji Cooper 20757718be8SEnji Cooper } 20857718be8SEnji Cooper } 20957718be8SEnji Cooper 21057718be8SEnji Cooper ATF_TC(nolwp); 21157718be8SEnji Cooper ATF_TC_HEAD(nolwp, tc) 21257718be8SEnji Cooper { 21357718be8SEnji Cooper 21457718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that curlwp for an implicit " 21557718be8SEnji Cooper "context is NULL"); 21657718be8SEnji Cooper } 21757718be8SEnji Cooper 21857718be8SEnji Cooper ATF_TC_BODY(nolwp, tc) 21957718be8SEnji Cooper { 22057718be8SEnji Cooper 22157718be8SEnji Cooper rump_init(); 22257718be8SEnji Cooper ATF_REQUIRE_EQ(rump_pub_lwproc_curlwp(), NULL); 22357718be8SEnji Cooper } 22457718be8SEnji Cooper 22557718be8SEnji Cooper ATF_TC(nullswitch); 22657718be8SEnji Cooper ATF_TC_HEAD(nullswitch, tc) 22757718be8SEnji Cooper { 22857718be8SEnji Cooper 22957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that switching to NULL marks " 23057718be8SEnji Cooper "current lwp as not running"); 23157718be8SEnji Cooper } 23257718be8SEnji Cooper 23357718be8SEnji Cooper ATF_TC_BODY(nullswitch, tc) 23457718be8SEnji Cooper { 23557718be8SEnji Cooper struct lwp *l; 23657718be8SEnji Cooper 23757718be8SEnji Cooper rump_init(); 23857718be8SEnji Cooper RZ(rump_pub_lwproc_newlwp(0)); 23957718be8SEnji Cooper l = rump_pub_lwproc_curlwp(); 24057718be8SEnji Cooper rump_pub_lwproc_switch(NULL); 24157718be8SEnji Cooper /* if remains LP_RUNNING, next call will panic */ 24257718be8SEnji Cooper rump_pub_lwproc_switch(l); 24357718be8SEnji Cooper } 24457718be8SEnji Cooper 24557718be8SEnji Cooper ATF_TC(rfork); 24657718be8SEnji Cooper ATF_TC_HEAD(rfork, tc) 24757718be8SEnji Cooper { 24857718be8SEnji Cooper 24957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that fork shares fd's"); 25057718be8SEnji Cooper } 25157718be8SEnji Cooper 25257718be8SEnji Cooper ATF_TC_BODY(rfork, tc) 25357718be8SEnji Cooper { 25457718be8SEnji Cooper struct stat sb; 25557718be8SEnji Cooper struct lwp *l, *l2; 25657718be8SEnji Cooper int fd; 25757718be8SEnji Cooper 25857718be8SEnji Cooper RZ(rump_init()); 25957718be8SEnji Cooper 26057718be8SEnji Cooper ATF_REQUIRE_EQ(rump_pub_lwproc_rfork(RUMP_RFFDG|RUMP_RFCFDG), EINVAL); 26157718be8SEnji Cooper 26257718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(0)); 26357718be8SEnji Cooper l = rump_pub_lwproc_curlwp(); 26457718be8SEnji Cooper 26557718be8SEnji Cooper RL(fd = rump_sys_open("/file", O_RDWR | O_CREAT, 0777)); 26657718be8SEnji Cooper 26757718be8SEnji Cooper /* ok, first check rfork(RUMP_RFCFDG) does *not* preserve fd's */ 26857718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 26957718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, rump_sys_write(fd, &fd, sizeof(fd)) == -1); 27057718be8SEnji Cooper 27157718be8SEnji Cooper /* then check that rfork(0) does */ 27257718be8SEnji Cooper rump_pub_lwproc_switch(l); 27357718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(0)); 27457718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); 27557718be8SEnji Cooper RL(rump_sys_fstat(fd, &sb)); 27657718be8SEnji Cooper l2 = rump_pub_lwproc_curlwp(); 27757718be8SEnji Cooper 27857718be8SEnji Cooper /* 27957718be8SEnji Cooper * check that the shared fd table is really shared by 28057718be8SEnji Cooper * closing fd in parent 28157718be8SEnji Cooper */ 28257718be8SEnji Cooper rump_pub_lwproc_switch(l); 28357718be8SEnji Cooper RL(rump_sys_close(fd)); 28457718be8SEnji Cooper rump_pub_lwproc_switch(l2); 28557718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, rump_sys_fstat(fd, &sb) == -1); 28657718be8SEnji Cooper 28757718be8SEnji Cooper /* redo, this time copying the fd table instead of sharing it */ 28857718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 28957718be8SEnji Cooper rump_pub_lwproc_switch(l); 29057718be8SEnji Cooper RL(fd = rump_sys_open("/file", O_RDWR, 0777)); 29157718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFFDG)); 29257718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); 29357718be8SEnji Cooper RL(rump_sys_fstat(fd, &sb)); 29457718be8SEnji Cooper l2 = rump_pub_lwproc_curlwp(); 29557718be8SEnji Cooper 29657718be8SEnji Cooper /* check that the fd table is copied */ 29757718be8SEnji Cooper rump_pub_lwproc_switch(l); 29857718be8SEnji Cooper RL(rump_sys_close(fd)); 29957718be8SEnji Cooper rump_pub_lwproc_switch(l2); 30057718be8SEnji Cooper RL(rump_sys_fstat(fd, &sb)); 30157718be8SEnji Cooper ATF_REQUIRE_EQ(sb.st_size, sizeof(fd)); 30257718be8SEnji Cooper } 30357718be8SEnji Cooper 30457718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 30557718be8SEnji Cooper { 30657718be8SEnji Cooper 30757718be8SEnji Cooper ATF_TP_ADD_TC(tp, makelwp); 30857718be8SEnji Cooper ATF_TP_ADD_TC(tp, proccreds); 30957718be8SEnji Cooper ATF_TP_ADD_TC(tp, inherit); 31057718be8SEnji Cooper ATF_TP_ADD_TC(tp, lwps); 31157718be8SEnji Cooper ATF_TP_ADD_TC(tp, nolwprelease); 31257718be8SEnji Cooper ATF_TP_ADD_TC(tp, nolwp); 31357718be8SEnji Cooper ATF_TP_ADD_TC(tp, nullswitch); 31457718be8SEnji Cooper ATF_TP_ADD_TC(tp, rfork); 31557718be8SEnji Cooper 31657718be8SEnji Cooper return atf_no_error(); 31757718be8SEnji Cooper } 318