1*2ddceed1Sad /* $NetBSD: t_lwproc.c,v 1.10 2020/01/08 17:38:43 ad Exp $ */
252e6ad15Spooka
352e6ad15Spooka /*
452e6ad15Spooka * Copyright (c) 2010 The NetBSD Foundation, Inc.
552e6ad15Spooka * All rights reserved.
652e6ad15Spooka *
752e6ad15Spooka * Redistribution and use in source and binary forms, with or without
852e6ad15Spooka * modification, are permitted provided that the following conditions
952e6ad15Spooka * are met:
1052e6ad15Spooka * 1. Redistributions of source code must retain the above copyright
1152e6ad15Spooka * notice, this list of conditions and the following disclaimer.
1252e6ad15Spooka * 2. Redistributions in binary form must reproduce the above copyright
1352e6ad15Spooka * notice, this list of conditions and the following disclaimer in the
1452e6ad15Spooka * documentation and/or other materials provided with the distribution.
1552e6ad15Spooka *
1652e6ad15Spooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
1752e6ad15Spooka * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
1852e6ad15Spooka * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1952e6ad15Spooka * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2052e6ad15Spooka * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
2152e6ad15Spooka * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2252e6ad15Spooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2352e6ad15Spooka * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2452e6ad15Spooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2552e6ad15Spooka * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2652e6ad15Spooka * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2752e6ad15Spooka * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2852e6ad15Spooka */
2952e6ad15Spooka
3052e6ad15Spooka #include <sys/types.h>
3152e6ad15Spooka #include <sys/wait.h>
3225f1087aSchristos #include <sys/stat.h>
3352e6ad15Spooka
3452e6ad15Spooka #include <rump/rump.h>
3552e6ad15Spooka #include <rump/rump_syscalls.h>
3652e6ad15Spooka
3752e6ad15Spooka #include <atf-c.h>
3852e6ad15Spooka #include <err.h>
3952e6ad15Spooka #include <errno.h>
405c3365ceSpooka #include <fcntl.h>
4152e6ad15Spooka #include <stdio.h>
4252e6ad15Spooka #include <stdlib.h>
4352e6ad15Spooka #include <string.h>
4452e6ad15Spooka #include <unistd.h>
4552e6ad15Spooka #include <util.h>
4652e6ad15Spooka
47c54cb811Schristos #include "h_macros.h"
4852e6ad15Spooka
4952e6ad15Spooka ATF_TC(makelwp);
ATF_TC_HEAD(makelwp,tc)5052e6ad15Spooka ATF_TC_HEAD(makelwp, tc)
5152e6ad15Spooka {
5252e6ad15Spooka
5352e6ad15Spooka atf_tc_set_md_var(tc, "descr", "tests that lwps can be attached to "
5452e6ad15Spooka "processes");
5552e6ad15Spooka }
5652e6ad15Spooka
ATF_TC_BODY(makelwp,tc)5752e6ad15Spooka ATF_TC_BODY(makelwp, tc)
5852e6ad15Spooka {
5952e6ad15Spooka struct lwp *l;
6052e6ad15Spooka pid_t pid;
6152e6ad15Spooka
6252e6ad15Spooka rump_init();
6352e6ad15Spooka RZ(rump_pub_lwproc_newlwp(0));
6452e6ad15Spooka ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(37), ESRCH);
6552e6ad15Spooka l = rump_pub_lwproc_curlwp();
6652e6ad15Spooka
675c3365ceSpooka RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
6852e6ad15Spooka ATF_REQUIRE(rump_pub_lwproc_curlwp() != l);
6952e6ad15Spooka l = rump_pub_lwproc_curlwp();
7052e6ad15Spooka
7152e6ad15Spooka RZ(rump_pub_lwproc_newlwp(rump_sys_getpid()));
7252e6ad15Spooka ATF_REQUIRE(rump_pub_lwproc_curlwp() != l);
7352e6ad15Spooka
7452e6ad15Spooka pid = rump_sys_getpid();
7552e6ad15Spooka ATF_REQUIRE(pid != -1 && pid != 0);
7652e6ad15Spooka }
7752e6ad15Spooka
7852e6ad15Spooka ATF_TC(proccreds);
ATF_TC_HEAD(proccreds,tc)7952e6ad15Spooka ATF_TC_HEAD(proccreds, tc)
8052e6ad15Spooka {
8152e6ad15Spooka
8252e6ad15Spooka atf_tc_set_md_var(tc, "descr", "check that procs have different creds");
8352e6ad15Spooka }
8452e6ad15Spooka
ATF_TC_BODY(proccreds,tc)8552e6ad15Spooka ATF_TC_BODY(proccreds, tc)
8652e6ad15Spooka {
8752e6ad15Spooka struct lwp *l1, *l2;
8852e6ad15Spooka
8952e6ad15Spooka rump_init();
905c3365ceSpooka RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
9152e6ad15Spooka l1 = rump_pub_lwproc_curlwp();
92fff8d9a1Spooka RZ(rump_pub_lwproc_newlwp(rump_sys_getpid()));
9352e6ad15Spooka
945c3365ceSpooka RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
9552e6ad15Spooka l2 = rump_pub_lwproc_curlwp();
9652e6ad15Spooka
9752e6ad15Spooka RL(rump_sys_setuid(22));
9852e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
9952e6ad15Spooka
10052e6ad15Spooka rump_pub_lwproc_switch(l1);
10152e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 0); /* from parent, proc0 */
10252e6ad15Spooka RL(rump_sys_setuid(11));
10352e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 11);
10452e6ad15Spooka
10552e6ad15Spooka rump_pub_lwproc_switch(l2);
10652e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
10752e6ad15Spooka rump_pub_lwproc_newlwp(rump_sys_getpid());
10852e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
10952e6ad15Spooka }
11052e6ad15Spooka
11152e6ad15Spooka
11252e6ad15Spooka ATF_TC(inherit);
ATF_TC_HEAD(inherit,tc)11352e6ad15Spooka ATF_TC_HEAD(inherit, tc)
11452e6ad15Spooka {
11552e6ad15Spooka
11652e6ad15Spooka atf_tc_set_md_var(tc, "descr", "new processes inherit creds from "
11752e6ad15Spooka "parents");
11852e6ad15Spooka }
11952e6ad15Spooka
ATF_TC_BODY(inherit,tc)12052e6ad15Spooka ATF_TC_BODY(inherit, tc)
12152e6ad15Spooka {
12252e6ad15Spooka
12352e6ad15Spooka rump_init();
12452e6ad15Spooka
1255c3365ceSpooka RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
12652e6ad15Spooka RL(rump_sys_setuid(66));
12752e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 66);
12852e6ad15Spooka
1295c3365ceSpooka RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
13052e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 66);
13152e6ad15Spooka
13252e6ad15Spooka /* release lwp and proc */
13352e6ad15Spooka rump_pub_lwproc_releaselwp();
13452e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 0);
13552e6ad15Spooka }
13652e6ad15Spooka
13752e6ad15Spooka ATF_TC(lwps);
ATF_TC_HEAD(lwps,tc)13852e6ad15Spooka ATF_TC_HEAD(lwps, tc)
13952e6ad15Spooka {
14052e6ad15Spooka
14152e6ad15Spooka atf_tc_set_md_var(tc, "descr", "proc can hold many lwps and is "
14252e6ad15Spooka "automatically g/c'd when the last one exits");
14352e6ad15Spooka }
14452e6ad15Spooka
14552e6ad15Spooka #define LOOPS 128
ATF_TC_BODY(lwps,tc)14652e6ad15Spooka ATF_TC_BODY(lwps, tc)
14752e6ad15Spooka {
14852e6ad15Spooka struct lwp *l[LOOPS];
14952e6ad15Spooka pid_t mypid;
15052e6ad15Spooka struct lwp *l_orig;
15152e6ad15Spooka int i;
15252e6ad15Spooka
15352e6ad15Spooka rump_init();
15452e6ad15Spooka
1555c3365ceSpooka RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
15652e6ad15Spooka mypid = rump_sys_getpid();
15752e6ad15Spooka RL(rump_sys_setuid(375));
15852e6ad15Spooka
15952e6ad15Spooka l_orig = rump_pub_lwproc_curlwp();
16052e6ad15Spooka for (i = 0; i < LOOPS; i++) {
16152e6ad15Spooka mypid = rump_sys_getpid();
16252e6ad15Spooka ATF_REQUIRE(mypid != -1 && mypid != 0);
16352e6ad15Spooka RZ(rump_pub_lwproc_newlwp(mypid));
16452e6ad15Spooka l[i] = rump_pub_lwproc_curlwp();
16552e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 375);
16652e6ad15Spooka }
16752e6ad15Spooka
16852e6ad15Spooka rump_pub_lwproc_switch(l_orig);
16952e6ad15Spooka rump_pub_lwproc_releaselwp();
17052e6ad15Spooka for (i = 0; i < LOOPS; i++) {
17152e6ad15Spooka rump_pub_lwproc_switch(l[i]);
17252e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getpid(), mypid);
17352e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 375);
17452e6ad15Spooka rump_pub_lwproc_releaselwp();
175a745e325Spooka ATF_REQUIRE_EQ(rump_sys_getpid(), 1);
17652e6ad15Spooka ATF_REQUIRE_EQ(rump_sys_getuid(), 0);
17752e6ad15Spooka }
17852e6ad15Spooka
17952e6ad15Spooka ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(mypid), ESRCH);
18052e6ad15Spooka }
18152e6ad15Spooka
18252e6ad15Spooka ATF_TC(nolwprelease);
ATF_TC_HEAD(nolwprelease,tc)18352e6ad15Spooka ATF_TC_HEAD(nolwprelease, tc)
18452e6ad15Spooka {
18552e6ad15Spooka
18652e6ad15Spooka atf_tc_set_md_var(tc, "descr", "check that lwp context is required "
18752e6ad15Spooka "for lwproc_releaselwp()");
18852e6ad15Spooka }
18952e6ad15Spooka
ATF_TC_BODY(nolwprelease,tc)19052e6ad15Spooka ATF_TC_BODY(nolwprelease, tc)
19152e6ad15Spooka {
19252e6ad15Spooka int status;
19352e6ad15Spooka
19452e6ad15Spooka switch (fork()) {
19552e6ad15Spooka case 0:
19652e6ad15Spooka rump_init();
19752e6ad15Spooka rump_pub_lwproc_releaselwp();
19852e6ad15Spooka atf_tc_fail("survived");
19952e6ad15Spooka break;
20052e6ad15Spooka case -1:
20152e6ad15Spooka atf_tc_fail_errno("fork");
20252e6ad15Spooka break;
20352e6ad15Spooka default:
20452e6ad15Spooka wait(&status);
20552e6ad15Spooka ATF_REQUIRE(WIFSIGNALED(status));
20652e6ad15Spooka ATF_REQUIRE_EQ(WTERMSIG(status), SIGABRT);
20752e6ad15Spooka
20852e6ad15Spooka }
20952e6ad15Spooka }
21052e6ad15Spooka
21152977569Spooka ATF_TC(nolwp);
ATF_TC_HEAD(nolwp,tc)21252977569Spooka ATF_TC_HEAD(nolwp, tc)
21352977569Spooka {
21452977569Spooka
21552977569Spooka atf_tc_set_md_var(tc, "descr", "check that curlwp for an implicit "
21652977569Spooka "context is NULL");
21752977569Spooka }
21852977569Spooka
ATF_TC_BODY(nolwp,tc)21952977569Spooka ATF_TC_BODY(nolwp, tc)
22052977569Spooka {
22152977569Spooka
22252977569Spooka rump_init();
22352977569Spooka ATF_REQUIRE_EQ(rump_pub_lwproc_curlwp(), NULL);
22452977569Spooka }
22552977569Spooka
226d85e9c34Spooka ATF_TC(nullswitch);
ATF_TC_HEAD(nullswitch,tc)227d85e9c34Spooka ATF_TC_HEAD(nullswitch, tc)
228d85e9c34Spooka {
229d85e9c34Spooka
230d85e9c34Spooka atf_tc_set_md_var(tc, "descr", "check that switching to NULL marks "
231d85e9c34Spooka "current lwp as not running");
232d85e9c34Spooka }
233d85e9c34Spooka
ATF_TC_BODY(nullswitch,tc)234d85e9c34Spooka ATF_TC_BODY(nullswitch, tc)
235d85e9c34Spooka {
236d85e9c34Spooka struct lwp *l;
237d85e9c34Spooka
238d85e9c34Spooka rump_init();
239d85e9c34Spooka RZ(rump_pub_lwproc_newlwp(0));
240d85e9c34Spooka l = rump_pub_lwproc_curlwp();
241d85e9c34Spooka rump_pub_lwproc_switch(NULL);
242*2ddceed1Sad /* if remains LW_RUNNING, next call will panic */
243d85e9c34Spooka rump_pub_lwproc_switch(l);
244d85e9c34Spooka }
245d85e9c34Spooka
2465c3365ceSpooka ATF_TC(rfork);
ATF_TC_HEAD(rfork,tc)2475c3365ceSpooka ATF_TC_HEAD(rfork, tc)
2485c3365ceSpooka {
2495c3365ceSpooka
2505c3365ceSpooka atf_tc_set_md_var(tc, "descr", "check that fork shares fd's");
2515c3365ceSpooka }
2525c3365ceSpooka
ATF_TC_BODY(rfork,tc)2535c3365ceSpooka ATF_TC_BODY(rfork, tc)
2545c3365ceSpooka {
2555c3365ceSpooka struct stat sb;
2565c3365ceSpooka struct lwp *l, *l2;
2575c3365ceSpooka int fd;
2585c3365ceSpooka
2595c3365ceSpooka RZ(rump_init());
2605c3365ceSpooka
2615c3365ceSpooka ATF_REQUIRE_EQ(rump_pub_lwproc_rfork(RUMP_RFFDG|RUMP_RFCFDG), EINVAL);
2625c3365ceSpooka
2635c3365ceSpooka RZ(rump_pub_lwproc_rfork(0));
2645c3365ceSpooka l = rump_pub_lwproc_curlwp();
2655c3365ceSpooka
2665c3365ceSpooka RL(fd = rump_sys_open("/file", O_RDWR | O_CREAT, 0777));
2675c3365ceSpooka
2685c3365ceSpooka /* ok, first check rfork(RUMP_RFCFDG) does *not* preserve fd's */
2695c3365ceSpooka RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
2705c3365ceSpooka ATF_REQUIRE_ERRNO(EBADF, rump_sys_write(fd, &fd, sizeof(fd)) == -1);
2715c3365ceSpooka
2725c3365ceSpooka /* then check that rfork(0) does */
2735c3365ceSpooka rump_pub_lwproc_switch(l);
2745c3365ceSpooka RZ(rump_pub_lwproc_rfork(0));
2755c3365ceSpooka ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd));
2765c3365ceSpooka RL(rump_sys_fstat(fd, &sb));
2775c3365ceSpooka l2 = rump_pub_lwproc_curlwp();
2785c3365ceSpooka
2795c3365ceSpooka /*
2805c3365ceSpooka * check that the shared fd table is really shared by
2815c3365ceSpooka * closing fd in parent
2825c3365ceSpooka */
2835c3365ceSpooka rump_pub_lwproc_switch(l);
2845c3365ceSpooka RL(rump_sys_close(fd));
2855c3365ceSpooka rump_pub_lwproc_switch(l2);
2865c3365ceSpooka ATF_REQUIRE_ERRNO(EBADF, rump_sys_fstat(fd, &sb) == -1);
2875c3365ceSpooka
2885c3365ceSpooka /* redo, this time copying the fd table instead of sharing it */
2895c3365ceSpooka rump_pub_lwproc_releaselwp();
2905c3365ceSpooka rump_pub_lwproc_switch(l);
2915c3365ceSpooka RL(fd = rump_sys_open("/file", O_RDWR, 0777));
2925c3365ceSpooka RZ(rump_pub_lwproc_rfork(RUMP_RFFDG));
2935c3365ceSpooka ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd));
2945c3365ceSpooka RL(rump_sys_fstat(fd, &sb));
2955c3365ceSpooka l2 = rump_pub_lwproc_curlwp();
2965c3365ceSpooka
2975c3365ceSpooka /* check that the fd table is copied */
2985c3365ceSpooka rump_pub_lwproc_switch(l);
2995c3365ceSpooka RL(rump_sys_close(fd));
3005c3365ceSpooka rump_pub_lwproc_switch(l2);
3015c3365ceSpooka RL(rump_sys_fstat(fd, &sb));
3025c3365ceSpooka ATF_REQUIRE_EQ(sb.st_size, sizeof(fd));
3035c3365ceSpooka }
3045c3365ceSpooka
ATF_TP_ADD_TCS(tp)30552e6ad15Spooka ATF_TP_ADD_TCS(tp)
30652e6ad15Spooka {
30752e6ad15Spooka
30852e6ad15Spooka ATF_TP_ADD_TC(tp, makelwp);
30952e6ad15Spooka ATF_TP_ADD_TC(tp, proccreds);
31052e6ad15Spooka ATF_TP_ADD_TC(tp, inherit);
31152e6ad15Spooka ATF_TP_ADD_TC(tp, lwps);
31252e6ad15Spooka ATF_TP_ADD_TC(tp, nolwprelease);
31352977569Spooka ATF_TP_ADD_TC(tp, nolwp);
314d85e9c34Spooka ATF_TP_ADD_TC(tp, nullswitch);
3155c3365ceSpooka ATF_TP_ADD_TC(tp, rfork);
31652e6ad15Spooka
31752e6ad15Spooka return atf_no_error();
31852e6ad15Spooka }
319