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