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