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