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