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