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