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