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