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