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