1*63d1fd59SEnji Cooper /* $NetBSD: t_lwproc.c,v 1.9 2017/01/13 21:30:43 christos 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> 32cdebaff8SEnji Cooper #include <sys/stat.h> 3357718be8SEnji Cooper 3457718be8SEnji Cooper #include <rump/rump.h> 3557718be8SEnji Cooper #include <rump/rump_syscalls.h> 3657718be8SEnji Cooper 3757718be8SEnji Cooper #include <atf-c.h> 3857718be8SEnji Cooper #include <err.h> 3957718be8SEnji Cooper #include <errno.h> 4057718be8SEnji Cooper #include <fcntl.h> 4157718be8SEnji Cooper #include <stdio.h> 4257718be8SEnji Cooper #include <stdlib.h> 4357718be8SEnji Cooper #include <string.h> 4457718be8SEnji Cooper #include <unistd.h> 4557718be8SEnji Cooper #include <util.h> 4657718be8SEnji Cooper 47*63d1fd59SEnji Cooper #include "h_macros.h" 4857718be8SEnji Cooper 4957718be8SEnji Cooper ATF_TC(makelwp); 5057718be8SEnji Cooper ATF_TC_HEAD(makelwp, tc) 5157718be8SEnji Cooper { 5257718be8SEnji Cooper 5357718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "tests that lwps can be attached to " 5457718be8SEnji Cooper "processes"); 5557718be8SEnji Cooper } 5657718be8SEnji Cooper 5757718be8SEnji Cooper ATF_TC_BODY(makelwp, tc) 5857718be8SEnji Cooper { 5957718be8SEnji Cooper struct lwp *l; 6057718be8SEnji Cooper pid_t pid; 6157718be8SEnji Cooper 6257718be8SEnji Cooper rump_init(); 6357718be8SEnji Cooper RZ(rump_pub_lwproc_newlwp(0)); 6457718be8SEnji Cooper ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(37), ESRCH); 6557718be8SEnji Cooper l = rump_pub_lwproc_curlwp(); 6657718be8SEnji Cooper 6757718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 6857718be8SEnji Cooper ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); 6957718be8SEnji Cooper l = rump_pub_lwproc_curlwp(); 7057718be8SEnji Cooper 7157718be8SEnji Cooper RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); 7257718be8SEnji Cooper ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); 7357718be8SEnji Cooper 7457718be8SEnji Cooper pid = rump_sys_getpid(); 7557718be8SEnji Cooper ATF_REQUIRE(pid != -1 && pid != 0); 7657718be8SEnji Cooper } 7757718be8SEnji Cooper 7857718be8SEnji Cooper ATF_TC(proccreds); 7957718be8SEnji Cooper ATF_TC_HEAD(proccreds, tc) 8057718be8SEnji Cooper { 8157718be8SEnji Cooper 8257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that procs have different creds"); 8357718be8SEnji Cooper } 8457718be8SEnji Cooper 8557718be8SEnji Cooper ATF_TC_BODY(proccreds, tc) 8657718be8SEnji Cooper { 8757718be8SEnji Cooper struct lwp *l1, *l2; 8857718be8SEnji Cooper 8957718be8SEnji Cooper rump_init(); 9057718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 9157718be8SEnji Cooper l1 = rump_pub_lwproc_curlwp(); 92640235e2SEnji Cooper RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); 9357718be8SEnji Cooper 9457718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 9557718be8SEnji Cooper l2 = rump_pub_lwproc_curlwp(); 9657718be8SEnji Cooper 9757718be8SEnji Cooper RL(rump_sys_setuid(22)); 9857718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 9957718be8SEnji Cooper 10057718be8SEnji Cooper rump_pub_lwproc_switch(l1); 10157718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 0); /* from parent, proc0 */ 10257718be8SEnji Cooper RL(rump_sys_setuid(11)); 10357718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 11); 10457718be8SEnji Cooper 10557718be8SEnji Cooper rump_pub_lwproc_switch(l2); 10657718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 10757718be8SEnji Cooper rump_pub_lwproc_newlwp(rump_sys_getpid()); 10857718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 22); 10957718be8SEnji Cooper } 11057718be8SEnji Cooper 11157718be8SEnji Cooper 11257718be8SEnji Cooper ATF_TC(inherit); 11357718be8SEnji Cooper ATF_TC_HEAD(inherit, tc) 11457718be8SEnji Cooper { 11557718be8SEnji Cooper 11657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "new processes inherit creds from " 11757718be8SEnji Cooper "parents"); 11857718be8SEnji Cooper } 11957718be8SEnji Cooper 12057718be8SEnji Cooper ATF_TC_BODY(inherit, tc) 12157718be8SEnji Cooper { 12257718be8SEnji Cooper 12357718be8SEnji Cooper rump_init(); 12457718be8SEnji Cooper 12557718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 12657718be8SEnji Cooper RL(rump_sys_setuid(66)); 12757718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 66); 12857718be8SEnji Cooper 12957718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 13057718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 66); 13157718be8SEnji Cooper 13257718be8SEnji Cooper /* release lwp and proc */ 13357718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 13457718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 0); 13557718be8SEnji Cooper } 13657718be8SEnji Cooper 13757718be8SEnji Cooper ATF_TC(lwps); 13857718be8SEnji Cooper ATF_TC_HEAD(lwps, tc) 13957718be8SEnji Cooper { 14057718be8SEnji Cooper 14157718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "proc can hold many lwps and is " 14257718be8SEnji Cooper "automatically g/c'd when the last one exits"); 14357718be8SEnji Cooper } 14457718be8SEnji Cooper 14557718be8SEnji Cooper #define LOOPS 128 14657718be8SEnji Cooper ATF_TC_BODY(lwps, tc) 14757718be8SEnji Cooper { 14857718be8SEnji Cooper struct lwp *l[LOOPS]; 14957718be8SEnji Cooper pid_t mypid; 15057718be8SEnji Cooper struct lwp *l_orig; 15157718be8SEnji Cooper int i; 15257718be8SEnji Cooper 15357718be8SEnji Cooper rump_init(); 15457718be8SEnji Cooper 15557718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 15657718be8SEnji Cooper mypid = rump_sys_getpid(); 15757718be8SEnji Cooper RL(rump_sys_setuid(375)); 15857718be8SEnji Cooper 15957718be8SEnji Cooper l_orig = rump_pub_lwproc_curlwp(); 16057718be8SEnji Cooper for (i = 0; i < LOOPS; i++) { 16157718be8SEnji Cooper mypid = rump_sys_getpid(); 16257718be8SEnji Cooper ATF_REQUIRE(mypid != -1 && mypid != 0); 16357718be8SEnji Cooper RZ(rump_pub_lwproc_newlwp(mypid)); 16457718be8SEnji Cooper l[i] = rump_pub_lwproc_curlwp(); 16557718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 375); 16657718be8SEnji Cooper } 16757718be8SEnji Cooper 16857718be8SEnji Cooper rump_pub_lwproc_switch(l_orig); 16957718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 17057718be8SEnji Cooper for (i = 0; i < LOOPS; i++) { 17157718be8SEnji Cooper rump_pub_lwproc_switch(l[i]); 17257718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getpid(), mypid); 17357718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 375); 17457718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 17557718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getpid(), 1); 17657718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_getuid(), 0); 17757718be8SEnji Cooper } 17857718be8SEnji Cooper 17957718be8SEnji Cooper ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(mypid), ESRCH); 18057718be8SEnji Cooper } 18157718be8SEnji Cooper 18257718be8SEnji Cooper ATF_TC(nolwprelease); 18357718be8SEnji Cooper ATF_TC_HEAD(nolwprelease, tc) 18457718be8SEnji Cooper { 18557718be8SEnji Cooper 18657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that lwp context is required " 18757718be8SEnji Cooper "for lwproc_releaselwp()"); 18857718be8SEnji Cooper } 18957718be8SEnji Cooper 19057718be8SEnji Cooper ATF_TC_BODY(nolwprelease, tc) 19157718be8SEnji Cooper { 19257718be8SEnji Cooper int status; 19357718be8SEnji Cooper 19457718be8SEnji Cooper switch (fork()) { 19557718be8SEnji Cooper case 0: 19657718be8SEnji Cooper rump_init(); 19757718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 19857718be8SEnji Cooper atf_tc_fail("survived"); 19957718be8SEnji Cooper break; 20057718be8SEnji Cooper case -1: 20157718be8SEnji Cooper atf_tc_fail_errno("fork"); 20257718be8SEnji Cooper break; 20357718be8SEnji Cooper default: 20457718be8SEnji Cooper wait(&status); 20557718be8SEnji Cooper ATF_REQUIRE(WIFSIGNALED(status)); 20657718be8SEnji Cooper ATF_REQUIRE_EQ(WTERMSIG(status), SIGABRT); 20757718be8SEnji Cooper 20857718be8SEnji Cooper } 20957718be8SEnji Cooper } 21057718be8SEnji Cooper 21157718be8SEnji Cooper ATF_TC(nolwp); 21257718be8SEnji Cooper ATF_TC_HEAD(nolwp, tc) 21357718be8SEnji Cooper { 21457718be8SEnji Cooper 21557718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that curlwp for an implicit " 21657718be8SEnji Cooper "context is NULL"); 21757718be8SEnji Cooper } 21857718be8SEnji Cooper 21957718be8SEnji Cooper ATF_TC_BODY(nolwp, tc) 22057718be8SEnji Cooper { 22157718be8SEnji Cooper 22257718be8SEnji Cooper rump_init(); 22357718be8SEnji Cooper ATF_REQUIRE_EQ(rump_pub_lwproc_curlwp(), NULL); 22457718be8SEnji Cooper } 22557718be8SEnji Cooper 22657718be8SEnji Cooper ATF_TC(nullswitch); 22757718be8SEnji Cooper ATF_TC_HEAD(nullswitch, tc) 22857718be8SEnji Cooper { 22957718be8SEnji Cooper 23057718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that switching to NULL marks " 23157718be8SEnji Cooper "current lwp as not running"); 23257718be8SEnji Cooper } 23357718be8SEnji Cooper 23457718be8SEnji Cooper ATF_TC_BODY(nullswitch, tc) 23557718be8SEnji Cooper { 23657718be8SEnji Cooper struct lwp *l; 23757718be8SEnji Cooper 23857718be8SEnji Cooper rump_init(); 23957718be8SEnji Cooper RZ(rump_pub_lwproc_newlwp(0)); 24057718be8SEnji Cooper l = rump_pub_lwproc_curlwp(); 24157718be8SEnji Cooper rump_pub_lwproc_switch(NULL); 24257718be8SEnji Cooper /* if remains LP_RUNNING, next call will panic */ 24357718be8SEnji Cooper rump_pub_lwproc_switch(l); 24457718be8SEnji Cooper } 24557718be8SEnji Cooper 24657718be8SEnji Cooper ATF_TC(rfork); 24757718be8SEnji Cooper ATF_TC_HEAD(rfork, tc) 24857718be8SEnji Cooper { 24957718be8SEnji Cooper 25057718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that fork shares fd's"); 25157718be8SEnji Cooper } 25257718be8SEnji Cooper 25357718be8SEnji Cooper ATF_TC_BODY(rfork, tc) 25457718be8SEnji Cooper { 25557718be8SEnji Cooper struct stat sb; 25657718be8SEnji Cooper struct lwp *l, *l2; 25757718be8SEnji Cooper int fd; 25857718be8SEnji Cooper 25957718be8SEnji Cooper RZ(rump_init()); 26057718be8SEnji Cooper 26157718be8SEnji Cooper ATF_REQUIRE_EQ(rump_pub_lwproc_rfork(RUMP_RFFDG|RUMP_RFCFDG), EINVAL); 26257718be8SEnji Cooper 26357718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(0)); 26457718be8SEnji Cooper l = rump_pub_lwproc_curlwp(); 26557718be8SEnji Cooper 26657718be8SEnji Cooper RL(fd = rump_sys_open("/file", O_RDWR | O_CREAT, 0777)); 26757718be8SEnji Cooper 26857718be8SEnji Cooper /* ok, first check rfork(RUMP_RFCFDG) does *not* preserve fd's */ 26957718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 27057718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, rump_sys_write(fd, &fd, sizeof(fd)) == -1); 27157718be8SEnji Cooper 27257718be8SEnji Cooper /* then check that rfork(0) does */ 27357718be8SEnji Cooper rump_pub_lwproc_switch(l); 27457718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(0)); 27557718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); 27657718be8SEnji Cooper RL(rump_sys_fstat(fd, &sb)); 27757718be8SEnji Cooper l2 = rump_pub_lwproc_curlwp(); 27857718be8SEnji Cooper 27957718be8SEnji Cooper /* 28057718be8SEnji Cooper * check that the shared fd table is really shared by 28157718be8SEnji Cooper * closing fd in parent 28257718be8SEnji Cooper */ 28357718be8SEnji Cooper rump_pub_lwproc_switch(l); 28457718be8SEnji Cooper RL(rump_sys_close(fd)); 28557718be8SEnji Cooper rump_pub_lwproc_switch(l2); 28657718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, rump_sys_fstat(fd, &sb) == -1); 28757718be8SEnji Cooper 28857718be8SEnji Cooper /* redo, this time copying the fd table instead of sharing it */ 28957718be8SEnji Cooper rump_pub_lwproc_releaselwp(); 29057718be8SEnji Cooper rump_pub_lwproc_switch(l); 29157718be8SEnji Cooper RL(fd = rump_sys_open("/file", O_RDWR, 0777)); 29257718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFFDG)); 29357718be8SEnji Cooper ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); 29457718be8SEnji Cooper RL(rump_sys_fstat(fd, &sb)); 29557718be8SEnji Cooper l2 = rump_pub_lwproc_curlwp(); 29657718be8SEnji Cooper 29757718be8SEnji Cooper /* check that the fd table is copied */ 29857718be8SEnji Cooper rump_pub_lwproc_switch(l); 29957718be8SEnji Cooper RL(rump_sys_close(fd)); 30057718be8SEnji Cooper rump_pub_lwproc_switch(l2); 30157718be8SEnji Cooper RL(rump_sys_fstat(fd, &sb)); 30257718be8SEnji Cooper ATF_REQUIRE_EQ(sb.st_size, sizeof(fd)); 30357718be8SEnji Cooper } 30457718be8SEnji Cooper 30557718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 30657718be8SEnji Cooper { 30757718be8SEnji Cooper 30857718be8SEnji Cooper ATF_TP_ADD_TC(tp, makelwp); 30957718be8SEnji Cooper ATF_TP_ADD_TC(tp, proccreds); 31057718be8SEnji Cooper ATF_TP_ADD_TC(tp, inherit); 31157718be8SEnji Cooper ATF_TP_ADD_TC(tp, lwps); 31257718be8SEnji Cooper ATF_TP_ADD_TC(tp, nolwprelease); 31357718be8SEnji Cooper ATF_TP_ADD_TC(tp, nolwp); 31457718be8SEnji Cooper ATF_TP_ADD_TC(tp, nullswitch); 31557718be8SEnji Cooper ATF_TP_ADD_TC(tp, rfork); 31657718be8SEnji Cooper 31757718be8SEnji Cooper return atf_no_error(); 31857718be8SEnji Cooper } 319