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