t_socket.c revision 1.1 1 1.1 jruoho /* $NetBSD: t_socket.c,v 1.1 2011/07/07 05:50:27 jruoho 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.1 jruoho #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.1 jruoho atf_tc_set_md_var(tc, "timeout", "2");
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.1 jruoho struct lwp *l1, *l2;
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.1 jruoho strncpy(sun.sun_path, SOCKPATH, sizeof(SOCKPATH));
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.1 jruoho l2 = 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.1 jruoho strncpy(sun.sun_path, SOCKPATH, sizeof(SOCKPATH));
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.1 jruoho ATF_TP_ADD_TCS(tp)
183 1.1 jruoho {
184 1.1 jruoho ATF_TP_ADD_TC(tp, cmsg_sendfd);
185 1.1 jruoho ATF_TP_ADD_TC(tp, cmsg_sendfd_bounds);
186 1.1 jruoho
187 1.1 jruoho return atf_no_error();
188 1.1 jruoho }
189