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