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