1/*
2 * Copyright (c) 2000-2014 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * Copyright (c) 1982, 1986, 1989, 1990, 1993
30 *	The Regents of the University of California.  All rights reserved.
31 *
32 * sendfile(2) and related extensions:
33 * Copyright (c) 1998, David Greenman. All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 *    notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 *    notice, this list of conditions and the following disclaimer in the
42 *    documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 *    must display the following acknowledgement:
45 *	This product includes software developed by the University of
46 *	California, Berkeley and its contributors.
47 * 4. Neither the name of the University nor the names of its contributors
48 *    may be used to endorse or promote products derived from this software
49 *    without specific prior written permission.
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE.
62 *
63 *	@(#)uipc_syscalls.c	8.4 (Berkeley) 2/21/94
64 */
65/*
66 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
67 * support for mandatory and extensible security protections.  This notice
68 * is included in support of clause 2.2 (b) of the Apple Public License,
69 * Version 2.0.
70 */
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/filedesc.h>
75#include <sys/proc_internal.h>
76#include <sys/file_internal.h>
77#include <sys/vnode_internal.h>
78#include <sys/malloc.h>
79#include <sys/mcache.h>
80#include <sys/mbuf.h>
81#include <kern/locks.h>
82#include <sys/domain.h>
83#include <sys/protosw.h>
84#include <sys/signalvar.h>
85#include <sys/socket.h>
86#include <sys/socketvar.h>
87#include <sys/kernel.h>
88#include <sys/uio_internal.h>
89#include <sys/kauth.h>
90#include <kern/task.h>
91#include <sys/priv.h>
92
93#include <security/audit/audit.h>
94
95#include <sys/kdebug.h>
96#include <sys/sysproto.h>
97#include <netinet/in.h>
98#include <net/route.h>
99#include <netinet/in_pcb.h>
100
101#if CONFIG_MACF_SOCKET_SUBSET
102#include <security/mac_framework.h>
103#endif /* MAC_SOCKET_SUBSET */
104
105#define	f_flag f_fglob->fg_flag
106#define	f_type f_fglob->fg_ops->fo_type
107#define	f_msgcount f_fglob->fg_msgcount
108#define	f_cred f_fglob->fg_cred
109#define	f_ops f_fglob->fg_ops
110#define	f_offset f_fglob->fg_offset
111#define	f_data f_fglob->fg_data
112
113#define	DBG_LAYER_IN_BEG	NETDBG_CODE(DBG_NETSOCK, 0)
114#define	DBG_LAYER_IN_END	NETDBG_CODE(DBG_NETSOCK, 2)
115#define	DBG_LAYER_OUT_BEG	NETDBG_CODE(DBG_NETSOCK, 1)
116#define	DBG_LAYER_OUT_END	NETDBG_CODE(DBG_NETSOCK, 3)
117#define	DBG_FNC_SENDMSG		NETDBG_CODE(DBG_NETSOCK, (1 << 8) | 1)
118#define	DBG_FNC_SENDTO		NETDBG_CODE(DBG_NETSOCK, (2 << 8) | 1)
119#define	DBG_FNC_SENDIT		NETDBG_CODE(DBG_NETSOCK, (3 << 8) | 1)
120#define	DBG_FNC_RECVFROM	NETDBG_CODE(DBG_NETSOCK, (5 << 8))
121#define	DBG_FNC_RECVMSG		NETDBG_CODE(DBG_NETSOCK, (6 << 8))
122#define	DBG_FNC_RECVIT		NETDBG_CODE(DBG_NETSOCK, (7 << 8))
123#define	DBG_FNC_SENDFILE	NETDBG_CODE(DBG_NETSOCK, (10 << 8))
124#define	DBG_FNC_SENDFILE_WAIT	NETDBG_CODE(DBG_NETSOCK, ((10 << 8) | 1))
125#define	DBG_FNC_SENDFILE_READ	NETDBG_CODE(DBG_NETSOCK, ((10 << 8) | 2))
126#define	DBG_FNC_SENDFILE_SEND	NETDBG_CODE(DBG_NETSOCK, ((10 << 8) | 3))
127#define	DBG_FNC_SENDMSG_X	NETDBG_CODE(DBG_NETSOCK, (11 << 8))
128#define	DBG_FNC_RECVMSG_X	NETDBG_CODE(DBG_NETSOCK, (12 << 8))
129
130
131/* TODO: should be in header file */
132int falloc_locked(proc_t, struct fileproc **, int *, vfs_context_t, int);
133
134static int sendit(struct proc *, int, struct user_msghdr *, uio_t, int,
135    int32_t *);
136static int recvit(struct proc *, int, struct user_msghdr *, uio_t, user_addr_t,
137    int32_t *);
138static int connectit(struct socket *, struct sockaddr *);
139static int getsockaddr(struct socket *, struct sockaddr **, user_addr_t,
140    size_t, boolean_t);
141static int getsockaddr_s(struct socket *, struct sockaddr_storage *,
142    user_addr_t, size_t, boolean_t);
143static int getsockaddrlist(struct socket *, struct sockaddr_list **,
144    user_addr_t, socklen_t, boolean_t);
145#if SENDFILE
146static void alloc_sendpkt(int, size_t, unsigned int *, struct mbuf **,
147    boolean_t);
148#endif /* SENDFILE */
149static int connectx_nocancel(struct proc *, struct connectx_args *, int *);
150static int connectitx(struct socket *, struct sockaddr_list **,
151    struct sockaddr_list **, struct proc *, uint32_t, associd_t, connid_t *);
152static int peeloff_nocancel(struct proc *, struct peeloff_args *, int *);
153static int disconnectx_nocancel(struct proc *, struct disconnectx_args *,
154    int *);
155static int socket_common(struct proc *, int, int, int, pid_t, int32_t *, int);
156
157static int internalize_user_msghdr_array(const void *, int, int, u_int,
158			struct user_msghdr_x *, struct uio **);
159static u_int externalize_user_msghdr_array(void *, int, int, u_int,
160			 const struct user_msghdr_x *, struct uio **);
161
162static void free_uio_array(struct uio **, u_int);
163static int uio_array_is_valid(struct uio **, u_int);
164
165/*
166 * System call interface to the socket abstraction.
167 */
168
169extern const struct fileops socketops;
170
171/*
172 * Returns:	0			Success
173 *		EACCES			Mandatory Access Control failure
174 *	falloc:ENFILE
175 *	falloc:EMFILE
176 *	falloc:ENOMEM
177 *	socreate:EAFNOSUPPORT
178 *	socreate:EPROTOTYPE
179 *	socreate:EPROTONOSUPPORT
180 *	socreate:ENOBUFS
181 *	socreate:ENOMEM
182 *	socreate:???			[other protocol families, IPSEC]
183 */
184int
185socket(struct proc *p,
186	struct socket_args *uap,
187	int32_t *retval)
188{
189	return (socket_common(p, uap->domain, uap->type, uap->protocol,
190	    proc_selfpid(), retval, 0));
191}
192
193int
194socket_delegate(struct proc *p,
195		struct socket_delegate_args *uap,
196		int32_t *retval)
197{
198	return socket_common(p, uap->domain, uap->type, uap->protocol,
199	    uap->epid, retval, 1);
200}
201
202static int
203socket_common(struct proc *p,
204		int domain,
205		int type,
206		int protocol,
207		pid_t epid,
208		int32_t *retval,
209		int delegate)
210{
211	struct socket *so;
212	struct fileproc *fp;
213	int fd, error;
214
215	AUDIT_ARG(socket, domain, type, protocol);
216#if CONFIG_MACF_SOCKET_SUBSET
217	if ((error = mac_socket_check_create(kauth_cred_get(), domain,
218	    type, protocol)) != 0)
219		return (error);
220#endif /* MAC_SOCKET_SUBSET */
221
222	if (delegate) {
223		error = priv_check_cred(kauth_cred_get(),
224		    PRIV_NET_PRIVILEGED_SOCKET_DELEGATE, 0);
225		if (error)
226			return (EACCES);
227	}
228
229	error = falloc(p, &fp, &fd, vfs_context_current());
230	if (error) {
231		return (error);
232	}
233	fp->f_flag = FREAD|FWRITE;
234	fp->f_ops = &socketops;
235
236	if (delegate)
237		error = socreate_delegate(domain, &so, type, protocol, epid);
238	else
239		error = socreate(domain, &so, type, protocol);
240
241	if (error) {
242		fp_free(p, fd, fp);
243	} else {
244		fp->f_data = (caddr_t)so;
245
246		proc_fdlock(p);
247		procfdtbl_releasefd(p, fd, NULL);
248
249		fp_drop(p, fd, fp, 1);
250		proc_fdunlock(p);
251
252		*retval = fd;
253	}
254	return (error);
255}
256
257/*
258 * Returns:	0			Success
259 *		EDESTADDRREQ		Destination address required
260 *		EBADF			Bad file descriptor
261 *		EACCES			Mandatory Access Control failure
262 *	file_socket:ENOTSOCK
263 *	file_socket:EBADF
264 *	getsockaddr:ENAMETOOLONG	Filename too long
265 *	getsockaddr:EINVAL		Invalid argument
266 *	getsockaddr:ENOMEM		Not enough space
267 *	getsockaddr:EFAULT		Bad address
268 *	sobindlock:???
269 */
270/* ARGSUSED */
271int
272bind(__unused proc_t p, struct bind_args *uap, __unused int32_t *retval)
273{
274	struct sockaddr_storage ss;
275	struct sockaddr *sa = NULL;
276	struct socket *so;
277	boolean_t want_free = TRUE;
278	int error;
279
280	AUDIT_ARG(fd, uap->s);
281	error = file_socket(uap->s, &so);
282	if (error != 0)
283		return (error);
284	if (so == NULL) {
285		error = EBADF;
286		goto out;
287	}
288	if (uap->name == USER_ADDR_NULL) {
289		error = EDESTADDRREQ;
290		goto out;
291	}
292	if (uap->namelen > sizeof (ss)) {
293		error = getsockaddr(so, &sa, uap->name, uap->namelen, TRUE);
294	} else {
295		error = getsockaddr_s(so, &ss, uap->name, uap->namelen, TRUE);
296		if (error == 0) {
297			sa = (struct sockaddr *)&ss;
298			want_free = FALSE;
299		}
300	}
301	if (error != 0)
302		goto out;
303	AUDIT_ARG(sockaddr, vfs_context_cwd(vfs_context_current()), sa);
304#if CONFIG_MACF_SOCKET_SUBSET
305	if ((error = mac_socket_check_bind(kauth_cred_get(), so, sa)) == 0)
306		error = sobindlock(so, sa, 1);	/* will lock socket */
307#else
308		error = sobindlock(so, sa, 1);	/* will lock socket */
309#endif /* MAC_SOCKET_SUBSET */
310	if (want_free)
311		FREE(sa, M_SONAME);
312out:
313	file_drop(uap->s);
314	return (error);
315}
316
317/*
318 * Returns:	0			Success
319 *		EBADF
320 *		EACCES			Mandatory Access Control failure
321 *	file_socket:ENOTSOCK
322 *	file_socket:EBADF
323 *	solisten:EINVAL
324 *	solisten:EOPNOTSUPP
325 *	solisten:???
326 */
327int
328listen(__unused struct proc *p, struct listen_args *uap,
329    __unused int32_t *retval)
330{
331	int error;
332	struct socket *so;
333
334	AUDIT_ARG(fd, uap->s);
335	error = file_socket(uap->s, &so);
336	if (error)
337		return (error);
338	if (so != NULL)
339#if CONFIG_MACF_SOCKET_SUBSET
340	{
341		error = mac_socket_check_listen(kauth_cred_get(), so);
342		if (error == 0)
343			error = solisten(so, uap->backlog);
344	}
345#else
346		error =  solisten(so, uap->backlog);
347#endif /* MAC_SOCKET_SUBSET */
348	else
349		error = EBADF;
350
351	file_drop(uap->s);
352	return (error);
353}
354
355/*
356 * Returns:	fp_getfsock:EBADF	Bad file descriptor
357 *		fp_getfsock:EOPNOTSUPP	...
358 *		xlate => :ENOTSOCK	Socket operation on non-socket
359 *		:EFAULT			Bad address on copyin/copyout
360 *		:EBADF			Bad file descriptor
361 *		:EOPNOTSUPP		Operation not supported on socket
362 *		:EINVAL			Invalid argument
363 *		:EWOULDBLOCK		Operation would block
364 *		:ECONNABORTED		Connection aborted
365 *		:EINTR			Interrupted function
366 *		:EACCES			Mandatory Access Control failure
367 *		falloc_locked:ENFILE	Too many files open in system
368 *		falloc_locked::EMFILE	Too many open files
369 *		falloc_locked::ENOMEM	Not enough space
370 *		0			Success
371 */
372int
373accept_nocancel(struct proc *p, struct accept_nocancel_args *uap,
374    int32_t *retval)
375{
376	struct fileproc *fp;
377	struct sockaddr *sa = NULL;
378	socklen_t namelen;
379	int error;
380	struct socket *head, *so = NULL;
381	lck_mtx_t *mutex_held;
382	int fd = uap->s;
383	int newfd;
384	short fflag;		/* type must match fp->f_flag */
385	int dosocklock = 0;
386
387	*retval = -1;
388
389	AUDIT_ARG(fd, uap->s);
390
391	if (uap->name) {
392		error = copyin(uap->anamelen, (caddr_t)&namelen,
393		    sizeof (socklen_t));
394		if (error)
395			return (error);
396	}
397	error = fp_getfsock(p, fd, &fp, &head);
398	if (error) {
399		if (error == EOPNOTSUPP)
400			error = ENOTSOCK;
401		return (error);
402	}
403	if (head == NULL) {
404		error = EBADF;
405		goto out;
406	}
407#if CONFIG_MACF_SOCKET_SUBSET
408	if ((error = mac_socket_check_accept(kauth_cred_get(), head)) != 0)
409		goto out;
410#endif /* MAC_SOCKET_SUBSET */
411
412	socket_lock(head, 1);
413
414	if (head->so_proto->pr_getlock != NULL)  {
415		mutex_held = (*head->so_proto->pr_getlock)(head, 0);
416		dosocklock = 1;
417	} else {
418		mutex_held = head->so_proto->pr_domain->dom_mtx;
419		dosocklock = 0;
420	}
421
422	if ((head->so_options & SO_ACCEPTCONN) == 0) {
423		if ((head->so_proto->pr_flags & PR_CONNREQUIRED) == 0) {
424			error = EOPNOTSUPP;
425		} else {
426			/* POSIX: The socket is not accepting connections */
427			error = EINVAL;
428		}
429		socket_unlock(head, 1);
430		goto out;
431	}
432	if ((head->so_state & SS_NBIO) && head->so_comp.tqh_first == NULL) {
433		socket_unlock(head, 1);
434		error = EWOULDBLOCK;
435		goto out;
436	}
437	while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
438		if (head->so_state & SS_CANTRCVMORE) {
439			head->so_error = ECONNABORTED;
440			break;
441		}
442		if (head->so_usecount < 1)
443			panic("accept: head=%p refcount=%d\n", head,
444			    head->so_usecount);
445		error = msleep((caddr_t)&head->so_timeo, mutex_held,
446		    PSOCK | PCATCH, "accept", 0);
447		if (head->so_usecount < 1)
448			panic("accept: 2 head=%p refcount=%d\n", head,
449			    head->so_usecount);
450		if ((head->so_state & SS_DRAINING)) {
451			error = ECONNABORTED;
452		}
453		if (error) {
454			socket_unlock(head, 1);
455			goto out;
456		}
457	}
458	if (head->so_error) {
459		error = head->so_error;
460		head->so_error = 0;
461		socket_unlock(head, 1);
462		goto out;
463	}
464
465
466	/*
467	 * At this point we know that there is at least one connection
468	 * ready to be accepted. Remove it from the queue prior to
469	 * allocating the file descriptor for it since falloc() may
470	 * block allowing another process to accept the connection
471	 * instead.
472	 */
473	lck_mtx_assert(mutex_held, LCK_MTX_ASSERT_OWNED);
474	so = TAILQ_FIRST(&head->so_comp);
475	TAILQ_REMOVE(&head->so_comp, so, so_list);
476	head->so_qlen--;
477	/* unlock head to avoid deadlock with select, keep a ref on head */
478	socket_unlock(head, 0);
479
480#if CONFIG_MACF_SOCKET_SUBSET
481	/*
482	 * Pass the pre-accepted socket to the MAC framework. This is
483	 * cheaper than allocating a file descriptor for the socket,
484	 * calling the protocol accept callback, and possibly freeing
485	 * the file descriptor should the MAC check fails.
486	 */
487	if ((error = mac_socket_check_accepted(kauth_cred_get(), so)) != 0) {
488		socket_lock(so, 1);
489		so->so_state &= ~(SS_NOFDREF | SS_COMP);
490		so->so_head = NULL;
491		socket_unlock(so, 1);
492		soclose(so);
493		/* Drop reference on listening socket */
494		sodereference(head);
495		goto out;
496	}
497#endif /* MAC_SOCKET_SUBSET */
498
499	/*
500	 * Pass the pre-accepted socket to any interested socket filter(s).
501	 * Upon failure, the socket would have been closed by the callee.
502	 */
503	if (so->so_filt != NULL && (error = soacceptfilter(so)) != 0) {
504		/* Drop reference on listening socket */
505		sodereference(head);
506		/* Propagate socket filter's error code to the caller */
507		goto out;
508	}
509
510	fflag = fp->f_flag;
511	error = falloc(p, &fp, &newfd, vfs_context_current());
512	if (error) {
513		/*
514		 * Probably ran out of file descriptors.
515		 *
516		 * <rdar://problem/8554930>
517		 * Don't put this back on the socket like we used to, that
518		 * just causes the client to spin. Drop the socket.
519		 */
520		socket_lock(so, 1);
521		so->so_state &= ~(SS_NOFDREF | SS_COMP);
522		so->so_head = NULL;
523		socket_unlock(so, 1);
524		soclose(so);
525		sodereference(head);
526		goto out;
527	}
528	*retval = newfd;
529	fp->f_flag = fflag;
530	fp->f_ops = &socketops;
531	fp->f_data = (caddr_t)so;
532
533	socket_lock(head, 0);
534	if (dosocklock)
535		socket_lock(so, 1);
536
537	so->so_state &= ~SS_COMP;
538	so->so_head = NULL;
539
540	/* Sync socket non-blocking/async state with file flags */
541	if (fp->f_flag & FNONBLOCK) {
542		so->so_state |= SS_NBIO;
543	} else {
544		so->so_state &= ~SS_NBIO;
545	}
546
547	if (fp->f_flag & FASYNC) {
548		so->so_state |= SS_ASYNC;
549		so->so_rcv.sb_flags |= SB_ASYNC;
550		so->so_snd.sb_flags |= SB_ASYNC;
551	} else {
552		so->so_state &= ~SS_ASYNC;
553		so->so_rcv.sb_flags &= ~SB_ASYNC;
554		so->so_snd.sb_flags &= ~SB_ASYNC;
555	}
556
557	(void) soacceptlock(so, &sa, 0);
558	socket_unlock(head, 1);
559	if (sa == NULL) {
560		namelen = 0;
561		if (uap->name)
562			goto gotnoname;
563		error = 0;
564		goto releasefd;
565	}
566	AUDIT_ARG(sockaddr, vfs_context_cwd(vfs_context_current()), sa);
567
568	if (uap->name) {
569		socklen_t	sa_len;
570
571		/* save sa_len before it is destroyed */
572		sa_len = sa->sa_len;
573		namelen = MIN(namelen, sa_len);
574		error = copyout(sa, uap->name, namelen);
575		if (!error)
576			/* return the actual, untruncated address length */
577			namelen = sa_len;
578gotnoname:
579		error = copyout((caddr_t)&namelen, uap->anamelen,
580		    sizeof (socklen_t));
581	}
582	FREE(sa, M_SONAME);
583
584releasefd:
585	/*
586	 * If the socket has been marked as inactive by sosetdefunct(),
587	 * disallow further operations on it.
588	 */
589	if (so->so_flags & SOF_DEFUNCT) {
590		sodefunct(current_proc(), so,
591		    SHUTDOWN_SOCKET_LEVEL_DISCONNECT_INTERNAL);
592	}
593
594	if (dosocklock)
595		socket_unlock(so, 1);
596
597	proc_fdlock(p);
598	procfdtbl_releasefd(p, newfd, NULL);
599	fp_drop(p, newfd, fp, 1);
600	proc_fdunlock(p);
601
602out:
603	file_drop(fd);
604	return (error);
605}
606
607int
608accept(struct proc *p, struct accept_args *uap, int32_t *retval)
609{
610	__pthread_testcancel(1);
611	return(accept_nocancel(p, (struct accept_nocancel_args *)uap, retval));
612}
613
614/*
615 * Returns:	0			Success
616 *		EBADF			Bad file descriptor
617 *		EALREADY		Connection already in progress
618 *		EINPROGRESS		Operation in progress
619 *		ECONNABORTED		Connection aborted
620 *		EINTR			Interrupted function
621 *		EACCES			Mandatory Access Control failure
622 *	file_socket:ENOTSOCK
623 *	file_socket:EBADF
624 *	getsockaddr:ENAMETOOLONG	Filename too long
625 *	getsockaddr:EINVAL		Invalid argument
626 *	getsockaddr:ENOMEM		Not enough space
627 *	getsockaddr:EFAULT		Bad address
628 *	soconnectlock:EOPNOTSUPP
629 *	soconnectlock:EISCONN
630 *	soconnectlock:???		[depends on protocol, filters]
631 *	msleep:EINTR
632 *
633 * Imputed:	so_error		error may be set from so_error, which
634 *					may have been set by soconnectlock.
635 */
636/* ARGSUSED */
637int
638connect(struct proc *p, struct connect_args *uap, int32_t *retval)
639{
640	__pthread_testcancel(1);
641	return(connect_nocancel(p, (struct connect_nocancel_args *)uap, retval));
642}
643
644int
645connect_nocancel(proc_t p, struct connect_nocancel_args *uap, int32_t *retval)
646{
647#pragma unused(p, retval)
648	struct socket *so;
649	struct sockaddr_storage ss;
650	struct sockaddr *sa = NULL;
651	int error;
652	int fd = uap->s;
653	boolean_t dgram;
654
655	AUDIT_ARG(fd, uap->s);
656	error = file_socket(fd, &so);
657	if (error != 0)
658		return (error);
659	if (so == NULL) {
660		error = EBADF;
661		goto out;
662	}
663
664	/*
665	 * Ask getsockaddr{_s} to not translate AF_UNSPEC to AF_INET
666	 * if this is a datagram socket; translate for other types.
667	 */
668	dgram = (so->so_type == SOCK_DGRAM);
669
670	/* Get socket address now before we obtain socket lock */
671	if (uap->namelen > sizeof (ss)) {
672		error = getsockaddr(so, &sa, uap->name, uap->namelen, !dgram);
673	} else {
674		error = getsockaddr_s(so, &ss, uap->name, uap->namelen, !dgram);
675		if (error == 0)
676			sa = (struct sockaddr *)&ss;
677	}
678	if (error != 0)
679		goto out;
680
681	error = connectit(so, sa);
682
683	if (sa != NULL && sa != SA(&ss))
684		FREE(sa, M_SONAME);
685	if (error == ERESTART)
686		error = EINTR;
687out:
688	file_drop(fd);
689	return (error);
690}
691
692static int
693connectx_nocancel(struct proc *p, struct connectx_args *uap, int *retval)
694{
695#pragma unused(p, retval)
696	struct sockaddr_list *src_sl = NULL, *dst_sl = NULL;
697	struct socket *so;
698	int error, fd = uap->s;
699	boolean_t dgram;
700	connid_t cid = CONNID_ANY;
701
702	AUDIT_ARG(fd, uap->s);
703	error = file_socket(fd, &so);
704	if (error != 0)
705		return (error);
706	if (so == NULL) {
707		error = EBADF;
708		goto out;
709	}
710
711	/*
712	 * XXX Workaround to ensure connectx does not fail because
713	 * of unreaped so_error.
714	 */
715	so->so_error = 0;
716
717	/*
718	 * Ask getsockaddr{_s} to not translate AF_UNSPEC to AF_INET
719	 * if this is a datagram socket; translate for other types.
720	 */
721	dgram = (so->so_type == SOCK_DGRAM);
722
723	/*
724	 * Get socket address(es) now before we obtain socket lock; use
725	 * sockaddr_list for src address for convenience, if present,
726	 * even though it won't hold more than one.
727	 */
728	if (uap->src != USER_ADDR_NULL && (error = getsockaddrlist(so,
729	    &src_sl, uap->src, uap->srclen, dgram)) != 0)
730		goto out;
731
732	error = getsockaddrlist(so, &dst_sl, uap->dsts, uap->dstlen, dgram);
733	if (error != 0)
734		goto out;
735
736	VERIFY(dst_sl != NULL &&
737	    !TAILQ_EMPTY(&dst_sl->sl_head) && dst_sl->sl_cnt > 0);
738
739	error = connectitx(so, &src_sl, &dst_sl, p, uap->ifscope,
740	    uap->aid, &cid);
741	if (error == ERESTART)
742		error = EINTR;
743
744	if (uap->cid != USER_ADDR_NULL)
745		(void) copyout(&cid, uap->cid, sizeof (cid));
746
747out:
748	file_drop(fd);
749	if (src_sl != NULL)
750		sockaddrlist_free(src_sl);
751	if (dst_sl != NULL)
752		sockaddrlist_free(dst_sl);
753	return (error);
754}
755
756int
757connectx(struct proc *p, struct connectx_args *uap, int *retval)
758{
759	/*
760	 * Due to similiarity with a POSIX interface, define as
761	 * an unofficial cancellation point.
762	 */
763	__pthread_testcancel(1);
764	return (connectx_nocancel(p, uap, retval));
765}
766
767static int
768connectit(struct socket *so, struct sockaddr *sa)
769{
770	int error;
771
772	AUDIT_ARG(sockaddr, vfs_context_cwd(vfs_context_current()), sa);
773#if CONFIG_MACF_SOCKET_SUBSET
774	if ((error = mac_socket_check_connect(kauth_cred_get(), so, sa)) != 0)
775		return (error);
776#endif /* MAC_SOCKET_SUBSET */
777
778	socket_lock(so, 1);
779	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
780		error = EALREADY;
781		goto out;
782	}
783	error = soconnectlock(so, sa, 0);
784	if (error != 0) {
785		so->so_state &= ~SS_ISCONNECTING;
786		goto out;
787	}
788	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
789		error = EINPROGRESS;
790		goto out;
791	}
792	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
793		lck_mtx_t *mutex_held;
794
795		if (so->so_proto->pr_getlock != NULL)
796			mutex_held = (*so->so_proto->pr_getlock)(so, 0);
797		else
798			mutex_held = so->so_proto->pr_domain->dom_mtx;
799		error = msleep((caddr_t)&so->so_timeo, mutex_held,
800		    PSOCK | PCATCH, __func__, 0);
801		if (so->so_state & SS_DRAINING) {
802			error = ECONNABORTED;
803		}
804		if (error != 0)
805			break;
806	}
807	if (error == 0) {
808		error = so->so_error;
809		so->so_error = 0;
810	}
811out:
812	socket_unlock(so, 1);
813	return (error);
814}
815
816static int
817connectitx(struct socket *so, struct sockaddr_list **src_sl,
818    struct sockaddr_list **dst_sl, struct proc *p, uint32_t ifscope,
819    associd_t aid, connid_t *pcid)
820{
821	struct sockaddr_entry *se;
822	int error;
823
824	VERIFY(dst_sl != NULL && *dst_sl != NULL);
825
826	TAILQ_FOREACH(se, &(*dst_sl)->sl_head, se_link) {
827		VERIFY(se->se_addr != NULL);
828		AUDIT_ARG(sockaddr, vfs_context_cwd(vfs_context_current()),
829		    se->se_addr);
830#if CONFIG_MACF_SOCKET_SUBSET
831		if ((error = mac_socket_check_connect(kauth_cred_get(),
832		    so, se->se_addr)) != 0)
833			return (error);
834#endif /* MAC_SOCKET_SUBSET */
835	}
836
837	socket_lock(so, 1);
838	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
839		error = EALREADY;
840		goto out;
841	}
842	error = soconnectxlocked(so, src_sl, dst_sl, p, ifscope,
843	    aid, pcid, 0, NULL, 0);
844	if (error != 0) {
845		so->so_state &= ~SS_ISCONNECTING;
846		goto out;
847	}
848	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
849		error = EINPROGRESS;
850		goto out;
851	}
852	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
853		lck_mtx_t *mutex_held;
854
855		if (so->so_proto->pr_getlock != NULL)
856			mutex_held = (*so->so_proto->pr_getlock)(so, 0);
857		else
858			mutex_held = so->so_proto->pr_domain->dom_mtx;
859		error = msleep((caddr_t)&so->so_timeo, mutex_held,
860		    PSOCK | PCATCH, __func__, 0);
861		if (so->so_state & SS_DRAINING) {
862			error = ECONNABORTED;
863		}
864		if (error != 0)
865			break;
866	}
867	if (error == 0) {
868		error = so->so_error;
869		so->so_error = 0;
870	}
871out:
872	socket_unlock(so, 1);
873	return (error);
874}
875
876int
877peeloff(struct proc *p, struct peeloff_args *uap, int *retval)
878{
879	/*
880	 * Due to similiarity with a POSIX interface, define as
881	 * an unofficial cancellation point.
882	 */
883	__pthread_testcancel(1);
884	return (peeloff_nocancel(p, uap, retval));
885}
886
887static int
888peeloff_nocancel(struct proc *p, struct peeloff_args *uap, int *retval)
889{
890	struct fileproc *fp;
891	struct socket *mp_so, *so = NULL;
892	int newfd, fd = uap->s;
893	short fflag;		/* type must match fp->f_flag */
894	int error;
895
896	*retval = -1;
897
898	error = fp_getfsock(p, fd, &fp, &mp_so);
899	if (error != 0) {
900		if (error == EOPNOTSUPP)
901			error = ENOTSOCK;
902		goto out_nofile;
903	}
904	if (mp_so == NULL) {
905		error = EBADF;
906		goto out;
907	}
908
909	socket_lock(mp_so, 1);
910	error = sopeelofflocked(mp_so, uap->aid, &so);
911	if (error != 0) {
912		socket_unlock(mp_so, 1);
913		goto out;
914	}
915	VERIFY(so != NULL);
916	socket_unlock(mp_so, 0);		/* keep ref on mp_so for us */
917
918	fflag = fp->f_flag;
919	error = falloc(p, &fp, &newfd, vfs_context_current());
920	if (error != 0) {
921		/* drop this socket (probably ran out of file descriptors) */
922		soclose(so);
923		sodereference(mp_so);		/* our mp_so ref */
924		goto out;
925	}
926
927	fp->f_flag = fflag;
928	fp->f_ops = &socketops;
929	fp->f_data = (caddr_t)so;
930
931	/*
932	 * If the socket has been marked as inactive by sosetdefunct(),
933	 * disallow further operations on it.
934	 */
935	if (so->so_flags & SOF_DEFUNCT) {
936		sodefunct(current_proc(), so,
937		    SHUTDOWN_SOCKET_LEVEL_DISCONNECT_INTERNAL);
938	}
939
940	proc_fdlock(p);
941	procfdtbl_releasefd(p, newfd, NULL);
942	fp_drop(p, newfd, fp, 1);
943	proc_fdunlock(p);
944
945	sodereference(mp_so);			/* our mp_so ref */
946	*retval = newfd;
947
948out:
949	file_drop(fd);
950
951out_nofile:
952	return (error);
953}
954
955int
956disconnectx(struct proc *p, struct disconnectx_args *uap, int *retval)
957{
958	/*
959	 * Due to similiarity with a POSIX interface, define as
960	 * an unofficial cancellation point.
961	 */
962	__pthread_testcancel(1);
963	return (disconnectx_nocancel(p, uap, retval));
964}
965
966static int
967disconnectx_nocancel(struct proc *p, struct disconnectx_args *uap, int *retval)
968{
969#pragma unused(p, retval)
970	struct socket *so;
971	int fd = uap->s;
972	int error;
973
974	error = file_socket(fd, &so);
975	if (error != 0)
976		return (error);
977	if (so == NULL) {
978		error = EBADF;
979		goto out;
980	}
981
982	error = sodisconnectx(so, uap->aid, uap->cid);
983out:
984	file_drop(fd);
985	return (error);
986}
987
988/*
989 * Returns:	0			Success
990 *	socreate:EAFNOSUPPORT
991 *	socreate:EPROTOTYPE
992 *	socreate:EPROTONOSUPPORT
993 *	socreate:ENOBUFS
994 *	socreate:ENOMEM
995 *	socreate:EISCONN
996 *	socreate:???			[other protocol families, IPSEC]
997 *	falloc:ENFILE
998 *	falloc:EMFILE
999 *	falloc:ENOMEM
1000 *	copyout:EFAULT
1001 *	soconnect2:EINVAL
1002 *	soconnect2:EPROTOTYPE
1003 *	soconnect2:???			[other protocol families[
1004 */
1005int
1006socketpair(struct proc *p, struct socketpair_args *uap,
1007    __unused int32_t *retval)
1008{
1009	struct fileproc *fp1, *fp2;
1010	struct socket *so1, *so2;
1011	int fd, error, sv[2];
1012
1013	AUDIT_ARG(socket, uap->domain, uap->type, uap->protocol);
1014	error = socreate(uap->domain, &so1, uap->type, uap->protocol);
1015	if (error)
1016		return (error);
1017	error = socreate(uap->domain, &so2, uap->type, uap->protocol);
1018	if (error)
1019		goto free1;
1020
1021	error = falloc(p, &fp1, &fd, vfs_context_current());
1022	if (error) {
1023		goto free2;
1024	}
1025	fp1->f_flag = FREAD|FWRITE;
1026	fp1->f_ops = &socketops;
1027	fp1->f_data = (caddr_t)so1;
1028	sv[0] = fd;
1029
1030	error = falloc(p, &fp2, &fd, vfs_context_current());
1031	if (error) {
1032		goto free3;
1033	}
1034	fp2->f_flag = FREAD|FWRITE;
1035	fp2->f_ops = &socketops;
1036	fp2->f_data = (caddr_t)so2;
1037	sv[1] = fd;
1038
1039	error = soconnect2(so1, so2);
1040	if (error) {
1041		goto free4;
1042	}
1043	if (uap->type == SOCK_DGRAM) {
1044		/*
1045		 * Datagram socket connection is asymmetric.
1046		 */
1047		error = soconnect2(so2, so1);
1048		if (error) {
1049			goto free4;
1050		}
1051	}
1052
1053	if ((error = copyout(sv, uap->rsv, 2 * sizeof (int))) != 0)
1054		goto free4;
1055
1056	proc_fdlock(p);
1057	procfdtbl_releasefd(p, sv[0], NULL);
1058	procfdtbl_releasefd(p, sv[1], NULL);
1059	fp_drop(p, sv[0], fp1, 1);
1060	fp_drop(p, sv[1], fp2, 1);
1061	proc_fdunlock(p);
1062
1063	return (0);
1064free4:
1065	fp_free(p, sv[1], fp2);
1066free3:
1067	fp_free(p, sv[0], fp1);
1068free2:
1069	(void) soclose(so2);
1070free1:
1071	(void) soclose(so1);
1072	return (error);
1073}
1074
1075/*
1076 * Returns:	0			Success
1077 *		EINVAL
1078 *		ENOBUFS
1079 *		EBADF
1080 *		EPIPE
1081 *		EACCES			Mandatory Access Control failure
1082 *	file_socket:ENOTSOCK
1083 *	file_socket:EBADF
1084 *	getsockaddr:ENAMETOOLONG	Filename too long
1085 *	getsockaddr:EINVAL		Invalid argument
1086 *	getsockaddr:ENOMEM		Not enough space
1087 *	getsockaddr:EFAULT		Bad address
1088 *	<pru_sosend>:EACCES[TCP]
1089 *	<pru_sosend>:EADDRINUSE[TCP]
1090 *	<pru_sosend>:EADDRNOTAVAIL[TCP]
1091 *	<pru_sosend>:EAFNOSUPPORT[TCP]
1092 *	<pru_sosend>:EAGAIN[TCP]
1093 *	<pru_sosend>:EBADF
1094 *	<pru_sosend>:ECONNRESET[TCP]
1095 *	<pru_sosend>:EFAULT
1096 *	<pru_sosend>:EHOSTUNREACH[TCP]
1097 *	<pru_sosend>:EINTR
1098 *	<pru_sosend>:EINVAL
1099 *	<pru_sosend>:EISCONN[AF_INET]
1100 *	<pru_sosend>:EMSGSIZE[TCP]
1101 *	<pru_sosend>:ENETDOWN[TCP]
1102 *	<pru_sosend>:ENETUNREACH[TCP]
1103 *	<pru_sosend>:ENOBUFS
1104 *	<pru_sosend>:ENOMEM[TCP]
1105 *	<pru_sosend>:ENOTCONN[AF_INET]
1106 *	<pru_sosend>:EOPNOTSUPP
1107 *	<pru_sosend>:EPERM[TCP]
1108 *	<pru_sosend>:EPIPE
1109 *	<pru_sosend>:EWOULDBLOCK
1110 *	<pru_sosend>:???[TCP]		[ignorable: mostly IPSEC/firewall/DLIL]
1111 *	<pru_sosend>:???[AF_INET]	[whatever a filter author chooses]
1112 *	<pru_sosend>:???		[value from so_error]
1113 *	sockargs:???
1114 */
1115static int
1116sendit(struct proc *p, int s, struct user_msghdr *mp, uio_t uiop,
1117    int flags, int32_t *retval)
1118{
1119	struct mbuf *control = NULL;
1120	struct sockaddr_storage ss;
1121	struct sockaddr *to = NULL;
1122	boolean_t want_free = TRUE;
1123	int error;
1124	struct socket *so;
1125	user_ssize_t len;
1126
1127	KERNEL_DEBUG(DBG_FNC_SENDIT | DBG_FUNC_START, 0, 0, 0, 0, 0);
1128
1129	error = file_socket(s, &so);
1130	if (error) {
1131		KERNEL_DEBUG(DBG_FNC_SENDIT | DBG_FUNC_END, error, 0, 0, 0, 0);
1132		return (error);
1133	}
1134	if (so == NULL) {
1135		error = EBADF;
1136		goto out;
1137	}
1138	if (mp->msg_name != USER_ADDR_NULL) {
1139		if (mp->msg_namelen > sizeof (ss)) {
1140			error = getsockaddr(so, &to, mp->msg_name,
1141			    mp->msg_namelen, TRUE);
1142		} else {
1143			error = getsockaddr_s(so, &ss, mp->msg_name,
1144			    mp->msg_namelen, TRUE);
1145			if (error == 0) {
1146				to = (struct sockaddr *)&ss;
1147				want_free = FALSE;
1148			}
1149		}
1150		if (error != 0)
1151			goto out;
1152		AUDIT_ARG(sockaddr, vfs_context_cwd(vfs_context_current()), to);
1153	}
1154	if (mp->msg_control != USER_ADDR_NULL) {
1155		if (mp->msg_controllen < sizeof (struct cmsghdr)) {
1156			error = EINVAL;
1157			goto bad;
1158		}
1159		error = sockargs(&control, mp->msg_control,
1160		    mp->msg_controllen, MT_CONTROL);
1161		if (error != 0)
1162			goto bad;
1163	}
1164
1165#if CONFIG_MACF_SOCKET_SUBSET
1166	/*
1167	 * We check the state without holding the socket lock;
1168	 * if a race condition occurs, it would simply result
1169	 * in an extra call to the MAC check function.
1170	 */
1171	if ( to != NULL &&
1172	    !(so->so_state & SS_DEFUNCT) &&
1173	    (error = mac_socket_check_send(kauth_cred_get(), so, to)) != 0)
1174		goto bad;
1175#endif /* MAC_SOCKET_SUBSET */
1176
1177	len = uio_resid(uiop);
1178	error = so->so_proto->pr_usrreqs->pru_sosend(so, to, uiop, 0,
1179		control, flags);
1180	if (error != 0) {
1181		if (uio_resid(uiop) != len && (error == ERESTART ||
1182		    error == EINTR || error == EWOULDBLOCK))
1183			error = 0;
1184		/* Generation of SIGPIPE can be controlled per socket */
1185		if (error == EPIPE && !(so->so_flags & SOF_NOSIGPIPE))
1186			psignal(p, SIGPIPE);
1187	}
1188	if (error == 0)
1189		*retval = (int)(len - uio_resid(uiop));
1190bad:
1191	if (to != NULL && want_free)
1192		FREE(to, M_SONAME);
1193out:
1194	KERNEL_DEBUG(DBG_FNC_SENDIT | DBG_FUNC_END, error, 0, 0, 0, 0);
1195	file_drop(s);
1196	return (error);
1197}
1198
1199/*
1200 * Returns:	0			Success
1201 *		ENOMEM
1202 *	sendit:???			[see sendit definition in this file]
1203 *	write:???			[4056224: applicable for pipes]
1204 */
1205int
1206sendto(struct proc *p, struct sendto_args *uap, int32_t *retval)
1207{
1208	__pthread_testcancel(1);
1209	return (sendto_nocancel(p, (struct sendto_nocancel_args *)uap, retval));
1210}
1211
1212int
1213sendto_nocancel(struct proc *p,
1214		struct sendto_nocancel_args *uap,
1215		int32_t *retval)
1216{
1217	struct user_msghdr msg;
1218	int error;
1219	uio_t auio = NULL;
1220
1221	KERNEL_DEBUG(DBG_FNC_SENDTO | DBG_FUNC_START, 0, 0, 0, 0, 0);
1222	AUDIT_ARG(fd, uap->s);
1223
1224	auio = uio_create(1, 0,
1225	    (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
1226	    UIO_WRITE);
1227	if (auio == NULL) {
1228		return (ENOMEM);
1229	}
1230	uio_addiov(auio, uap->buf, uap->len);
1231
1232	msg.msg_name = uap->to;
1233	msg.msg_namelen = uap->tolen;
1234	/* no need to set up msg_iov.  sendit uses uio_t we send it */
1235	msg.msg_iov = 0;
1236	msg.msg_iovlen = 0;
1237	msg.msg_control = 0;
1238	msg.msg_flags = 0;
1239
1240	error = sendit(p, uap->s, &msg, auio, uap->flags, retval);
1241
1242	if (auio != NULL) {
1243		uio_free(auio);
1244	}
1245
1246	KERNEL_DEBUG(DBG_FNC_SENDTO | DBG_FUNC_END, error, *retval, 0, 0, 0);
1247
1248	return (error);
1249}
1250
1251/*
1252 * Returns:	0			Success
1253 *		ENOBUFS
1254 *	copyin:EFAULT
1255 *	sendit:???			[see sendit definition in this file]
1256 */
1257int
1258sendmsg(struct proc *p, struct sendmsg_args *uap, int32_t *retval)
1259{
1260	__pthread_testcancel(1);
1261	return (sendmsg_nocancel(p, (struct sendmsg_nocancel_args *)uap, retval));
1262}
1263
1264int
1265sendmsg_nocancel(struct proc *p, struct sendmsg_nocancel_args *uap, int32_t *retval)
1266{
1267	struct user32_msghdr msg32;
1268	struct user64_msghdr msg64;
1269	struct user_msghdr user_msg;
1270	caddr_t msghdrp;
1271	int	size_of_msghdr;
1272	int error;
1273	uio_t auio = NULL;
1274	struct user_iovec *iovp;
1275
1276	KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_START, 0, 0, 0, 0, 0);
1277	AUDIT_ARG(fd, uap->s);
1278	if (IS_64BIT_PROCESS(p)) {
1279		msghdrp = (caddr_t)&msg64;
1280		size_of_msghdr = sizeof (msg64);
1281	} else {
1282		msghdrp = (caddr_t)&msg32;
1283		size_of_msghdr = sizeof (msg32);
1284	}
1285	error = copyin(uap->msg, msghdrp, size_of_msghdr);
1286	if (error) {
1287		KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_END, error, 0, 0, 0, 0);
1288		return (error);
1289	}
1290
1291	if (IS_64BIT_PROCESS(p)) {
1292		user_msg.msg_flags = msg64.msg_flags;
1293		user_msg.msg_controllen = msg64.msg_controllen;
1294		user_msg.msg_control = msg64.msg_control;
1295		user_msg.msg_iovlen = msg64.msg_iovlen;
1296		user_msg.msg_iov = msg64.msg_iov;
1297		user_msg.msg_namelen = msg64.msg_namelen;
1298		user_msg.msg_name = msg64.msg_name;
1299	} else {
1300		user_msg.msg_flags = msg32.msg_flags;
1301		user_msg.msg_controllen = msg32.msg_controllen;
1302		user_msg.msg_control = msg32.msg_control;
1303		user_msg.msg_iovlen = msg32.msg_iovlen;
1304		user_msg.msg_iov = msg32.msg_iov;
1305		user_msg.msg_namelen = msg32.msg_namelen;
1306		user_msg.msg_name = msg32.msg_name;
1307	}
1308
1309	if (user_msg.msg_iovlen <= 0 || user_msg.msg_iovlen > UIO_MAXIOV) {
1310		KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_END, EMSGSIZE,
1311		    0, 0, 0, 0);
1312		return (EMSGSIZE);
1313	}
1314
1315	/* allocate a uio large enough to hold the number of iovecs passed */
1316	auio = uio_create(user_msg.msg_iovlen, 0,
1317	    (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
1318	    UIO_WRITE);
1319	if (auio == NULL) {
1320		error = ENOBUFS;
1321		goto done;
1322	}
1323
1324	if (user_msg.msg_iovlen) {
1325		/*
1326		 * get location of iovecs within the uio.
1327		 * then copyin the iovecs from user space.
1328		 */
1329		iovp = uio_iovsaddr(auio);
1330		if (iovp == NULL) {
1331			error = ENOBUFS;
1332			goto done;
1333		}
1334		error = copyin_user_iovec_array(user_msg.msg_iov,
1335			IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32,
1336			user_msg.msg_iovlen, iovp);
1337		if (error)
1338			goto done;
1339		user_msg.msg_iov = CAST_USER_ADDR_T(iovp);
1340
1341		/* finish setup of uio_t */
1342		error = uio_calculateresid(auio);
1343		if (error) {
1344			goto done;
1345		}
1346	} else {
1347		user_msg.msg_iov = 0;
1348	}
1349
1350	/* msg_flags is ignored for send */
1351	user_msg.msg_flags = 0;
1352
1353	error = sendit(p, uap->s, &user_msg, auio, uap->flags, retval);
1354done:
1355	if (auio != NULL) {
1356		uio_free(auio);
1357	}
1358	KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_END, error, 0, 0, 0, 0);
1359
1360	return (error);
1361}
1362
1363int
1364sendmsg_x(struct proc *p, struct sendmsg_x_args *uap, user_ssize_t *retval)
1365{
1366	int error = 0;
1367	struct user_msghdr_x *user_msg = NULL;
1368	struct uio **uiop = NULL;
1369	struct socket *so;
1370	u_int i;
1371	struct sockaddr *to = NULL;
1372	struct mbuf *control = NULL;
1373	user_ssize_t len_before = 0, len_after;
1374	int need_drop = 0;
1375	size_t size_of_msghdr;
1376	void *umsgp = NULL;
1377	u_int uiocnt;
1378
1379	KERNEL_DEBUG(DBG_FNC_SENDMSG_X | DBG_FUNC_START, 0, 0, 0, 0, 0);
1380
1381	error = file_socket(uap->s, &so);
1382	if (error) {
1383		goto out;
1384	}
1385	need_drop = 1;
1386	if (so == NULL) {
1387		error = EBADF;
1388		goto out;
1389	}
1390	if (so->so_proto->pr_usrreqs->pru_sosend_list == NULL) {
1391		printf("%s no pru_sosend_list\n", __func__);
1392		error = EOPNOTSUPP;
1393		goto out;
1394	}
1395
1396	/*
1397	 * Input parameter range check
1398	 */
1399	if (uap->cnt == 0 || uap->cnt > UIO_MAXIOV) {
1400		error = EINVAL;
1401		goto out;
1402	}
1403	user_msg = _MALLOC(uap->cnt * sizeof(struct user_msghdr_x),
1404			M_TEMP, M_WAITOK | M_ZERO);
1405	if (user_msg == NULL) {
1406		printf("%s _MALLOC() user_msg failed\n", __func__);
1407		error = ENOMEM;
1408		goto out;
1409	}
1410	uiop = _MALLOC(uap->cnt * sizeof(struct uio *),
1411		M_TEMP, M_WAITOK | M_ZERO);
1412	if (uiop == NULL) {
1413		printf("%s _MALLOC() uiop failed\n", __func__);
1414		error = ENOMEM;
1415		goto out;
1416	}
1417
1418	size_of_msghdr = IS_64BIT_PROCESS(p) ?
1419		sizeof(struct user64_msghdr_x) : sizeof(struct user32_msghdr_x);
1420
1421	umsgp = _MALLOC(uap->cnt * size_of_msghdr,
1422			M_TEMP, M_WAITOK | M_ZERO);
1423	if (umsgp == NULL) {
1424		printf("%s _MALLOC() user_msg failed\n", __func__);
1425		error = ENOMEM;
1426		goto out;
1427	}
1428	error = copyin(uap->msgp, umsgp, uap->cnt * size_of_msghdr);
1429	if (error) {
1430		printf("%s copyin() failed\n", __func__);
1431		goto out;
1432	}
1433	error = internalize_user_msghdr_array(umsgp,
1434		IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32,
1435		UIO_WRITE, uap->cnt, user_msg, uiop);
1436	if (error) {
1437		printf("%s copyin_user_msghdr_array() failed\n", __func__);
1438		goto out;
1439	}
1440	/*
1441	 * Make sure the size of each message iovec and
1442	 * the aggregate size of all the iovec is valid
1443	 */
1444	if (uio_array_is_valid(uiop, uap->cnt) == 0) {
1445		error = EINVAL;
1446		goto out;
1447	}
1448
1449	/*
1450	 * Sanity check on passed arguments
1451	 */
1452	for (i = 0; i < uap->cnt; i++) {
1453		struct user_msghdr_x *mp = &user_msg[i];
1454
1455		/*
1456		 * No flags on send message
1457		 */
1458		if (mp->msg_flags != 0) {
1459			error = EINVAL;
1460			goto out;
1461		}
1462		/*
1463		 * No support for address or ancillary data (yet)
1464		 */
1465		if (mp->msg_name != USER_ADDR_NULL || mp->msg_namelen != 0) {
1466			error = EINVAL;
1467			goto out;
1468		}
1469		if (mp->msg_control != USER_ADDR_NULL ||
1470		    mp->msg_controllen != 0) {
1471			error = EINVAL;
1472			goto out;
1473		}
1474#if CONFIG_MACF_SOCKET_SUBSET
1475		/*
1476		 * We check the state without holding the socket lock;
1477		 * if a race condition occurs, it would simply result
1478		 * in an extra call to the MAC check function.
1479		 *
1480		 * Note: The following check is never true taken with the
1481		 * current limitation that we do not accept to pass an address,
1482		 * this is effectively placeholder code. If we add support for addresses,
1483		 * we will have to check every address.
1484		 */
1485		if ( to != NULL &&
1486		    !(so->so_state & SS_DEFUNCT) &&
1487		    (error = mac_socket_check_send(kauth_cred_get(), so, to)) != 0)
1488			goto out;
1489#endif /* MAC_SOCKET_SUBSET */
1490	}
1491
1492	len_before = uio_array_resid(uiop, uap->cnt);
1493
1494	error = so->so_proto->pr_usrreqs->pru_sosend_list(so, to, uiop,
1495		uap->cnt, 0, control, uap->flags);
1496
1497	len_after = uio_array_resid(uiop, uap->cnt);
1498
1499	if (error != 0) {
1500		if (len_after != len_before && (error == ERESTART ||
1501		    error == EINTR || error == EWOULDBLOCK))
1502			error = 0;
1503		/* Generation of SIGPIPE can be controlled per socket */
1504		if (error == EPIPE && !(so->so_flags & SOF_NOSIGPIPE))
1505			psignal(p, SIGPIPE);
1506	}
1507	if (error == 0) {
1508		uiocnt = externalize_user_msghdr_array(umsgp,
1509		    IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32,
1510		    UIO_WRITE, uap->cnt, user_msg, uiop);
1511
1512		*retval = (int)(uiocnt);
1513	}
1514out:
1515	if (need_drop)
1516		file_drop(uap->s);
1517	if (umsgp != NULL)
1518		_FREE(umsgp, M_TEMP);
1519	if (uiop != NULL) {
1520		free_uio_array(uiop, uap->cnt);
1521		_FREE(uiop, M_TEMP);
1522	}
1523	if (user_msg != NULL)
1524		_FREE(user_msg, M_TEMP);
1525
1526	KERNEL_DEBUG(DBG_FNC_SENDMSG_X | DBG_FUNC_END, error, 0, 0, 0, 0);
1527
1528	return (error);
1529}
1530
1531/*
1532 * Returns:	0			Success
1533 *		ENOTSOCK
1534 *		EINVAL
1535 *		EBADF
1536 *		EACCES			Mandatory Access Control failure
1537 *	copyout:EFAULT
1538 *	fp_lookup:EBADF
1539 *	<pru_soreceive>:ENOBUFS
1540 *	<pru_soreceive>:ENOTCONN
1541 *	<pru_soreceive>:EWOULDBLOCK
1542 *	<pru_soreceive>:EFAULT
1543 *	<pru_soreceive>:EINTR
1544 *	<pru_soreceive>:EBADF
1545 *	<pru_soreceive>:EINVAL
1546 *	<pru_soreceive>:EMSGSIZE
1547 *	<pru_soreceive>:???
1548 *
1549 * Notes:	Additional return values from calls through <pru_soreceive>
1550 *		depend on protocols other than TCP or AF_UNIX, which are
1551 *		documented above.
1552 */
1553static int
1554recvit(struct proc *p, int s, struct user_msghdr *mp, uio_t uiop,
1555    user_addr_t namelenp, int32_t *retval)
1556{
1557	ssize_t len;
1558	int error;
1559	struct mbuf *m, *control = 0;
1560	user_addr_t ctlbuf;
1561	struct socket *so;
1562	struct sockaddr *fromsa = 0;
1563	struct fileproc *fp;
1564
1565	KERNEL_DEBUG(DBG_FNC_RECVIT | DBG_FUNC_START, 0, 0, 0, 0, 0);
1566	proc_fdlock(p);
1567	if ((error = fp_lookup(p, s, &fp, 1))) {
1568		KERNEL_DEBUG(DBG_FNC_RECVIT | DBG_FUNC_END, error, 0, 0, 0, 0);
1569		proc_fdunlock(p);
1570		return (error);
1571	}
1572	if (fp->f_type != DTYPE_SOCKET) {
1573		fp_drop(p, s, fp, 1);
1574		proc_fdunlock(p);
1575		return (ENOTSOCK);
1576	}
1577
1578	so = (struct socket *)fp->f_data;
1579	if (so == NULL) {
1580		fp_drop(p, s, fp, 1);
1581		proc_fdunlock(p);
1582		return (EBADF);
1583	}
1584
1585	proc_fdunlock(p);
1586
1587#if CONFIG_MACF_SOCKET_SUBSET
1588	/*
1589	 * We check the state without holding the socket lock;
1590	 * if a race condition occurs, it would simply result
1591	 * in an extra call to the MAC check function.
1592	 */
1593	if (!(so->so_state & SS_DEFUNCT) &&
1594	    !(so->so_state & SS_ISCONNECTED) &&
1595	    !(so->so_proto->pr_flags & PR_CONNREQUIRED) &&
1596	    (error = mac_socket_check_receive(kauth_cred_get(), so)) != 0)
1597		goto out1;
1598#endif /* MAC_SOCKET_SUBSET */
1599	if (uio_resid(uiop) < 0) {
1600		KERNEL_DEBUG(DBG_FNC_RECVIT | DBG_FUNC_END, EINVAL, 0, 0, 0, 0);
1601		error = EINVAL;
1602		goto out1;
1603	}
1604
1605	len = uio_resid(uiop);
1606	error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, uiop,
1607	    (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0,
1608	    &mp->msg_flags);
1609	if (fromsa)
1610		AUDIT_ARG(sockaddr, vfs_context_cwd(vfs_context_current()),
1611		    fromsa);
1612	if (error) {
1613		if (uio_resid(uiop) != len && (error == ERESTART ||
1614		    error == EINTR || error == EWOULDBLOCK))
1615			error = 0;
1616	}
1617
1618	if (error)
1619		goto out;
1620
1621	*retval = len - uio_resid(uiop);
1622	if (mp->msg_name) {
1623		socklen_t sa_len = 0;
1624
1625		len = mp->msg_namelen;
1626		if (len <= 0 || fromsa == 0) {
1627			len = 0;
1628		} else {
1629#ifndef MIN
1630#define	MIN(a, b) ((a) > (b) ? (b) : (a))
1631#endif
1632			sa_len = fromsa->sa_len;
1633			len = MIN((unsigned int)len, sa_len);
1634			error = copyout(fromsa, mp->msg_name, (unsigned)len);
1635			if (error)
1636				goto out;
1637		}
1638		mp->msg_namelen = sa_len;
1639		/* return the actual, untruncated address length */
1640		if (namelenp &&
1641		    (error = copyout((caddr_t)&sa_len, namelenp,
1642		    sizeof (int)))) {
1643			goto out;
1644		}
1645	}
1646	if (mp->msg_control) {
1647		len = mp->msg_controllen;
1648		m = control;
1649		mp->msg_controllen = 0;
1650		ctlbuf = mp->msg_control;
1651
1652		while (m && len > 0) {
1653			unsigned int tocopy;
1654			struct cmsghdr *cp = mtod(m, struct cmsghdr *);
1655			int cp_size = CMSG_ALIGN(cp->cmsg_len);
1656			int buflen = m->m_len;
1657
1658			while (buflen > 0 && len > 0) {
1659
1660				/*
1661				 SCM_TIMESTAMP hack because  struct timeval has a
1662				 * different size for 32 bits and 64 bits processes
1663				 */
1664				if (cp->cmsg_level == SOL_SOCKET &&  cp->cmsg_type == SCM_TIMESTAMP) {
1665					unsigned char tmp_buffer[CMSG_SPACE(sizeof(struct user64_timeval))];
1666					struct cmsghdr *tmp_cp = (struct cmsghdr *)(void *)tmp_buffer;
1667					int tmp_space;
1668					struct timeval *tv = (struct timeval *)(void *)CMSG_DATA(cp);
1669
1670					tmp_cp->cmsg_level = SOL_SOCKET;
1671					tmp_cp->cmsg_type = SCM_TIMESTAMP;
1672
1673					if (proc_is64bit(p)) {
1674						struct user64_timeval *tv64 = (struct user64_timeval *)(void *)CMSG_DATA(tmp_cp);
1675
1676						tv64->tv_sec = tv->tv_sec;
1677						tv64->tv_usec = tv->tv_usec;
1678
1679						tmp_cp->cmsg_len = CMSG_LEN(sizeof(struct user64_timeval));
1680						tmp_space = CMSG_SPACE(sizeof(struct user64_timeval));
1681					} else {
1682						struct user32_timeval *tv32 = (struct user32_timeval *)(void *)CMSG_DATA(tmp_cp);
1683
1684						tv32->tv_sec = tv->tv_sec;
1685						tv32->tv_usec = tv->tv_usec;
1686
1687						tmp_cp->cmsg_len = CMSG_LEN(sizeof(struct user32_timeval));
1688						tmp_space = CMSG_SPACE(sizeof(struct user32_timeval));
1689					}
1690					if (len >= tmp_space) {
1691						tocopy = tmp_space;
1692					} else {
1693						mp->msg_flags |= MSG_CTRUNC;
1694						tocopy = len;
1695					}
1696					error = copyout(tmp_buffer, ctlbuf, tocopy);
1697					if (error)
1698						goto out;
1699
1700				} else {
1701
1702					if (cp_size > buflen) {
1703						panic("cp_size > buflen, something wrong with alignment!");
1704					}
1705
1706					if (len >= cp_size) {
1707						tocopy = cp_size;
1708					} else {
1709						mp->msg_flags |= MSG_CTRUNC;
1710						tocopy = len;
1711					}
1712
1713					error = copyout((caddr_t) cp, ctlbuf,
1714									tocopy);
1715					if (error)
1716						goto out;
1717				}
1718
1719
1720				ctlbuf += tocopy;
1721				len -= tocopy;
1722
1723				buflen -= cp_size;
1724				cp = (struct cmsghdr *)(void *)((unsigned char *) cp + cp_size);
1725				cp_size = CMSG_ALIGN(cp->cmsg_len);
1726			}
1727
1728			m = m->m_next;
1729		}
1730		mp->msg_controllen = ctlbuf - mp->msg_control;
1731	}
1732out:
1733	if (fromsa)
1734		FREE(fromsa, M_SONAME);
1735	if (control)
1736		m_freem(control);
1737	KERNEL_DEBUG(DBG_FNC_RECVIT | DBG_FUNC_END, error, 0, 0, 0, 0);
1738out1:
1739	fp_drop(p, s, fp, 0);
1740	return (error);
1741}
1742
1743/*
1744 * Returns:	0			Success
1745 *		ENOMEM
1746 *	copyin:EFAULT
1747 *	recvit:???
1748 *	read:???			[4056224: applicable for pipes]
1749 *
1750 * Notes:	The read entry point is only called as part of support for
1751 *		binary backward compatability; new code should use read
1752 *		instead of recv or recvfrom when attempting to read data
1753 *		from pipes.
1754 *
1755 *		For full documentation of the return codes from recvit, see
1756 *		the block header for the recvit function.
1757 */
1758int
1759recvfrom(struct proc *p, struct recvfrom_args *uap, int32_t *retval)
1760{
1761	__pthread_testcancel(1);
1762	return(recvfrom_nocancel(p, (struct recvfrom_nocancel_args *)uap, retval));
1763}
1764
1765int
1766recvfrom_nocancel(struct proc *p, struct recvfrom_nocancel_args *uap, int32_t *retval)
1767{
1768	struct user_msghdr msg;
1769	int error;
1770	uio_t auio = NULL;
1771
1772	KERNEL_DEBUG(DBG_FNC_RECVFROM | DBG_FUNC_START, 0, 0, 0, 0, 0);
1773	AUDIT_ARG(fd, uap->s);
1774
1775	if (uap->fromlenaddr) {
1776		error = copyin(uap->fromlenaddr,
1777		    (caddr_t)&msg.msg_namelen, sizeof (msg.msg_namelen));
1778		if (error)
1779			return (error);
1780	} else {
1781		msg.msg_namelen = 0;
1782	}
1783	msg.msg_name = uap->from;
1784	auio = uio_create(1, 0,
1785	    (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
1786	    UIO_READ);
1787	if (auio == NULL) {
1788		return (ENOMEM);
1789	}
1790
1791	uio_addiov(auio, uap->buf, uap->len);
1792	/* no need to set up msg_iov.  recvit uses uio_t we send it */
1793	msg.msg_iov = 0;
1794	msg.msg_iovlen = 0;
1795	msg.msg_control = 0;
1796	msg.msg_controllen = 0;
1797	msg.msg_flags = uap->flags;
1798	error = recvit(p, uap->s, &msg, auio, uap->fromlenaddr, retval);
1799	if (auio != NULL) {
1800		uio_free(auio);
1801	}
1802
1803	KERNEL_DEBUG(DBG_FNC_RECVFROM | DBG_FUNC_END, error, 0, 0, 0, 0);
1804
1805	return (error);
1806}
1807
1808/*
1809 * Returns:	0			Success
1810 *		EMSGSIZE
1811 *		ENOMEM
1812 *	copyin:EFAULT
1813 *	copyout:EFAULT
1814 *	recvit:???
1815 *
1816 * Notes:	For full documentation of the return codes from recvit, see
1817 *		the block header for the recvit function.
1818 */
1819int
1820recvmsg(struct proc *p, struct recvmsg_args *uap, int32_t *retval)
1821{
1822	__pthread_testcancel(1);
1823	return(recvmsg_nocancel(p, (struct recvmsg_nocancel_args *)uap, retval));
1824}
1825
1826int
1827recvmsg_nocancel(struct proc *p, struct recvmsg_nocancel_args *uap, int32_t *retval)
1828{
1829	struct user32_msghdr msg32;
1830	struct user64_msghdr msg64;
1831	struct user_msghdr user_msg;
1832	caddr_t msghdrp;
1833	int	size_of_msghdr;
1834	user_addr_t uiov;
1835	int error;
1836	uio_t auio = NULL;
1837	struct user_iovec *iovp;
1838
1839	KERNEL_DEBUG(DBG_FNC_RECVMSG | DBG_FUNC_START, 0, 0, 0, 0, 0);
1840	AUDIT_ARG(fd, uap->s);
1841	if (IS_64BIT_PROCESS(p)) {
1842		msghdrp = (caddr_t)&msg64;
1843		size_of_msghdr = sizeof (msg64);
1844	} else {
1845		msghdrp = (caddr_t)&msg32;
1846		size_of_msghdr = sizeof (msg32);
1847	}
1848	error = copyin(uap->msg, msghdrp, size_of_msghdr);
1849	if (error) {
1850		KERNEL_DEBUG(DBG_FNC_RECVMSG | DBG_FUNC_END, error, 0, 0, 0, 0);
1851		return (error);
1852	}
1853
1854	/* only need to copy if user process is not 64-bit */
1855	if (IS_64BIT_PROCESS(p)) {
1856		user_msg.msg_flags = msg64.msg_flags;
1857		user_msg.msg_controllen = msg64.msg_controllen;
1858		user_msg.msg_control = msg64.msg_control;
1859		user_msg.msg_iovlen = msg64.msg_iovlen;
1860		user_msg.msg_iov = msg64.msg_iov;
1861		user_msg.msg_namelen = msg64.msg_namelen;
1862		user_msg.msg_name = msg64.msg_name;
1863	} else {
1864		user_msg.msg_flags = msg32.msg_flags;
1865		user_msg.msg_controllen = msg32.msg_controllen;
1866		user_msg.msg_control = msg32.msg_control;
1867		user_msg.msg_iovlen = msg32.msg_iovlen;
1868		user_msg.msg_iov = msg32.msg_iov;
1869		user_msg.msg_namelen = msg32.msg_namelen;
1870		user_msg.msg_name = msg32.msg_name;
1871	}
1872
1873	if (user_msg.msg_iovlen <= 0 || user_msg.msg_iovlen > UIO_MAXIOV) {
1874		KERNEL_DEBUG(DBG_FNC_RECVMSG | DBG_FUNC_END, EMSGSIZE,
1875		    0, 0, 0, 0);
1876		return (EMSGSIZE);
1877	}
1878
1879	user_msg.msg_flags = uap->flags;
1880
1881	/* allocate a uio large enough to hold the number of iovecs passed */
1882	auio = uio_create(user_msg.msg_iovlen, 0,
1883	    (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
1884	    UIO_READ);
1885	if (auio == NULL) {
1886		error = ENOMEM;
1887		goto done;
1888	}
1889
1890	/*
1891	 * get location of iovecs within the uio.  then copyin the iovecs from
1892	 * user space.
1893	 */
1894	iovp = uio_iovsaddr(auio);
1895	if (iovp == NULL) {
1896		error = ENOMEM;
1897		goto done;
1898	}
1899	uiov = user_msg.msg_iov;
1900	user_msg.msg_iov = CAST_USER_ADDR_T(iovp);
1901	error = copyin_user_iovec_array(uiov,
1902		IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32,
1903		user_msg.msg_iovlen, iovp);
1904	if (error)
1905		goto done;
1906
1907	/* finish setup of uio_t */
1908	error = uio_calculateresid(auio);
1909	if (error) {
1910		goto done;
1911	}
1912
1913	error = recvit(p, uap->s, &user_msg, auio, 0, retval);
1914	if (!error) {
1915		user_msg.msg_iov = uiov;
1916		if (IS_64BIT_PROCESS(p)) {
1917			msg64.msg_flags = user_msg.msg_flags;
1918			msg64.msg_controllen = user_msg.msg_controllen;
1919			msg64.msg_control = user_msg.msg_control;
1920			msg64.msg_iovlen = user_msg.msg_iovlen;
1921			msg64.msg_iov = user_msg.msg_iov;
1922			msg64.msg_namelen = user_msg.msg_namelen;
1923			msg64.msg_name = user_msg.msg_name;
1924		} else {
1925			msg32.msg_flags = user_msg.msg_flags;
1926			msg32.msg_controllen = user_msg.msg_controllen;
1927			msg32.msg_control = user_msg.msg_control;
1928			msg32.msg_iovlen = user_msg.msg_iovlen;
1929			msg32.msg_iov = user_msg.msg_iov;
1930			msg32.msg_namelen = user_msg.msg_namelen;
1931			msg32.msg_name = user_msg.msg_name;
1932		}
1933		error = copyout(msghdrp, uap->msg, size_of_msghdr);
1934	}
1935done:
1936	if (auio != NULL) {
1937		uio_free(auio);
1938	}
1939	KERNEL_DEBUG(DBG_FNC_RECVMSG | DBG_FUNC_END, error, 0, 0, 0, 0);
1940	return (error);
1941}
1942
1943int
1944recvmsg_x(struct proc *p, struct recvmsg_x_args *uap, user_ssize_t *retval)
1945{
1946	int error = EOPNOTSUPP;
1947	struct user_msghdr_x *user_msg = NULL;
1948	struct uio **uiop = NULL;
1949	struct socket *so;
1950	user_ssize_t len_before = 0, len_after;
1951	int need_drop = 0;
1952	size_t size_of_msghdr;
1953	void *umsgp = NULL;
1954	u_int i;
1955	u_int uiocnt;
1956
1957	KERNEL_DEBUG(DBG_FNC_RECVMSG_X | DBG_FUNC_START, 0, 0, 0, 0, 0);
1958
1959	error = file_socket(uap->s, &so);
1960	if (error) {
1961		goto out;
1962	}
1963	need_drop = 1;
1964	if (so == NULL) {
1965		error = EBADF;
1966		goto out;
1967	}
1968	if (so->so_proto->pr_usrreqs->pru_soreceive_list == NULL) {
1969		printf("%s no pru_soreceive_list\n", __func__);
1970		error = EOPNOTSUPP;
1971		goto out;
1972	}
1973
1974	/*
1975	 * Input parameter range check
1976	 */
1977	if (uap->cnt == 0 || uap->cnt > UIO_MAXIOV) {
1978		error = EINVAL;
1979		goto out;
1980	}
1981	user_msg = _MALLOC(uap->cnt * sizeof(struct user_msghdr_x),
1982	    M_TEMP, M_WAITOK | M_ZERO);
1983	if (user_msg == NULL) {
1984		printf("%s _MALLOC() user_msg failed\n", __func__);
1985		error = ENOMEM;
1986		goto out;
1987	}
1988	uiop = _MALLOC(uap->cnt * sizeof(struct uio *),
1989	    M_TEMP, M_WAITOK | M_ZERO);
1990	if (uiop == NULL) {
1991		printf("%s _MALLOC() uiop failed\n", __func__);
1992		error = ENOMEM;
1993		goto out;
1994	}
1995
1996	size_of_msghdr = IS_64BIT_PROCESS(p) ?
1997	    sizeof(struct user64_msghdr_x) : sizeof(struct user32_msghdr_x);
1998
1999	umsgp = _MALLOC(uap->cnt * size_of_msghdr, M_TEMP, M_WAITOK | M_ZERO);
2000	if (umsgp == NULL) {
2001		printf("%s _MALLOC() user_msg failed\n", __func__);
2002		error = ENOMEM;
2003		goto out;
2004	}
2005	error = copyin(uap->msgp, umsgp, uap->cnt * size_of_msghdr);
2006	if (error) {
2007		printf("%s copyin() failed\n", __func__);
2008		goto out;
2009	}
2010	error = internalize_user_msghdr_array(umsgp,
2011	    IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32,
2012	    UIO_READ, uap->cnt, user_msg, uiop);
2013	if (error) {
2014		printf("%s copyin_user_msghdr_array() failed\n", __func__);
2015		goto out;
2016	}
2017	/*
2018	 * Make sure the size of each message iovec and
2019	 * the aggregate size of all the iovec is valid
2020	 */
2021	if (uio_array_is_valid(uiop, uap->cnt) == 0) {
2022		error = EINVAL;
2023		goto out;
2024	}
2025
2026	/*
2027	 * Sanity check on passed arguments
2028	 */
2029	for (i = 0; i < uap->cnt; i++) {
2030		struct user_msghdr_x *mp = &user_msg[i];
2031
2032		if (mp->msg_flags != 0) {
2033			error = EINVAL;
2034			goto out;
2035		}
2036		/*
2037		 * No support for address or ancillary data (yet)
2038		 */
2039		if (mp->msg_name != USER_ADDR_NULL || mp->msg_namelen != 0) {
2040			error = EINVAL;
2041			goto out;
2042		}
2043		if (mp->msg_control != USER_ADDR_NULL ||
2044		    mp->msg_controllen != 0) {
2045			error = EINVAL;
2046			goto out;
2047		}
2048	}
2049#if CONFIG_MACF_SOCKET_SUBSET
2050	/*
2051	 * We check the state without holding the socket lock;
2052	 * if a race condition occurs, it would simply result
2053	 * in an extra call to the MAC check function.
2054	 */
2055	if (!(so->so_state & SS_DEFUNCT) &&
2056	    !(so->so_state & SS_ISCONNECTED) &&
2057	    !(so->so_proto->pr_flags & PR_CONNREQUIRED) &&
2058	    (error = mac_socket_check_receive(kauth_cred_get(), so)) != 0)
2059		goto out;
2060#endif /* MAC_SOCKET_SUBSET */
2061
2062	len_before = uio_array_resid(uiop, uap->cnt);
2063
2064	error = so->so_proto->pr_usrreqs->pru_soreceive_list(so, NULL, uiop,
2065	    uap->cnt, (struct mbuf **)0, NULL, NULL);
2066
2067	len_after = uio_array_resid(uiop, uap->cnt);
2068
2069	if (error) {
2070		if (len_after != len_before && (error == ERESTART ||
2071		    error == EINTR || error == EWOULDBLOCK))
2072			error = 0;
2073	}
2074	if (error == 0) {
2075		uiocnt = externalize_user_msghdr_array(umsgp,
2076		    IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32,
2077		    UIO_READ, uap->cnt, user_msg, uiop);
2078
2079		error = copyout(umsgp, uap->msgp, uap->cnt * size_of_msghdr);
2080		if (error) {
2081			printf("%s copyout() failed\n", __func__);
2082			goto out;
2083		}
2084		*retval = (int)(uiocnt);
2085	}
2086out:
2087	if (need_drop)
2088		file_drop(uap->s);
2089	if (umsgp != NULL)
2090		_FREE(umsgp, M_TEMP);
2091	if (uiop != NULL) {
2092		free_uio_array(uiop, uap->cnt);
2093		_FREE(uiop, M_TEMP);
2094	}
2095	if (user_msg != NULL)
2096		_FREE(user_msg, M_TEMP);
2097
2098	KERNEL_DEBUG(DBG_FNC_RECVMSG_X | DBG_FUNC_END, error, 0, 0, 0, 0);
2099
2100	return (error);
2101}
2102
2103/*
2104 * Returns:	0			Success
2105 *		EBADF
2106 *	file_socket:ENOTSOCK
2107 *	file_socket:EBADF
2108 *	soshutdown:EINVAL
2109 *	soshutdown:ENOTCONN
2110 *	soshutdown:EADDRNOTAVAIL[TCP]
2111 *	soshutdown:ENOBUFS[TCP]
2112 *	soshutdown:EMSGSIZE[TCP]
2113 *	soshutdown:EHOSTUNREACH[TCP]
2114 *	soshutdown:ENETUNREACH[TCP]
2115 *	soshutdown:ENETDOWN[TCP]
2116 *	soshutdown:ENOMEM[TCP]
2117 *	soshutdown:EACCES[TCP]
2118 *	soshutdown:EMSGSIZE[TCP]
2119 *	soshutdown:ENOBUFS[TCP]
2120 *	soshutdown:???[TCP]		[ignorable: mostly IPSEC/firewall/DLIL]
2121 *	soshutdown:???			[other protocol families]
2122 */
2123/* ARGSUSED */
2124int
2125shutdown(__unused struct proc *p, struct shutdown_args *uap,
2126    __unused int32_t *retval)
2127{
2128	struct socket *so;
2129	int error;
2130
2131	AUDIT_ARG(fd, uap->s);
2132	error = file_socket(uap->s, &so);
2133	if (error)
2134		return (error);
2135	if (so == NULL) {
2136		error = EBADF;
2137		goto out;
2138	}
2139	error =  soshutdown((struct socket *)so, uap->how);
2140out:
2141	file_drop(uap->s);
2142	return (error);
2143}
2144
2145/*
2146 * Returns:	0			Success
2147 *		EFAULT
2148 *		EINVAL
2149 *		EACCES			Mandatory Access Control failure
2150 *	file_socket:ENOTSOCK
2151 *	file_socket:EBADF
2152 *	sosetopt:EINVAL
2153 *	sosetopt:ENOPROTOOPT
2154 *	sosetopt:ENOBUFS
2155 *	sosetopt:EDOM
2156 *	sosetopt:EFAULT
2157 *	sosetopt:EOPNOTSUPP[AF_UNIX]
2158 *	sosetopt:???
2159 */
2160/* ARGSUSED */
2161int
2162setsockopt(struct proc *p, struct setsockopt_args *uap,
2163    __unused int32_t *retval)
2164{
2165	struct socket *so;
2166	struct sockopt sopt;
2167	int error;
2168
2169	AUDIT_ARG(fd, uap->s);
2170	if (uap->val == 0 && uap->valsize != 0)
2171		return (EFAULT);
2172	/* No bounds checking on size (it's unsigned) */
2173
2174	error = file_socket(uap->s, &so);
2175	if (error)
2176		return (error);
2177
2178	sopt.sopt_dir = SOPT_SET;
2179	sopt.sopt_level = uap->level;
2180	sopt.sopt_name = uap->name;
2181	sopt.sopt_val = uap->val;
2182	sopt.sopt_valsize = uap->valsize;
2183	sopt.sopt_p = p;
2184
2185	if (so == NULL) {
2186		error = EINVAL;
2187		goto out;
2188	}
2189#if CONFIG_MACF_SOCKET_SUBSET
2190	if ((error = mac_socket_check_setsockopt(kauth_cred_get(), so,
2191	    &sopt)) != 0)
2192		goto out;
2193#endif /* MAC_SOCKET_SUBSET */
2194	error = sosetoptlock(so, &sopt, 1);	/* will lock socket */
2195out:
2196	file_drop(uap->s);
2197	return (error);
2198}
2199
2200
2201
2202/*
2203 * Returns:	0			Success
2204 *		EINVAL
2205 *		EBADF
2206 *		EACCES			Mandatory Access Control failure
2207 *	copyin:EFAULT
2208 *	copyout:EFAULT
2209 *	file_socket:ENOTSOCK
2210 *	file_socket:EBADF
2211 *	sogetopt:???
2212 */
2213int
2214getsockopt(struct proc *p, struct getsockopt_args  *uap,
2215    __unused int32_t *retval)
2216{
2217	int		error;
2218	socklen_t	valsize;
2219	struct sockopt	sopt;
2220	struct socket *so;
2221
2222	error = file_socket(uap->s, &so);
2223	if (error)
2224		return (error);
2225	if (uap->val) {
2226		error = copyin(uap->avalsize, (caddr_t)&valsize,
2227		    sizeof (valsize));
2228		if (error)
2229			goto out;
2230		/* No bounds checking on size (it's unsigned) */
2231	} else {
2232		valsize = 0;
2233	}
2234	sopt.sopt_dir = SOPT_GET;
2235	sopt.sopt_level = uap->level;
2236	sopt.sopt_name = uap->name;
2237	sopt.sopt_val = uap->val;
2238	sopt.sopt_valsize = (size_t)valsize; /* checked non-negative above */
2239	sopt.sopt_p = p;
2240
2241	if (so == NULL) {
2242		error = EBADF;
2243		goto out;
2244	}
2245#if CONFIG_MACF_SOCKET_SUBSET
2246	if ((error = mac_socket_check_getsockopt(kauth_cred_get(), so,
2247	    &sopt)) != 0)
2248		goto out;
2249#endif /* MAC_SOCKET_SUBSET */
2250	error = sogetoptlock((struct socket *)so, &sopt, 1);	/* will lock */
2251	if (error == 0) {
2252		valsize = sopt.sopt_valsize;
2253		error = copyout((caddr_t)&valsize, uap->avalsize,
2254		    sizeof (valsize));
2255	}
2256out:
2257	file_drop(uap->s);
2258	return (error);
2259}
2260
2261
2262/*
2263 * Get socket name.
2264 *
2265 * Returns:	0			Success
2266 *		EBADF
2267 *	file_socket:ENOTSOCK
2268 *	file_socket:EBADF
2269 *	copyin:EFAULT
2270 *	copyout:EFAULT
2271 *	<pru_sockaddr>:ENOBUFS[TCP]
2272 *	<pru_sockaddr>:ECONNRESET[TCP]
2273 *	<pru_sockaddr>:EINVAL[AF_UNIX]
2274 *	<sf_getsockname>:???
2275 */
2276/* ARGSUSED */
2277int
2278getsockname(__unused struct proc *p, struct getsockname_args *uap,
2279    __unused int32_t *retval)
2280{
2281	struct socket *so;
2282	struct sockaddr *sa;
2283	socklen_t len;
2284	socklen_t sa_len;
2285	int error;
2286
2287	error = file_socket(uap->fdes, &so);
2288	if (error)
2289		return (error);
2290	error = copyin(uap->alen, (caddr_t)&len, sizeof (socklen_t));
2291	if (error)
2292		goto out;
2293	if (so == NULL) {
2294		error = EBADF;
2295		goto out;
2296	}
2297	sa = 0;
2298	socket_lock(so, 1);
2299	error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &sa);
2300	if (error == 0) {
2301		error = sflt_getsockname(so, &sa);
2302		if (error == EJUSTRETURN)
2303			error = 0;
2304	}
2305	socket_unlock(so, 1);
2306	if (error)
2307		goto bad;
2308	if (sa == 0) {
2309		len = 0;
2310		goto gotnothing;
2311	}
2312
2313	sa_len = sa->sa_len;
2314	len = MIN(len, sa_len);
2315	error = copyout((caddr_t)sa, uap->asa, len);
2316	if (error)
2317		goto bad;
2318	/* return the actual, untruncated address length */
2319	len = sa_len;
2320gotnothing:
2321		error = copyout((caddr_t)&len, uap->alen, sizeof (socklen_t));
2322bad:
2323	if (sa)
2324		FREE(sa, M_SONAME);
2325out:
2326	file_drop(uap->fdes);
2327	return (error);
2328}
2329
2330/*
2331 * Get name of peer for connected socket.
2332 *
2333 * Returns:	0			Success
2334 *		EBADF
2335 *		EINVAL
2336 *		ENOTCONN
2337 *	file_socket:ENOTSOCK
2338 *	file_socket:EBADF
2339 *	copyin:EFAULT
2340 *	copyout:EFAULT
2341 *	<pru_peeraddr>:???
2342 *	<sf_getpeername>:???
2343 */
2344/* ARGSUSED */
2345int
2346getpeername(__unused struct proc *p, struct getpeername_args *uap,
2347    __unused int32_t *retval)
2348{
2349	struct socket *so;
2350	struct sockaddr *sa;
2351	socklen_t len;
2352	socklen_t sa_len;
2353	int error;
2354
2355	error = file_socket(uap->fdes, &so);
2356	if (error)
2357		return (error);
2358	if (so == NULL) {
2359		error = EBADF;
2360		goto out;
2361	}
2362
2363	socket_lock(so, 1);
2364
2365	if ((so->so_state & (SS_CANTRCVMORE | SS_CANTSENDMORE)) ==
2366	    (SS_CANTRCVMORE | SS_CANTSENDMORE)) {
2367		/* the socket has been shutdown, no more getpeername's */
2368		socket_unlock(so, 1);
2369		error = EINVAL;
2370		goto out;
2371	}
2372
2373	if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
2374		socket_unlock(so, 1);
2375		error = ENOTCONN;
2376		goto out;
2377	}
2378	error = copyin(uap->alen, (caddr_t)&len, sizeof (socklen_t));
2379	if (error) {
2380		socket_unlock(so, 1);
2381		goto out;
2382	}
2383	sa = 0;
2384	error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &sa);
2385	if (error == 0) {
2386		error = sflt_getpeername(so, &sa);
2387		if (error == EJUSTRETURN)
2388			error = 0;
2389	}
2390	socket_unlock(so, 1);
2391	if (error)
2392		goto bad;
2393	if (sa == 0) {
2394		len = 0;
2395		goto gotnothing;
2396	}
2397	sa_len = sa->sa_len;
2398	len = MIN(len, sa_len);
2399	error = copyout(sa, uap->asa, len);
2400	if (error)
2401		goto bad;
2402	/* return the actual, untruncated address length */
2403	len = sa_len;
2404gotnothing:
2405	error = copyout((caddr_t)&len, uap->alen, sizeof (socklen_t));
2406bad:
2407	if (sa) FREE(sa, M_SONAME);
2408out:
2409	file_drop(uap->fdes);
2410	return (error);
2411}
2412
2413int
2414sockargs(struct mbuf **mp, user_addr_t data, int buflen, int type)
2415{
2416	struct sockaddr *sa;
2417	struct mbuf *m;
2418	int error;
2419
2420	size_t alloc_buflen = (size_t)buflen;
2421
2422	if(alloc_buflen > INT_MAX/2)
2423		return (EINVAL);
2424#ifdef __LP64__
2425	/* The fd's in the buffer must expand to be pointers, thus we need twice as much space */
2426	if(type == MT_CONTROL)
2427		alloc_buflen = ((buflen - sizeof(struct cmsghdr))*2) + sizeof(struct cmsghdr);
2428#endif
2429	if (alloc_buflen > MLEN) {
2430		if (type == MT_SONAME && alloc_buflen <= 112)
2431			alloc_buflen = MLEN;		/* unix domain compat. hack */
2432		else if (alloc_buflen > MCLBYTES)
2433			return (EINVAL);
2434	}
2435	m = m_get(M_WAIT, type);
2436	if (m == NULL)
2437		return (ENOBUFS);
2438	if (alloc_buflen > MLEN) {
2439		MCLGET(m, M_WAIT);
2440		if ((m->m_flags & M_EXT) == 0) {
2441			m_free(m);
2442			return (ENOBUFS);
2443		}
2444	}
2445	/* K64: We still copyin the original buflen because it gets expanded later
2446	 * and we lie about the size of the mbuf because it only affects unp_* functions
2447	 */
2448	m->m_len = buflen;
2449	error = copyin(data, mtod(m, caddr_t), (u_int)buflen);
2450	if (error) {
2451		(void) m_free(m);
2452	} else {
2453		*mp = m;
2454		if (type == MT_SONAME) {
2455			sa = mtod(m, struct sockaddr *);
2456			sa->sa_len = buflen;
2457		}
2458	}
2459	return (error);
2460}
2461
2462/*
2463 * Given a user_addr_t of length len, allocate and fill out a *sa.
2464 *
2465 * Returns:	0			Success
2466 *		ENAMETOOLONG		Filename too long
2467 *		EINVAL			Invalid argument
2468 *		ENOMEM			Not enough space
2469 *		copyin:EFAULT		Bad address
2470 */
2471static int
2472getsockaddr(struct socket *so, struct sockaddr **namp, user_addr_t uaddr,
2473    size_t len, boolean_t translate_unspec)
2474{
2475	struct sockaddr *sa;
2476	int error;
2477
2478	if (len > SOCK_MAXADDRLEN)
2479		return (ENAMETOOLONG);
2480
2481	if (len < offsetof(struct sockaddr, sa_data[0]))
2482		return (EINVAL);
2483
2484	MALLOC(sa, struct sockaddr *, len, M_SONAME, M_WAITOK | M_ZERO);
2485	if (sa == NULL) {
2486		return (ENOMEM);
2487	}
2488	error = copyin(uaddr, (caddr_t)sa, len);
2489	if (error) {
2490		FREE(sa, M_SONAME);
2491	} else {
2492		/*
2493		 * Force sa_family to AF_INET on AF_INET sockets to handle
2494		 * legacy applications that use AF_UNSPEC (0).  On all other
2495		 * sockets we leave it unchanged and let the lower layer
2496		 * handle it.
2497		 */
2498		if (translate_unspec && sa->sa_family == AF_UNSPEC &&
2499		    SOCK_CHECK_DOM(so, PF_INET) &&
2500		    len == sizeof (struct sockaddr_in))
2501			sa->sa_family = AF_INET;
2502
2503		sa->sa_len = len;
2504		*namp = sa;
2505	}
2506	return (error);
2507}
2508
2509static int
2510getsockaddr_s(struct socket *so, struct sockaddr_storage *ss,
2511    user_addr_t uaddr, size_t len, boolean_t translate_unspec)
2512{
2513	int error;
2514
2515	if (ss == NULL || uaddr == USER_ADDR_NULL ||
2516	    len < offsetof(struct sockaddr, sa_data[0]))
2517		return (EINVAL);
2518
2519	/*
2520	 * sockaddr_storage size is less than SOCK_MAXADDRLEN,
2521	 * so the check here is inclusive.
2522	 */
2523	if (len > sizeof (*ss))
2524		return (ENAMETOOLONG);
2525
2526	bzero(ss, sizeof (*ss));
2527	error = copyin(uaddr, (caddr_t)ss, len);
2528	if (error == 0) {
2529		/*
2530		 * Force sa_family to AF_INET on AF_INET sockets to handle
2531		 * legacy applications that use AF_UNSPEC (0).  On all other
2532		 * sockets we leave it unchanged and let the lower layer
2533		 * handle it.
2534		 */
2535		if (translate_unspec && ss->ss_family == AF_UNSPEC &&
2536		    SOCK_CHECK_DOM(so, PF_INET) &&
2537		    len == sizeof (struct sockaddr_in))
2538			ss->ss_family = AF_INET;
2539
2540		ss->ss_len = len;
2541	}
2542	return (error);
2543}
2544
2545/*
2546 * Hard limit on the number of source and/or destination addresses
2547 * that can be specified by an application.
2548 */
2549#define	SOCKADDRLIST_MAX_ENTRIES	64
2550
2551static int
2552getsockaddrlist(struct socket *so, struct sockaddr_list **slp,
2553    user_addr_t uaddr, socklen_t uaddrlen, boolean_t xlate_unspec)
2554{
2555	struct sockaddr_list *sl;
2556	int error = 0;
2557
2558	*slp = NULL;
2559
2560	if (uaddr == USER_ADDR_NULL || uaddrlen == 0)
2561		return (EINVAL);
2562
2563	sl = sockaddrlist_alloc(M_WAITOK);
2564	if (sl == NULL)
2565		return (ENOMEM);
2566
2567	VERIFY(sl->sl_cnt == 0);
2568	while (uaddrlen > 0 && sl->sl_cnt < SOCKADDRLIST_MAX_ENTRIES) {
2569		struct sockaddr_storage ss;
2570		struct sockaddr_entry *se;
2571		struct sockaddr *sa;
2572
2573		if (uaddrlen < sizeof (struct sockaddr)) {
2574			error = EINVAL;
2575			break;
2576		}
2577
2578		bzero(&ss, sizeof (ss));
2579		error = copyin(uaddr, (caddr_t)&ss, sizeof (struct sockaddr));
2580		if (error != 0)
2581			break;
2582
2583		/* getsockaddr does the same but we need them now */
2584		if (uaddrlen < ss.ss_len ||
2585		    ss.ss_len < offsetof(struct sockaddr, sa_data[0])) {
2586			error = EINVAL;
2587			break;
2588		} else if (ss.ss_len > sizeof (ss)) {
2589			/*
2590			 * sockaddr_storage size is less than SOCK_MAXADDRLEN,
2591			 * so the check here is inclusive.  We could user the
2592			 * latter instead, but seems like an overkill for now.
2593			 */
2594			error = ENAMETOOLONG;
2595			break;
2596		}
2597
2598		se = sockaddrentry_alloc(M_WAITOK);
2599		if (se == NULL)
2600			break;
2601
2602		sockaddrlist_insert(sl, se);
2603
2604		error = getsockaddr(so, &sa, uaddr, ss.ss_len, xlate_unspec);
2605		if (error != 0)
2606			break;
2607
2608		VERIFY(sa != NULL && sa->sa_len == ss.ss_len);
2609		se->se_addr = sa;
2610
2611		uaddr += ss.ss_len;
2612		VERIFY(((signed)uaddrlen - ss.ss_len) >= 0);
2613		uaddrlen -= ss.ss_len;
2614	}
2615
2616	if (error != 0)
2617		sockaddrlist_free(sl);
2618	else
2619		*slp = sl;
2620
2621	return (error);
2622}
2623
2624int
2625internalize_user_msghdr_array(const void *src, int spacetype, int direction,
2626	u_int count, struct user_msghdr_x *dst, struct uio **uiop)
2627{
2628	int error = 0;
2629	u_int i;
2630
2631	for (i = 0; i < count; i++) {
2632		uio_t auio;
2633		struct user_iovec *iovp;
2634		struct user_msghdr_x *user_msg = &dst[i];
2635
2636		if (spacetype == UIO_USERSPACE64) {
2637			struct user64_msghdr_x *msghdr64;
2638
2639			msghdr64 = ((struct user64_msghdr_x *)src) + i;
2640
2641			user_msg->msg_name = msghdr64->msg_name;
2642			user_msg->msg_namelen = msghdr64->msg_namelen;
2643			user_msg->msg_iov = msghdr64->msg_iov;
2644			user_msg->msg_iovlen = msghdr64->msg_iovlen;
2645			user_msg->msg_control = msghdr64->msg_control;
2646			user_msg->msg_controllen = msghdr64->msg_controllen;
2647			user_msg->msg_flags = msghdr64->msg_flags;
2648			user_msg->msg_datalen = msghdr64->msg_datalen;
2649		} else {
2650			struct user32_msghdr_x *msghdr32;
2651
2652			msghdr32 = ((struct user32_msghdr_x *)src) + i;
2653
2654			user_msg->msg_name = msghdr32->msg_name;
2655			user_msg->msg_namelen = msghdr32->msg_namelen;
2656			user_msg->msg_iov = msghdr32->msg_iov;
2657			user_msg->msg_iovlen = msghdr32->msg_iovlen;
2658			user_msg->msg_control = msghdr32->msg_control;
2659			user_msg->msg_controllen = msghdr32->msg_controllen;
2660			user_msg->msg_flags = msghdr32->msg_flags;
2661			user_msg->msg_datalen = msghdr32->msg_datalen;
2662		}
2663
2664		if (user_msg->msg_iovlen <= 0 || user_msg->msg_iovlen > UIO_MAXIOV) {
2665			error = EMSGSIZE;
2666			goto done;
2667		}
2668		auio = uio_create(user_msg->msg_iovlen, 0, spacetype, direction);
2669		if (auio == NULL) {
2670			error = ENOMEM;
2671			goto done;
2672		}
2673		uiop[i] = auio;
2674
2675		if (user_msg->msg_iovlen) {
2676			iovp = uio_iovsaddr(auio);
2677			if (iovp == NULL) {
2678				error = ENOMEM;
2679				goto done;
2680			}
2681			error = copyin_user_iovec_array(user_msg->msg_iov,
2682				spacetype, user_msg->msg_iovlen, iovp);
2683			 if (error)
2684				goto done;
2685			user_msg->msg_iov = CAST_USER_ADDR_T(iovp);
2686
2687			error = uio_calculateresid(auio);
2688			if (error)
2689				goto done;
2690			user_msg->msg_datalen = uio_resid(auio);
2691		} else {
2692			user_msg->msg_datalen = 0;
2693		}
2694	}
2695done:
2696	return (error);
2697}
2698
2699u_int
2700externalize_user_msghdr_array(void *dst, int spacetype, int direction,
2701	 u_int count, const struct user_msghdr_x *src, struct uio **uiop)
2702{
2703#pragma unused(direction)
2704	u_int i;
2705	int seenlast = 0;
2706	u_int retcnt = 0;
2707
2708	for (i = 0; i < count; i++) {
2709		const struct user_msghdr_x *user_msg = &src[i];
2710		uio_t auio = uiop[i];
2711		user_ssize_t len = user_msg->msg_datalen - uio_resid(auio);
2712
2713		if (user_msg->msg_datalen != 0 && len == 0)
2714			seenlast = 1;
2715
2716		if (seenlast == 0)
2717			retcnt ++;
2718
2719		if (spacetype == UIO_USERSPACE64) {
2720			struct user64_msghdr_x *msghdr64;
2721
2722			msghdr64 = ((struct user64_msghdr_x *)dst) + i;
2723
2724			msghdr64->msg_flags = user_msg->msg_flags;
2725			msghdr64->msg_datalen = len;
2726
2727		} else {
2728			struct user32_msghdr_x *msghdr32;
2729
2730			msghdr32 = ((struct user32_msghdr_x *)dst) + i;
2731
2732			msghdr32->msg_flags = user_msg->msg_flags;
2733			msghdr32->msg_datalen = len;
2734		}
2735	}
2736	return (retcnt);
2737}
2738
2739void
2740free_uio_array(struct uio **uiop, u_int count)
2741{
2742	u_int i;
2743
2744	for (i = 0; i < count; i++) {
2745		if (uiop[i] != NULL)
2746			uio_free(uiop[i]);
2747	}
2748}
2749
2750__private_extern__ user_ssize_t
2751uio_array_resid(struct uio **uiop, u_int count)
2752{
2753	user_ssize_t len = 0;
2754	u_int i;
2755
2756	for (i = 0; i < count; i++) {
2757		struct uio *auio = uiop[i];
2758
2759		if (auio!= NULL)
2760			len += uio_resid(auio);
2761	}
2762	return (len);
2763}
2764
2765int
2766uio_array_is_valid(struct uio **uiop, u_int count)
2767{
2768	user_ssize_t len = 0;
2769	u_int i;
2770
2771	for (i = 0; i < count; i++) {
2772		struct uio *auio = uiop[i];
2773
2774		if (auio != NULL) {
2775			user_ssize_t resid = uio_resid(auio);
2776
2777			/*
2778			 * Sanity check on the validity of the iovec:
2779			 * no point of going over sb_max
2780			 */
2781			if (resid < 0 || (u_int32_t)resid > sb_max)
2782				return (0);
2783
2784			len += resid;
2785			if (len < 0 || (u_int32_t)len > sb_max)
2786				return (0);
2787		}
2788	}
2789	return (1);
2790}
2791
2792#if SENDFILE
2793
2794#define	SFUIOBUFS 64
2795
2796/* Macros to compute the number of mbufs needed depending on cluster size */
2797#define	HOWMANY_16K(n)	((((unsigned int)(n) - 1) >> (PGSHIFT + 2)) + 1)
2798#define	HOWMANY_4K(n)	((((unsigned int)(n) - 1) >> PGSHIFT) + 1)
2799
2800/* Upper send limit in bytes (SFUIOBUFS * PAGESIZE) */
2801#define SENDFILE_MAX_BYTES	(SFUIOBUFS << PGSHIFT)
2802
2803/* Upper send limit in the number of mbuf clusters */
2804#define	SENDFILE_MAX_16K	HOWMANY_16K(SENDFILE_MAX_BYTES)
2805#define	SENDFILE_MAX_4K		HOWMANY_4K(SENDFILE_MAX_BYTES)
2806
2807static void
2808alloc_sendpkt(int how, size_t pktlen, unsigned int *maxchunks,
2809    struct mbuf **m, boolean_t jumbocl)
2810{
2811	unsigned int needed;
2812
2813	if (pktlen == 0)
2814		panic("%s: pktlen (%ld) must be non-zero\n", __func__, pktlen);
2815
2816	/*
2817	 * Try to allocate for the whole thing.  Since we want full control
2818	 * over the buffer size and be able to accept partial result, we can't
2819	 * use mbuf_allocpacket().  The logic below is similar to sosend().
2820	 */
2821	*m = NULL;
2822	if (pktlen > MBIGCLBYTES && jumbocl) {
2823		needed = MIN(SENDFILE_MAX_16K, HOWMANY_16K(pktlen));
2824		*m = m_getpackets_internal(&needed, 1, how, 0, M16KCLBYTES);
2825	}
2826	if (*m == NULL) {
2827		needed = MIN(SENDFILE_MAX_4K, HOWMANY_4K(pktlen));
2828		*m = m_getpackets_internal(&needed, 1, how, 0, MBIGCLBYTES);
2829	}
2830
2831	/*
2832	 * Our previous attempt(s) at allocation had failed; the system
2833	 * may be short on mbufs, and we want to block until they are
2834	 * available.  This time, ask just for 1 mbuf and don't return
2835	 * until we get it.
2836	 */
2837	if (*m == NULL) {
2838		needed = 1;
2839		*m = m_getpackets_internal(&needed, 1, M_WAIT, 1, MBIGCLBYTES);
2840	}
2841	if (*m == NULL)
2842		panic("%s: blocking allocation returned NULL\n", __func__);
2843
2844	*maxchunks = needed;
2845}
2846
2847/*
2848 * sendfile(2).
2849 * int sendfile(int fd, int s, off_t offset, off_t *nbytes,
2850 *	 struct sf_hdtr *hdtr, int flags)
2851 *
2852 * Send a file specified by 'fd' and starting at 'offset' to a socket
2853 * specified by 's'. Send only '*nbytes' of the file or until EOF if
2854 * *nbytes == 0. Optionally add a header and/or trailer to the socket
2855 * output. If specified, write the total number of bytes sent into *nbytes.
2856 */
2857int
2858sendfile(struct proc *p, struct sendfile_args *uap, __unused int *retval)
2859{
2860	struct fileproc *fp;
2861	struct vnode *vp;
2862	struct socket *so;
2863	struct writev_nocancel_args nuap;
2864	user_ssize_t writev_retval;
2865	struct user_sf_hdtr user_hdtr;
2866	struct user32_sf_hdtr user32_hdtr;
2867	struct user64_sf_hdtr user64_hdtr;
2868	off_t off, xfsize;
2869	off_t nbytes = 0, sbytes = 0;
2870	int error = 0;
2871	size_t sizeof_hdtr;
2872	off_t file_size;
2873	struct vfs_context context = *vfs_context_current();
2874#define ENXIO_10146739_DBG(err_str) {	\
2875	if (error == ENXIO) {		\
2876		printf(err_str,		\
2877		__func__,		\
2878		"File a radar related to rdar://10146739 \n");	\
2879	}				\
2880}
2881	KERNEL_DEBUG_CONSTANT((DBG_FNC_SENDFILE | DBG_FUNC_START), uap->s,
2882	    0, 0, 0, 0);
2883
2884	AUDIT_ARG(fd, uap->fd);
2885	AUDIT_ARG(value32, uap->s);
2886
2887	/*
2888	 * Do argument checking. Must be a regular file in, stream
2889	 * type and connected socket out, positive offset.
2890	 */
2891	if ((error = fp_getfvp(p, uap->fd, &fp, &vp))) {
2892		ENXIO_10146739_DBG("%s: fp_getfvp error. %s");
2893		goto done;
2894	}
2895	if ((fp->f_flag & FREAD) == 0) {
2896		error = EBADF;
2897		goto done1;
2898	}
2899	if (vnode_isreg(vp) == 0) {
2900		error = ENOTSUP;
2901		goto done1;
2902	}
2903	error = file_socket(uap->s, &so);
2904	if (error) {
2905		ENXIO_10146739_DBG("%s: file_socket error. %s");
2906		goto done1;
2907	}
2908	if (so == NULL) {
2909		error = EBADF;
2910		goto done2;
2911	}
2912	if (so->so_type != SOCK_STREAM) {
2913		error = EINVAL;
2914		goto done2;
2915	}
2916	if ((so->so_state & SS_ISCONNECTED) == 0) {
2917		error = ENOTCONN;
2918		goto done2;
2919	}
2920	if (uap->offset < 0) {
2921		error = EINVAL;
2922		goto done2;
2923	}
2924	if (uap->nbytes == USER_ADDR_NULL) {
2925		error = EINVAL;
2926		goto done2;
2927	}
2928	if (uap->flags != 0) {
2929		error = EINVAL;
2930		goto done2;
2931	}
2932
2933	context.vc_ucred = fp->f_fglob->fg_cred;
2934
2935#if CONFIG_MACF_SOCKET_SUBSET
2936	/* JMM - fetch connected sockaddr? */
2937	error = mac_socket_check_send(context.vc_ucred, so, NULL);
2938	if (error)
2939		goto done2;
2940#endif
2941
2942	/*
2943	 * Get number of bytes to send
2944	 * Should it applies to size of header and trailer?
2945	 * JMM - error handling?
2946	 */
2947	copyin(uap->nbytes, &nbytes, sizeof (off_t));
2948
2949	/*
2950	 * If specified, get the pointer to the sf_hdtr struct for
2951	 * any headers/trailers.
2952	 */
2953	if (uap->hdtr != USER_ADDR_NULL) {
2954		caddr_t hdtrp;
2955
2956		bzero(&user_hdtr, sizeof (user_hdtr));
2957		if (IS_64BIT_PROCESS(p)) {
2958			hdtrp = (caddr_t)&user64_hdtr;
2959			sizeof_hdtr = sizeof (user64_hdtr);
2960		} else {
2961			hdtrp = (caddr_t)&user32_hdtr;
2962			sizeof_hdtr = sizeof (user32_hdtr);
2963		}
2964		error = copyin(uap->hdtr, hdtrp, sizeof_hdtr);
2965		if (error)
2966			goto done2;
2967		if (IS_64BIT_PROCESS(p)) {
2968			user_hdtr.headers = user64_hdtr.headers;
2969			user_hdtr.hdr_cnt = user64_hdtr.hdr_cnt;
2970			user_hdtr.trailers = user64_hdtr.trailers;
2971			user_hdtr.trl_cnt = user64_hdtr.trl_cnt;
2972		} else {
2973			user_hdtr.headers = user32_hdtr.headers;
2974			user_hdtr.hdr_cnt = user32_hdtr.hdr_cnt;
2975			user_hdtr.trailers = user32_hdtr.trailers;
2976			user_hdtr.trl_cnt = user32_hdtr.trl_cnt;
2977		}
2978
2979		/*
2980		 * Send any headers. Wimp out and use writev(2).
2981		 */
2982		if (user_hdtr.headers != USER_ADDR_NULL) {
2983			bzero(&nuap, sizeof (struct writev_args));
2984			nuap.fd = uap->s;
2985			nuap.iovp = user_hdtr.headers;
2986			nuap.iovcnt = user_hdtr.hdr_cnt;
2987			error = writev_nocancel(p, &nuap, &writev_retval);
2988			if (error) {
2989				ENXIO_10146739_DBG("%s: writev_nocancel error. %s");
2990				goto done2;
2991			}
2992			sbytes += writev_retval;
2993		}
2994	}
2995
2996	/*
2997	 * Get the file size for 2 reasons:
2998	 *  1. We don't want to allocate more mbufs than necessary
2999	 *  2. We don't want to read past the end of file
3000	 */
3001	if ((error = vnode_size(vp, &file_size, vfs_context_current())) != 0) {
3002		ENXIO_10146739_DBG("%s: vnode_size error. %s");
3003		goto done2;
3004	}
3005
3006	/*
3007	 * Simply read file data into a chain of mbufs that used with scatter
3008	 * gather reads. We're not (yet?) setup to use zero copy external
3009	 * mbufs that point to the file pages.
3010	 */
3011	socket_lock(so, 1);
3012	error = sblock(&so->so_snd, SBL_WAIT);
3013	if (error) {
3014		socket_unlock(so, 1);
3015		goto done2;
3016	}
3017	for (off = uap->offset; ; off += xfsize, sbytes += xfsize) {
3018		mbuf_t	m0 = NULL, m;
3019		unsigned int	nbufs = SFUIOBUFS, i;
3020		uio_t	auio;
3021		char	uio_buf[UIO_SIZEOF(SFUIOBUFS)]; /* 1 KB !!! */
3022		size_t	uiolen;
3023		user_ssize_t	rlen;
3024		off_t	pgoff;
3025		size_t	pktlen;
3026		boolean_t jumbocl;
3027
3028		/*
3029		 * Calculate the amount to transfer.
3030		 * Align to round number of pages.
3031		 * Not to exceed send socket buffer,
3032		 * the EOF, or the passed in nbytes.
3033		 */
3034		xfsize = sbspace(&so->so_snd);
3035
3036		if (xfsize <= 0) {
3037			if (so->so_state & SS_CANTSENDMORE) {
3038				error = EPIPE;
3039				goto done3;
3040			} else if ((so->so_state & SS_NBIO)) {
3041				error = EAGAIN;
3042				goto done3;
3043			} else {
3044				xfsize = PAGE_SIZE;
3045			}
3046		}
3047
3048		if (xfsize > SENDFILE_MAX_BYTES)
3049			xfsize = SENDFILE_MAX_BYTES;
3050		else if (xfsize > PAGE_SIZE)
3051			xfsize = trunc_page(xfsize);
3052		pgoff = off & PAGE_MASK_64;
3053		if (pgoff > 0 && PAGE_SIZE - pgoff < xfsize)
3054			xfsize = PAGE_SIZE_64 - pgoff;
3055		if (nbytes && xfsize > (nbytes - sbytes))
3056			xfsize = nbytes - sbytes;
3057		if (xfsize <= 0)
3058			break;
3059		if (off + xfsize > file_size)
3060			xfsize = file_size - off;
3061		if (xfsize <= 0)
3062			break;
3063
3064		/*
3065		 * Attempt to use larger than system page-size clusters for
3066		 * large writes only if there is a jumbo cluster pool and
3067		 * if the socket is marked accordingly.
3068		 */
3069		jumbocl = sosendjcl && njcl > 0 &&
3070		    ((so->so_flags & SOF_MULTIPAGES) || sosendjcl_ignore_capab);
3071
3072		socket_unlock(so, 0);
3073		alloc_sendpkt(M_WAIT, xfsize, &nbufs, &m0, jumbocl);
3074		pktlen = mbuf_pkthdr_maxlen(m0);
3075		if (pktlen < (size_t)xfsize)
3076			xfsize = pktlen;
3077
3078		auio = uio_createwithbuffer(nbufs, off, UIO_SYSSPACE,
3079		    UIO_READ, &uio_buf[0], sizeof (uio_buf));
3080		if (auio == NULL) {
3081			printf("sendfile failed. nbufs = %d. %s", nbufs,
3082				"File a radar related to rdar://10146739.\n");
3083			mbuf_freem(m0);
3084			error = ENXIO;
3085			socket_lock(so, 0);
3086			goto done3;
3087		}
3088
3089		for (i = 0, m = m0, uiolen = 0;
3090		    i < nbufs && m != NULL && uiolen < (size_t)xfsize;
3091		    i++, m = mbuf_next(m)) {
3092			size_t mlen = mbuf_maxlen(m);
3093
3094			if (mlen + uiolen > (size_t)xfsize)
3095				mlen = xfsize - uiolen;
3096			mbuf_setlen(m, mlen);
3097			uio_addiov(auio, CAST_USER_ADDR_T(mbuf_datastart(m)),
3098			    mlen);
3099			uiolen += mlen;
3100		}
3101
3102		if (xfsize != uio_resid(auio))
3103			printf("sendfile: xfsize: %lld != uio_resid(auio): "
3104				"%lld\n", xfsize, (long long)uio_resid(auio));
3105
3106		KERNEL_DEBUG_CONSTANT((DBG_FNC_SENDFILE_READ | DBG_FUNC_START),
3107		    uap->s, (unsigned int)((xfsize >> 32) & 0x0ffffffff),
3108		    (unsigned int)(xfsize & 0x0ffffffff), 0, 0);
3109		error = fo_read(fp, auio, FOF_OFFSET, &context);
3110		socket_lock(so, 0);
3111		if (error != 0) {
3112			if (uio_resid(auio) != xfsize && (error == ERESTART ||
3113			    error == EINTR || error == EWOULDBLOCK)) {
3114				error = 0;
3115			} else {
3116				ENXIO_10146739_DBG("%s: fo_read error. %s");
3117				mbuf_freem(m0);
3118				goto done3;
3119			}
3120		}
3121		xfsize -= uio_resid(auio);
3122		KERNEL_DEBUG_CONSTANT((DBG_FNC_SENDFILE_READ | DBG_FUNC_END),
3123		    uap->s, (unsigned int)((xfsize >> 32) & 0x0ffffffff),
3124		    (unsigned int)(xfsize & 0x0ffffffff), 0, 0);
3125
3126		if (xfsize == 0) {
3127			//printf("sendfile: fo_read 0 bytes, EOF\n");
3128			break;
3129		}
3130		if (xfsize + off > file_size)
3131			printf("sendfile: xfsize: %lld + off: %lld > file_size:"
3132			    "%lld\n", xfsize, off, file_size);
3133		for (i = 0, m = m0, rlen = 0;
3134		    i < nbufs && m != NULL && rlen < xfsize;
3135		    i++, m = mbuf_next(m)) {
3136			size_t mlen = mbuf_maxlen(m);
3137
3138			if (rlen + mlen > (size_t)xfsize)
3139				mlen = xfsize - rlen;
3140			mbuf_setlen(m, mlen);
3141
3142			rlen += mlen;
3143		}
3144		mbuf_pkthdr_setlen(m0, xfsize);
3145
3146retry_space:
3147		/*
3148		 * Make sure that the socket is still able to take more data.
3149		 * CANTSENDMORE being true usually means that the connection
3150		 * was closed. so_error is true when an error was sensed after
3151		 * a previous send.
3152		 * The state is checked after the page mapping and buffer
3153		 * allocation above since those operations may block and make
3154		 * any socket checks stale. From this point forward, nothing
3155		 * blocks before the pru_send (or more accurately, any blocking
3156		 * results in a loop back to here to re-check).
3157		 */
3158		if ((so->so_state & SS_CANTSENDMORE) || so->so_error) {
3159			if (so->so_state & SS_CANTSENDMORE) {
3160				error = EPIPE;
3161			} else {
3162				error = so->so_error;
3163				so->so_error = 0;
3164			}
3165			m_freem(m0);
3166			ENXIO_10146739_DBG("%s: Unexpected socket error. %s");
3167			goto done3;
3168		}
3169		/*
3170		 * Wait for socket space to become available. We do this just
3171		 * after checking the connection state above in order to avoid
3172		 * a race condition with sbwait().
3173		 */
3174		if (sbspace(&so->so_snd) < (long)so->so_snd.sb_lowat) {
3175			if (so->so_state & SS_NBIO) {
3176				m_freem(m0);
3177				error = EAGAIN;
3178				goto done3;
3179			}
3180			KERNEL_DEBUG_CONSTANT((DBG_FNC_SENDFILE_WAIT |
3181			    DBG_FUNC_START), uap->s, 0, 0, 0, 0);
3182			error = sbwait(&so->so_snd);
3183			KERNEL_DEBUG_CONSTANT((DBG_FNC_SENDFILE_WAIT|
3184			    DBG_FUNC_END), uap->s, 0, 0, 0, 0);
3185			/*
3186			 * An error from sbwait usually indicates that we've
3187			 * been interrupted by a signal. If we've sent anything
3188			 * then return bytes sent, otherwise return the error.
3189			 */
3190			if (error) {
3191				m_freem(m0);
3192				goto done3;
3193			}
3194			goto retry_space;
3195		}
3196
3197		struct mbuf *control = NULL;
3198		{
3199			/*
3200			 * Socket filter processing
3201			 */
3202
3203			error = sflt_data_out(so, NULL, &m0, &control, 0);
3204			if (error) {
3205				if (error == EJUSTRETURN) {
3206					error = 0;
3207					continue;
3208				}
3209				ENXIO_10146739_DBG("%s: sflt_data_out error. %s");
3210				goto done3;
3211			}
3212			/*
3213			 * End Socket filter processing
3214			 */
3215		}
3216		KERNEL_DEBUG_CONSTANT((DBG_FNC_SENDFILE_SEND | DBG_FUNC_START),
3217		    uap->s, 0, 0, 0, 0);
3218		error = (*so->so_proto->pr_usrreqs->pru_send)(so, 0, m0,
3219		    0, control, p);
3220		KERNEL_DEBUG_CONSTANT((DBG_FNC_SENDFILE_SEND | DBG_FUNC_START),
3221		    uap->s, 0, 0, 0, 0);
3222		if (error) {
3223			ENXIO_10146739_DBG("%s: pru_send error. %s");
3224			goto done3;
3225		}
3226	}
3227	sbunlock(&so->so_snd, FALSE);	/* will unlock socket */
3228	/*
3229	 * Send trailers. Wimp out and use writev(2).
3230	 */
3231	if (uap->hdtr != USER_ADDR_NULL &&
3232	    user_hdtr.trailers != USER_ADDR_NULL) {
3233		bzero(&nuap, sizeof (struct writev_args));
3234		nuap.fd = uap->s;
3235		nuap.iovp = user_hdtr.trailers;
3236		nuap.iovcnt = user_hdtr.trl_cnt;
3237		error = writev_nocancel(p, &nuap, &writev_retval);
3238		if (error) {
3239			ENXIO_10146739_DBG("%s: writev_nocancel error. %s");
3240			goto done2;
3241		}
3242		sbytes += writev_retval;
3243	}
3244done2:
3245	file_drop(uap->s);
3246done1:
3247	file_drop(uap->fd);
3248done:
3249	if (uap->nbytes != USER_ADDR_NULL) {
3250		/* XXX this appears bogus for some early failure conditions */
3251		copyout(&sbytes, uap->nbytes, sizeof (off_t));
3252	}
3253	KERNEL_DEBUG_CONSTANT((DBG_FNC_SENDFILE | DBG_FUNC_END), uap->s,
3254	    (unsigned int)((sbytes >> 32) & 0x0ffffffff),
3255	    (unsigned int)(sbytes & 0x0ffffffff), error, 0);
3256	return (error);
3257done3:
3258	sbunlock(&so->so_snd, FALSE);	/* will unlock socket */
3259	goto done2;
3260}
3261
3262
3263#endif /* SENDFILE */
3264