Home | History | Annotate | Line # | Download | only in sys
      1  1.6       mrg /*	$NetBSD: t_socket.c,v 1.6 2019/10/06 01:05:36 mrg Exp $	*/
      2  1.1    jruoho 
      3  1.1    jruoho #include <sys/types.h>
      4  1.1    jruoho #include <sys/mount.h>
      5  1.1    jruoho #include <sys/socket.h>
      6  1.1    jruoho #include <sys/un.h>
      7  1.1    jruoho 
      8  1.1    jruoho #include <rump/rump.h>
      9  1.1    jruoho #include <rump/rump_syscalls.h>
     10  1.1    jruoho 
     11  1.1    jruoho #include <atf-c.h>
     12  1.1    jruoho #include <fcntl.h>
     13  1.1    jruoho #include <err.h>
     14  1.1    jruoho #include <errno.h>
     15  1.1    jruoho #include <stdio.h>
     16  1.1    jruoho #include <stdlib.h>
     17  1.1    jruoho #include <string.h>
     18  1.1    jruoho #include <unistd.h>
     19  1.1    jruoho #include <util.h>
     20  1.1    jruoho 
     21  1.5  christos #include "h_macros.h"
     22  1.1    jruoho 
     23  1.1    jruoho ATF_TC(cmsg_sendfd_bounds);
     24  1.1    jruoho ATF_TC_HEAD(cmsg_sendfd_bounds, tc)
     25  1.1    jruoho {
     26  1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Checks that attempting to pass an "
     27  1.1    jruoho 	    "invalid fd returns an error");
     28  1.1    jruoho }
     29  1.1    jruoho 
     30  1.1    jruoho ATF_TC_BODY(cmsg_sendfd_bounds, tc)
     31  1.1    jruoho {
     32  1.1    jruoho 	struct cmsghdr *cmp;
     33  1.1    jruoho 	struct msghdr msg;
     34  1.1    jruoho 	struct iovec iov;
     35  1.1    jruoho 	int s[2];
     36  1.1    jruoho 	int fd;
     37  1.1    jruoho 
     38  1.1    jruoho 	rump_init();
     39  1.1    jruoho 
     40  1.1    jruoho 	if (rump_sys_socketpair(AF_LOCAL, SOCK_STREAM, 0, s) == -1)
     41  1.1    jruoho 		atf_tc_fail("rump_sys_socket");
     42  1.1    jruoho 
     43  1.1    jruoho 	cmp = malloc(CMSG_SPACE(sizeof(int)));
     44  1.1    jruoho 
     45  1.1    jruoho 	iov.iov_base = &fd;
     46  1.1    jruoho 	iov.iov_len = sizeof(int);
     47  1.1    jruoho 
     48  1.1    jruoho 	cmp->cmsg_level = SOL_SOCKET;
     49  1.1    jruoho 	cmp->cmsg_type = SCM_RIGHTS;
     50  1.1    jruoho 	cmp->cmsg_len = CMSG_LEN(sizeof(int));
     51  1.1    jruoho 
     52  1.1    jruoho 	msg.msg_iov = &iov;
     53  1.1    jruoho 	msg.msg_iovlen = 1;
     54  1.1    jruoho 	msg.msg_name = NULL;
     55  1.1    jruoho 	msg.msg_namelen = 0;
     56  1.1    jruoho 	msg.msg_control = cmp;
     57  1.1    jruoho 	msg.msg_controllen = CMSG_SPACE(sizeof(int));
     58  1.1    jruoho 
     59  1.1    jruoho 	/*
     60  1.1    jruoho 	 * ERROR HERE: trying to pass invalid fd
     61  1.1    jruoho 	 * (This value was previously directly used to index the fd
     62  1.1    jruoho 	 *  array and therefore we are passing a hyperspace index)
     63  1.1    jruoho 	 */
     64  1.1    jruoho 	*(int *)CMSG_DATA(cmp) = 0x12345678;
     65  1.1    jruoho 
     66  1.1    jruoho 	rump_sys_sendmsg(s[0], &msg, 0);
     67  1.1    jruoho 	if (errno != EBADF)
     68  1.1    jruoho 		atf_tc_fail("descriptor passing failed: expected EBADF (9), "
     69  1.1    jruoho 		    "got %d\n(%s)", errno, strerror(errno));
     70  1.1    jruoho }
     71  1.1    jruoho 
     72  1.1    jruoho 
     73  1.1    jruoho ATF_TC(cmsg_sendfd);
     74  1.1    jruoho ATF_TC_HEAD(cmsg_sendfd, tc)
     75  1.1    jruoho {
     76  1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Checks that fd passing works");
     77  1.4    martin 	atf_tc_set_md_var(tc, "timeout", "10");
     78  1.1    jruoho }
     79  1.1    jruoho 
     80  1.1    jruoho ATF_TC_BODY(cmsg_sendfd, tc)
     81  1.1    jruoho {
     82  1.1    jruoho 	char buf[128];
     83  1.1    jruoho 	struct cmsghdr *cmp;
     84  1.1    jruoho 	struct msghdr msg;
     85  1.1    jruoho 	struct sockaddr_un sun;
     86  1.3  christos 	struct lwp *l1;
     87  1.1    jruoho 	struct iovec iov;
     88  1.1    jruoho 	socklen_t sl;
     89  1.1    jruoho 	int s1, s2, sgot;
     90  1.1    jruoho 	int rfd, fd[2], storage;
     91  1.1    jruoho 
     92  1.1    jruoho 	rump_init();
     93  1.1    jruoho 
     94  1.1    jruoho 	RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
     95  1.1    jruoho 	l1 = rump_pub_lwproc_curlwp();
     96  1.1    jruoho 
     97  1.1    jruoho 	/* create unix socket and bind it to a path */
     98  1.1    jruoho 	memset(&sun, 0, sizeof(sun));
     99  1.1    jruoho 	sun.sun_family = AF_LOCAL;
    100  1.1    jruoho #define SOCKPATH "/com"
    101  1.6       mrg 	memcpy(sun.sun_path, SOCKPATH, sizeof(SOCKPATH) - 1);
    102  1.1    jruoho 	s1 = rump_sys_socket(AF_LOCAL, SOCK_STREAM, 0);
    103  1.1    jruoho 	if (s1 == -1)
    104  1.1    jruoho 		atf_tc_fail_errno("socket 1");
    105  1.1    jruoho 	if (rump_sys_bind(s1, (struct sockaddr *)&sun, SUN_LEN(&sun)) == -1)
    106  1.1    jruoho 		atf_tc_fail_errno("socket 1 bind");
    107  1.1    jruoho 	if (rump_sys_listen(s1, 1) == -1)
    108  1.1    jruoho 		atf_tc_fail_errno("socket 1 listen");
    109  1.1    jruoho 
    110  1.1    jruoho 	/* create second process for test */
    111  1.1    jruoho 	RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
    112  1.3  christos 	(void)rump_pub_lwproc_curlwp();
    113  1.1    jruoho 
    114  1.1    jruoho 	/* connect to unix domain socket */
    115  1.1    jruoho 	memset(&sun, 0, sizeof(sun));
    116  1.1    jruoho 	sun.sun_family = AF_LOCAL;
    117  1.6       mrg 	memcpy(sun.sun_path, SOCKPATH, sizeof(SOCKPATH) - 1);
    118  1.1    jruoho 	s2 = rump_sys_socket(AF_LOCAL, SOCK_STREAM, 0);
    119  1.1    jruoho 	if (s2 == -1)
    120  1.1    jruoho 		atf_tc_fail_errno("socket 2");
    121  1.1    jruoho 	if (rump_sys_connect(s2, (struct sockaddr *)&sun, SUN_LEN(&sun)) == -1)
    122  1.1    jruoho 		atf_tc_fail_errno("socket 2 connect");
    123  1.1    jruoho 
    124  1.1    jruoho 	/* open a pipe and write stuff to it */
    125  1.1    jruoho 	if (rump_sys_pipe(fd) == -1)
    126  1.1    jruoho 		atf_tc_fail_errno("can't open pipe");
    127  1.1    jruoho #define MAGICSTRING "duam xnaht"
    128  1.1    jruoho 	if (rump_sys_write(fd[1], MAGICSTRING, sizeof(MAGICSTRING)) !=
    129  1.1    jruoho 	    sizeof(MAGICSTRING))
    130  1.1    jruoho 		atf_tc_fail_errno("pipe write"); /* XXX: errno */
    131  1.1    jruoho 
    132  1.1    jruoho 	cmp = malloc(CMSG_SPACE(sizeof(int)));
    133  1.1    jruoho 
    134  1.1    jruoho 	iov.iov_base = &storage;
    135  1.1    jruoho 	iov.iov_len = sizeof(int);
    136  1.1    jruoho 
    137  1.1    jruoho 	cmp->cmsg_level = SOL_SOCKET;
    138  1.1    jruoho 	cmp->cmsg_type = SCM_RIGHTS;
    139  1.1    jruoho 	cmp->cmsg_len = CMSG_LEN(sizeof(int));
    140  1.1    jruoho 
    141  1.1    jruoho 	msg.msg_iov = &iov;
    142  1.1    jruoho 	msg.msg_iovlen = 1;
    143  1.1    jruoho 	msg.msg_name = NULL;
    144  1.1    jruoho 	msg.msg_namelen = 0;
    145  1.1    jruoho 	msg.msg_control = cmp;
    146  1.1    jruoho 	msg.msg_controllen = CMSG_SPACE(sizeof(int));
    147  1.1    jruoho 	*(int *)CMSG_DATA(cmp) = fd[0];
    148  1.1    jruoho 
    149  1.1    jruoho 	/* pass the fd */
    150  1.1    jruoho 	if (rump_sys_sendmsg(s2, &msg, 0) == -1)
    151  1.1    jruoho 		atf_tc_fail_errno("sendmsg failed");
    152  1.1    jruoho 
    153  1.1    jruoho 	/*
    154  1.1    jruoho 	 * We will read to the same cmsg space.  Overwrite the space
    155  1.1    jruoho 	 * with an invalid fd to make sure we get an explicit error
    156  1.1    jruoho 	 * if we don't manage to read the fd.
    157  1.1    jruoho 	 */
    158  1.1    jruoho 	*(int *)CMSG_DATA(cmp) = -1;
    159  1.1    jruoho 
    160  1.1    jruoho 	/* switch back to original proc */
    161  1.1    jruoho 	rump_pub_lwproc_switch(l1);
    162  1.1    jruoho 
    163  1.1    jruoho 	/* accept connection and read fd */
    164  1.1    jruoho 	sl = sizeof(sun);
    165  1.1    jruoho 	sgot = rump_sys_accept(s1, (struct sockaddr *)&sun, &sl);
    166  1.1    jruoho 	if (sgot == -1)
    167  1.1    jruoho 		atf_tc_fail_errno("accept");
    168  1.1    jruoho 	if (rump_sys_recvmsg(sgot, &msg, 0) == -1)
    169  1.1    jruoho 		atf_tc_fail_errno("recvmsg failed");
    170  1.1    jruoho 	rfd = *(int *)CMSG_DATA(cmp);
    171  1.1    jruoho 
    172  1.1    jruoho 	/* read from the fd */
    173  1.1    jruoho 	memset(buf, 0, sizeof(buf));
    174  1.1    jruoho 	if (rump_sys_read(rfd, buf, sizeof(buf)) == -1)
    175  1.1    jruoho 		atf_tc_fail_errno("read rfd");
    176  1.1    jruoho 
    177  1.1    jruoho 	/* check that we got the right stuff */
    178  1.1    jruoho 	if (strcmp(buf, MAGICSTRING) != 0)
    179  1.1    jruoho 		atf_tc_fail("expected \"%s\", got \"%s\"", MAGICSTRING, buf);
    180  1.1    jruoho }
    181  1.1    jruoho 
    182  1.2     pooka ATF_TC(sock_cloexec);
    183  1.2     pooka ATF_TC_HEAD(sock_cloexec, tc)
    184  1.2     pooka {
    185  1.2     pooka 	atf_tc_set_md_var(tc, "descr", "SOCK_CLOEXEC kernel invariant failure");
    186  1.2     pooka }
    187  1.2     pooka 
    188  1.2     pooka ATF_TC_BODY(sock_cloexec, tc)
    189  1.2     pooka {
    190  1.2     pooka 
    191  1.2     pooka 	rump_init();
    192  1.2     pooka 	rump_pub_lwproc_rfork(RUMP_RFFDG);
    193  1.2     pooka 	if (rump_sys_socket(-1, SOCK_CLOEXEC, 0) != -1)
    194  1.2     pooka 		atf_tc_fail("invalid socket parameters unexpectedly worked");
    195  1.2     pooka 	rump_pub_lwproc_releaselwp();
    196  1.2     pooka }
    197  1.2     pooka 
    198  1.1    jruoho ATF_TP_ADD_TCS(tp)
    199  1.1    jruoho {
    200  1.1    jruoho 	ATF_TP_ADD_TC(tp, cmsg_sendfd);
    201  1.1    jruoho 	ATF_TP_ADD_TC(tp, cmsg_sendfd_bounds);
    202  1.2     pooka 	ATF_TP_ADD_TC(tp, sock_cloexec);
    203  1.1    jruoho 
    204  1.1    jruoho 	return atf_no_error();
    205  1.1    jruoho }
    206