xref: /freebsd/sys/kern/uipc_syscalls.c (revision a35f04fba2ebb8f86d4cbdc710c89a094572b08e)
1 /*-
2  * Copyright (c) 1982, 1986, 1989, 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *	@(#)uipc_syscalls.c	8.4 (Berkeley) 2/21/94
30  */
31 
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #include "opt_capsicum.h"
36 #include "opt_inet.h"
37 #include "opt_inet6.h"
38 #include "opt_compat.h"
39 #include "opt_ktrace.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/capsicum.h>
44 #include <sys/kernel.h>
45 #include <sys/lock.h>
46 #include <sys/mutex.h>
47 #include <sys/sysproto.h>
48 #include <sys/malloc.h>
49 #include <sys/filedesc.h>
50 #include <sys/proc.h>
51 #include <sys/filio.h>
52 #include <sys/jail.h>
53 #include <sys/mbuf.h>
54 #include <sys/protosw.h>
55 #include <sys/rwlock.h>
56 #include <sys/socket.h>
57 #include <sys/socketvar.h>
58 #include <sys/syscallsubr.h>
59 #ifdef KTRACE
60 #include <sys/ktrace.h>
61 #endif
62 #ifdef COMPAT_FREEBSD32
63 #include <compat/freebsd32/freebsd32_util.h>
64 #endif
65 
66 #include <net/vnet.h>
67 
68 #include <security/audit/audit.h>
69 #include <security/mac/mac_framework.h>
70 
71 /*
72  * Flags for accept1() and kern_accept4(), in addition to SOCK_CLOEXEC
73  * and SOCK_NONBLOCK.
74  */
75 #define	ACCEPT4_INHERIT	0x1
76 #define	ACCEPT4_COMPAT	0x2
77 
78 static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
79 static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
80 
81 static int accept1(struct thread *td, int s, struct sockaddr *uname,
82 		   socklen_t *anamelen, int flags);
83 static int getsockname1(struct thread *td, struct getsockname_args *uap,
84 			int compat);
85 static int getpeername1(struct thread *td, struct getpeername_args *uap,
86 			int compat);
87 static int sockargs(struct mbuf **, char *, socklen_t, int);
88 
89 /*
90  * Convert a user file descriptor to a kernel file entry and check if required
91  * capability rights are present.
92  * If required copy of current set of capability rights is returned.
93  * A reference on the file entry is held upon returning.
94  */
95 int
96 getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
97     struct file **fpp, u_int *fflagp, struct filecaps *havecapsp)
98 {
99 	struct file *fp;
100 	int error;
101 
102 	error = fget_cap(td, fd, rightsp, &fp, havecapsp);
103 	if (error != 0)
104 		return (error);
105 	if (fp->f_type != DTYPE_SOCKET) {
106 		fdrop(fp, td);
107 		if (havecapsp != NULL)
108 			filecaps_free(havecapsp);
109 		return (ENOTSOCK);
110 	}
111 	if (fflagp != NULL)
112 		*fflagp = fp->f_flag;
113 	*fpp = fp;
114 	return (0);
115 }
116 
117 /*
118  * System call interface to the socket abstraction.
119  */
120 #if defined(COMPAT_43)
121 #define COMPAT_OLDSOCK
122 #endif
123 
124 int
125 sys_socket(struct thread *td, struct socket_args *uap)
126 {
127 
128 	return (kern_socket(td, uap->domain, uap->type, uap->protocol));
129 }
130 
131 int
132 kern_socket(struct thread *td, int domain, int type, int protocol)
133 {
134 	struct socket *so;
135 	struct file *fp;
136 	int fd, error, oflag, fflag;
137 
138 	AUDIT_ARG_SOCKET(domain, type, protocol);
139 
140 	oflag = 0;
141 	fflag = 0;
142 	if ((type & SOCK_CLOEXEC) != 0) {
143 		type &= ~SOCK_CLOEXEC;
144 		oflag |= O_CLOEXEC;
145 	}
146 	if ((type & SOCK_NONBLOCK) != 0) {
147 		type &= ~SOCK_NONBLOCK;
148 		fflag |= FNONBLOCK;
149 	}
150 
151 #ifdef MAC
152 	error = mac_socket_check_create(td->td_ucred, domain, type, protocol);
153 	if (error != 0)
154 		return (error);
155 #endif
156 	error = falloc(td, &fp, &fd, oflag);
157 	if (error != 0)
158 		return (error);
159 	/* An extra reference on `fp' has been held for us by falloc(). */
160 	error = socreate(domain, &so, type, protocol, td->td_ucred, td);
161 	if (error != 0) {
162 		fdclose(td, fp, fd);
163 	} else {
164 		finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops);
165 		if ((fflag & FNONBLOCK) != 0)
166 			(void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td);
167 		td->td_retval[0] = fd;
168 	}
169 	fdrop(fp, td);
170 	return (error);
171 }
172 
173 int
174 sys_bind(struct thread *td, struct bind_args *uap)
175 {
176 	struct sockaddr *sa;
177 	int error;
178 
179 	error = getsockaddr(&sa, uap->name, uap->namelen);
180 	if (error == 0) {
181 		error = kern_bindat(td, AT_FDCWD, uap->s, sa);
182 		free(sa, M_SONAME);
183 	}
184 	return (error);
185 }
186 
187 int
188 kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
189 {
190 	struct socket *so;
191 	struct file *fp;
192 	cap_rights_t rights;
193 	int error;
194 
195 	AUDIT_ARG_FD(fd);
196 	AUDIT_ARG_SOCKADDR(td, dirfd, sa);
197 	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND),
198 	    &fp, NULL, NULL);
199 	if (error != 0)
200 		return (error);
201 	so = fp->f_data;
202 #ifdef KTRACE
203 	if (KTRPOINT(td, KTR_STRUCT))
204 		ktrsockaddr(sa);
205 #endif
206 #ifdef MAC
207 	error = mac_socket_check_bind(td->td_ucred, so, sa);
208 	if (error == 0) {
209 #endif
210 		if (dirfd == AT_FDCWD)
211 			error = sobind(so, sa, td);
212 		else
213 			error = sobindat(dirfd, so, sa, td);
214 #ifdef MAC
215 	}
216 #endif
217 	fdrop(fp, td);
218 	return (error);
219 }
220 
221 int
222 sys_bindat(struct thread *td, struct bindat_args *uap)
223 {
224 	struct sockaddr *sa;
225 	int error;
226 
227 	error = getsockaddr(&sa, uap->name, uap->namelen);
228 	if (error == 0) {
229 		error = kern_bindat(td, uap->fd, uap->s, sa);
230 		free(sa, M_SONAME);
231 	}
232 	return (error);
233 }
234 
235 int
236 sys_listen(struct thread *td, struct listen_args *uap)
237 {
238 
239 	return (kern_listen(td, uap->s, uap->backlog));
240 }
241 
242 int
243 kern_listen(struct thread *td, int s, int backlog)
244 {
245 	struct socket *so;
246 	struct file *fp;
247 	cap_rights_t rights;
248 	int error;
249 
250 	AUDIT_ARG_FD(s);
251 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_LISTEN),
252 	    &fp, NULL, NULL);
253 	if (error == 0) {
254 		so = fp->f_data;
255 #ifdef MAC
256 		error = mac_socket_check_listen(td->td_ucred, so);
257 		if (error == 0)
258 #endif
259 			error = solisten(so, backlog, td);
260 		fdrop(fp, td);
261 	}
262 	return (error);
263 }
264 
265 /*
266  * accept1()
267  */
268 static int
269 accept1(td, s, uname, anamelen, flags)
270 	struct thread *td;
271 	int s;
272 	struct sockaddr *uname;
273 	socklen_t *anamelen;
274 	int flags;
275 {
276 	struct sockaddr *name;
277 	socklen_t namelen;
278 	struct file *fp;
279 	int error;
280 
281 	if (uname == NULL)
282 		return (kern_accept4(td, s, NULL, NULL, flags, NULL));
283 
284 	error = copyin(anamelen, &namelen, sizeof (namelen));
285 	if (error != 0)
286 		return (error);
287 
288 	error = kern_accept4(td, s, &name, &namelen, flags, &fp);
289 
290 	if (error != 0)
291 		return (error);
292 
293 	if (error == 0 && uname != NULL) {
294 #ifdef COMPAT_OLDSOCK
295 		if (flags & ACCEPT4_COMPAT)
296 			((struct osockaddr *)name)->sa_family =
297 			    name->sa_family;
298 #endif
299 		error = copyout(name, uname, namelen);
300 	}
301 	if (error == 0)
302 		error = copyout(&namelen, anamelen,
303 		    sizeof(namelen));
304 	if (error != 0)
305 		fdclose(td, fp, td->td_retval[0]);
306 	fdrop(fp, td);
307 	free(name, M_SONAME);
308 	return (error);
309 }
310 
311 int
312 kern_accept(struct thread *td, int s, struct sockaddr **name,
313     socklen_t *namelen, struct file **fp)
314 {
315 	return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp));
316 }
317 
318 int
319 kern_accept4(struct thread *td, int s, struct sockaddr **name,
320     socklen_t *namelen, int flags, struct file **fp)
321 {
322 	struct file *headfp, *nfp = NULL;
323 	struct sockaddr *sa = NULL;
324 	struct socket *head, *so;
325 	struct filecaps fcaps;
326 	cap_rights_t rights;
327 	u_int fflag;
328 	pid_t pgid;
329 	int error, fd, tmp;
330 
331 	if (name != NULL)
332 		*name = NULL;
333 
334 	AUDIT_ARG_FD(s);
335 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT),
336 	    &headfp, &fflag, &fcaps);
337 	if (error != 0)
338 		return (error);
339 	head = headfp->f_data;
340 	if ((head->so_options & SO_ACCEPTCONN) == 0) {
341 		error = EINVAL;
342 		goto done;
343 	}
344 #ifdef MAC
345 	error = mac_socket_check_accept(td->td_ucred, head);
346 	if (error != 0)
347 		goto done;
348 #endif
349 	error = falloc_caps(td, &nfp, &fd,
350 	    (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps);
351 	if (error != 0)
352 		goto done;
353 	ACCEPT_LOCK();
354 	if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
355 		ACCEPT_UNLOCK();
356 		error = EWOULDBLOCK;
357 		goto noconnection;
358 	}
359 	while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
360 		if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
361 			head->so_error = ECONNABORTED;
362 			break;
363 		}
364 		error = msleep(&head->so_timeo, &accept_mtx, PSOCK | PCATCH,
365 		    "accept", 0);
366 		if (error != 0) {
367 			ACCEPT_UNLOCK();
368 			goto noconnection;
369 		}
370 	}
371 	if (head->so_error) {
372 		error = head->so_error;
373 		head->so_error = 0;
374 		ACCEPT_UNLOCK();
375 		goto noconnection;
376 	}
377 	so = TAILQ_FIRST(&head->so_comp);
378 	KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
379 	KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP"));
380 
381 	/*
382 	 * Before changing the flags on the socket, we have to bump the
383 	 * reference count.  Otherwise, if the protocol calls sofree(),
384 	 * the socket will be released due to a zero refcount.
385 	 */
386 	SOCK_LOCK(so);			/* soref() and so_state update */
387 	soref(so);			/* file descriptor reference */
388 
389 	TAILQ_REMOVE(&head->so_comp, so, so_list);
390 	head->so_qlen--;
391 	if (flags & ACCEPT4_INHERIT)
392 		so->so_state |= (head->so_state & SS_NBIO);
393 	else
394 		so->so_state |= (flags & SOCK_NONBLOCK) ? SS_NBIO : 0;
395 	so->so_qstate &= ~SQ_COMP;
396 	so->so_head = NULL;
397 
398 	SOCK_UNLOCK(so);
399 	ACCEPT_UNLOCK();
400 
401 	/* An extra reference on `nfp' has been held for us by falloc(). */
402 	td->td_retval[0] = fd;
403 
404 	/* connection has been removed from the listen queue */
405 	KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0);
406 
407 	if (flags & ACCEPT4_INHERIT) {
408 		pgid = fgetown(&head->so_sigio);
409 		if (pgid != 0)
410 			fsetown(pgid, &so->so_sigio);
411 	} else {
412 		fflag &= ~(FNONBLOCK | FASYNC);
413 		if (flags & SOCK_NONBLOCK)
414 			fflag |= FNONBLOCK;
415 	}
416 
417 	finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
418 	/* Sync socket nonblocking/async state with file flags */
419 	tmp = fflag & FNONBLOCK;
420 	(void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
421 	tmp = fflag & FASYNC;
422 	(void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
423 	sa = NULL;
424 	error = soaccept(so, &sa);
425 	if (error != 0)
426 		goto noconnection;
427 	if (sa == NULL) {
428 		if (name)
429 			*namelen = 0;
430 		goto done;
431 	}
432 	AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
433 	if (name) {
434 		/* check sa_len before it is destroyed */
435 		if (*namelen > sa->sa_len)
436 			*namelen = sa->sa_len;
437 #ifdef KTRACE
438 		if (KTRPOINT(td, KTR_STRUCT))
439 			ktrsockaddr(sa);
440 #endif
441 		*name = sa;
442 		sa = NULL;
443 	}
444 noconnection:
445 	free(sa, M_SONAME);
446 
447 	/*
448 	 * close the new descriptor, assuming someone hasn't ripped it
449 	 * out from under us.
450 	 */
451 	if (error != 0)
452 		fdclose(td, nfp, fd);
453 
454 	/*
455 	 * Release explicitly held references before returning.  We return
456 	 * a reference on nfp to the caller on success if they request it.
457 	 */
458 done:
459 	if (nfp == NULL)
460 		filecaps_free(&fcaps);
461 	if (fp != NULL) {
462 		if (error == 0) {
463 			*fp = nfp;
464 			nfp = NULL;
465 		} else
466 			*fp = NULL;
467 	}
468 	if (nfp != NULL)
469 		fdrop(nfp, td);
470 	fdrop(headfp, td);
471 	return (error);
472 }
473 
474 int
475 sys_accept(td, uap)
476 	struct thread *td;
477 	struct accept_args *uap;
478 {
479 
480 	return (accept1(td, uap->s, uap->name, uap->anamelen, ACCEPT4_INHERIT));
481 }
482 
483 int
484 sys_accept4(td, uap)
485 	struct thread *td;
486 	struct accept4_args *uap;
487 {
488 
489 	if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
490 		return (EINVAL);
491 
492 	return (accept1(td, uap->s, uap->name, uap->anamelen, uap->flags));
493 }
494 
495 #ifdef COMPAT_OLDSOCK
496 int
497 oaccept(td, uap)
498 	struct thread *td;
499 	struct accept_args *uap;
500 {
501 
502 	return (accept1(td, uap->s, uap->name, uap->anamelen,
503 	    ACCEPT4_INHERIT | ACCEPT4_COMPAT));
504 }
505 #endif /* COMPAT_OLDSOCK */
506 
507 int
508 sys_connect(struct thread *td, struct connect_args *uap)
509 {
510 	struct sockaddr *sa;
511 	int error;
512 
513 	error = getsockaddr(&sa, uap->name, uap->namelen);
514 	if (error == 0) {
515 		error = kern_connectat(td, AT_FDCWD, uap->s, sa);
516 		free(sa, M_SONAME);
517 	}
518 	return (error);
519 }
520 
521 int
522 kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
523 {
524 	struct socket *so;
525 	struct file *fp;
526 	cap_rights_t rights;
527 	int error, interrupted = 0;
528 
529 	AUDIT_ARG_FD(fd);
530 	AUDIT_ARG_SOCKADDR(td, dirfd, sa);
531 	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT),
532 	    &fp, NULL, NULL);
533 	if (error != 0)
534 		return (error);
535 	so = fp->f_data;
536 	if (so->so_state & SS_ISCONNECTING) {
537 		error = EALREADY;
538 		goto done1;
539 	}
540 #ifdef KTRACE
541 	if (KTRPOINT(td, KTR_STRUCT))
542 		ktrsockaddr(sa);
543 #endif
544 #ifdef MAC
545 	error = mac_socket_check_connect(td->td_ucred, so, sa);
546 	if (error != 0)
547 		goto bad;
548 #endif
549 	if (dirfd == AT_FDCWD)
550 		error = soconnect(so, sa, td);
551 	else
552 		error = soconnectat(dirfd, so, sa, td);
553 	if (error != 0)
554 		goto bad;
555 	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
556 		error = EINPROGRESS;
557 		goto done1;
558 	}
559 	SOCK_LOCK(so);
560 	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
561 		error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH,
562 		    "connec", 0);
563 		if (error != 0) {
564 			if (error == EINTR || error == ERESTART)
565 				interrupted = 1;
566 			break;
567 		}
568 	}
569 	if (error == 0) {
570 		error = so->so_error;
571 		so->so_error = 0;
572 	}
573 	SOCK_UNLOCK(so);
574 bad:
575 	if (!interrupted)
576 		so->so_state &= ~SS_ISCONNECTING;
577 	if (error == ERESTART)
578 		error = EINTR;
579 done1:
580 	fdrop(fp, td);
581 	return (error);
582 }
583 
584 int
585 sys_connectat(struct thread *td, struct connectat_args *uap)
586 {
587 	struct sockaddr *sa;
588 	int error;
589 
590 	error = getsockaddr(&sa, uap->name, uap->namelen);
591 	if (error == 0) {
592 		error = kern_connectat(td, uap->fd, uap->s, sa);
593 		free(sa, M_SONAME);
594 	}
595 	return (error);
596 }
597 
598 int
599 kern_socketpair(struct thread *td, int domain, int type, int protocol,
600     int *rsv)
601 {
602 	struct file *fp1, *fp2;
603 	struct socket *so1, *so2;
604 	int fd, error, oflag, fflag;
605 
606 	AUDIT_ARG_SOCKET(domain, type, protocol);
607 
608 	oflag = 0;
609 	fflag = 0;
610 	if ((type & SOCK_CLOEXEC) != 0) {
611 		type &= ~SOCK_CLOEXEC;
612 		oflag |= O_CLOEXEC;
613 	}
614 	if ((type & SOCK_NONBLOCK) != 0) {
615 		type &= ~SOCK_NONBLOCK;
616 		fflag |= FNONBLOCK;
617 	}
618 #ifdef MAC
619 	/* We might want to have a separate check for socket pairs. */
620 	error = mac_socket_check_create(td->td_ucred, domain, type,
621 	    protocol);
622 	if (error != 0)
623 		return (error);
624 #endif
625 	error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
626 	if (error != 0)
627 		return (error);
628 	error = socreate(domain, &so2, type, protocol, td->td_ucred, td);
629 	if (error != 0)
630 		goto free1;
631 	/* On success extra reference to `fp1' and 'fp2' is set by falloc. */
632 	error = falloc(td, &fp1, &fd, oflag);
633 	if (error != 0)
634 		goto free2;
635 	rsv[0] = fd;
636 	fp1->f_data = so1;	/* so1 already has ref count */
637 	error = falloc(td, &fp2, &fd, oflag);
638 	if (error != 0)
639 		goto free3;
640 	fp2->f_data = so2;	/* so2 already has ref count */
641 	rsv[1] = fd;
642 	error = soconnect2(so1, so2);
643 	if (error != 0)
644 		goto free4;
645 	if (type == SOCK_DGRAM) {
646 		/*
647 		 * Datagram socket connection is asymmetric.
648 		 */
649 		 error = soconnect2(so2, so1);
650 		 if (error != 0)
651 			goto free4;
652 	}
653 	finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data,
654 	    &socketops);
655 	finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data,
656 	    &socketops);
657 	if ((fflag & FNONBLOCK) != 0) {
658 		(void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
659 		(void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
660 	}
661 	fdrop(fp1, td);
662 	fdrop(fp2, td);
663 	return (0);
664 free4:
665 	fdclose(td, fp2, rsv[1]);
666 	fdrop(fp2, td);
667 free3:
668 	fdclose(td, fp1, rsv[0]);
669 	fdrop(fp1, td);
670 free2:
671 	if (so2 != NULL)
672 		(void)soclose(so2);
673 free1:
674 	if (so1 != NULL)
675 		(void)soclose(so1);
676 	return (error);
677 }
678 
679 int
680 sys_socketpair(struct thread *td, struct socketpair_args *uap)
681 {
682 	int error, sv[2];
683 
684 	error = kern_socketpair(td, uap->domain, uap->type,
685 	    uap->protocol, sv);
686 	if (error != 0)
687 		return (error);
688 	error = copyout(sv, uap->rsv, 2 * sizeof(int));
689 	if (error != 0) {
690 		(void)kern_close(td, sv[0]);
691 		(void)kern_close(td, sv[1]);
692 	}
693 	return (error);
694 }
695 
696 static int
697 sendit(struct thread *td, int s, struct msghdr *mp, int flags)
698 {
699 	struct mbuf *control;
700 	struct sockaddr *to;
701 	int error;
702 
703 #ifdef CAPABILITY_MODE
704 	if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL))
705 		return (ECAPMODE);
706 #endif
707 
708 	if (mp->msg_name != NULL) {
709 		error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
710 		if (error != 0) {
711 			to = NULL;
712 			goto bad;
713 		}
714 		mp->msg_name = to;
715 	} else {
716 		to = NULL;
717 	}
718 
719 	if (mp->msg_control) {
720 		if (mp->msg_controllen < sizeof(struct cmsghdr)
721 #ifdef COMPAT_OLDSOCK
722 		    && mp->msg_flags != MSG_COMPAT
723 #endif
724 		) {
725 			error = EINVAL;
726 			goto bad;
727 		}
728 		error = sockargs(&control, mp->msg_control,
729 		    mp->msg_controllen, MT_CONTROL);
730 		if (error != 0)
731 			goto bad;
732 #ifdef COMPAT_OLDSOCK
733 		if (mp->msg_flags == MSG_COMPAT) {
734 			struct cmsghdr *cm;
735 
736 			M_PREPEND(control, sizeof(*cm), M_WAITOK);
737 			cm = mtod(control, struct cmsghdr *);
738 			cm->cmsg_len = control->m_len;
739 			cm->cmsg_level = SOL_SOCKET;
740 			cm->cmsg_type = SCM_RIGHTS;
741 		}
742 #endif
743 	} else {
744 		control = NULL;
745 	}
746 
747 	error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE);
748 
749 bad:
750 	free(to, M_SONAME);
751 	return (error);
752 }
753 
754 int
755 kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
756     struct mbuf *control, enum uio_seg segflg)
757 {
758 	struct file *fp;
759 	struct uio auio;
760 	struct iovec *iov;
761 	struct socket *so;
762 	cap_rights_t rights;
763 #ifdef KTRACE
764 	struct uio *ktruio = NULL;
765 #endif
766 	ssize_t len;
767 	int i, error;
768 
769 	AUDIT_ARG_FD(s);
770 	cap_rights_init(&rights, CAP_SEND);
771 	if (mp->msg_name != NULL) {
772 		AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
773 		cap_rights_set(&rights, CAP_CONNECT);
774 	}
775 	error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
776 	if (error != 0) {
777 		m_freem(control);
778 		return (error);
779 	}
780 	so = (struct socket *)fp->f_data;
781 
782 #ifdef KTRACE
783 	if (mp->msg_name != NULL && KTRPOINT(td, KTR_STRUCT))
784 		ktrsockaddr(mp->msg_name);
785 #endif
786 #ifdef MAC
787 	if (mp->msg_name != NULL) {
788 		error = mac_socket_check_connect(td->td_ucred, so,
789 		    mp->msg_name);
790 		if (error != 0) {
791 			m_freem(control);
792 			goto bad;
793 		}
794 	}
795 	error = mac_socket_check_send(td->td_ucred, so);
796 	if (error != 0) {
797 		m_freem(control);
798 		goto bad;
799 	}
800 #endif
801 
802 	auio.uio_iov = mp->msg_iov;
803 	auio.uio_iovcnt = mp->msg_iovlen;
804 	auio.uio_segflg = segflg;
805 	auio.uio_rw = UIO_WRITE;
806 	auio.uio_td = td;
807 	auio.uio_offset = 0;			/* XXX */
808 	auio.uio_resid = 0;
809 	iov = mp->msg_iov;
810 	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
811 		if ((auio.uio_resid += iov->iov_len) < 0) {
812 			error = EINVAL;
813 			m_freem(control);
814 			goto bad;
815 		}
816 	}
817 #ifdef KTRACE
818 	if (KTRPOINT(td, KTR_GENIO))
819 		ktruio = cloneuio(&auio);
820 #endif
821 	len = auio.uio_resid;
822 	error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
823 	if (error != 0) {
824 		if (auio.uio_resid != len && (error == ERESTART ||
825 		    error == EINTR || error == EWOULDBLOCK))
826 			error = 0;
827 		/* Generation of SIGPIPE can be controlled per socket */
828 		if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
829 		    !(flags & MSG_NOSIGNAL)) {
830 			PROC_LOCK(td->td_proc);
831 			tdsignal(td, SIGPIPE);
832 			PROC_UNLOCK(td->td_proc);
833 		}
834 	}
835 	if (error == 0)
836 		td->td_retval[0] = len - auio.uio_resid;
837 #ifdef KTRACE
838 	if (ktruio != NULL) {
839 		ktruio->uio_resid = td->td_retval[0];
840 		ktrgenio(s, UIO_WRITE, ktruio, error);
841 	}
842 #endif
843 bad:
844 	fdrop(fp, td);
845 	return (error);
846 }
847 
848 int
849 sys_sendto(struct thread *td, struct sendto_args *uap)
850 {
851 	struct msghdr msg;
852 	struct iovec aiov;
853 
854 	msg.msg_name = uap->to;
855 	msg.msg_namelen = uap->tolen;
856 	msg.msg_iov = &aiov;
857 	msg.msg_iovlen = 1;
858 	msg.msg_control = 0;
859 #ifdef COMPAT_OLDSOCK
860 	msg.msg_flags = 0;
861 #endif
862 	aiov.iov_base = uap->buf;
863 	aiov.iov_len = uap->len;
864 	return (sendit(td, uap->s, &msg, uap->flags));
865 }
866 
867 #ifdef COMPAT_OLDSOCK
868 int
869 osend(struct thread *td, struct osend_args *uap)
870 {
871 	struct msghdr msg;
872 	struct iovec aiov;
873 
874 	msg.msg_name = 0;
875 	msg.msg_namelen = 0;
876 	msg.msg_iov = &aiov;
877 	msg.msg_iovlen = 1;
878 	aiov.iov_base = uap->buf;
879 	aiov.iov_len = uap->len;
880 	msg.msg_control = 0;
881 	msg.msg_flags = 0;
882 	return (sendit(td, uap->s, &msg, uap->flags));
883 }
884 
885 int
886 osendmsg(struct thread *td, struct osendmsg_args *uap)
887 {
888 	struct msghdr msg;
889 	struct iovec *iov;
890 	int error;
891 
892 	error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
893 	if (error != 0)
894 		return (error);
895 	error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
896 	if (error != 0)
897 		return (error);
898 	msg.msg_iov = iov;
899 	msg.msg_flags = MSG_COMPAT;
900 	error = sendit(td, uap->s, &msg, uap->flags);
901 	free(iov, M_IOV);
902 	return (error);
903 }
904 #endif
905 
906 int
907 sys_sendmsg(struct thread *td, struct sendmsg_args *uap)
908 {
909 	struct msghdr msg;
910 	struct iovec *iov;
911 	int error;
912 
913 	error = copyin(uap->msg, &msg, sizeof (msg));
914 	if (error != 0)
915 		return (error);
916 	error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
917 	if (error != 0)
918 		return (error);
919 	msg.msg_iov = iov;
920 #ifdef COMPAT_OLDSOCK
921 	msg.msg_flags = 0;
922 #endif
923 	error = sendit(td, uap->s, &msg, uap->flags);
924 	free(iov, M_IOV);
925 	return (error);
926 }
927 
928 int
929 kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
930     struct mbuf **controlp)
931 {
932 	struct uio auio;
933 	struct iovec *iov;
934 	struct mbuf *m, *control = NULL;
935 	caddr_t ctlbuf;
936 	struct file *fp;
937 	struct socket *so;
938 	struct sockaddr *fromsa = NULL;
939 	cap_rights_t rights;
940 #ifdef KTRACE
941 	struct uio *ktruio = NULL;
942 #endif
943 	ssize_t len;
944 	int error, i;
945 
946 	if (controlp != NULL)
947 		*controlp = NULL;
948 
949 	AUDIT_ARG_FD(s);
950 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV),
951 	    &fp, NULL, NULL);
952 	if (error != 0)
953 		return (error);
954 	so = fp->f_data;
955 
956 #ifdef MAC
957 	error = mac_socket_check_receive(td->td_ucred, so);
958 	if (error != 0) {
959 		fdrop(fp, td);
960 		return (error);
961 	}
962 #endif
963 
964 	auio.uio_iov = mp->msg_iov;
965 	auio.uio_iovcnt = mp->msg_iovlen;
966 	auio.uio_segflg = UIO_USERSPACE;
967 	auio.uio_rw = UIO_READ;
968 	auio.uio_td = td;
969 	auio.uio_offset = 0;			/* XXX */
970 	auio.uio_resid = 0;
971 	iov = mp->msg_iov;
972 	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
973 		if ((auio.uio_resid += iov->iov_len) < 0) {
974 			fdrop(fp, td);
975 			return (EINVAL);
976 		}
977 	}
978 #ifdef KTRACE
979 	if (KTRPOINT(td, KTR_GENIO))
980 		ktruio = cloneuio(&auio);
981 #endif
982 	len = auio.uio_resid;
983 	error = soreceive(so, &fromsa, &auio, NULL,
984 	    (mp->msg_control || controlp) ? &control : NULL,
985 	    &mp->msg_flags);
986 	if (error != 0) {
987 		if (auio.uio_resid != len && (error == ERESTART ||
988 		    error == EINTR || error == EWOULDBLOCK))
989 			error = 0;
990 	}
991 	if (fromsa != NULL)
992 		AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa);
993 #ifdef KTRACE
994 	if (ktruio != NULL) {
995 		ktruio->uio_resid = len - auio.uio_resid;
996 		ktrgenio(s, UIO_READ, ktruio, error);
997 	}
998 #endif
999 	if (error != 0)
1000 		goto out;
1001 	td->td_retval[0] = len - auio.uio_resid;
1002 	if (mp->msg_name) {
1003 		len = mp->msg_namelen;
1004 		if (len <= 0 || fromsa == NULL)
1005 			len = 0;
1006 		else {
1007 			/* save sa_len before it is destroyed by MSG_COMPAT */
1008 			len = MIN(len, fromsa->sa_len);
1009 #ifdef COMPAT_OLDSOCK
1010 			if (mp->msg_flags & MSG_COMPAT)
1011 				((struct osockaddr *)fromsa)->sa_family =
1012 				    fromsa->sa_family;
1013 #endif
1014 			if (fromseg == UIO_USERSPACE) {
1015 				error = copyout(fromsa, mp->msg_name,
1016 				    (unsigned)len);
1017 				if (error != 0)
1018 					goto out;
1019 			} else
1020 				bcopy(fromsa, mp->msg_name, len);
1021 		}
1022 		mp->msg_namelen = len;
1023 	}
1024 	if (mp->msg_control && controlp == NULL) {
1025 #ifdef COMPAT_OLDSOCK
1026 		/*
1027 		 * We assume that old recvmsg calls won't receive access
1028 		 * rights and other control info, esp. as control info
1029 		 * is always optional and those options didn't exist in 4.3.
1030 		 * If we receive rights, trim the cmsghdr; anything else
1031 		 * is tossed.
1032 		 */
1033 		if (control && mp->msg_flags & MSG_COMPAT) {
1034 			if (mtod(control, struct cmsghdr *)->cmsg_level !=
1035 			    SOL_SOCKET ||
1036 			    mtod(control, struct cmsghdr *)->cmsg_type !=
1037 			    SCM_RIGHTS) {
1038 				mp->msg_controllen = 0;
1039 				goto out;
1040 			}
1041 			control->m_len -= sizeof (struct cmsghdr);
1042 			control->m_data += sizeof (struct cmsghdr);
1043 		}
1044 #endif
1045 		len = mp->msg_controllen;
1046 		m = control;
1047 		mp->msg_controllen = 0;
1048 		ctlbuf = mp->msg_control;
1049 
1050 		while (m && len > 0) {
1051 			unsigned int tocopy;
1052 
1053 			if (len >= m->m_len)
1054 				tocopy = m->m_len;
1055 			else {
1056 				mp->msg_flags |= MSG_CTRUNC;
1057 				tocopy = len;
1058 			}
1059 
1060 			if ((error = copyout(mtod(m, caddr_t),
1061 					ctlbuf, tocopy)) != 0)
1062 				goto out;
1063 
1064 			ctlbuf += tocopy;
1065 			len -= tocopy;
1066 			m = m->m_next;
1067 		}
1068 		mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control;
1069 	}
1070 out:
1071 	fdrop(fp, td);
1072 #ifdef KTRACE
1073 	if (fromsa && KTRPOINT(td, KTR_STRUCT))
1074 		ktrsockaddr(fromsa);
1075 #endif
1076 	free(fromsa, M_SONAME);
1077 
1078 	if (error == 0 && controlp != NULL)
1079 		*controlp = control;
1080 	else  if (control)
1081 		m_freem(control);
1082 
1083 	return (error);
1084 }
1085 
1086 static int
1087 recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
1088 {
1089 	int error;
1090 
1091 	error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL);
1092 	if (error != 0)
1093 		return (error);
1094 	if (namelenp != NULL) {
1095 		error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t));
1096 #ifdef COMPAT_OLDSOCK
1097 		if (mp->msg_flags & MSG_COMPAT)
1098 			error = 0;	/* old recvfrom didn't check */
1099 #endif
1100 	}
1101 	return (error);
1102 }
1103 
1104 int
1105 sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
1106 {
1107 	struct msghdr msg;
1108 	struct iovec aiov;
1109 	int error;
1110 
1111 	if (uap->fromlenaddr) {
1112 		error = copyin(uap->fromlenaddr,
1113 		    &msg.msg_namelen, sizeof (msg.msg_namelen));
1114 		if (error != 0)
1115 			goto done2;
1116 	} else {
1117 		msg.msg_namelen = 0;
1118 	}
1119 	msg.msg_name = uap->from;
1120 	msg.msg_iov = &aiov;
1121 	msg.msg_iovlen = 1;
1122 	aiov.iov_base = uap->buf;
1123 	aiov.iov_len = uap->len;
1124 	msg.msg_control = 0;
1125 	msg.msg_flags = uap->flags;
1126 	error = recvit(td, uap->s, &msg, uap->fromlenaddr);
1127 done2:
1128 	return (error);
1129 }
1130 
1131 #ifdef COMPAT_OLDSOCK
1132 int
1133 orecvfrom(struct thread *td, struct recvfrom_args *uap)
1134 {
1135 
1136 	uap->flags |= MSG_COMPAT;
1137 	return (sys_recvfrom(td, uap));
1138 }
1139 #endif
1140 
1141 #ifdef COMPAT_OLDSOCK
1142 int
1143 orecv(struct thread *td, struct orecv_args *uap)
1144 {
1145 	struct msghdr msg;
1146 	struct iovec aiov;
1147 
1148 	msg.msg_name = 0;
1149 	msg.msg_namelen = 0;
1150 	msg.msg_iov = &aiov;
1151 	msg.msg_iovlen = 1;
1152 	aiov.iov_base = uap->buf;
1153 	aiov.iov_len = uap->len;
1154 	msg.msg_control = 0;
1155 	msg.msg_flags = uap->flags;
1156 	return (recvit(td, uap->s, &msg, NULL));
1157 }
1158 
1159 /*
1160  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
1161  * overlays the new one, missing only the flags, and with the (old) access
1162  * rights where the control fields are now.
1163  */
1164 int
1165 orecvmsg(struct thread *td, struct orecvmsg_args *uap)
1166 {
1167 	struct msghdr msg;
1168 	struct iovec *iov;
1169 	int error;
1170 
1171 	error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
1172 	if (error != 0)
1173 		return (error);
1174 	error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1175 	if (error != 0)
1176 		return (error);
1177 	msg.msg_flags = uap->flags | MSG_COMPAT;
1178 	msg.msg_iov = iov;
1179 	error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen);
1180 	if (msg.msg_controllen && error == 0)
1181 		error = copyout(&msg.msg_controllen,
1182 		    &uap->msg->msg_accrightslen, sizeof (int));
1183 	free(iov, M_IOV);
1184 	return (error);
1185 }
1186 #endif
1187 
1188 int
1189 sys_recvmsg(struct thread *td, struct recvmsg_args *uap)
1190 {
1191 	struct msghdr msg;
1192 	struct iovec *uiov, *iov;
1193 	int error;
1194 
1195 	error = copyin(uap->msg, &msg, sizeof (msg));
1196 	if (error != 0)
1197 		return (error);
1198 	error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1199 	if (error != 0)
1200 		return (error);
1201 	msg.msg_flags = uap->flags;
1202 #ifdef COMPAT_OLDSOCK
1203 	msg.msg_flags &= ~MSG_COMPAT;
1204 #endif
1205 	uiov = msg.msg_iov;
1206 	msg.msg_iov = iov;
1207 	error = recvit(td, uap->s, &msg, NULL);
1208 	if (error == 0) {
1209 		msg.msg_iov = uiov;
1210 		error = copyout(&msg, uap->msg, sizeof(msg));
1211 	}
1212 	free(iov, M_IOV);
1213 	return (error);
1214 }
1215 
1216 int
1217 sys_shutdown(struct thread *td, struct shutdown_args *uap)
1218 {
1219 
1220 	return (kern_shutdown(td, uap->s, uap->how));
1221 }
1222 
1223 int
1224 kern_shutdown(struct thread *td, int s, int how)
1225 {
1226 	struct socket *so;
1227 	struct file *fp;
1228 	cap_rights_t rights;
1229 	int error;
1230 
1231 	AUDIT_ARG_FD(s);
1232 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SHUTDOWN),
1233 	    &fp, NULL, NULL);
1234 	if (error == 0) {
1235 		so = fp->f_data;
1236 		error = soshutdown(so, how);
1237 		/*
1238 		 * Previous versions did not return ENOTCONN, but 0 in
1239 		 * case the socket was not connected. Some important
1240 		 * programs like syslogd up to r279016, 2015-02-19,
1241 		 * still depend on this behavior.
1242 		 */
1243 		if (error == ENOTCONN &&
1244 		    td->td_proc->p_osrel < P_OSREL_SHUTDOWN_ENOTCONN)
1245 			error = 0;
1246 		fdrop(fp, td);
1247 	}
1248 	return (error);
1249 }
1250 
1251 int
1252 sys_setsockopt(struct thread *td, struct setsockopt_args *uap)
1253 {
1254 
1255 	return (kern_setsockopt(td, uap->s, uap->level, uap->name,
1256 	    uap->val, UIO_USERSPACE, uap->valsize));
1257 }
1258 
1259 int
1260 kern_setsockopt(struct thread *td, int s, int level, int name, void *val,
1261     enum uio_seg valseg, socklen_t valsize)
1262 {
1263 	struct socket *so;
1264 	struct file *fp;
1265 	struct sockopt sopt;
1266 	cap_rights_t rights;
1267 	int error;
1268 
1269 	if (val == NULL && valsize != 0)
1270 		return (EFAULT);
1271 	if ((int)valsize < 0)
1272 		return (EINVAL);
1273 
1274 	sopt.sopt_dir = SOPT_SET;
1275 	sopt.sopt_level = level;
1276 	sopt.sopt_name = name;
1277 	sopt.sopt_val = val;
1278 	sopt.sopt_valsize = valsize;
1279 	switch (valseg) {
1280 	case UIO_USERSPACE:
1281 		sopt.sopt_td = td;
1282 		break;
1283 	case UIO_SYSSPACE:
1284 		sopt.sopt_td = NULL;
1285 		break;
1286 	default:
1287 		panic("kern_setsockopt called with bad valseg");
1288 	}
1289 
1290 	AUDIT_ARG_FD(s);
1291 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT),
1292 	    &fp, NULL, NULL);
1293 	if (error == 0) {
1294 		so = fp->f_data;
1295 		error = sosetopt(so, &sopt);
1296 		fdrop(fp, td);
1297 	}
1298 	return(error);
1299 }
1300 
1301 int
1302 sys_getsockopt(struct thread *td, struct getsockopt_args *uap)
1303 {
1304 	socklen_t valsize;
1305 	int error;
1306 
1307 	if (uap->val) {
1308 		error = copyin(uap->avalsize, &valsize, sizeof (valsize));
1309 		if (error != 0)
1310 			return (error);
1311 	}
1312 
1313 	error = kern_getsockopt(td, uap->s, uap->level, uap->name,
1314 	    uap->val, UIO_USERSPACE, &valsize);
1315 
1316 	if (error == 0)
1317 		error = copyout(&valsize, uap->avalsize, sizeof (valsize));
1318 	return (error);
1319 }
1320 
1321 /*
1322  * Kernel version of getsockopt.
1323  * optval can be a userland or userspace. optlen is always a kernel pointer.
1324  */
1325 int
1326 kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
1327     enum uio_seg valseg, socklen_t *valsize)
1328 {
1329 	struct socket *so;
1330 	struct file *fp;
1331 	struct sockopt sopt;
1332 	cap_rights_t rights;
1333 	int error;
1334 
1335 	if (val == NULL)
1336 		*valsize = 0;
1337 	if ((int)*valsize < 0)
1338 		return (EINVAL);
1339 
1340 	sopt.sopt_dir = SOPT_GET;
1341 	sopt.sopt_level = level;
1342 	sopt.sopt_name = name;
1343 	sopt.sopt_val = val;
1344 	sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
1345 	switch (valseg) {
1346 	case UIO_USERSPACE:
1347 		sopt.sopt_td = td;
1348 		break;
1349 	case UIO_SYSSPACE:
1350 		sopt.sopt_td = NULL;
1351 		break;
1352 	default:
1353 		panic("kern_getsockopt called with bad valseg");
1354 	}
1355 
1356 	AUDIT_ARG_FD(s);
1357 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT),
1358 	    &fp, NULL, NULL);
1359 	if (error == 0) {
1360 		so = fp->f_data;
1361 		error = sogetopt(so, &sopt);
1362 		*valsize = sopt.sopt_valsize;
1363 		fdrop(fp, td);
1364 	}
1365 	return (error);
1366 }
1367 
1368 /*
1369  * getsockname1() - Get socket name.
1370  */
1371 static int
1372 getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
1373 {
1374 	struct sockaddr *sa;
1375 	socklen_t len;
1376 	int error;
1377 
1378 	error = copyin(uap->alen, &len, sizeof(len));
1379 	if (error != 0)
1380 		return (error);
1381 
1382 	error = kern_getsockname(td, uap->fdes, &sa, &len);
1383 	if (error != 0)
1384 		return (error);
1385 
1386 	if (len != 0) {
1387 #ifdef COMPAT_OLDSOCK
1388 		if (compat)
1389 			((struct osockaddr *)sa)->sa_family = sa->sa_family;
1390 #endif
1391 		error = copyout(sa, uap->asa, (u_int)len);
1392 	}
1393 	free(sa, M_SONAME);
1394 	if (error == 0)
1395 		error = copyout(&len, uap->alen, sizeof(len));
1396 	return (error);
1397 }
1398 
1399 int
1400 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
1401     socklen_t *alen)
1402 {
1403 	struct socket *so;
1404 	struct file *fp;
1405 	cap_rights_t rights;
1406 	socklen_t len;
1407 	int error;
1408 
1409 	AUDIT_ARG_FD(fd);
1410 	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME),
1411 	    &fp, NULL, NULL);
1412 	if (error != 0)
1413 		return (error);
1414 	so = fp->f_data;
1415 	*sa = NULL;
1416 	CURVNET_SET(so->so_vnet);
1417 	error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa);
1418 	CURVNET_RESTORE();
1419 	if (error != 0)
1420 		goto bad;
1421 	if (*sa == NULL)
1422 		len = 0;
1423 	else
1424 		len = MIN(*alen, (*sa)->sa_len);
1425 	*alen = len;
1426 #ifdef KTRACE
1427 	if (KTRPOINT(td, KTR_STRUCT))
1428 		ktrsockaddr(*sa);
1429 #endif
1430 bad:
1431 	fdrop(fp, td);
1432 	if (error != 0 && *sa != NULL) {
1433 		free(*sa, M_SONAME);
1434 		*sa = NULL;
1435 	}
1436 	return (error);
1437 }
1438 
1439 int
1440 sys_getsockname(struct thread *td, struct getsockname_args *uap)
1441 {
1442 
1443 	return (getsockname1(td, uap, 0));
1444 }
1445 
1446 #ifdef COMPAT_OLDSOCK
1447 int
1448 ogetsockname(struct thread *td, struct getsockname_args *uap)
1449 {
1450 
1451 	return (getsockname1(td, uap, 1));
1452 }
1453 #endif /* COMPAT_OLDSOCK */
1454 
1455 /*
1456  * getpeername1() - Get name of peer for connected socket.
1457  */
1458 static int
1459 getpeername1(struct thread *td, struct getpeername_args *uap, int compat)
1460 {
1461 	struct sockaddr *sa;
1462 	socklen_t len;
1463 	int error;
1464 
1465 	error = copyin(uap->alen, &len, sizeof (len));
1466 	if (error != 0)
1467 		return (error);
1468 
1469 	error = kern_getpeername(td, uap->fdes, &sa, &len);
1470 	if (error != 0)
1471 		return (error);
1472 
1473 	if (len != 0) {
1474 #ifdef COMPAT_OLDSOCK
1475 		if (compat)
1476 			((struct osockaddr *)sa)->sa_family = sa->sa_family;
1477 #endif
1478 		error = copyout(sa, uap->asa, (u_int)len);
1479 	}
1480 	free(sa, M_SONAME);
1481 	if (error == 0)
1482 		error = copyout(&len, uap->alen, sizeof(len));
1483 	return (error);
1484 }
1485 
1486 int
1487 kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
1488     socklen_t *alen)
1489 {
1490 	struct socket *so;
1491 	struct file *fp;
1492 	cap_rights_t rights;
1493 	socklen_t len;
1494 	int error;
1495 
1496 	AUDIT_ARG_FD(fd);
1497 	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME),
1498 	    &fp, NULL, NULL);
1499 	if (error != 0)
1500 		return (error);
1501 	so = fp->f_data;
1502 	if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
1503 		error = ENOTCONN;
1504 		goto done;
1505 	}
1506 	*sa = NULL;
1507 	CURVNET_SET(so->so_vnet);
1508 	error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa);
1509 	CURVNET_RESTORE();
1510 	if (error != 0)
1511 		goto bad;
1512 	if (*sa == NULL)
1513 		len = 0;
1514 	else
1515 		len = MIN(*alen, (*sa)->sa_len);
1516 	*alen = len;
1517 #ifdef KTRACE
1518 	if (KTRPOINT(td, KTR_STRUCT))
1519 		ktrsockaddr(*sa);
1520 #endif
1521 bad:
1522 	if (error != 0 && *sa != NULL) {
1523 		free(*sa, M_SONAME);
1524 		*sa = NULL;
1525 	}
1526 done:
1527 	fdrop(fp, td);
1528 	return (error);
1529 }
1530 
1531 int
1532 sys_getpeername(struct thread *td, struct getpeername_args *uap)
1533 {
1534 
1535 	return (getpeername1(td, uap, 0));
1536 }
1537 
1538 #ifdef COMPAT_OLDSOCK
1539 int
1540 ogetpeername(struct thread *td, struct ogetpeername_args *uap)
1541 {
1542 
1543 	/* XXX uap should have type `getpeername_args *' to begin with. */
1544 	return (getpeername1(td, (struct getpeername_args *)uap, 1));
1545 }
1546 #endif /* COMPAT_OLDSOCK */
1547 
1548 static int
1549 sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type)
1550 {
1551 	struct sockaddr *sa;
1552 	struct mbuf *m;
1553 	int error;
1554 
1555 	if (buflen > MLEN) {
1556 #ifdef COMPAT_OLDSOCK
1557 		if (type == MT_SONAME && buflen <= 112)
1558 			buflen = MLEN;		/* unix domain compat. hack */
1559 		else
1560 #endif
1561 			if (buflen > MCLBYTES)
1562 				return (EINVAL);
1563 	}
1564 	m = m_get2(buflen, M_WAITOK, type, 0);
1565 	m->m_len = buflen;
1566 	error = copyin(buf, mtod(m, void *), buflen);
1567 	if (error != 0)
1568 		(void) m_free(m);
1569 	else {
1570 		*mp = m;
1571 		if (type == MT_SONAME) {
1572 			sa = mtod(m, struct sockaddr *);
1573 
1574 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1575 			if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1576 				sa->sa_family = sa->sa_len;
1577 #endif
1578 			sa->sa_len = buflen;
1579 		}
1580 	}
1581 	return (error);
1582 }
1583 
1584 int
1585 getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len)
1586 {
1587 	struct sockaddr *sa;
1588 	int error;
1589 
1590 	if (len > SOCK_MAXADDRLEN)
1591 		return (ENAMETOOLONG);
1592 	if (len < offsetof(struct sockaddr, sa_data[0]))
1593 		return (EINVAL);
1594 	sa = malloc(len, M_SONAME, M_WAITOK);
1595 	error = copyin(uaddr, sa, len);
1596 	if (error != 0) {
1597 		free(sa, M_SONAME);
1598 	} else {
1599 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1600 		if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1601 			sa->sa_family = sa->sa_len;
1602 #endif
1603 		sa->sa_len = len;
1604 		*namp = sa;
1605 	}
1606 	return (error);
1607 }
1608