View | Details | Raw Unified | Return to bug 181741 | Differences between
and this patch

Collapse All | Expand All

(-)tools/regression/sockets/unix_passfd/unix_passfd.c (-25 / +79 lines)
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
}

Return to bug 181741