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