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