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