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