Lines 29-39
Link Here
|
29 |
#include <sys/types.h> |
29 |
#include <sys/types.h> |
30 |
#include <sys/socket.h> |
30 |
#include <sys/socket.h> |
31 |
#include <sys/stat.h> |
31 |
#include <sys/stat.h> |
|
|
32 |
#include <sys/sysctl.h> |
33 |
#include <sys/un.h> |
32 |
|
34 |
|
33 |
#include <err.h> |
35 |
#include <err.h> |
34 |
#include <fcntl.h> |
36 |
#include <fcntl.h> |
35 |
#include <limits.h> |
37 |
#include <limits.h> |
36 |
#include <stdio.h> |
38 |
#include <stdio.h> |
|
|
39 |
#include <stdlib.h> |
37 |
#include <string.h> |
40 |
#include <string.h> |
38 |
#include <unistd.h> |
41 |
#include <unistd.h> |
39 |
|
42 |
|
Lines 106-116
samefile(const char *test, struct stat *sb1, struc
Link Here
|
106 |
} |
109 |
} |
107 |
|
110 |
|
108 |
static void |
111 |
static void |
109 |
sendfd(const char *test, int sockfd, int sendfd) |
112 |
sendfd_payload(const char *test, int sockfd, int sendfd, |
|
|
113 |
void *payload, size_t paylen) |
110 |
{ |
114 |
{ |
111 |
struct iovec iovec; |
115 |
struct iovec iovec; |
112 |
char ch; |
|
|
113 |
|
114 |
char message[CMSG_SPACE(sizeof(int))]; |
116 |
char message[CMSG_SPACE(sizeof(int))]; |
115 |
struct cmsghdr *cmsghdr; |
117 |
struct cmsghdr *cmsghdr; |
116 |
struct msghdr msghdr; |
118 |
struct msghdr msghdr; |
Lines 118-130
static void
Link Here
|
118 |
|
120 |
|
119 |
bzero(&msghdr, sizeof(msghdr)); |
121 |
bzero(&msghdr, sizeof(msghdr)); |
120 |
bzero(&message, sizeof(message)); |
122 |
bzero(&message, sizeof(message)); |
121 |
ch = 0; |
|
|
122 |
|
123 |
|
123 |
msghdr.msg_control = message; |
124 |
msghdr.msg_control = message; |
124 |
msghdr.msg_controllen = sizeof(message); |
125 |
msghdr.msg_controllen = sizeof(message); |
125 |
|
126 |
|
126 |
iovec.iov_base = &ch; |
127 |
iovec.iov_base = payload; |
127 |
iovec.iov_len = sizeof(ch); |
128 |
iovec.iov_len = paylen; |
128 |
|
129 |
|
129 |
msghdr.msg_iov = &iovec; |
130 |
msghdr.msg_iov = &iovec; |
130 |
msghdr.msg_iovlen = 1; |
131 |
msghdr.msg_iovlen = 1; |
Lines 138-192
static void
Link Here
|
138 |
len = sendmsg(sockfd, &msghdr, 0); |
139 |
len = sendmsg(sockfd, &msghdr, 0); |
139 |
if (len < 0) |
140 |
if (len < 0) |
140 |
err(-1, "%s: sendmsg", test); |
141 |
err(-1, "%s: sendmsg", test); |
141 |
if (len != sizeof(ch)) |
142 |
if (len != paylen) |
142 |
errx(-1, "%s: sendmsg: %zd bytes sent", test, len); |
143 |
errx(-1, "%s: sendmsg: %zd bytes sent", test, len); |
143 |
} |
144 |
} |
144 |
|
145 |
|
145 |
static void |
146 |
static void |
146 |
recvfd(const char *test, int sockfd, int *recvfd) |
147 |
sendfd(const char *test, int sockfd, int sendfd) |
147 |
{ |
148 |
{ |
|
|
149 |
char ch; |
150 |
|
151 |
return (sendfd_payload(test, sockfd, sendfd, &ch, sizeof(ch))); |
152 |
} |
153 |
|
154 |
static void |
155 |
recvfd_payload(const char *test, int sockfd, int *recvfd, |
156 |
void *buf, size_t buflen) |
157 |
{ |
148 |
struct cmsghdr *cmsghdr; |
158 |
struct cmsghdr *cmsghdr; |
149 |
char message[CMSG_SPACE(sizeof(int))]; |
159 |
char message[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + sizeof(int)]; |
150 |
struct msghdr msghdr; |
160 |
struct msghdr msghdr; |
151 |
struct iovec iovec; |
161 |
struct iovec iovec; |
152 |
ssize_t len; |
162 |
ssize_t len; |
153 |
char ch; |
|
|
154 |
|
163 |
|
155 |
bzero(&msghdr, sizeof(msghdr)); |
164 |
bzero(&msghdr, sizeof(msghdr)); |
156 |
ch = 0; |
|
|
157 |
|
165 |
|
158 |
msghdr.msg_control = message; |
166 |
msghdr.msg_control = message; |
159 |
msghdr.msg_controllen = sizeof(message); |
167 |
msghdr.msg_controllen = sizeof(message); |
160 |
|
168 |
|
161 |
iovec.iov_base = &ch; |
169 |
iovec.iov_base = buf; |
162 |
iovec.iov_len = sizeof(ch); |
170 |
iovec.iov_len = buflen; |
163 |
|
171 |
|
164 |
msghdr.msg_iov = &iovec; |
172 |
msghdr.msg_iov = &iovec; |
165 |
msghdr.msg_iovlen = 1; |
173 |
msghdr.msg_iovlen = 1; |
166 |
|
174 |
|
167 |
iovec.iov_len = sizeof(ch); |
|
|
168 |
|
169 |
msghdr.msg_iov = &iovec; |
170 |
msghdr.msg_iovlen = 1; |
171 |
|
172 |
len = recvmsg(sockfd, &msghdr, 0); |
175 |
len = recvmsg(sockfd, &msghdr, 0); |
173 |
if (len < 0) |
176 |
if (len < 0) |
174 |
err(-1, "%s: recvmsg", test); |
177 |
err(-1, "%s: recvmsg", test); |
175 |
if (len != sizeof(ch)) |
178 |
if (len != buflen) |
176 |
errx(-1, "%s: recvmsg: %zd bytes received", test, len); |
179 |
errx(-1, "%s: recvmsg: %zd bytes received", test, len); |
|
|
180 |
|
177 |
cmsghdr = CMSG_FIRSTHDR(&msghdr); |
181 |
cmsghdr = CMSG_FIRSTHDR(&msghdr); |
178 |
if (cmsghdr == NULL) |
182 |
if (cmsghdr == NULL) |
179 |
errx(-1, "%s: recvmsg: did not receive control message", test); |
183 |
errx(-1, "%s: recvmsg: did not receive control message", test); |
180 |
if (cmsghdr->cmsg_len != CMSG_LEN(sizeof(int)) || |
184 |
*recvfd = -1; |
181 |
cmsghdr->cmsg_level != SOL_SOCKET || |
185 |
for (; cmsghdr != NULL; cmsghdr = CMSG_NXTHDR(&msghdr, cmsghdr)) { |
182 |
cmsghdr->cmsg_type != SCM_RIGHTS) |
186 |
if (cmsghdr->cmsg_level == SOL_SOCKET && |
|
|
187 |
cmsghdr->cmsg_type == SCM_RIGHTS && |
188 |
cmsghdr->cmsg_len == CMSG_LEN(sizeof(int))) { |
189 |
*recvfd = *(int *)CMSG_DATA(cmsghdr); |
190 |
if (*recvfd == -1) |
191 |
errx(-1, "%s: recvmsg: received fd -1", test); |
192 |
} |
193 |
} |
194 |
if (*recvfd == -1) |
183 |
errx(-1, "%s: recvmsg: did not receive single-fd message", |
195 |
errx(-1, "%s: recvmsg: did not receive single-fd message", |
184 |
test); |
196 |
test); |
185 |
*recvfd = *(int *)CMSG_DATA(cmsghdr); |
|
|
186 |
if (*recvfd == -1) |
187 |
errx(-1, "%s: recvmsg: received fd -1", test); |
188 |
} |
197 |
} |
189 |
|
198 |
|
|
|
199 |
static void |
200 |
recvfd(const char *test, int sockfd, int *recvfd) |
201 |
{ |
202 |
char ch; |
203 |
|
204 |
return (recvfd_payload(test, sockfd, recvfd, &ch, sizeof(ch))); |
205 |
} |
206 |
|
190 |
int |
207 |
int |
191 |
main(int argc, char *argv[]) |
208 |
main(int argc, char *argv[]) |
192 |
{ |
209 |
{ |
Lines 330-335
main(int argc, char *argv[])
Link Here
|
330 |
closesocketpair(fd); |
347 |
closesocketpair(fd); |
331 |
|
348 |
|
332 |
printf("%s passed\n", test); |
349 |
printf("%s passed\n", test); |
|
|
350 |
|
351 |
/* |
352 |
* Test for PR 181741. Receiver sets LOCAL_CREDS, and kernel |
353 |
* prepends a control message to the data. Sender sends large |
354 |
* payload. Payload + SCM_RIGHTS + LOCAL_CREDS hit socket buffer |
355 |
* limit, and receiver receives truncated data. |
356 |
*/ |
357 |
test = "test8-rigths+creds+payload"; |
358 |
printf("beginning %s\n", test); |
359 |
|
360 |
{ |
361 |
const int on = 1; |
362 |
u_long sendspace; |
363 |
size_t len; |
364 |
void *buf; |
365 |
|
366 |
len = sizeof(sendspace); |
367 |
if (sysctlbyname("net.local.stream.sendspace", &sendspace, |
368 |
&len, NULL, 0) < 0) |
369 |
err(-1, "%s: sysctlbyname(net.local.stream.sendspace)", |
370 |
test); |
371 |
|
372 |
if ((buf = malloc(sendspace)) == NULL) |
373 |
err(-1, "%s: malloc", test); |
374 |
|
375 |
domainsocketpair(test, fd); |
376 |
if (setsockopt(fd[1], 0, LOCAL_CREDS, &on, sizeof(on)) < 0) |
377 |
err(-1, "%s: setsockopt(LOCAL_CREDS)", test); |
378 |
tempfile(test, &putfd_1); |
379 |
sendfd_payload(test, fd[0], putfd_1, buf, sendspace); |
380 |
recvfd_payload(test, fd[1], &getfd_1, buf, sendspace); |
381 |
close(putfd_1); |
382 |
close(getfd_1); |
383 |
closesocketpair(fd); |
384 |
} |
385 |
|
386 |
printf("%s passed\n", test); |
333 |
|
387 |
|
334 |
return (0); |
388 |
return (0); |
335 |
} |
389 |
} |