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 #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 int error; 188 189 #ifdef CAPABILITY_MODE 190 if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD)) 191 return (ECAPMODE); 192 #endif 193 194 AUDIT_ARG_FD(fd); 195 AUDIT_ARG_SOCKADDR(td, dirfd, sa); 196 error = getsock_cap(td, fd, &cap_bind_rights, 197 &fp, NULL, NULL); 198 if (error != 0) 199 return (error); 200 so = fp->f_data; 201 #ifdef KTRACE 202 if (KTRPOINT(td, KTR_STRUCT)) 203 ktrsockaddr(sa); 204 #endif 205 #ifdef MAC 206 error = mac_socket_check_bind(td->td_ucred, so, sa); 207 if (error == 0) { 208 #endif 209 if (dirfd == AT_FDCWD) 210 error = sobind(so, sa, td); 211 else 212 error = sobindat(dirfd, so, sa, td); 213 #ifdef MAC 214 } 215 #endif 216 fdrop(fp, td); 217 return (error); 218 } 219 220 int 221 sys_bindat(struct thread *td, struct bindat_args *uap) 222 { 223 struct sockaddr *sa; 224 int error; 225 226 error = getsockaddr(&sa, uap->name, uap->namelen); 227 if (error == 0) { 228 error = kern_bindat(td, uap->fd, uap->s, sa); 229 free(sa, M_SONAME); 230 } 231 return (error); 232 } 233 234 int 235 sys_listen(struct thread *td, struct listen_args *uap) 236 { 237 238 return (kern_listen(td, uap->s, uap->backlog)); 239 } 240 241 int 242 kern_listen(struct thread *td, int s, int backlog) 243 { 244 struct socket *so; 245 struct file *fp; 246 int error; 247 248 AUDIT_ARG_FD(s); 249 error = getsock_cap(td, s, &cap_listen_rights, 250 &fp, NULL, NULL); 251 if (error == 0) { 252 so = fp->f_data; 253 #ifdef MAC 254 error = mac_socket_check_listen(td->td_ucred, so); 255 if (error == 0) 256 #endif 257 error = solisten(so, backlog, td); 258 fdrop(fp, td); 259 } 260 return (error); 261 } 262 263 /* 264 * accept1() 265 */ 266 static int 267 accept1(td, s, uname, anamelen, flags) 268 struct thread *td; 269 int s; 270 struct sockaddr *uname; 271 socklen_t *anamelen; 272 int flags; 273 { 274 struct sockaddr *name; 275 socklen_t namelen; 276 struct file *fp; 277 int error; 278 279 if (uname == NULL) 280 return (kern_accept4(td, s, NULL, NULL, flags, NULL)); 281 282 error = copyin(anamelen, &namelen, sizeof (namelen)); 283 if (error != 0) 284 return (error); 285 286 error = kern_accept4(td, s, &name, &namelen, flags, &fp); 287 288 if (error != 0) 289 return (error); 290 291 if (error == 0 && uname != NULL) { 292 #ifdef COMPAT_OLDSOCK 293 if (flags & ACCEPT4_COMPAT) 294 ((struct osockaddr *)name)->sa_family = 295 name->sa_family; 296 #endif 297 error = copyout(name, uname, namelen); 298 } 299 if (error == 0) 300 error = copyout(&namelen, anamelen, 301 sizeof(namelen)); 302 if (error != 0) 303 fdclose(td, fp, td->td_retval[0]); 304 fdrop(fp, td); 305 free(name, M_SONAME); 306 return (error); 307 } 308 309 int 310 kern_accept(struct thread *td, int s, struct sockaddr **name, 311 socklen_t *namelen, struct file **fp) 312 { 313 return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp)); 314 } 315 316 int 317 kern_accept4(struct thread *td, int s, struct sockaddr **name, 318 socklen_t *namelen, int flags, struct file **fp) 319 { 320 struct file *headfp, *nfp = NULL; 321 struct sockaddr *sa = NULL; 322 struct socket *head, *so; 323 struct filecaps fcaps; 324 u_int fflag; 325 pid_t pgid; 326 int error, fd, tmp; 327 328 if (name != NULL) 329 *name = NULL; 330 331 AUDIT_ARG_FD(s); 332 error = getsock_cap(td, s, &cap_accept_rights, 333 &headfp, &fflag, &fcaps); 334 if (error != 0) 335 return (error); 336 head = headfp->f_data; 337 if ((head->so_options & SO_ACCEPTCONN) == 0) { 338 error = EINVAL; 339 goto done; 340 } 341 #ifdef MAC 342 error = mac_socket_check_accept(td->td_ucred, head); 343 if (error != 0) 344 goto done; 345 #endif 346 error = falloc_caps(td, &nfp, &fd, 347 (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps); 348 if (error != 0) 349 goto done; 350 SOCK_LOCK(head); 351 if (!SOLISTENING(head)) { 352 SOCK_UNLOCK(head); 353 error = EINVAL; 354 goto noconnection; 355 } 356 357 error = solisten_dequeue(head, &so, flags); 358 if (error != 0) 359 goto noconnection; 360 361 /* An extra reference on `nfp' has been held for us by falloc(). */ 362 td->td_retval[0] = fd; 363 364 /* Connection has been removed from the listen queue. */ 365 KNOTE_UNLOCKED(&head->so_rdsel.si_note, 0); 366 367 if (flags & ACCEPT4_INHERIT) { 368 pgid = fgetown(&head->so_sigio); 369 if (pgid != 0) 370 fsetown(pgid, &so->so_sigio); 371 } else { 372 fflag &= ~(FNONBLOCK | FASYNC); 373 if (flags & SOCK_NONBLOCK) 374 fflag |= FNONBLOCK; 375 } 376 377 finit(nfp, fflag, DTYPE_SOCKET, so, &socketops); 378 /* Sync socket nonblocking/async state with file flags */ 379 tmp = fflag & FNONBLOCK; 380 (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td); 381 tmp = fflag & FASYNC; 382 (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td); 383 error = soaccept(so, &sa); 384 if (error != 0) 385 goto noconnection; 386 if (sa == NULL) { 387 if (name) 388 *namelen = 0; 389 goto done; 390 } 391 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa); 392 if (name) { 393 /* check sa_len before it is destroyed */ 394 if (*namelen > sa->sa_len) 395 *namelen = sa->sa_len; 396 #ifdef KTRACE 397 if (KTRPOINT(td, KTR_STRUCT)) 398 ktrsockaddr(sa); 399 #endif 400 *name = sa; 401 sa = NULL; 402 } 403 noconnection: 404 free(sa, M_SONAME); 405 406 /* 407 * close the new descriptor, assuming someone hasn't ripped it 408 * out from under us. 409 */ 410 if (error != 0) 411 fdclose(td, nfp, fd); 412 413 /* 414 * Release explicitly held references before returning. We return 415 * a reference on nfp to the caller on success if they request it. 416 */ 417 done: 418 if (nfp == NULL) 419 filecaps_free(&fcaps); 420 if (fp != NULL) { 421 if (error == 0) { 422 *fp = nfp; 423 nfp = NULL; 424 } else 425 *fp = NULL; 426 } 427 if (nfp != NULL) 428 fdrop(nfp, td); 429 fdrop(headfp, td); 430 return (error); 431 } 432 433 int 434 sys_accept(td, uap) 435 struct thread *td; 436 struct accept_args *uap; 437 { 438 439 return (accept1(td, uap->s, uap->name, uap->anamelen, ACCEPT4_INHERIT)); 440 } 441 442 int 443 sys_accept4(td, uap) 444 struct thread *td; 445 struct accept4_args *uap; 446 { 447 448 if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) 449 return (EINVAL); 450 451 return (accept1(td, uap->s, uap->name, uap->anamelen, uap->flags)); 452 } 453 454 #ifdef COMPAT_OLDSOCK 455 int 456 oaccept(td, uap) 457 struct thread *td; 458 struct accept_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 } 616 finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data, 617 &socketops); 618 finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data, 619 &socketops); 620 if ((fflag & FNONBLOCK) != 0) { 621 (void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td); 622 (void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td); 623 } 624 fdrop(fp1, td); 625 fdrop(fp2, td); 626 return (0); 627 free4: 628 fdclose(td, fp2, rsv[1]); 629 fdrop(fp2, td); 630 free3: 631 fdclose(td, fp1, rsv[0]); 632 fdrop(fp1, td); 633 free2: 634 if (so2 != NULL) 635 (void)soclose(so2); 636 free1: 637 if (so1 != NULL) 638 (void)soclose(so1); 639 return (error); 640 } 641 642 int 643 sys_socketpair(struct thread *td, struct socketpair_args *uap) 644 { 645 int error, sv[2]; 646 647 error = kern_socketpair(td, uap->domain, uap->type, 648 uap->protocol, sv); 649 if (error != 0) 650 return (error); 651 error = copyout(sv, uap->rsv, 2 * sizeof(int)); 652 if (error != 0) { 653 (void)kern_close(td, sv[0]); 654 (void)kern_close(td, sv[1]); 655 } 656 return (error); 657 } 658 659 static int 660 sendit(struct thread *td, int s, struct msghdr *mp, int flags) 661 { 662 struct mbuf *control; 663 struct sockaddr *to; 664 int error; 665 666 #ifdef CAPABILITY_MODE 667 if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL)) 668 return (ECAPMODE); 669 #endif 670 671 if (mp->msg_name != NULL) { 672 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); 673 if (error != 0) { 674 to = NULL; 675 goto bad; 676 } 677 mp->msg_name = to; 678 } else { 679 to = NULL; 680 } 681 682 if (mp->msg_control) { 683 if (mp->msg_controllen < sizeof(struct cmsghdr) 684 #ifdef COMPAT_OLDSOCK 685 && mp->msg_flags != MSG_COMPAT 686 #endif 687 ) { 688 error = EINVAL; 689 goto bad; 690 } 691 error = sockargs(&control, mp->msg_control, 692 mp->msg_controllen, MT_CONTROL); 693 if (error != 0) 694 goto bad; 695 #ifdef COMPAT_OLDSOCK 696 if (mp->msg_flags == MSG_COMPAT) { 697 struct cmsghdr *cm; 698 699 M_PREPEND(control, sizeof(*cm), M_WAITOK); 700 cm = mtod(control, struct cmsghdr *); 701 cm->cmsg_len = control->m_len; 702 cm->cmsg_level = SOL_SOCKET; 703 cm->cmsg_type = SCM_RIGHTS; 704 } 705 #endif 706 } else { 707 control = NULL; 708 } 709 710 error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE); 711 712 bad: 713 free(to, M_SONAME); 714 return (error); 715 } 716 717 int 718 kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, 719 struct mbuf *control, enum uio_seg segflg) 720 { 721 struct file *fp; 722 struct uio auio; 723 struct iovec *iov; 724 struct socket *so; 725 cap_rights_t rights; 726 #ifdef KTRACE 727 struct uio *ktruio = NULL; 728 #endif 729 ssize_t len; 730 int i, error; 731 732 AUDIT_ARG_FD(s); 733 cap_rights_init(&rights, CAP_SEND); 734 if (mp->msg_name != NULL) { 735 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name); 736 cap_rights_set(&rights, CAP_CONNECT); 737 } 738 error = getsock_cap(td, s, &rights, &fp, NULL, NULL); 739 if (error != 0) { 740 m_freem(control); 741 return (error); 742 } 743 so = (struct socket *)fp->f_data; 744 745 #ifdef KTRACE 746 if (mp->msg_name != NULL && KTRPOINT(td, KTR_STRUCT)) 747 ktrsockaddr(mp->msg_name); 748 #endif 749 #ifdef MAC 750 if (mp->msg_name != NULL) { 751 error = mac_socket_check_connect(td->td_ucred, so, 752 mp->msg_name); 753 if (error != 0) { 754 m_freem(control); 755 goto bad; 756 } 757 } 758 error = mac_socket_check_send(td->td_ucred, so); 759 if (error != 0) { 760 m_freem(control); 761 goto bad; 762 } 763 #endif 764 765 auio.uio_iov = mp->msg_iov; 766 auio.uio_iovcnt = mp->msg_iovlen; 767 auio.uio_segflg = segflg; 768 auio.uio_rw = UIO_WRITE; 769 auio.uio_td = td; 770 auio.uio_offset = 0; /* XXX */ 771 auio.uio_resid = 0; 772 iov = mp->msg_iov; 773 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 774 if ((auio.uio_resid += iov->iov_len) < 0) { 775 error = EINVAL; 776 m_freem(control); 777 goto bad; 778 } 779 } 780 #ifdef KTRACE 781 if (KTRPOINT(td, KTR_GENIO)) 782 ktruio = cloneuio(&auio); 783 #endif 784 len = auio.uio_resid; 785 error = sosend(so, mp->msg_name, &auio, 0, control, flags, td); 786 if (error != 0) { 787 if (auio.uio_resid != len && (error == ERESTART || 788 error == EINTR || error == EWOULDBLOCK)) 789 error = 0; 790 /* Generation of SIGPIPE can be controlled per socket */ 791 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) && 792 !(flags & MSG_NOSIGNAL)) { 793 PROC_LOCK(td->td_proc); 794 tdsignal(td, SIGPIPE); 795 PROC_UNLOCK(td->td_proc); 796 } 797 } 798 if (error == 0) 799 td->td_retval[0] = len - auio.uio_resid; 800 #ifdef KTRACE 801 if (ktruio != NULL) { 802 ktruio->uio_resid = td->td_retval[0]; 803 ktrgenio(s, UIO_WRITE, ktruio, error); 804 } 805 #endif 806 bad: 807 fdrop(fp, td); 808 return (error); 809 } 810 811 int 812 sys_sendto(struct thread *td, struct sendto_args *uap) 813 { 814 struct msghdr msg; 815 struct iovec aiov; 816 817 msg.msg_name = uap->to; 818 msg.msg_namelen = uap->tolen; 819 msg.msg_iov = &aiov; 820 msg.msg_iovlen = 1; 821 msg.msg_control = 0; 822 #ifdef COMPAT_OLDSOCK 823 msg.msg_flags = 0; 824 #endif 825 aiov.iov_base = uap->buf; 826 aiov.iov_len = uap->len; 827 return (sendit(td, uap->s, &msg, uap->flags)); 828 } 829 830 #ifdef COMPAT_OLDSOCK 831 int 832 osend(struct thread *td, struct osend_args *uap) 833 { 834 struct msghdr msg; 835 struct iovec aiov; 836 837 msg.msg_name = 0; 838 msg.msg_namelen = 0; 839 msg.msg_iov = &aiov; 840 msg.msg_iovlen = 1; 841 aiov.iov_base = uap->buf; 842 aiov.iov_len = uap->len; 843 msg.msg_control = 0; 844 msg.msg_flags = 0; 845 return (sendit(td, uap->s, &msg, uap->flags)); 846 } 847 848 int 849 osendmsg(struct thread *td, struct osendmsg_args *uap) 850 { 851 struct msghdr msg; 852 struct iovec *iov; 853 int error; 854 855 error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); 856 if (error != 0) 857 return (error); 858 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); 859 if (error != 0) 860 return (error); 861 msg.msg_iov = iov; 862 msg.msg_flags = MSG_COMPAT; 863 error = sendit(td, uap->s, &msg, uap->flags); 864 free(iov, M_IOV); 865 return (error); 866 } 867 #endif 868 869 int 870 sys_sendmsg(struct thread *td, struct sendmsg_args *uap) 871 { 872 struct msghdr msg; 873 struct iovec *iov; 874 int error; 875 876 error = copyin(uap->msg, &msg, sizeof (msg)); 877 if (error != 0) 878 return (error); 879 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); 880 if (error != 0) 881 return (error); 882 msg.msg_iov = iov; 883 #ifdef COMPAT_OLDSOCK 884 msg.msg_flags = 0; 885 #endif 886 error = sendit(td, uap->s, &msg, uap->flags); 887 free(iov, M_IOV); 888 return (error); 889 } 890 891 int 892 kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg, 893 struct mbuf **controlp) 894 { 895 struct uio auio; 896 struct iovec *iov; 897 struct mbuf *m, *control = NULL; 898 caddr_t ctlbuf; 899 struct file *fp; 900 struct socket *so; 901 struct sockaddr *fromsa = NULL; 902 #ifdef KTRACE 903 struct uio *ktruio = NULL; 904 #endif 905 ssize_t len; 906 int error, i; 907 908 if (controlp != NULL) 909 *controlp = NULL; 910 911 AUDIT_ARG_FD(s); 912 error = getsock_cap(td, s, &cap_recv_rights, 913 &fp, NULL, NULL); 914 if (error != 0) 915 return (error); 916 so = fp->f_data; 917 918 #ifdef MAC 919 error = mac_socket_check_receive(td->td_ucred, so); 920 if (error != 0) { 921 fdrop(fp, td); 922 return (error); 923 } 924 #endif 925 926 auio.uio_iov = mp->msg_iov; 927 auio.uio_iovcnt = mp->msg_iovlen; 928 auio.uio_segflg = UIO_USERSPACE; 929 auio.uio_rw = UIO_READ; 930 auio.uio_td = td; 931 auio.uio_offset = 0; /* XXX */ 932 auio.uio_resid = 0; 933 iov = mp->msg_iov; 934 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 935 if ((auio.uio_resid += iov->iov_len) < 0) { 936 fdrop(fp, td); 937 return (EINVAL); 938 } 939 } 940 #ifdef KTRACE 941 if (KTRPOINT(td, KTR_GENIO)) 942 ktruio = cloneuio(&auio); 943 #endif 944 len = auio.uio_resid; 945 error = soreceive(so, &fromsa, &auio, NULL, 946 (mp->msg_control || controlp) ? &control : NULL, 947 &mp->msg_flags); 948 if (error != 0) { 949 if (auio.uio_resid != len && (error == ERESTART || 950 error == EINTR || error == EWOULDBLOCK)) 951 error = 0; 952 } 953 if (fromsa != NULL) 954 AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa); 955 #ifdef KTRACE 956 if (ktruio != NULL) { 957 ktruio->uio_resid = len - auio.uio_resid; 958 ktrgenio(s, UIO_READ, ktruio, error); 959 } 960 #endif 961 if (error != 0) 962 goto out; 963 td->td_retval[0] = len - auio.uio_resid; 964 if (mp->msg_name) { 965 len = mp->msg_namelen; 966 if (len <= 0 || fromsa == NULL) 967 len = 0; 968 else { 969 /* save sa_len before it is destroyed by MSG_COMPAT */ 970 len = MIN(len, fromsa->sa_len); 971 #ifdef COMPAT_OLDSOCK 972 if (mp->msg_flags & MSG_COMPAT) 973 ((struct osockaddr *)fromsa)->sa_family = 974 fromsa->sa_family; 975 #endif 976 if (fromseg == UIO_USERSPACE) { 977 error = copyout(fromsa, mp->msg_name, 978 (unsigned)len); 979 if (error != 0) 980 goto out; 981 } else 982 bcopy(fromsa, mp->msg_name, len); 983 } 984 mp->msg_namelen = len; 985 } 986 if (mp->msg_control && controlp == NULL) { 987 #ifdef COMPAT_OLDSOCK 988 /* 989 * We assume that old recvmsg calls won't receive access 990 * rights and other control info, esp. as control info 991 * is always optional and those options didn't exist in 4.3. 992 * If we receive rights, trim the cmsghdr; anything else 993 * is tossed. 994 */ 995 if (control && mp->msg_flags & MSG_COMPAT) { 996 if (mtod(control, struct cmsghdr *)->cmsg_level != 997 SOL_SOCKET || 998 mtod(control, struct cmsghdr *)->cmsg_type != 999 SCM_RIGHTS) { 1000 mp->msg_controllen = 0; 1001 goto out; 1002 } 1003 control->m_len -= sizeof (struct cmsghdr); 1004 control->m_data += sizeof (struct cmsghdr); 1005 } 1006 #endif 1007 len = mp->msg_controllen; 1008 m = control; 1009 mp->msg_controllen = 0; 1010 ctlbuf = mp->msg_control; 1011 1012 while (m && len > 0) { 1013 unsigned int tocopy; 1014 1015 if (len >= m->m_len) 1016 tocopy = m->m_len; 1017 else { 1018 mp->msg_flags |= MSG_CTRUNC; 1019 tocopy = len; 1020 } 1021 1022 if ((error = copyout(mtod(m, caddr_t), 1023 ctlbuf, tocopy)) != 0) 1024 goto out; 1025 1026 ctlbuf += tocopy; 1027 len -= tocopy; 1028 m = m->m_next; 1029 } 1030 mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control; 1031 } 1032 out: 1033 fdrop(fp, td); 1034 #ifdef KTRACE 1035 if (fromsa && KTRPOINT(td, KTR_STRUCT)) 1036 ktrsockaddr(fromsa); 1037 #endif 1038 free(fromsa, M_SONAME); 1039 1040 if (error == 0 && controlp != NULL) 1041 *controlp = control; 1042 else if (control) 1043 m_freem(control); 1044 1045 return (error); 1046 } 1047 1048 static int 1049 recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp) 1050 { 1051 int error; 1052 1053 error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL); 1054 if (error != 0) 1055 return (error); 1056 if (namelenp != NULL) { 1057 error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t)); 1058 #ifdef COMPAT_OLDSOCK 1059 if (mp->msg_flags & MSG_COMPAT) 1060 error = 0; /* old recvfrom didn't check */ 1061 #endif 1062 } 1063 return (error); 1064 } 1065 1066 int 1067 sys_recvfrom(struct thread *td, struct recvfrom_args *uap) 1068 { 1069 struct msghdr msg; 1070 struct iovec aiov; 1071 int error; 1072 1073 if (uap->fromlenaddr) { 1074 error = copyin(uap->fromlenaddr, 1075 &msg.msg_namelen, sizeof (msg.msg_namelen)); 1076 if (error != 0) 1077 goto done2; 1078 } else { 1079 msg.msg_namelen = 0; 1080 } 1081 msg.msg_name = uap->from; 1082 msg.msg_iov = &aiov; 1083 msg.msg_iovlen = 1; 1084 aiov.iov_base = uap->buf; 1085 aiov.iov_len = uap->len; 1086 msg.msg_control = 0; 1087 msg.msg_flags = uap->flags; 1088 error = recvit(td, uap->s, &msg, uap->fromlenaddr); 1089 done2: 1090 return (error); 1091 } 1092 1093 #ifdef COMPAT_OLDSOCK 1094 int 1095 orecvfrom(struct thread *td, struct recvfrom_args *uap) 1096 { 1097 1098 uap->flags |= MSG_COMPAT; 1099 return (sys_recvfrom(td, uap)); 1100 } 1101 #endif 1102 1103 #ifdef COMPAT_OLDSOCK 1104 int 1105 orecv(struct thread *td, struct orecv_args *uap) 1106 { 1107 struct msghdr msg; 1108 struct iovec aiov; 1109 1110 msg.msg_name = 0; 1111 msg.msg_namelen = 0; 1112 msg.msg_iov = &aiov; 1113 msg.msg_iovlen = 1; 1114 aiov.iov_base = uap->buf; 1115 aiov.iov_len = uap->len; 1116 msg.msg_control = 0; 1117 msg.msg_flags = uap->flags; 1118 return (recvit(td, uap->s, &msg, NULL)); 1119 } 1120 1121 /* 1122 * Old recvmsg. This code takes advantage of the fact that the old msghdr 1123 * overlays the new one, missing only the flags, and with the (old) access 1124 * rights where the control fields are now. 1125 */ 1126 int 1127 orecvmsg(struct thread *td, struct orecvmsg_args *uap) 1128 { 1129 struct msghdr msg; 1130 struct iovec *iov; 1131 int error; 1132 1133 error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); 1134 if (error != 0) 1135 return (error); 1136 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); 1137 if (error != 0) 1138 return (error); 1139 msg.msg_flags = uap->flags | MSG_COMPAT; 1140 msg.msg_iov = iov; 1141 error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen); 1142 if (msg.msg_controllen && error == 0) 1143 error = copyout(&msg.msg_controllen, 1144 &uap->msg->msg_accrightslen, sizeof (int)); 1145 free(iov, M_IOV); 1146 return (error); 1147 } 1148 #endif 1149 1150 int 1151 sys_recvmsg(struct thread *td, struct recvmsg_args *uap) 1152 { 1153 struct msghdr msg; 1154 struct iovec *uiov, *iov; 1155 int error; 1156 1157 error = copyin(uap->msg, &msg, sizeof (msg)); 1158 if (error != 0) 1159 return (error); 1160 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); 1161 if (error != 0) 1162 return (error); 1163 msg.msg_flags = uap->flags; 1164 #ifdef COMPAT_OLDSOCK 1165 msg.msg_flags &= ~MSG_COMPAT; 1166 #endif 1167 uiov = msg.msg_iov; 1168 msg.msg_iov = iov; 1169 error = recvit(td, uap->s, &msg, NULL); 1170 if (error == 0) { 1171 msg.msg_iov = uiov; 1172 error = copyout(&msg, uap->msg, sizeof(msg)); 1173 } 1174 free(iov, M_IOV); 1175 return (error); 1176 } 1177 1178 int 1179 sys_shutdown(struct thread *td, struct shutdown_args *uap) 1180 { 1181 1182 return (kern_shutdown(td, uap->s, uap->how)); 1183 } 1184 1185 int 1186 kern_shutdown(struct thread *td, int s, int how) 1187 { 1188 struct socket *so; 1189 struct file *fp; 1190 int error; 1191 1192 AUDIT_ARG_FD(s); 1193 error = getsock_cap(td, s, &cap_shutdown_rights, 1194 &fp, NULL, NULL); 1195 if (error == 0) { 1196 so = fp->f_data; 1197 error = soshutdown(so, how); 1198 /* 1199 * Previous versions did not return ENOTCONN, but 0 in 1200 * case the socket was not connected. Some important 1201 * programs like syslogd up to r279016, 2015-02-19, 1202 * still depend on this behavior. 1203 */ 1204 if (error == ENOTCONN && 1205 td->td_proc->p_osrel < P_OSREL_SHUTDOWN_ENOTCONN) 1206 error = 0; 1207 fdrop(fp, td); 1208 } 1209 return (error); 1210 } 1211 1212 int 1213 sys_setsockopt(struct thread *td, struct setsockopt_args *uap) 1214 { 1215 1216 return (kern_setsockopt(td, uap->s, uap->level, uap->name, 1217 uap->val, UIO_USERSPACE, uap->valsize)); 1218 } 1219 1220 int 1221 kern_setsockopt(struct thread *td, int s, int level, int name, void *val, 1222 enum uio_seg valseg, socklen_t valsize) 1223 { 1224 struct socket *so; 1225 struct file *fp; 1226 struct sockopt sopt; 1227 int error; 1228 1229 if (val == NULL && valsize != 0) 1230 return (EFAULT); 1231 if ((int)valsize < 0) 1232 return (EINVAL); 1233 1234 sopt.sopt_dir = SOPT_SET; 1235 sopt.sopt_level = level; 1236 sopt.sopt_name = name; 1237 sopt.sopt_val = val; 1238 sopt.sopt_valsize = valsize; 1239 switch (valseg) { 1240 case UIO_USERSPACE: 1241 sopt.sopt_td = td; 1242 break; 1243 case UIO_SYSSPACE: 1244 sopt.sopt_td = NULL; 1245 break; 1246 default: 1247 panic("kern_setsockopt called with bad valseg"); 1248 } 1249 1250 AUDIT_ARG_FD(s); 1251 error = getsock_cap(td, s, &cap_setsockopt_rights, 1252 &fp, NULL, NULL); 1253 if (error == 0) { 1254 so = fp->f_data; 1255 error = sosetopt(so, &sopt); 1256 fdrop(fp, td); 1257 } 1258 return(error); 1259 } 1260 1261 int 1262 sys_getsockopt(struct thread *td, struct getsockopt_args *uap) 1263 { 1264 socklen_t valsize; 1265 int error; 1266 1267 if (uap->val) { 1268 error = copyin(uap->avalsize, &valsize, sizeof (valsize)); 1269 if (error != 0) 1270 return (error); 1271 } 1272 1273 error = kern_getsockopt(td, uap->s, uap->level, uap->name, 1274 uap->val, UIO_USERSPACE, &valsize); 1275 1276 if (error == 0) 1277 error = copyout(&valsize, uap->avalsize, sizeof (valsize)); 1278 return (error); 1279 } 1280 1281 /* 1282 * Kernel version of getsockopt. 1283 * optval can be a userland or userspace. optlen is always a kernel pointer. 1284 */ 1285 int 1286 kern_getsockopt(struct thread *td, int s, int level, int name, void *val, 1287 enum uio_seg valseg, socklen_t *valsize) 1288 { 1289 struct socket *so; 1290 struct file *fp; 1291 struct sockopt sopt; 1292 int error; 1293 1294 if (val == NULL) 1295 *valsize = 0; 1296 if ((int)*valsize < 0) 1297 return (EINVAL); 1298 1299 sopt.sopt_dir = SOPT_GET; 1300 sopt.sopt_level = level; 1301 sopt.sopt_name = name; 1302 sopt.sopt_val = val; 1303 sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */ 1304 switch (valseg) { 1305 case UIO_USERSPACE: 1306 sopt.sopt_td = td; 1307 break; 1308 case UIO_SYSSPACE: 1309 sopt.sopt_td = NULL; 1310 break; 1311 default: 1312 panic("kern_getsockopt called with bad valseg"); 1313 } 1314 1315 AUDIT_ARG_FD(s); 1316 error = getsock_cap(td, s, &cap_getsockopt_rights, 1317 &fp, NULL, NULL); 1318 if (error == 0) { 1319 so = fp->f_data; 1320 error = sogetopt(so, &sopt); 1321 *valsize = sopt.sopt_valsize; 1322 fdrop(fp, td); 1323 } 1324 return (error); 1325 } 1326 1327 /* 1328 * getsockname1() - Get socket name. 1329 */ 1330 static int 1331 getsockname1(struct thread *td, struct getsockname_args *uap, int compat) 1332 { 1333 struct sockaddr *sa; 1334 socklen_t len; 1335 int error; 1336 1337 error = copyin(uap->alen, &len, sizeof(len)); 1338 if (error != 0) 1339 return (error); 1340 1341 error = kern_getsockname(td, uap->fdes, &sa, &len); 1342 if (error != 0) 1343 return (error); 1344 1345 if (len != 0) { 1346 #ifdef COMPAT_OLDSOCK 1347 if (compat) 1348 ((struct osockaddr *)sa)->sa_family = sa->sa_family; 1349 #endif 1350 error = copyout(sa, uap->asa, (u_int)len); 1351 } 1352 free(sa, M_SONAME); 1353 if (error == 0) 1354 error = copyout(&len, uap->alen, sizeof(len)); 1355 return (error); 1356 } 1357 1358 int 1359 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, 1360 socklen_t *alen) 1361 { 1362 struct socket *so; 1363 struct file *fp; 1364 socklen_t len; 1365 int error; 1366 1367 AUDIT_ARG_FD(fd); 1368 error = getsock_cap(td, fd, &cap_getsockname_rights, 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 socklen_t len; 1451 int error; 1452 1453 AUDIT_ARG_FD(fd); 1454 error = getsock_cap(td, fd, &cap_getpeername_rights, 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