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