xref: /freebsd/sys/kern/uipc_syscalls.c (revision 3c4ba5f55438f7afd4f4b0b56f88f2bb505fd6a6)
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 	if (error == 0 && uname != NULL) {
302 #ifdef COMPAT_OLDSOCK
303 		if (SV_PROC_FLAG(td->td_proc, SV_AOUT) &&
304 		    (flags & ACCEPT4_COMPAT) != 0)
305 			((struct osockaddr *)name)->sa_family =
306 			    name->sa_family;
307 #endif
308 		error = copyout(name, uname, namelen);
309 	}
310 	if (error == 0)
311 		error = copyout(&namelen, anamelen,
312 		    sizeof(namelen));
313 	if (error != 0)
314 		fdclose(td, fp, td->td_retval[0]);
315 	fdrop(fp, td);
316 	free(name, M_SONAME);
317 	return (error);
318 }
319 
320 int
321 kern_accept(struct thread *td, int s, struct sockaddr **name,
322     socklen_t *namelen, struct file **fp)
323 {
324 	return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp));
325 }
326 
327 int
328 kern_accept4(struct thread *td, int s, struct sockaddr **name,
329     socklen_t *namelen, int flags, struct file **fp)
330 {
331 	struct file *headfp, *nfp = NULL;
332 	struct sockaddr *sa = NULL;
333 	struct socket *head, *so;
334 	struct filecaps fcaps;
335 	u_int fflag;
336 	pid_t pgid;
337 	int error, fd, tmp;
338 
339 	if (name != NULL)
340 		*name = NULL;
341 
342 	AUDIT_ARG_FD(s);
343 	error = getsock_cap(td, s, &cap_accept_rights,
344 	    &headfp, &fcaps);
345 	if (error != 0)
346 		return (error);
347 	fflag = atomic_load_int(&headfp->f_flag);
348 	head = headfp->f_data;
349 	if (!SOLISTENING(head)) {
350 		error = EINVAL;
351 		goto done;
352 	}
353 #ifdef MAC
354 	error = mac_socket_check_accept(td->td_ucred, head);
355 	if (error != 0)
356 		goto done;
357 #endif
358 	error = falloc_caps(td, &nfp, &fd,
359 	    (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps);
360 	if (error != 0)
361 		goto done;
362 	SOCK_LOCK(head);
363 	if (!SOLISTENING(head)) {
364 		SOCK_UNLOCK(head);
365 		error = EINVAL;
366 		goto noconnection;
367 	}
368 
369 	error = solisten_dequeue(head, &so, flags);
370 	if (error != 0)
371 		goto noconnection;
372 
373 	/* An extra reference on `nfp' has been held for us by falloc(). */
374 	td->td_retval[0] = fd;
375 
376 	/* Connection has been removed from the listen queue. */
377 	KNOTE_UNLOCKED(&head->so_rdsel.si_note, 0);
378 
379 	if (flags & ACCEPT4_INHERIT) {
380 		pgid = fgetown(&head->so_sigio);
381 		if (pgid != 0)
382 			fsetown(pgid, &so->so_sigio);
383 	} else {
384 		fflag &= ~(FNONBLOCK | FASYNC);
385 		if (flags & SOCK_NONBLOCK)
386 			fflag |= FNONBLOCK;
387 	}
388 
389 	finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
390 	/* Sync socket nonblocking/async state with file flags */
391 	tmp = fflag & FNONBLOCK;
392 	(void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
393 	tmp = fflag & FASYNC;
394 	(void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
395 	error = soaccept(so, &sa);
396 	if (error != 0)
397 		goto noconnection;
398 	if (sa == NULL) {
399 		if (name)
400 			*namelen = 0;
401 		goto done;
402 	}
403 	AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
404 	if (name) {
405 		/* check sa_len before it is destroyed */
406 		if (*namelen > sa->sa_len)
407 			*namelen = sa->sa_len;
408 #ifdef KTRACE
409 		if (KTRPOINT(td, KTR_STRUCT))
410 			ktrsockaddr(sa);
411 #endif
412 		*name = sa;
413 		sa = NULL;
414 	}
415 noconnection:
416 	free(sa, M_SONAME);
417 
418 	/*
419 	 * close the new descriptor, assuming someone hasn't ripped it
420 	 * out from under us.
421 	 */
422 	if (error != 0)
423 		fdclose(td, nfp, fd);
424 
425 	/*
426 	 * Release explicitly held references before returning.  We return
427 	 * a reference on nfp to the caller on success if they request it.
428 	 */
429 done:
430 	if (nfp == NULL)
431 		filecaps_free(&fcaps);
432 	if (fp != NULL) {
433 		if (error == 0) {
434 			*fp = nfp;
435 			nfp = NULL;
436 		} else
437 			*fp = NULL;
438 	}
439 	if (nfp != NULL)
440 		fdrop(nfp, td);
441 	fdrop(headfp, td);
442 	return (error);
443 }
444 
445 int
446 sys_accept(struct thread *td, struct accept_args *uap)
447 {
448 
449 	return (accept1(td, uap->s, uap->name, uap->anamelen, ACCEPT4_INHERIT));
450 }
451 
452 int
453 sys_accept4(struct thread *td, struct accept4_args *uap)
454 {
455 
456 	if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
457 		return (EINVAL);
458 
459 	return (accept1(td, uap->s, uap->name, uap->anamelen, uap->flags));
460 }
461 
462 #ifdef COMPAT_OLDSOCK
463 int
464 oaccept(struct thread *td, struct oaccept_args *uap)
465 {
466 
467 	return (accept1(td, uap->s, uap->name, uap->anamelen,
468 	    ACCEPT4_INHERIT | ACCEPT4_COMPAT));
469 }
470 #endif /* COMPAT_OLDSOCK */
471 
472 int
473 sys_connect(struct thread *td, struct connect_args *uap)
474 {
475 	struct sockaddr *sa;
476 	int error;
477 
478 	error = getsockaddr(&sa, uap->name, uap->namelen);
479 	if (error == 0) {
480 		error = kern_connectat(td, AT_FDCWD, uap->s, sa);
481 		free(sa, M_SONAME);
482 	}
483 	return (error);
484 }
485 
486 int
487 kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
488 {
489 	struct socket *so;
490 	struct file *fp;
491 	int error;
492 
493 #ifdef CAPABILITY_MODE
494 	if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
495 		return (ECAPMODE);
496 #endif
497 
498 	AUDIT_ARG_FD(fd);
499 	AUDIT_ARG_SOCKADDR(td, dirfd, sa);
500 	error = getsock(td, fd, &cap_connect_rights, &fp);
501 	if (error != 0)
502 		return (error);
503 	so = fp->f_data;
504 	if (so->so_state & SS_ISCONNECTING) {
505 		error = EALREADY;
506 		goto done1;
507 	}
508 #ifdef KTRACE
509 	if (KTRPOINT(td, KTR_STRUCT))
510 		ktrsockaddr(sa);
511 #endif
512 #ifdef MAC
513 	error = mac_socket_check_connect(td->td_ucred, so, sa);
514 	if (error != 0)
515 		goto bad;
516 #endif
517 	error = soconnectat(dirfd, so, sa, td);
518 	if (error != 0)
519 		goto bad;
520 	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
521 		error = EINPROGRESS;
522 		goto done1;
523 	}
524 	SOCK_LOCK(so);
525 	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
526 		error = msleep(&so->so_timeo, &so->so_lock, PSOCK | PCATCH,
527 		    "connec", 0);
528 		if (error != 0)
529 			break;
530 	}
531 	if (error == 0) {
532 		error = so->so_error;
533 		so->so_error = 0;
534 	}
535 	SOCK_UNLOCK(so);
536 bad:
537 	if (error == ERESTART)
538 		error = EINTR;
539 done1:
540 	fdrop(fp, td);
541 	return (error);
542 }
543 
544 int
545 sys_connectat(struct thread *td, struct connectat_args *uap)
546 {
547 	struct sockaddr *sa;
548 	int error;
549 
550 	error = getsockaddr(&sa, uap->name, uap->namelen);
551 	if (error == 0) {
552 		error = kern_connectat(td, uap->fd, uap->s, sa);
553 		free(sa, M_SONAME);
554 	}
555 	return (error);
556 }
557 
558 int
559 kern_socketpair(struct thread *td, int domain, int type, int protocol,
560     int *rsv)
561 {
562 	struct file *fp1, *fp2;
563 	struct socket *so1, *so2;
564 	int fd, error, oflag, fflag;
565 
566 	AUDIT_ARG_SOCKET(domain, type, protocol);
567 
568 	oflag = 0;
569 	fflag = 0;
570 	if ((type & SOCK_CLOEXEC) != 0) {
571 		type &= ~SOCK_CLOEXEC;
572 		oflag |= O_CLOEXEC;
573 	}
574 	if ((type & SOCK_NONBLOCK) != 0) {
575 		type &= ~SOCK_NONBLOCK;
576 		fflag |= FNONBLOCK;
577 	}
578 #ifdef MAC
579 	/* We might want to have a separate check for socket pairs. */
580 	error = mac_socket_check_create(td->td_ucred, domain, type,
581 	    protocol);
582 	if (error != 0)
583 		return (error);
584 #endif
585 	error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
586 	if (error != 0)
587 		return (error);
588 	error = socreate(domain, &so2, type, protocol, td->td_ucred, td);
589 	if (error != 0)
590 		goto free1;
591 	/* On success extra reference to `fp1' and 'fp2' is set by falloc. */
592 	error = falloc(td, &fp1, &fd, oflag);
593 	if (error != 0)
594 		goto free2;
595 	rsv[0] = fd;
596 	fp1->f_data = so1;	/* so1 already has ref count */
597 	error = falloc(td, &fp2, &fd, oflag);
598 	if (error != 0)
599 		goto free3;
600 	fp2->f_data = so2;	/* so2 already has ref count */
601 	rsv[1] = fd;
602 	error = soconnect2(so1, so2);
603 	if (error != 0)
604 		goto free4;
605 	if (type == SOCK_DGRAM) {
606 		/*
607 		 * Datagram socket connection is asymmetric.
608 		 */
609 		 error = soconnect2(so2, so1);
610 		 if (error != 0)
611 			goto free4;
612 	} else if (so1->so_proto->pr_flags & PR_CONNREQUIRED) {
613 		struct unpcb *unp, *unp2;
614 		unp = sotounpcb(so1);
615 		unp2 = sotounpcb(so2);
616 		/*
617 		 * No need to lock the unps, because the sockets are brand-new.
618 		 * No other threads can be using them yet
619 		 */
620 		unp_copy_peercred(td, unp, unp2, unp);
621 	}
622 	finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data,
623 	    &socketops);
624 	finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data,
625 	    &socketops);
626 	if ((fflag & FNONBLOCK) != 0) {
627 		(void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
628 		(void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
629 	}
630 	fdrop(fp1, td);
631 	fdrop(fp2, td);
632 	return (0);
633 free4:
634 	fdclose(td, fp2, rsv[1]);
635 	fdrop(fp2, td);
636 free3:
637 	fdclose(td, fp1, rsv[0]);
638 	fdrop(fp1, td);
639 free2:
640 	if (so2 != NULL)
641 		(void)soclose(so2);
642 free1:
643 	if (so1 != NULL)
644 		(void)soclose(so1);
645 	return (error);
646 }
647 
648 int
649 sys_socketpair(struct thread *td, struct socketpair_args *uap)
650 {
651 	int error, sv[2];
652 
653 	error = kern_socketpair(td, uap->domain, uap->type,
654 	    uap->protocol, sv);
655 	if (error != 0)
656 		return (error);
657 	error = copyout(sv, uap->rsv, 2 * sizeof(int));
658 	if (error != 0) {
659 		(void)kern_close(td, sv[0]);
660 		(void)kern_close(td, sv[1]);
661 	}
662 	return (error);
663 }
664 
665 static int
666 sendit(struct thread *td, int s, struct msghdr *mp, int flags)
667 {
668 	struct mbuf *control;
669 	struct sockaddr *to;
670 	int error;
671 
672 #ifdef CAPABILITY_MODE
673 	if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL))
674 		return (ECAPMODE);
675 #endif
676 
677 	if (mp->msg_name != NULL) {
678 		error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
679 		if (error != 0) {
680 			to = NULL;
681 			goto bad;
682 		}
683 		mp->msg_name = to;
684 	} else {
685 		to = NULL;
686 	}
687 
688 	if (mp->msg_control) {
689 		if (mp->msg_controllen < sizeof(struct cmsghdr)
690 #ifdef COMPAT_OLDSOCK
691 		    && (mp->msg_flags != MSG_COMPAT ||
692 		    !SV_PROC_FLAG(td->td_proc, SV_AOUT))
693 #endif
694 		) {
695 			error = EINVAL;
696 			goto bad;
697 		}
698 		error = sockargs(&control, mp->msg_control,
699 		    mp->msg_controllen, MT_CONTROL);
700 		if (error != 0)
701 			goto bad;
702 #ifdef COMPAT_OLDSOCK
703 		if (mp->msg_flags == MSG_COMPAT &&
704 		    SV_PROC_FLAG(td->td_proc, SV_AOUT)) {
705 			struct cmsghdr *cm;
706 
707 			M_PREPEND(control, sizeof(*cm), M_WAITOK);
708 			cm = mtod(control, struct cmsghdr *);
709 			cm->cmsg_len = control->m_len;
710 			cm->cmsg_level = SOL_SOCKET;
711 			cm->cmsg_type = SCM_RIGHTS;
712 		}
713 #endif
714 	} else {
715 		control = NULL;
716 	}
717 
718 	error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE);
719 
720 bad:
721 	free(to, M_SONAME);
722 	return (error);
723 }
724 
725 int
726 kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
727     struct mbuf *control, enum uio_seg segflg)
728 {
729 	struct file *fp;
730 	struct uio auio;
731 	struct iovec *iov;
732 	struct socket *so;
733 	cap_rights_t *rights;
734 #ifdef KTRACE
735 	struct uio *ktruio = NULL;
736 #endif
737 	ssize_t len;
738 	int i, error;
739 
740 	AUDIT_ARG_FD(s);
741 	rights = &cap_send_rights;
742 	if (mp->msg_name != NULL) {
743 		AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
744 		rights = &cap_send_connect_rights;
745 	}
746 	error = getsock(td, s, rights, &fp);
747 	if (error != 0) {
748 		m_freem(control);
749 		return (error);
750 	}
751 	so = (struct socket *)fp->f_data;
752 
753 #ifdef KTRACE
754 	if (mp->msg_name != NULL && KTRPOINT(td, KTR_STRUCT))
755 		ktrsockaddr(mp->msg_name);
756 #endif
757 #ifdef MAC
758 	if (mp->msg_name != NULL) {
759 		error = mac_socket_check_connect(td->td_ucred, so,
760 		    mp->msg_name);
761 		if (error != 0) {
762 			m_freem(control);
763 			goto bad;
764 		}
765 	}
766 	error = mac_socket_check_send(td->td_ucred, so);
767 	if (error != 0) {
768 		m_freem(control);
769 		goto bad;
770 	}
771 #endif
772 
773 	auio.uio_iov = mp->msg_iov;
774 	auio.uio_iovcnt = mp->msg_iovlen;
775 	auio.uio_segflg = segflg;
776 	auio.uio_rw = UIO_WRITE;
777 	auio.uio_td = td;
778 	auio.uio_offset = 0;			/* XXX */
779 	auio.uio_resid = 0;
780 	iov = mp->msg_iov;
781 	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
782 		if ((auio.uio_resid += iov->iov_len) < 0) {
783 			error = EINVAL;
784 			m_freem(control);
785 			goto bad;
786 		}
787 	}
788 #ifdef KTRACE
789 	if (KTRPOINT(td, KTR_GENIO))
790 		ktruio = cloneuio(&auio);
791 #endif
792 	len = auio.uio_resid;
793 	error = sousrsend(so, mp->msg_name, &auio, control, flags, NULL);
794 	if (error == 0)
795 		td->td_retval[0] = len - auio.uio_resid;
796 #ifdef KTRACE
797 	if (ktruio != NULL) {
798 		ktruio->uio_resid = td->td_retval[0];
799 		ktrgenio(s, UIO_WRITE, ktruio, error);
800 	}
801 #endif
802 bad:
803 	fdrop(fp, td);
804 	return (error);
805 }
806 
807 int
808 sys_sendto(struct thread *td, struct sendto_args *uap)
809 {
810 	struct msghdr msg;
811 	struct iovec aiov;
812 
813 	msg.msg_name = __DECONST(void *, uap->to);
814 	msg.msg_namelen = uap->tolen;
815 	msg.msg_iov = &aiov;
816 	msg.msg_iovlen = 1;
817 	msg.msg_control = 0;
818 #ifdef COMPAT_OLDSOCK
819 	if (SV_PROC_FLAG(td->td_proc, SV_AOUT))
820 		msg.msg_flags = 0;
821 #endif
822 	aiov.iov_base = __DECONST(void *, uap->buf);
823 	aiov.iov_len = uap->len;
824 	return (sendit(td, uap->s, &msg, uap->flags));
825 }
826 
827 #ifdef COMPAT_OLDSOCK
828 int
829 osend(struct thread *td, struct osend_args *uap)
830 {
831 	struct msghdr msg;
832 	struct iovec aiov;
833 
834 	msg.msg_name = 0;
835 	msg.msg_namelen = 0;
836 	msg.msg_iov = &aiov;
837 	msg.msg_iovlen = 1;
838 	aiov.iov_base = __DECONST(void *, uap->buf);
839 	aiov.iov_len = uap->len;
840 	msg.msg_control = 0;
841 	msg.msg_flags = 0;
842 	return (sendit(td, uap->s, &msg, uap->flags));
843 }
844 
845 int
846 osendmsg(struct thread *td, struct osendmsg_args *uap)
847 {
848 	struct msghdr msg;
849 	struct iovec *iov;
850 	int error;
851 
852 	error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
853 	if (error != 0)
854 		return (error);
855 	error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
856 	if (error != 0)
857 		return (error);
858 	msg.msg_iov = iov;
859 	msg.msg_flags = MSG_COMPAT;
860 	error = sendit(td, uap->s, &msg, uap->flags);
861 	free(iov, M_IOV);
862 	return (error);
863 }
864 #endif
865 
866 int
867 sys_sendmsg(struct thread *td, struct sendmsg_args *uap)
868 {
869 	struct msghdr msg;
870 	struct iovec *iov;
871 	int error;
872 
873 	error = copyin(uap->msg, &msg, sizeof (msg));
874 	if (error != 0)
875 		return (error);
876 	error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
877 	if (error != 0)
878 		return (error);
879 	msg.msg_iov = iov;
880 #ifdef COMPAT_OLDSOCK
881 	if (SV_PROC_FLAG(td->td_proc, SV_AOUT))
882 		msg.msg_flags = 0;
883 #endif
884 	error = sendit(td, uap->s, &msg, uap->flags);
885 	free(iov, M_IOV);
886 	return (error);
887 }
888 
889 int
890 kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
891     struct mbuf **controlp)
892 {
893 	struct uio auio;
894 	struct iovec *iov;
895 	struct mbuf *control, *m;
896 	caddr_t ctlbuf;
897 	struct file *fp;
898 	struct socket *so;
899 	struct sockaddr *fromsa = NULL;
900 #ifdef KTRACE
901 	struct uio *ktruio = NULL;
902 #endif
903 	ssize_t len;
904 	int error, i;
905 
906 	if (controlp != NULL)
907 		*controlp = NULL;
908 
909 	AUDIT_ARG_FD(s);
910 	error = getsock(td, s, &cap_recv_rights, &fp);
911 	if (error != 0)
912 		return (error);
913 	so = fp->f_data;
914 
915 #ifdef MAC
916 	error = mac_socket_check_receive(td->td_ucred, so);
917 	if (error != 0) {
918 		fdrop(fp, td);
919 		return (error);
920 	}
921 #endif
922 
923 	auio.uio_iov = mp->msg_iov;
924 	auio.uio_iovcnt = mp->msg_iovlen;
925 	auio.uio_segflg = UIO_USERSPACE;
926 	auio.uio_rw = UIO_READ;
927 	auio.uio_td = td;
928 	auio.uio_offset = 0;			/* XXX */
929 	auio.uio_resid = 0;
930 	iov = mp->msg_iov;
931 	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
932 		if ((auio.uio_resid += iov->iov_len) < 0) {
933 			fdrop(fp, td);
934 			return (EINVAL);
935 		}
936 	}
937 #ifdef KTRACE
938 	if (KTRPOINT(td, KTR_GENIO))
939 		ktruio = cloneuio(&auio);
940 #endif
941 	control = NULL;
942 	len = auio.uio_resid;
943 	error = soreceive(so, &fromsa, &auio, NULL,
944 	    (mp->msg_control || controlp) ? &control : NULL,
945 	    &mp->msg_flags);
946 	if (error != 0) {
947 		if (auio.uio_resid != len && (error == ERESTART ||
948 		    error == EINTR || error == EWOULDBLOCK))
949 			error = 0;
950 	}
951 	if (fromsa != NULL)
952 		AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa);
953 #ifdef KTRACE
954 	if (ktruio != NULL) {
955 		ktruio->uio_resid = len - auio.uio_resid;
956 		ktrgenio(s, UIO_READ, ktruio, error);
957 	}
958 #endif
959 	if (error != 0)
960 		goto out;
961 	td->td_retval[0] = len - auio.uio_resid;
962 	if (mp->msg_name) {
963 		len = mp->msg_namelen;
964 		if (len <= 0 || fromsa == NULL)
965 			len = 0;
966 		else {
967 			/* save sa_len before it is destroyed by MSG_COMPAT */
968 			len = MIN(len, fromsa->sa_len);
969 #ifdef COMPAT_OLDSOCK
970 			if ((mp->msg_flags & MSG_COMPAT) != 0 &&
971 			    SV_PROC_FLAG(td->td_proc, SV_AOUT))
972 				((struct osockaddr *)fromsa)->sa_family =
973 				    fromsa->sa_family;
974 #endif
975 			if (fromseg == UIO_USERSPACE) {
976 				error = copyout(fromsa, mp->msg_name,
977 				    (unsigned)len);
978 				if (error != 0)
979 					goto out;
980 			} else
981 				bcopy(fromsa, mp->msg_name, len);
982 		}
983 		mp->msg_namelen = len;
984 	}
985 	if (mp->msg_control && controlp == NULL) {
986 #ifdef COMPAT_OLDSOCK
987 		/*
988 		 * We assume that old recvmsg calls won't receive access
989 		 * rights and other control info, esp. as control info
990 		 * is always optional and those options didn't exist in 4.3.
991 		 * If we receive rights, trim the cmsghdr; anything else
992 		 * is tossed.
993 		 */
994 		if (control && (mp->msg_flags & MSG_COMPAT) != 0 &&
995 		    SV_PROC_FLAG(td->td_proc, SV_AOUT)) {
996 			if (mtod(control, struct cmsghdr *)->cmsg_level !=
997 			    SOL_SOCKET ||
998 			    mtod(control, struct cmsghdr *)->cmsg_type !=
999 			    SCM_RIGHTS) {
1000 				mp->msg_controllen = 0;
1001 				goto out;
1002 			}
1003 			control->m_len -= sizeof (struct cmsghdr);
1004 			control->m_data += sizeof (struct cmsghdr);
1005 		}
1006 #endif
1007 		ctlbuf = mp->msg_control;
1008 		len = mp->msg_controllen;
1009 		mp->msg_controllen = 0;
1010 		for (m = control; m != NULL && len >= m->m_len; m = m->m_next) {
1011 			if ((error = copyout(mtod(m, caddr_t), ctlbuf,
1012 			    m->m_len)) != 0)
1013 				goto out;
1014 
1015 			ctlbuf += m->m_len;
1016 			len -= m->m_len;
1017 			mp->msg_controllen += m->m_len;
1018 		}
1019 		if (m != NULL) {
1020 			mp->msg_flags |= MSG_CTRUNC;
1021 			m_dispose_extcontrolm(m);
1022 		}
1023 	}
1024 out:
1025 	fdrop(fp, td);
1026 #ifdef KTRACE
1027 	if (fromsa && KTRPOINT(td, KTR_STRUCT))
1028 		ktrsockaddr(fromsa);
1029 #endif
1030 	free(fromsa, M_SONAME);
1031 
1032 	if (error == 0 && controlp != NULL)
1033 		*controlp = control;
1034 	else if (control != NULL) {
1035 		if (error != 0)
1036 			m_dispose_extcontrolm(control);
1037 		m_freem(control);
1038 	}
1039 
1040 	return (error);
1041 }
1042 
1043 static int
1044 recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
1045 {
1046 	int error;
1047 
1048 	error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL);
1049 	if (error != 0)
1050 		return (error);
1051 	if (namelenp != NULL) {
1052 		error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t));
1053 #ifdef COMPAT_OLDSOCK
1054 		if ((mp->msg_flags & MSG_COMPAT) != 0 &&
1055 		    SV_PROC_FLAG(td->td_proc, SV_AOUT))
1056 			error = 0;	/* old recvfrom didn't check */
1057 #endif
1058 	}
1059 	return (error);
1060 }
1061 
1062 static int
1063 kern_recvfrom(struct thread *td, int s, void *buf, size_t len, int flags,
1064     struct sockaddr *from, socklen_t *fromlenaddr)
1065 {
1066 	struct msghdr msg;
1067 	struct iovec aiov;
1068 	int error;
1069 
1070 	if (fromlenaddr != NULL) {
1071 		error = copyin(fromlenaddr, &msg.msg_namelen,
1072 		    sizeof (msg.msg_namelen));
1073 		if (error != 0)
1074 			goto done2;
1075 	} else {
1076 		msg.msg_namelen = 0;
1077 	}
1078 	msg.msg_name = from;
1079 	msg.msg_iov = &aiov;
1080 	msg.msg_iovlen = 1;
1081 	aiov.iov_base = buf;
1082 	aiov.iov_len = len;
1083 	msg.msg_control = 0;
1084 	msg.msg_flags = flags;
1085 	error = recvit(td, s, &msg, fromlenaddr);
1086 done2:
1087 	return (error);
1088 }
1089 
1090 int
1091 sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
1092 {
1093 	return (kern_recvfrom(td, uap->s, uap->buf, uap->len,
1094 	    uap->flags, uap->from, uap->fromlenaddr));
1095 }
1096 
1097 
1098 #ifdef COMPAT_OLDSOCK
1099 int
1100 orecvfrom(struct thread *td, struct orecvfrom_args *uap)
1101 {
1102 	return (kern_recvfrom(td, uap->s, uap->buf, uap->len,
1103 	    uap->flags | MSG_COMPAT, uap->from, uap->fromlenaddr));
1104 }
1105 #endif
1106 
1107 #ifdef COMPAT_OLDSOCK
1108 int
1109 orecv(struct thread *td, struct orecv_args *uap)
1110 {
1111 	struct msghdr msg;
1112 	struct iovec aiov;
1113 
1114 	msg.msg_name = 0;
1115 	msg.msg_namelen = 0;
1116 	msg.msg_iov = &aiov;
1117 	msg.msg_iovlen = 1;
1118 	aiov.iov_base = uap->buf;
1119 	aiov.iov_len = uap->len;
1120 	msg.msg_control = 0;
1121 	msg.msg_flags = uap->flags;
1122 	return (recvit(td, uap->s, &msg, NULL));
1123 }
1124 
1125 /*
1126  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
1127  * overlays the new one, missing only the flags, and with the (old) access
1128  * rights where the control fields are now.
1129  */
1130 int
1131 orecvmsg(struct thread *td, struct orecvmsg_args *uap)
1132 {
1133 	struct msghdr msg;
1134 	struct iovec *iov;
1135 	int error;
1136 
1137 	error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
1138 	if (error != 0)
1139 		return (error);
1140 	error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1141 	if (error != 0)
1142 		return (error);
1143 	msg.msg_flags = uap->flags | MSG_COMPAT;
1144 	msg.msg_iov = iov;
1145 	error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen);
1146 	if (msg.msg_controllen && error == 0)
1147 		error = copyout(&msg.msg_controllen,
1148 		    &uap->msg->msg_accrightslen, sizeof (int));
1149 	free(iov, M_IOV);
1150 	return (error);
1151 }
1152 #endif
1153 
1154 int
1155 sys_recvmsg(struct thread *td, struct recvmsg_args *uap)
1156 {
1157 	struct msghdr msg;
1158 	struct iovec *uiov, *iov;
1159 	int error;
1160 
1161 	error = copyin(uap->msg, &msg, sizeof (msg));
1162 	if (error != 0)
1163 		return (error);
1164 	error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1165 	if (error != 0)
1166 		return (error);
1167 	msg.msg_flags = uap->flags;
1168 #ifdef COMPAT_OLDSOCK
1169 	if (SV_PROC_FLAG(td->td_proc, SV_AOUT))
1170 		msg.msg_flags &= ~MSG_COMPAT;
1171 #endif
1172 	uiov = msg.msg_iov;
1173 	msg.msg_iov = iov;
1174 	error = recvit(td, uap->s, &msg, NULL);
1175 	if (error == 0) {
1176 		msg.msg_iov = uiov;
1177 		error = copyout(&msg, uap->msg, sizeof(msg));
1178 	}
1179 	free(iov, M_IOV);
1180 	return (error);
1181 }
1182 
1183 int
1184 sys_shutdown(struct thread *td, struct shutdown_args *uap)
1185 {
1186 
1187 	return (kern_shutdown(td, uap->s, uap->how));
1188 }
1189 
1190 int
1191 kern_shutdown(struct thread *td, int s, int how)
1192 {
1193 	struct socket *so;
1194 	struct file *fp;
1195 	int error;
1196 
1197 	AUDIT_ARG_FD(s);
1198 	error = getsock(td, s, &cap_shutdown_rights, &fp);
1199 	if (error == 0) {
1200 		so = fp->f_data;
1201 		error = soshutdown(so, how);
1202 		/*
1203 		 * Previous versions did not return ENOTCONN, but 0 in
1204 		 * case the socket was not connected. Some important
1205 		 * programs like syslogd up to r279016, 2015-02-19,
1206 		 * still depend on this behavior.
1207 		 */
1208 		if (error == ENOTCONN &&
1209 		    td->td_proc->p_osrel < P_OSREL_SHUTDOWN_ENOTCONN)
1210 			error = 0;
1211 		fdrop(fp, td);
1212 	}
1213 	return (error);
1214 }
1215 
1216 int
1217 sys_setsockopt(struct thread *td, struct setsockopt_args *uap)
1218 {
1219 
1220 	return (kern_setsockopt(td, uap->s, uap->level, uap->name,
1221 	    uap->val, UIO_USERSPACE, uap->valsize));
1222 }
1223 
1224 int
1225 kern_setsockopt(struct thread *td, int s, int level, int name, const void *val,
1226     enum uio_seg valseg, socklen_t valsize)
1227 {
1228 	struct socket *so;
1229 	struct file *fp;
1230 	struct sockopt sopt;
1231 	int error;
1232 
1233 	if (val == NULL && valsize != 0)
1234 		return (EFAULT);
1235 	if ((int)valsize < 0)
1236 		return (EINVAL);
1237 
1238 	sopt.sopt_dir = SOPT_SET;
1239 	sopt.sopt_level = level;
1240 	sopt.sopt_name = name;
1241 	sopt.sopt_val = __DECONST(void *, val);
1242 	sopt.sopt_valsize = valsize;
1243 	switch (valseg) {
1244 	case UIO_USERSPACE:
1245 		sopt.sopt_td = td;
1246 		break;
1247 	case UIO_SYSSPACE:
1248 		sopt.sopt_td = NULL;
1249 		break;
1250 	default:
1251 		panic("kern_setsockopt called with bad valseg");
1252 	}
1253 
1254 	AUDIT_ARG_FD(s);
1255 	error = getsock(td, s, &cap_setsockopt_rights, &fp);
1256 	if (error == 0) {
1257 		so = fp->f_data;
1258 		error = sosetopt(so, &sopt);
1259 		fdrop(fp, td);
1260 	}
1261 	return(error);
1262 }
1263 
1264 int
1265 sys_getsockopt(struct thread *td, struct getsockopt_args *uap)
1266 {
1267 	socklen_t valsize;
1268 	int error;
1269 
1270 	if (uap->val) {
1271 		error = copyin(uap->avalsize, &valsize, sizeof (valsize));
1272 		if (error != 0)
1273 			return (error);
1274 	}
1275 
1276 	error = kern_getsockopt(td, uap->s, uap->level, uap->name,
1277 	    uap->val, UIO_USERSPACE, &valsize);
1278 
1279 	if (error == 0)
1280 		error = copyout(&valsize, uap->avalsize, sizeof (valsize));
1281 	return (error);
1282 }
1283 
1284 /*
1285  * Kernel version of getsockopt.
1286  * optval can be a userland or userspace. optlen is always a kernel pointer.
1287  */
1288 int
1289 kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
1290     enum uio_seg valseg, socklen_t *valsize)
1291 {
1292 	struct socket *so;
1293 	struct file *fp;
1294 	struct sockopt sopt;
1295 	int error;
1296 
1297 	if (val == NULL)
1298 		*valsize = 0;
1299 	if ((int)*valsize < 0)
1300 		return (EINVAL);
1301 
1302 	sopt.sopt_dir = SOPT_GET;
1303 	sopt.sopt_level = level;
1304 	sopt.sopt_name = name;
1305 	sopt.sopt_val = val;
1306 	sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
1307 	switch (valseg) {
1308 	case UIO_USERSPACE:
1309 		sopt.sopt_td = td;
1310 		break;
1311 	case UIO_SYSSPACE:
1312 		sopt.sopt_td = NULL;
1313 		break;
1314 	default:
1315 		panic("kern_getsockopt called with bad valseg");
1316 	}
1317 
1318 	AUDIT_ARG_FD(s);
1319 	error = getsock(td, s, &cap_getsockopt_rights, &fp);
1320 	if (error == 0) {
1321 		so = fp->f_data;
1322 		error = sogetopt(so, &sopt);
1323 		*valsize = sopt.sopt_valsize;
1324 		fdrop(fp, td);
1325 	}
1326 	return (error);
1327 }
1328 
1329 static int
1330 user_getsockname(struct thread *td, int fdes, struct sockaddr *asa,
1331     socklen_t *alen, bool compat)
1332 {
1333 	struct sockaddr *sa;
1334 	socklen_t len;
1335 	int error;
1336 
1337 	error = copyin(alen, &len, sizeof(len));
1338 	if (error != 0)
1339 		return (error);
1340 
1341 	error = kern_getsockname(td, fdes, &sa, &len);
1342 	if (error != 0)
1343 		return (error);
1344 
1345 	if (len != 0) {
1346 #ifdef COMPAT_OLDSOCK
1347 		if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
1348 			((struct osockaddr *)sa)->sa_family = sa->sa_family;
1349 #endif
1350 		error = copyout(sa, asa, len);
1351 	}
1352 	free(sa, M_SONAME);
1353 	if (error == 0)
1354 		error = copyout(&len, alen, sizeof(len));
1355 	return (error);
1356 }
1357 
1358 int
1359 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
1360     socklen_t *alen)
1361 {
1362 	struct socket *so;
1363 	struct file *fp;
1364 	socklen_t len;
1365 	int error;
1366 
1367 	AUDIT_ARG_FD(fd);
1368 	error = getsock(td, fd, &cap_getsockname_rights, &fp);
1369 	if (error != 0)
1370 		return (error);
1371 	so = fp->f_data;
1372 	*sa = NULL;
1373 	CURVNET_SET(so->so_vnet);
1374 	error = so->so_proto->pr_sockaddr(so, sa);
1375 	CURVNET_RESTORE();
1376 	if (error != 0)
1377 		goto bad;
1378 	if (*sa == NULL)
1379 		len = 0;
1380 	else
1381 		len = MIN(*alen, (*sa)->sa_len);
1382 	*alen = len;
1383 #ifdef KTRACE
1384 	if (KTRPOINT(td, KTR_STRUCT))
1385 		ktrsockaddr(*sa);
1386 #endif
1387 bad:
1388 	fdrop(fp, td);
1389 	if (error != 0 && *sa != NULL) {
1390 		free(*sa, M_SONAME);
1391 		*sa = NULL;
1392 	}
1393 	return (error);
1394 }
1395 
1396 int
1397 sys_getsockname(struct thread *td, struct getsockname_args *uap)
1398 {
1399 	return (user_getsockname(td, uap->fdes, uap->asa, uap->alen, false));
1400 }
1401 
1402 #ifdef COMPAT_OLDSOCK
1403 int
1404 ogetsockname(struct thread *td, struct ogetsockname_args *uap)
1405 {
1406 	return (user_getsockname(td, uap->fdes, uap->asa, uap->alen, true));
1407 }
1408 #endif /* COMPAT_OLDSOCK */
1409 
1410 static int
1411 user_getpeername(struct thread *td, int fdes, struct sockaddr *asa,
1412     socklen_t *alen, bool compat)
1413 {
1414 	struct sockaddr *sa;
1415 	socklen_t len;
1416 	int error;
1417 
1418 	error = copyin(alen, &len, sizeof (len));
1419 	if (error != 0)
1420 		return (error);
1421 
1422 	error = kern_getpeername(td, fdes, &sa, &len);
1423 	if (error != 0)
1424 		return (error);
1425 
1426 	if (len != 0) {
1427 #ifdef COMPAT_OLDSOCK
1428 		if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
1429 			((struct osockaddr *)sa)->sa_family = sa->sa_family;
1430 #endif
1431 		error = copyout(sa, asa, len);
1432 	}
1433 	free(sa, M_SONAME);
1434 	if (error == 0)
1435 		error = copyout(&len, alen, sizeof(len));
1436 	return (error);
1437 }
1438 
1439 int
1440 kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
1441     socklen_t *alen)
1442 {
1443 	struct socket *so;
1444 	struct file *fp;
1445 	socklen_t len;
1446 	int error;
1447 
1448 	AUDIT_ARG_FD(fd);
1449 	error = getsock(td, fd, &cap_getpeername_rights, &fp);
1450 	if (error != 0)
1451 		return (error);
1452 	so = fp->f_data;
1453 	if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
1454 		error = ENOTCONN;
1455 		goto done;
1456 	}
1457 	*sa = NULL;
1458 	CURVNET_SET(so->so_vnet);
1459 	error = so->so_proto->pr_peeraddr(so, sa);
1460 	CURVNET_RESTORE();
1461 	if (error != 0)
1462 		goto bad;
1463 	if (*sa == NULL)
1464 		len = 0;
1465 	else
1466 		len = MIN(*alen, (*sa)->sa_len);
1467 	*alen = len;
1468 #ifdef KTRACE
1469 	if (KTRPOINT(td, KTR_STRUCT))
1470 		ktrsockaddr(*sa);
1471 #endif
1472 bad:
1473 	if (error != 0 && *sa != NULL) {
1474 		free(*sa, M_SONAME);
1475 		*sa = NULL;
1476 	}
1477 done:
1478 	fdrop(fp, td);
1479 	return (error);
1480 }
1481 
1482 int
1483 sys_getpeername(struct thread *td, struct getpeername_args *uap)
1484 {
1485 	return (user_getpeername(td, uap->fdes, uap->asa, uap->alen, false));
1486 }
1487 
1488 #ifdef COMPAT_OLDSOCK
1489 int
1490 ogetpeername(struct thread *td, struct ogetpeername_args *uap)
1491 {
1492 	return (user_getpeername(td, uap->fdes, uap->asa, uap->alen, true));
1493 }
1494 #endif /* COMPAT_OLDSOCK */
1495 
1496 static int
1497 sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type)
1498 {
1499 	struct sockaddr *sa;
1500 	struct mbuf *m;
1501 	int error;
1502 
1503 	if (buflen > MLEN) {
1504 #ifdef COMPAT_OLDSOCK
1505 		if (type == MT_SONAME && buflen <= 112 &&
1506 		    SV_CURPROC_FLAG(SV_AOUT))
1507 			buflen = MLEN;		/* unix domain compat. hack */
1508 		else
1509 #endif
1510 			if (buflen > MCLBYTES)
1511 				return (EMSGSIZE);
1512 	}
1513 	m = m_get2(buflen, M_WAITOK, type, 0);
1514 	m->m_len = buflen;
1515 	error = copyin(buf, mtod(m, void *), buflen);
1516 	if (error != 0)
1517 		(void) m_free(m);
1518 	else {
1519 		*mp = m;
1520 		if (type == MT_SONAME) {
1521 			sa = mtod(m, struct sockaddr *);
1522 
1523 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1524 			if (sa->sa_family == 0 && sa->sa_len < AF_MAX &&
1525 			    SV_CURPROC_FLAG(SV_AOUT))
1526 				sa->sa_family = sa->sa_len;
1527 #endif
1528 			sa->sa_len = buflen;
1529 		}
1530 	}
1531 	return (error);
1532 }
1533 
1534 int
1535 getsockaddr(struct sockaddr **namp, const struct sockaddr *uaddr, size_t len)
1536 {
1537 	struct sockaddr *sa;
1538 	int error;
1539 
1540 	if (len > SOCK_MAXADDRLEN)
1541 		return (ENAMETOOLONG);
1542 	if (len < offsetof(struct sockaddr, sa_data[0]))
1543 		return (EINVAL);
1544 	sa = malloc(len, M_SONAME, M_WAITOK);
1545 	error = copyin(uaddr, sa, len);
1546 	if (error != 0) {
1547 		free(sa, M_SONAME);
1548 	} else {
1549 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
1550 		if (sa->sa_family == 0 && sa->sa_len < AF_MAX &&
1551 		    SV_CURPROC_FLAG(SV_AOUT))
1552 			sa->sa_family = sa->sa_len;
1553 #endif
1554 		sa->sa_len = len;
1555 		*namp = sa;
1556 	}
1557 	return (error);
1558 }
1559 
1560 /*
1561  * Dispose of externalized rights from an SCM_RIGHTS message.  This function
1562  * should be used in error or truncation cases to avoid leaking file descriptors
1563  * into the recipient's (the current thread's) table.
1564  */
1565 void
1566 m_dispose_extcontrolm(struct mbuf *m)
1567 {
1568 	struct cmsghdr *cm;
1569 	struct file *fp;
1570 	struct thread *td;
1571 	socklen_t clen, datalen;
1572 	int error, fd, *fds, nfd;
1573 
1574 	td = curthread;
1575 	for (; m != NULL; m = m->m_next) {
1576 		if (m->m_type != MT_EXTCONTROL)
1577 			continue;
1578 		cm = mtod(m, struct cmsghdr *);
1579 		clen = m->m_len;
1580 		while (clen > 0) {
1581 			if (clen < sizeof(*cm))
1582 				panic("%s: truncated mbuf %p", __func__, m);
1583 			datalen = CMSG_SPACE(cm->cmsg_len - CMSG_SPACE(0));
1584 			if (clen < datalen)
1585 				panic("%s: truncated mbuf %p", __func__, m);
1586 
1587 			if (cm->cmsg_level == SOL_SOCKET &&
1588 			    cm->cmsg_type == SCM_RIGHTS) {
1589 				fds = (int *)CMSG_DATA(cm);
1590 				nfd = (cm->cmsg_len - CMSG_SPACE(0)) /
1591 				    sizeof(int);
1592 
1593 				while (nfd-- > 0) {
1594 					fd = *fds++;
1595 					error = fget(td, fd, &cap_no_rights,
1596 					    &fp);
1597 					if (error == 0) {
1598 						fdclose(td, fp, fd);
1599 						fdrop(fp, td);
1600 					}
1601 				}
1602 			}
1603 			clen -= datalen;
1604 			cm = (struct cmsghdr *)((uint8_t *)cm + datalen);
1605 		}
1606 		m_chtype(m, MT_CONTROL);
1607 	}
1608 }
1609