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