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