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 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, &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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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