1 /* $NetBSD: t_socket.c,v 1.3 2013/10/19 17:45:00 christos Exp $ */
5 #include <sys/socket.h>
9 #include <rump/rump_syscalls.h>
21 #include "../../h_macros.h"
23 ATF_TC(cmsg_sendfd_bounds
);
24 ATF_TC_HEAD(cmsg_sendfd_bounds
, tc
)
26 atf_tc_set_md_var(tc
, "descr", "Checks that attempting to pass an "
27 "invalid fd returns an error");
30 ATF_TC_BODY(cmsg_sendfd_bounds
, tc
)
40 if (rump_sys_socketpair(AF_LOCAL
, SOCK_STREAM
, 0, s
) == -1)
41 atf_tc_fail("rump_sys_socket");
43 cmp
= malloc(CMSG_SPACE(sizeof(int)));
46 iov
.iov_len
= sizeof(int);
48 cmp
->cmsg_level
= SOL_SOCKET
;
49 cmp
->cmsg_type
= SCM_RIGHTS
;
50 cmp
->cmsg_len
= CMSG_LEN(sizeof(int));
56 msg
.msg_control
= cmp
;
57 msg
.msg_controllen
= CMSG_SPACE(sizeof(int));
60 * ERROR HERE: trying to pass invalid fd
61 * (This value was previously directly used to index the fd
62 * array and therefore we are passing a hyperspace index)
64 *(int *)CMSG_DATA(cmp
) = 0x12345678;
66 rump_sys_sendmsg(s
[0], &msg
, 0);
68 atf_tc_fail("descriptor passing failed: expected EBADF (9), "
69 "got %d\n(%s)", errno
, strerror(errno
));
74 ATF_TC_HEAD(cmsg_sendfd
, tc
)
76 atf_tc_set_md_var(tc
, "descr", "Checks that fd passing works");
77 atf_tc_set_md_var(tc
, "timeout", "2");
80 ATF_TC_BODY(cmsg_sendfd
, tc
)
85 struct sockaddr_un sun
;
90 int rfd
, fd
[2], storage
;
94 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG
));
95 l1
= rump_pub_lwproc_curlwp();
97 /* create unix socket and bind it to a path */
98 memset(&sun
, 0, sizeof(sun
));
99 sun
.sun_family
= AF_LOCAL
;
100 #define SOCKPATH "/com"
101 strncpy(sun
.sun_path
, SOCKPATH
, sizeof(SOCKPATH
));
102 s1
= rump_sys_socket(AF_LOCAL
, SOCK_STREAM
, 0);
104 atf_tc_fail_errno("socket 1");
105 if (rump_sys_bind(s1
, (struct sockaddr
*)&sun
, SUN_LEN(&sun
)) == -1)
106 atf_tc_fail_errno("socket 1 bind");
107 if (rump_sys_listen(s1
, 1) == -1)
108 atf_tc_fail_errno("socket 1 listen");
110 /* create second process for test */
111 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG
));
112 (void)rump_pub_lwproc_curlwp();
114 /* connect to unix domain socket */
115 memset(&sun
, 0, sizeof(sun
));
116 sun
.sun_family
= AF_LOCAL
;
117 strncpy(sun
.sun_path
, SOCKPATH
, sizeof(SOCKPATH
));
118 s2
= rump_sys_socket(AF_LOCAL
, SOCK_STREAM
, 0);
120 atf_tc_fail_errno("socket 2");
121 if (rump_sys_connect(s2
, (struct sockaddr
*)&sun
, SUN_LEN(&sun
)) == -1)
122 atf_tc_fail_errno("socket 2 connect");
124 /* open a pipe and write stuff to it */
125 if (rump_sys_pipe(fd
) == -1)
126 atf_tc_fail_errno("can't open pipe");
127 #define MAGICSTRING "duam xnaht"
128 if (rump_sys_write(fd
[1], MAGICSTRING
, sizeof(MAGICSTRING
)) !=
130 atf_tc_fail_errno("pipe write"); /* XXX: errno */
132 cmp
= malloc(CMSG_SPACE(sizeof(int)));
134 iov
.iov_base
= &storage
;
135 iov
.iov_len
= sizeof(int);
137 cmp
->cmsg_level
= SOL_SOCKET
;
138 cmp
->cmsg_type
= SCM_RIGHTS
;
139 cmp
->cmsg_len
= CMSG_LEN(sizeof(int));
145 msg
.msg_control
= cmp
;
146 msg
.msg_controllen
= CMSG_SPACE(sizeof(int));
147 *(int *)CMSG_DATA(cmp
) = fd
[0];
150 if (rump_sys_sendmsg(s2
, &msg
, 0) == -1)
151 atf_tc_fail_errno("sendmsg failed");
154 * We will read to the same cmsg space. Overwrite the space
155 * with an invalid fd to make sure we get an explicit error
156 * if we don't manage to read the fd.
158 *(int *)CMSG_DATA(cmp
) = -1;
160 /* switch back to original proc */
161 rump_pub_lwproc_switch(l1
);
163 /* accept connection and read fd */
165 sgot
= rump_sys_accept(s1
, (struct sockaddr
*)&sun
, &sl
);
167 atf_tc_fail_errno("accept");
168 if (rump_sys_recvmsg(sgot
, &msg
, 0) == -1)
169 atf_tc_fail_errno("recvmsg failed");
170 rfd
= *(int *)CMSG_DATA(cmp
);
172 /* read from the fd */
173 memset(buf
, 0, sizeof(buf
));
174 if (rump_sys_read(rfd
, buf
, sizeof(buf
)) == -1)
175 atf_tc_fail_errno("read rfd");
177 /* check that we got the right stuff */
178 if (strcmp(buf
, MAGICSTRING
) != 0)
179 atf_tc_fail("expected \"%s\", got \"%s\"", MAGICSTRING
, buf
);
182 ATF_TC(sock_cloexec
);
183 ATF_TC_HEAD(sock_cloexec
, tc
)
185 atf_tc_set_md_var(tc
, "descr", "SOCK_CLOEXEC kernel invariant failure");
188 ATF_TC_BODY(sock_cloexec
, tc
)
192 rump_pub_lwproc_rfork(RUMP_RFFDG
);
193 if (rump_sys_socket(-1, SOCK_CLOEXEC
, 0) != -1)
194 atf_tc_fail("invalid socket parameters unexpectedly worked");
195 rump_pub_lwproc_releaselwp();
200 ATF_TP_ADD_TC(tp
, cmsg_sendfd
);
201 ATF_TP_ADD_TC(tp
, cmsg_sendfd_bounds
);
202 ATF_TP_ADD_TC(tp
, sock_cloexec
);
204 return atf_no_error();