1 /* $NetBSD: t_cmsg.c,v 1.12 2009/11/26 17:33:23 pooka 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 /* create first (non-proc0) process to be used in test */
95 l1
= rump_pub_newproc_switch();
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 l2
= rump_pub_newproc_switch();
113 /* connect to unix domain socket */
114 memset(&sun
, 0, sizeof(sun
));
115 sun
.sun_family
= AF_LOCAL
;
116 strncpy(sun
.sun_path
, SOCKPATH
, sizeof(SOCKPATH
));
117 s2
= rump_sys_socket(AF_LOCAL
, SOCK_STREAM
, 0);
119 atf_tc_fail_errno("socket 2");
120 if (rump_sys_connect(s2
, (struct sockaddr
*)&sun
, SUN_LEN(&sun
)) == -1)
121 atf_tc_fail_errno("socket 2 connect");
123 /* open a pipe and write stuff to it */
124 if (rump_sys_pipe(fd
) == -1)
125 atf_tc_fail_errno("can't open pipe");
126 #define MAGICSTRING "duam xnaht"
127 if (rump_sys_write(fd
[1], MAGICSTRING
, sizeof(MAGICSTRING
)) !=
129 atf_tc_fail_errno("pipe write"); /* XXX: errno */
131 cmp
= malloc(CMSG_SPACE(sizeof(int)));
133 iov
.iov_base
= &storage
;
134 iov
.iov_len
= sizeof(int);
136 cmp
->cmsg_level
= SOL_SOCKET
;
137 cmp
->cmsg_type
= SCM_RIGHTS
;
138 cmp
->cmsg_len
= CMSG_SPACE(sizeof(int));
144 msg
.msg_control
= cmp
;
145 msg
.msg_controllen
= CMSG_LEN(sizeof(int));
146 *(int *)CMSG_DATA(cmp
) = fd
[0];
149 if (rump_sys_sendmsg(s2
, &msg
, 0) == -1)
150 atf_tc_fail_errno("sendmsg failed");
153 * We will read to the same cmsg space. Overwrite the space
154 * with an invalid fd to make sure we get an explicit error
155 * if we don't manage to read the fd.
157 *(int *)CMSG_DATA(cmp
) = -1;
159 /* switch back to original proc */
160 rump_pub_lwp_switch(l1
);
162 /* accept connection and read fd */
164 sgot
= rump_sys_accept(s1
, (struct sockaddr
*)&sun
, &sl
);
166 atf_tc_fail_errno("accept");
167 if (rump_sys_recvmsg(sgot
, &msg
, 0) == -1)
168 atf_tc_fail_errno("recvmsg failed");
169 rfd
= *(int *)CMSG_DATA(cmp
);
171 /* read from the fd */
172 memset(buf
, 0, sizeof(buf
));
173 if (rump_sys_read(rfd
, buf
, sizeof(buf
)) == -1)
174 atf_tc_fail_errno("read rfd");
176 /* check that we got the right stuff */
177 if (strcmp(buf
, MAGICSTRING
) != 0)
178 atf_tc_fail("expected \"%s\", got \"%s\"", MAGICSTRING
, buf
);
183 ATF_TP_ADD_TC(tp
, cmsg_sendfd
);
184 ATF_TP_ADD_TC(tp
, cmsg_sendfd_bounds
);
186 return atf_no_error();