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