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