1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 1995 Søren Schmidt 5 * 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 /* XXX we use functions that might not exist. */ 33 #include "opt_compat.h" 34 #include "opt_inet6.h" 35 36 #include <sys/param.h> 37 #include <sys/proc.h> 38 #include <sys/systm.h> 39 #include <sys/sysproto.h> 40 #include <sys/capsicum.h> 41 #include <sys/fcntl.h> 42 #include <sys/file.h> 43 #include <sys/limits.h> 44 #include <sys/lock.h> 45 #include <sys/malloc.h> 46 #include <sys/mutex.h> 47 #include <sys/mbuf.h> 48 #include <sys/socket.h> 49 #include <sys/socketvar.h> 50 #include <sys/syscallsubr.h> 51 #include <sys/uio.h> 52 #include <sys/stat.h> 53 #include <sys/syslog.h> 54 #include <sys/un.h> 55 #include <sys/unistd.h> 56 57 #include <security/audit/audit.h> 58 59 #include <net/if.h> 60 #include <net/vnet.h> 61 #include <netinet/in.h> 62 #include <netinet/in_systm.h> 63 #include <netinet/ip.h> 64 #include <netinet/tcp.h> 65 #ifdef INET6 66 #include <netinet/ip6.h> 67 #include <netinet6/ip6_var.h> 68 #endif 69 70 #ifdef COMPAT_LINUX32 71 #include <machine/../linux32/linux.h> 72 #include <machine/../linux32/linux32_proto.h> 73 #else 74 #include <machine/../linux/linux.h> 75 #include <machine/../linux/linux_proto.h> 76 #endif 77 #include <compat/linux/linux_common.h> 78 #include <compat/linux/linux_file.h> 79 #include <compat/linux/linux_mib.h> 80 #include <compat/linux/linux_socket.h> 81 #include <compat/linux/linux_timer.h> 82 #include <compat/linux/linux_util.h> 83 84 static int linux_sendmsg_common(struct thread *, l_int, struct l_msghdr *, 85 l_uint); 86 static int linux_recvmsg_common(struct thread *, l_int, struct l_msghdr *, 87 l_uint, struct msghdr *); 88 static int linux_set_socket_flags(int, int *); 89 90 91 static int 92 linux_to_bsd_sockopt_level(int level) 93 { 94 95 switch (level) { 96 case LINUX_SOL_SOCKET: 97 return (SOL_SOCKET); 98 } 99 return (level); 100 } 101 102 static int 103 bsd_to_linux_sockopt_level(int level) 104 { 105 106 switch (level) { 107 case SOL_SOCKET: 108 return (LINUX_SOL_SOCKET); 109 } 110 return (level); 111 } 112 113 static int 114 linux_to_bsd_ip_sockopt(int opt) 115 { 116 117 switch (opt) { 118 case LINUX_IP_TOS: 119 return (IP_TOS); 120 case LINUX_IP_TTL: 121 return (IP_TTL); 122 case LINUX_IP_OPTIONS: 123 return (IP_OPTIONS); 124 case LINUX_IP_MULTICAST_IF: 125 return (IP_MULTICAST_IF); 126 case LINUX_IP_MULTICAST_TTL: 127 return (IP_MULTICAST_TTL); 128 case LINUX_IP_MULTICAST_LOOP: 129 return (IP_MULTICAST_LOOP); 130 case LINUX_IP_ADD_MEMBERSHIP: 131 return (IP_ADD_MEMBERSHIP); 132 case LINUX_IP_DROP_MEMBERSHIP: 133 return (IP_DROP_MEMBERSHIP); 134 case LINUX_IP_HDRINCL: 135 return (IP_HDRINCL); 136 } 137 return (-1); 138 } 139 140 static int 141 linux_to_bsd_ip6_sockopt(int opt) 142 { 143 144 switch (opt) { 145 case LINUX_IPV6_NEXTHOP: 146 return (IPV6_NEXTHOP); 147 case LINUX_IPV6_UNICAST_HOPS: 148 return (IPV6_UNICAST_HOPS); 149 case LINUX_IPV6_MULTICAST_IF: 150 return (IPV6_MULTICAST_IF); 151 case LINUX_IPV6_MULTICAST_HOPS: 152 return (IPV6_MULTICAST_HOPS); 153 case LINUX_IPV6_MULTICAST_LOOP: 154 return (IPV6_MULTICAST_LOOP); 155 case LINUX_IPV6_ADD_MEMBERSHIP: 156 return (IPV6_JOIN_GROUP); 157 case LINUX_IPV6_DROP_MEMBERSHIP: 158 return (IPV6_LEAVE_GROUP); 159 case LINUX_IPV6_V6ONLY: 160 return (IPV6_V6ONLY); 161 case LINUX_IPV6_DONTFRAG: 162 return (IPV6_DONTFRAG); 163 #if 0 164 case LINUX_IPV6_CHECKSUM: 165 return (IPV6_CHECKSUM); 166 case LINUX_IPV6_RECVPKTINFO: 167 return (IPV6_RECVPKTINFO); 168 case LINUX_IPV6_PKTINFO: 169 return (IPV6_PKTINFO); 170 case LINUX_IPV6_RECVHOPLIMIT: 171 return (IPV6_RECVHOPLIMIT); 172 case LINUX_IPV6_HOPLIMIT: 173 return (IPV6_HOPLIMIT); 174 case LINUX_IPV6_RECVHOPOPTS: 175 return (IPV6_RECVHOPOPTS); 176 case LINUX_IPV6_HOPOPTS: 177 return (IPV6_HOPOPTS); 178 case LINUX_IPV6_RTHDRDSTOPTS: 179 return (IPV6_RTHDRDSTOPTS); 180 case LINUX_IPV6_RECVRTHDR: 181 return (IPV6_RECVRTHDR); 182 case LINUX_IPV6_RTHDR: 183 return (IPV6_RTHDR); 184 case LINUX_IPV6_RECVDSTOPTS: 185 return (IPV6_RECVDSTOPTS); 186 case LINUX_IPV6_DSTOPTS: 187 return (IPV6_DSTOPTS); 188 case LINUX_IPV6_RECVPATHMTU: 189 return (IPV6_RECVPATHMTU); 190 case LINUX_IPV6_PATHMTU: 191 return (IPV6_PATHMTU); 192 #endif 193 } 194 return (-1); 195 } 196 197 static int 198 linux_to_bsd_so_sockopt(int opt) 199 { 200 201 switch (opt) { 202 case LINUX_SO_DEBUG: 203 return (SO_DEBUG); 204 case LINUX_SO_REUSEADDR: 205 return (SO_REUSEADDR); 206 case LINUX_SO_TYPE: 207 return (SO_TYPE); 208 case LINUX_SO_ERROR: 209 return (SO_ERROR); 210 case LINUX_SO_DONTROUTE: 211 return (SO_DONTROUTE); 212 case LINUX_SO_BROADCAST: 213 return (SO_BROADCAST); 214 case LINUX_SO_SNDBUF: 215 return (SO_SNDBUF); 216 case LINUX_SO_RCVBUF: 217 return (SO_RCVBUF); 218 case LINUX_SO_KEEPALIVE: 219 return (SO_KEEPALIVE); 220 case LINUX_SO_OOBINLINE: 221 return (SO_OOBINLINE); 222 case LINUX_SO_LINGER: 223 return (SO_LINGER); 224 case LINUX_SO_PEERCRED: 225 return (LOCAL_PEERCRED); 226 case LINUX_SO_RCVLOWAT: 227 return (SO_RCVLOWAT); 228 case LINUX_SO_SNDLOWAT: 229 return (SO_SNDLOWAT); 230 case LINUX_SO_RCVTIMEO: 231 return (SO_RCVTIMEO); 232 case LINUX_SO_SNDTIMEO: 233 return (SO_SNDTIMEO); 234 case LINUX_SO_TIMESTAMP: 235 return (SO_TIMESTAMP); 236 case LINUX_SO_ACCEPTCONN: 237 return (SO_ACCEPTCONN); 238 } 239 return (-1); 240 } 241 242 static int 243 linux_to_bsd_tcp_sockopt(int opt) 244 { 245 246 switch (opt) { 247 case LINUX_TCP_NODELAY: 248 return (TCP_NODELAY); 249 case LINUX_TCP_MAXSEG: 250 return (TCP_MAXSEG); 251 case LINUX_TCP_CORK: 252 return (TCP_NOPUSH); 253 case LINUX_TCP_KEEPIDLE: 254 return (TCP_KEEPIDLE); 255 case LINUX_TCP_KEEPINTVL: 256 return (TCP_KEEPINTVL); 257 case LINUX_TCP_KEEPCNT: 258 return (TCP_KEEPCNT); 259 case LINUX_TCP_MD5SIG: 260 return (TCP_MD5SIG); 261 } 262 return (-1); 263 } 264 265 static int 266 linux_to_bsd_msg_flags(int flags) 267 { 268 int ret_flags = 0; 269 270 if (flags & LINUX_MSG_OOB) 271 ret_flags |= MSG_OOB; 272 if (flags & LINUX_MSG_PEEK) 273 ret_flags |= MSG_PEEK; 274 if (flags & LINUX_MSG_DONTROUTE) 275 ret_flags |= MSG_DONTROUTE; 276 if (flags & LINUX_MSG_CTRUNC) 277 ret_flags |= MSG_CTRUNC; 278 if (flags & LINUX_MSG_TRUNC) 279 ret_flags |= MSG_TRUNC; 280 if (flags & LINUX_MSG_DONTWAIT) 281 ret_flags |= MSG_DONTWAIT; 282 if (flags & LINUX_MSG_EOR) 283 ret_flags |= MSG_EOR; 284 if (flags & LINUX_MSG_WAITALL) 285 ret_flags |= MSG_WAITALL; 286 if (flags & LINUX_MSG_NOSIGNAL) 287 ret_flags |= MSG_NOSIGNAL; 288 #if 0 /* not handled */ 289 if (flags & LINUX_MSG_PROXY) 290 ; 291 if (flags & LINUX_MSG_FIN) 292 ; 293 if (flags & LINUX_MSG_SYN) 294 ; 295 if (flags & LINUX_MSG_CONFIRM) 296 ; 297 if (flags & LINUX_MSG_RST) 298 ; 299 if (flags & LINUX_MSG_ERRQUEUE) 300 ; 301 #endif 302 return (ret_flags); 303 } 304 305 static int 306 linux_to_bsd_cmsg_type(int cmsg_type) 307 { 308 309 switch (cmsg_type) { 310 case LINUX_SCM_RIGHTS: 311 return (SCM_RIGHTS); 312 case LINUX_SCM_CREDENTIALS: 313 return (SCM_CREDS); 314 } 315 return (-1); 316 } 317 318 static int 319 bsd_to_linux_cmsg_type(int cmsg_type) 320 { 321 322 switch (cmsg_type) { 323 case SCM_RIGHTS: 324 return (LINUX_SCM_RIGHTS); 325 case SCM_CREDS: 326 return (LINUX_SCM_CREDENTIALS); 327 case SCM_TIMESTAMP: 328 return (LINUX_SCM_TIMESTAMP); 329 } 330 return (-1); 331 } 332 333 static int 334 linux_to_bsd_msghdr(struct msghdr *bhdr, const struct l_msghdr *lhdr) 335 { 336 if (lhdr->msg_controllen > INT_MAX) 337 return (ENOBUFS); 338 339 bhdr->msg_name = PTRIN(lhdr->msg_name); 340 bhdr->msg_namelen = lhdr->msg_namelen; 341 bhdr->msg_iov = PTRIN(lhdr->msg_iov); 342 bhdr->msg_iovlen = lhdr->msg_iovlen; 343 bhdr->msg_control = PTRIN(lhdr->msg_control); 344 345 /* 346 * msg_controllen is skipped since BSD and LINUX control messages 347 * are potentially different sizes (e.g. the cred structure used 348 * by SCM_CREDS is different between the two operating system). 349 * 350 * The caller can set it (if necessary) after converting all the 351 * control messages. 352 */ 353 354 bhdr->msg_flags = linux_to_bsd_msg_flags(lhdr->msg_flags); 355 return (0); 356 } 357 358 static int 359 bsd_to_linux_msghdr(const struct msghdr *bhdr, struct l_msghdr *lhdr) 360 { 361 lhdr->msg_name = PTROUT(bhdr->msg_name); 362 lhdr->msg_namelen = bhdr->msg_namelen; 363 lhdr->msg_iov = PTROUT(bhdr->msg_iov); 364 lhdr->msg_iovlen = bhdr->msg_iovlen; 365 lhdr->msg_control = PTROUT(bhdr->msg_control); 366 367 /* 368 * msg_controllen is skipped since BSD and LINUX control messages 369 * are potentially different sizes (e.g. the cred structure used 370 * by SCM_CREDS is different between the two operating system). 371 * 372 * The caller can set it (if necessary) after converting all the 373 * control messages. 374 */ 375 376 /* msg_flags skipped */ 377 return (0); 378 } 379 380 static int 381 linux_set_socket_flags(int lflags, int *flags) 382 { 383 384 if (lflags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) 385 return (EINVAL); 386 if (lflags & LINUX_SOCK_NONBLOCK) 387 *flags |= SOCK_NONBLOCK; 388 if (lflags & LINUX_SOCK_CLOEXEC) 389 *flags |= SOCK_CLOEXEC; 390 return (0); 391 } 392 393 static int 394 linux_sendit(struct thread *td, int s, struct msghdr *mp, int flags, 395 struct mbuf *control, enum uio_seg segflg) 396 { 397 struct sockaddr *to; 398 int error, len; 399 400 if (mp->msg_name != NULL) { 401 len = mp->msg_namelen; 402 error = linux_to_bsd_sockaddr(mp->msg_name, &to, &len); 403 if (error != 0) 404 return (error); 405 mp->msg_name = to; 406 } else 407 to = NULL; 408 409 error = kern_sendit(td, s, mp, linux_to_bsd_msg_flags(flags), control, 410 segflg); 411 412 if (to) 413 free(to, M_SONAME); 414 return (error); 415 } 416 417 /* Return 0 if IP_HDRINCL is set for the given socket. */ 418 static int 419 linux_check_hdrincl(struct thread *td, int s) 420 { 421 int error, optval; 422 socklen_t size_val; 423 424 size_val = sizeof(optval); 425 error = kern_getsockopt(td, s, IPPROTO_IP, IP_HDRINCL, 426 &optval, UIO_SYSSPACE, &size_val); 427 if (error != 0) 428 return (error); 429 430 return (optval == 0); 431 } 432 433 /* 434 * Updated sendto() when IP_HDRINCL is set: 435 * tweak endian-dependent fields in the IP packet. 436 */ 437 static int 438 linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args) 439 { 440 /* 441 * linux_ip_copysize defines how many bytes we should copy 442 * from the beginning of the IP packet before we customize it for BSD. 443 * It should include all the fields we modify (ip_len and ip_off). 444 */ 445 #define linux_ip_copysize 8 446 447 struct ip *packet; 448 struct msghdr msg; 449 struct iovec aiov[1]; 450 int error; 451 452 /* Check that the packet isn't too big or too small. */ 453 if (linux_args->len < linux_ip_copysize || 454 linux_args->len > IP_MAXPACKET) 455 return (EINVAL); 456 457 packet = (struct ip *)malloc(linux_args->len, M_LINUX, M_WAITOK); 458 459 /* Make kernel copy of the packet to be sent */ 460 if ((error = copyin(PTRIN(linux_args->msg), packet, 461 linux_args->len))) 462 goto goout; 463 464 /* Convert fields from Linux to BSD raw IP socket format */ 465 packet->ip_len = linux_args->len; 466 packet->ip_off = ntohs(packet->ip_off); 467 468 /* Prepare the msghdr and iovec structures describing the new packet */ 469 msg.msg_name = PTRIN(linux_args->to); 470 msg.msg_namelen = linux_args->tolen; 471 msg.msg_iov = aiov; 472 msg.msg_iovlen = 1; 473 msg.msg_control = NULL; 474 msg.msg_flags = 0; 475 aiov[0].iov_base = (char *)packet; 476 aiov[0].iov_len = linux_args->len; 477 error = linux_sendit(td, linux_args->s, &msg, linux_args->flags, 478 NULL, UIO_SYSSPACE); 479 goout: 480 free(packet, M_LINUX); 481 return (error); 482 } 483 484 int 485 linux_socket(struct thread *td, struct linux_socket_args *args) 486 { 487 int domain, retval_socket, type; 488 489 type = args->type & LINUX_SOCK_TYPE_MASK; 490 if (type < 0 || type > LINUX_SOCK_MAX) 491 return (EINVAL); 492 retval_socket = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK, 493 &type); 494 if (retval_socket != 0) 495 return (retval_socket); 496 domain = linux_to_bsd_domain(args->domain); 497 if (domain == -1) 498 return (EAFNOSUPPORT); 499 500 retval_socket = kern_socket(td, domain, type, args->protocol); 501 if (retval_socket) 502 return (retval_socket); 503 504 if (type == SOCK_RAW 505 && (args->protocol == IPPROTO_RAW || args->protocol == 0) 506 && domain == PF_INET) { 507 /* It's a raw IP socket: set the IP_HDRINCL option. */ 508 int hdrincl; 509 510 hdrincl = 1; 511 /* We ignore any error returned by kern_setsockopt() */ 512 kern_setsockopt(td, td->td_retval[0], IPPROTO_IP, IP_HDRINCL, 513 &hdrincl, UIO_SYSSPACE, sizeof(hdrincl)); 514 } 515 #ifdef INET6 516 /* 517 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by default 518 * and some apps depend on this. So, set V6ONLY to 0 for Linux apps. 519 * For simplicity we do this unconditionally of the net.inet6.ip6.v6only 520 * sysctl value. 521 */ 522 if (domain == PF_INET6) { 523 int v6only; 524 525 v6only = 0; 526 /* We ignore any error returned by setsockopt() */ 527 kern_setsockopt(td, td->td_retval[0], IPPROTO_IPV6, IPV6_V6ONLY, 528 &v6only, UIO_SYSSPACE, sizeof(v6only)); 529 } 530 #endif 531 532 return (retval_socket); 533 } 534 535 int 536 linux_bind(struct thread *td, struct linux_bind_args *args) 537 { 538 struct sockaddr *sa; 539 int error; 540 541 error = linux_to_bsd_sockaddr(PTRIN(args->name), &sa, 542 &args->namelen); 543 if (error != 0) 544 return (error); 545 546 error = kern_bindat(td, AT_FDCWD, args->s, sa); 547 free(sa, M_SONAME); 548 549 /* XXX */ 550 if (error == EADDRNOTAVAIL && args->namelen != sizeof(struct sockaddr_in)) 551 return (EINVAL); 552 return (error); 553 } 554 555 int 556 linux_connect(struct thread *td, struct linux_connect_args *args) 557 { 558 struct socket *so; 559 struct sockaddr *sa; 560 struct file *fp; 561 u_int fflag; 562 int error; 563 564 error = linux_to_bsd_sockaddr(PTRIN(args->name), &sa, 565 &args->namelen); 566 if (error != 0) 567 return (error); 568 569 error = kern_connectat(td, AT_FDCWD, args->s, sa); 570 free(sa, M_SONAME); 571 if (error != EISCONN) 572 return (error); 573 574 /* 575 * Linux doesn't return EISCONN the first time it occurs, 576 * when on a non-blocking socket. Instead it returns the 577 * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. 578 */ 579 error = getsock_cap(td, args->s, &cap_connect_rights, 580 &fp, &fflag, NULL); 581 if (error != 0) 582 return (error); 583 584 error = EISCONN; 585 so = fp->f_data; 586 if (fflag & FNONBLOCK) { 587 SOCK_LOCK(so); 588 if (so->so_emuldata == 0) 589 error = so->so_error; 590 so->so_emuldata = (void *)1; 591 SOCK_UNLOCK(so); 592 } 593 fdrop(fp, td); 594 595 return (error); 596 } 597 598 int 599 linux_listen(struct thread *td, struct linux_listen_args *args) 600 { 601 602 return (kern_listen(td, args->s, args->backlog)); 603 } 604 605 static int 606 linux_accept_common(struct thread *td, int s, l_uintptr_t addr, 607 l_uintptr_t namelen, int flags) 608 { 609 struct l_sockaddr *lsa; 610 struct sockaddr *sa; 611 struct file *fp; 612 int bflags, len; 613 struct socket *so; 614 int error, error1; 615 616 bflags = 0; 617 error = linux_set_socket_flags(flags, &bflags); 618 if (error != 0) 619 return (error); 620 621 sa = NULL; 622 if (PTRIN(addr) == NULL) { 623 len = 0; 624 error = kern_accept4(td, s, NULL, NULL, bflags, NULL); 625 } else { 626 error = copyin(PTRIN(namelen), &len, sizeof(len)); 627 if (error != 0) 628 return (error); 629 if (len < 0) 630 return (EINVAL); 631 error = kern_accept4(td, s, &sa, &len, bflags, &fp); 632 if (error == 0) 633 fdrop(fp, td); 634 } 635 636 if (error != 0) { 637 /* 638 * XXX. This is wrong, different sockaddr structures 639 * have different sizes. 640 */ 641 if (error == EFAULT && namelen != sizeof(struct sockaddr_in)) 642 { 643 error = EINVAL; 644 goto out; 645 } 646 if (error == EINVAL) { 647 error1 = getsock_cap(td, s, &cap_accept_rights, &fp, NULL, NULL); 648 if (error1 != 0) { 649 error = error1; 650 goto out; 651 } 652 so = fp->f_data; 653 if (so->so_type == SOCK_DGRAM) 654 error = EOPNOTSUPP; 655 fdrop(fp, td); 656 } 657 goto out; 658 } 659 660 if (len != 0 && error == 0) { 661 error = bsd_to_linux_sockaddr(sa, &lsa, len); 662 if (error == 0) 663 error = copyout(lsa, PTRIN(addr), len); 664 free(lsa, M_SONAME); 665 } 666 667 free(sa, M_SONAME); 668 669 out: 670 if (error != 0) { 671 (void)kern_close(td, td->td_retval[0]); 672 td->td_retval[0] = 0; 673 } 674 return (error); 675 } 676 677 int 678 linux_accept(struct thread *td, struct linux_accept_args *args) 679 { 680 681 return (linux_accept_common(td, args->s, args->addr, 682 args->namelen, 0)); 683 } 684 685 int 686 linux_accept4(struct thread *td, struct linux_accept4_args *args) 687 { 688 689 return (linux_accept_common(td, args->s, args->addr, 690 args->namelen, args->flags)); 691 } 692 693 int 694 linux_getsockname(struct thread *td, struct linux_getsockname_args *args) 695 { 696 struct l_sockaddr *lsa; 697 struct sockaddr *sa; 698 int len, error; 699 700 error = copyin(PTRIN(args->namelen), &len, sizeof(len)); 701 if (error != 0) 702 return (error); 703 704 error = kern_getsockname(td, args->s, &sa, &len); 705 if (error != 0) 706 return (error); 707 708 if (len != 0) { 709 error = bsd_to_linux_sockaddr(sa, &lsa, len); 710 if (error == 0) 711 error = copyout(lsa, PTRIN(args->addr), 712 len); 713 free(lsa, M_SONAME); 714 } 715 716 free(sa, M_SONAME); 717 if (error == 0) 718 error = copyout(&len, PTRIN(args->namelen), sizeof(len)); 719 return (error); 720 } 721 722 int 723 linux_getpeername(struct thread *td, struct linux_getpeername_args *args) 724 { 725 struct l_sockaddr *lsa; 726 struct sockaddr *sa; 727 int len, error; 728 729 error = copyin(PTRIN(args->namelen), &len, sizeof(len)); 730 if (error != 0) 731 return (error); 732 if (len < 0) 733 return (EINVAL); 734 735 error = kern_getpeername(td, args->s, &sa, &len); 736 if (error != 0) 737 return (error); 738 739 if (len != 0) { 740 error = bsd_to_linux_sockaddr(sa, &lsa, len); 741 if (error == 0) 742 error = copyout(lsa, PTRIN(args->addr), 743 len); 744 free(lsa, M_SONAME); 745 } 746 747 free(sa, M_SONAME); 748 if (error == 0) 749 error = copyout(&len, PTRIN(args->namelen), sizeof(len)); 750 return (error); 751 } 752 753 int 754 linux_socketpair(struct thread *td, struct linux_socketpair_args *args) 755 { 756 int domain, error, sv[2], type; 757 758 domain = linux_to_bsd_domain(args->domain); 759 if (domain != PF_LOCAL) 760 return (EAFNOSUPPORT); 761 type = args->type & LINUX_SOCK_TYPE_MASK; 762 if (type < 0 || type > LINUX_SOCK_MAX) 763 return (EINVAL); 764 error = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK, 765 &type); 766 if (error != 0) 767 return (error); 768 if (args->protocol != 0 && args->protocol != PF_UNIX) { 769 770 /* 771 * Use of PF_UNIX as protocol argument is not right, 772 * but Linux does it. 773 * Do not map PF_UNIX as its Linux value is identical 774 * to FreeBSD one. 775 */ 776 return (EPROTONOSUPPORT); 777 } 778 error = kern_socketpair(td, domain, type, 0, sv); 779 if (error != 0) 780 return (error); 781 error = copyout(sv, PTRIN(args->rsv), 2 * sizeof(int)); 782 if (error != 0) { 783 (void)kern_close(td, sv[0]); 784 (void)kern_close(td, sv[1]); 785 } 786 return (error); 787 } 788 789 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 790 struct linux_send_args { 791 register_t s; 792 register_t msg; 793 register_t len; 794 register_t flags; 795 }; 796 797 static int 798 linux_send(struct thread *td, struct linux_send_args *args) 799 { 800 struct sendto_args /* { 801 int s; 802 caddr_t buf; 803 int len; 804 int flags; 805 caddr_t to; 806 int tolen; 807 } */ bsd_args; 808 struct file *fp; 809 int error, fflag; 810 811 bsd_args.s = args->s; 812 bsd_args.buf = (caddr_t)PTRIN(args->msg); 813 bsd_args.len = args->len; 814 bsd_args.flags = args->flags; 815 bsd_args.to = NULL; 816 bsd_args.tolen = 0; 817 error = sys_sendto(td, &bsd_args); 818 if (error == ENOTCONN) { 819 /* 820 * Linux doesn't return ENOTCONN for non-blocking sockets. 821 * Instead it returns the EAGAIN. 822 */ 823 error = getsock_cap(td, args->s, &cap_send_rights, &fp, 824 &fflag, NULL); 825 if (error == 0) { 826 if (fflag & FNONBLOCK) 827 error = EAGAIN; 828 fdrop(fp, td); 829 } 830 } 831 return (error); 832 } 833 834 struct linux_recv_args { 835 register_t s; 836 register_t msg; 837 register_t len; 838 register_t flags; 839 }; 840 841 static int 842 linux_recv(struct thread *td, struct linux_recv_args *args) 843 { 844 struct recvfrom_args /* { 845 int s; 846 caddr_t buf; 847 int len; 848 int flags; 849 struct sockaddr *from; 850 socklen_t fromlenaddr; 851 } */ bsd_args; 852 853 bsd_args.s = args->s; 854 bsd_args.buf = (caddr_t)PTRIN(args->msg); 855 bsd_args.len = args->len; 856 bsd_args.flags = linux_to_bsd_msg_flags(args->flags); 857 bsd_args.from = NULL; 858 bsd_args.fromlenaddr = 0; 859 return (sys_recvfrom(td, &bsd_args)); 860 } 861 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 862 863 int 864 linux_sendto(struct thread *td, struct linux_sendto_args *args) 865 { 866 struct msghdr msg; 867 struct iovec aiov; 868 869 if (linux_check_hdrincl(td, args->s) == 0) 870 /* IP_HDRINCL set, tweak the packet before sending */ 871 return (linux_sendto_hdrincl(td, args)); 872 873 msg.msg_name = PTRIN(args->to); 874 msg.msg_namelen = args->tolen; 875 msg.msg_iov = &aiov; 876 msg.msg_iovlen = 1; 877 msg.msg_control = NULL; 878 msg.msg_flags = 0; 879 aiov.iov_base = PTRIN(args->msg); 880 aiov.iov_len = args->len; 881 return (linux_sendit(td, args->s, &msg, args->flags, NULL, 882 UIO_USERSPACE)); 883 } 884 885 int 886 linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) 887 { 888 struct l_sockaddr *lsa; 889 struct sockaddr *sa; 890 struct msghdr msg; 891 struct iovec aiov; 892 int error, fromlen; 893 894 if (PTRIN(args->fromlen) != NULL) { 895 error = copyin(PTRIN(args->fromlen), &fromlen, 896 sizeof(fromlen)); 897 if (error != 0) 898 return (error); 899 if (fromlen < 0) 900 return (EINVAL); 901 sa = malloc(fromlen, M_SONAME, M_WAITOK); 902 } else { 903 fromlen = 0; 904 sa = NULL; 905 } 906 907 msg.msg_name = sa; 908 msg.msg_namelen = fromlen; 909 msg.msg_iov = &aiov; 910 msg.msg_iovlen = 1; 911 aiov.iov_base = PTRIN(args->buf); 912 aiov.iov_len = args->len; 913 msg.msg_control = 0; 914 msg.msg_flags = linux_to_bsd_msg_flags(args->flags); 915 916 error = kern_recvit(td, args->s, &msg, UIO_SYSSPACE, NULL); 917 if (error != 0) 918 goto out; 919 920 if (PTRIN(args->from) != NULL) { 921 error = bsd_to_linux_sockaddr(sa, &lsa, msg.msg_namelen); 922 if (error == 0) 923 error = copyout(lsa, PTRIN(args->from), 924 msg.msg_namelen); 925 free(lsa, M_SONAME); 926 } 927 928 if (error == 0 && PTRIN(args->fromlen) != NULL) 929 error = copyout(&msg.msg_namelen, PTRIN(args->fromlen), 930 sizeof(msg.msg_namelen)); 931 out: 932 free(sa, M_SONAME); 933 return (error); 934 } 935 936 static int 937 linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, 938 l_uint flags) 939 { 940 struct cmsghdr *cmsg; 941 struct mbuf *control; 942 struct msghdr msg; 943 struct l_cmsghdr linux_cmsg; 944 struct l_cmsghdr *ptr_cmsg; 945 struct l_msghdr linux_msg; 946 struct iovec *iov; 947 socklen_t datalen; 948 struct sockaddr *sa; 949 struct socket *so; 950 sa_family_t sa_family; 951 struct file *fp; 952 void *data; 953 l_size_t len; 954 l_size_t clen; 955 int error, fflag; 956 957 error = copyin(msghdr, &linux_msg, sizeof(linux_msg)); 958 if (error != 0) 959 return (error); 960 961 /* 962 * Some Linux applications (ping) define a non-NULL control data 963 * pointer, but a msg_controllen of 0, which is not allowed in the 964 * FreeBSD system call interface. NULL the msg_control pointer in 965 * order to handle this case. This should be checked, but allows the 966 * Linux ping to work. 967 */ 968 if (PTRIN(linux_msg.msg_control) != NULL && linux_msg.msg_controllen == 0) 969 linux_msg.msg_control = PTROUT(NULL); 970 971 error = linux_to_bsd_msghdr(&msg, &linux_msg); 972 if (error != 0) 973 return (error); 974 975 #ifdef COMPAT_LINUX32 976 error = linux32_copyiniov(PTRIN(msg.msg_iov), msg.msg_iovlen, 977 &iov, EMSGSIZE); 978 #else 979 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); 980 #endif 981 if (error != 0) 982 return (error); 983 984 control = NULL; 985 986 error = kern_getsockname(td, s, &sa, &datalen); 987 if (error != 0) 988 goto bad; 989 sa_family = sa->sa_family; 990 free(sa, M_SONAME); 991 992 if (flags & LINUX_MSG_OOB) { 993 error = EOPNOTSUPP; 994 if (sa_family == AF_UNIX) 995 goto bad; 996 997 error = getsock_cap(td, s, &cap_send_rights, &fp, 998 &fflag, NULL); 999 if (error != 0) 1000 goto bad; 1001 so = fp->f_data; 1002 if (so->so_type != SOCK_STREAM) 1003 error = EOPNOTSUPP; 1004 fdrop(fp, td); 1005 if (error != 0) 1006 goto bad; 1007 } 1008 1009 if (linux_msg.msg_controllen >= sizeof(struct l_cmsghdr)) { 1010 1011 error = ENOBUFS; 1012 control = m_get(M_WAITOK, MT_CONTROL); 1013 MCLGET(control, M_WAITOK); 1014 data = mtod(control, void *); 1015 datalen = 0; 1016 1017 ptr_cmsg = PTRIN(linux_msg.msg_control); 1018 clen = linux_msg.msg_controllen; 1019 do { 1020 error = copyin(ptr_cmsg, &linux_cmsg, 1021 sizeof(struct l_cmsghdr)); 1022 if (error != 0) 1023 goto bad; 1024 1025 error = EINVAL; 1026 if (linux_cmsg.cmsg_len < sizeof(struct l_cmsghdr) || 1027 linux_cmsg.cmsg_len > clen) 1028 goto bad; 1029 1030 if (datalen + CMSG_HDRSZ > MCLBYTES) 1031 goto bad; 1032 1033 /* 1034 * Now we support only SCM_RIGHTS and SCM_CRED, 1035 * so return EINVAL in any other cmsg_type 1036 */ 1037 cmsg = data; 1038 cmsg->cmsg_type = 1039 linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type); 1040 cmsg->cmsg_level = 1041 linux_to_bsd_sockopt_level(linux_cmsg.cmsg_level); 1042 if (cmsg->cmsg_type == -1 1043 || cmsg->cmsg_level != SOL_SOCKET) 1044 goto bad; 1045 1046 /* 1047 * Some applications (e.g. pulseaudio) attempt to 1048 * send ancillary data even if the underlying protocol 1049 * doesn't support it which is not allowed in the 1050 * FreeBSD system call interface. 1051 */ 1052 if (sa_family != AF_UNIX) 1053 continue; 1054 1055 if (cmsg->cmsg_type == SCM_CREDS) { 1056 len = sizeof(struct cmsgcred); 1057 if (datalen + CMSG_SPACE(len) > MCLBYTES) 1058 goto bad; 1059 1060 /* 1061 * The lower levels will fill in the structure 1062 */ 1063 memset(CMSG_DATA(data), 0, len); 1064 } else { 1065 len = linux_cmsg.cmsg_len - L_CMSG_HDRSZ; 1066 if (datalen + CMSG_SPACE(len) < datalen || 1067 datalen + CMSG_SPACE(len) > MCLBYTES) 1068 goto bad; 1069 1070 error = copyin(LINUX_CMSG_DATA(ptr_cmsg), 1071 CMSG_DATA(data), len); 1072 if (error != 0) 1073 goto bad; 1074 } 1075 1076 cmsg->cmsg_len = CMSG_LEN(len); 1077 data = (char *)data + CMSG_SPACE(len); 1078 datalen += CMSG_SPACE(len); 1079 1080 if (clen <= LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len)) 1081 break; 1082 1083 clen -= LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len); 1084 ptr_cmsg = (struct l_cmsghdr *)((char *)ptr_cmsg + 1085 LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len)); 1086 } while(clen >= sizeof(struct l_cmsghdr)); 1087 1088 control->m_len = datalen; 1089 if (datalen == 0) { 1090 m_freem(control); 1091 control = NULL; 1092 } 1093 } 1094 1095 msg.msg_iov = iov; 1096 msg.msg_flags = 0; 1097 error = linux_sendit(td, s, &msg, flags, control, UIO_USERSPACE); 1098 control = NULL; 1099 1100 bad: 1101 m_freem(control); 1102 free(iov, M_IOV); 1103 return (error); 1104 } 1105 1106 int 1107 linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) 1108 { 1109 1110 return (linux_sendmsg_common(td, args->s, PTRIN(args->msg), 1111 args->flags)); 1112 } 1113 1114 int 1115 linux_sendmmsg(struct thread *td, struct linux_sendmmsg_args *args) 1116 { 1117 struct l_mmsghdr *msg; 1118 l_uint retval; 1119 int error, datagrams; 1120 1121 if (args->vlen > UIO_MAXIOV) 1122 args->vlen = UIO_MAXIOV; 1123 1124 msg = PTRIN(args->msg); 1125 datagrams = 0; 1126 while (datagrams < args->vlen) { 1127 error = linux_sendmsg_common(td, args->s, &msg->msg_hdr, 1128 args->flags); 1129 if (error != 0) 1130 break; 1131 1132 retval = td->td_retval[0]; 1133 error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len)); 1134 if (error != 0) 1135 break; 1136 ++msg; 1137 ++datagrams; 1138 } 1139 if (error == 0) 1140 td->td_retval[0] = datagrams; 1141 return (error); 1142 } 1143 1144 static int 1145 linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, 1146 l_uint flags, struct msghdr *msg) 1147 { 1148 struct cmsghdr *cm; 1149 struct cmsgcred *cmcred; 1150 struct l_cmsghdr *linux_cmsg = NULL; 1151 struct l_ucred linux_ucred; 1152 socklen_t datalen, maxlen, outlen; 1153 struct l_msghdr linux_msg; 1154 struct iovec *iov, *uiov; 1155 struct mbuf *control = NULL; 1156 struct mbuf **controlp; 1157 struct timeval *ftmvl; 1158 struct l_sockaddr *lsa; 1159 struct sockaddr *sa; 1160 l_timeval ltmvl; 1161 caddr_t outbuf; 1162 void *data; 1163 int error, i, fd, fds, *fdp; 1164 1165 error = copyin(msghdr, &linux_msg, sizeof(linux_msg)); 1166 if (error != 0) 1167 return (error); 1168 1169 error = linux_to_bsd_msghdr(msg, &linux_msg); 1170 if (error != 0) 1171 return (error); 1172 1173 #ifdef COMPAT_LINUX32 1174 error = linux32_copyiniov(PTRIN(msg->msg_iov), msg->msg_iovlen, 1175 &iov, EMSGSIZE); 1176 #else 1177 error = copyiniov(msg->msg_iov, msg->msg_iovlen, &iov, EMSGSIZE); 1178 #endif 1179 if (error != 0) 1180 return (error); 1181 1182 if (msg->msg_name) { 1183 sa = malloc(msg->msg_namelen, M_SONAME, M_WAITOK); 1184 msg->msg_name = sa; 1185 } else 1186 sa = NULL; 1187 1188 uiov = msg->msg_iov; 1189 msg->msg_iov = iov; 1190 controlp = (msg->msg_control != NULL) ? &control : NULL; 1191 error = kern_recvit(td, s, msg, UIO_SYSSPACE, controlp); 1192 msg->msg_iov = uiov; 1193 if (error != 0) 1194 goto bad; 1195 1196 if (msg->msg_name) { 1197 msg->msg_name = PTRIN(linux_msg.msg_name); 1198 error = bsd_to_linux_sockaddr(sa, &lsa, msg->msg_namelen); 1199 if (error == 0) 1200 error = copyout(lsa, PTRIN(msg->msg_name), 1201 msg->msg_namelen); 1202 free(lsa, M_SONAME); 1203 if (error != 0) 1204 goto bad; 1205 } 1206 1207 error = bsd_to_linux_msghdr(msg, &linux_msg); 1208 if (error != 0) 1209 goto bad; 1210 1211 maxlen = linux_msg.msg_controllen; 1212 linux_msg.msg_controllen = 0; 1213 if (control) { 1214 linux_cmsg = malloc(L_CMSG_HDRSZ, M_LINUX, M_WAITOK | M_ZERO); 1215 1216 msg->msg_control = mtod(control, struct cmsghdr *); 1217 msg->msg_controllen = control->m_len; 1218 1219 cm = CMSG_FIRSTHDR(msg); 1220 outbuf = PTRIN(linux_msg.msg_control); 1221 outlen = 0; 1222 while (cm != NULL) { 1223 linux_cmsg->cmsg_type = 1224 bsd_to_linux_cmsg_type(cm->cmsg_type); 1225 linux_cmsg->cmsg_level = 1226 bsd_to_linux_sockopt_level(cm->cmsg_level); 1227 if (linux_cmsg->cmsg_type == -1 || 1228 cm->cmsg_level != SOL_SOCKET) { 1229 error = EINVAL; 1230 goto bad; 1231 } 1232 1233 data = CMSG_DATA(cm); 1234 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1235 1236 switch (cm->cmsg_type) { 1237 case SCM_RIGHTS: 1238 if (flags & LINUX_MSG_CMSG_CLOEXEC) { 1239 fds = datalen / sizeof(int); 1240 fdp = data; 1241 for (i = 0; i < fds; i++) { 1242 fd = *fdp++; 1243 (void)kern_fcntl(td, fd, 1244 F_SETFD, FD_CLOEXEC); 1245 } 1246 } 1247 break; 1248 1249 case SCM_CREDS: 1250 /* 1251 * Currently LOCAL_CREDS is never in 1252 * effect for Linux so no need to worry 1253 * about sockcred 1254 */ 1255 if (datalen != sizeof(*cmcred)) { 1256 error = EMSGSIZE; 1257 goto bad; 1258 } 1259 cmcred = (struct cmsgcred *)data; 1260 bzero(&linux_ucred, sizeof(linux_ucred)); 1261 linux_ucred.pid = cmcred->cmcred_pid; 1262 linux_ucred.uid = cmcred->cmcred_uid; 1263 linux_ucred.gid = cmcred->cmcred_gid; 1264 data = &linux_ucred; 1265 datalen = sizeof(linux_ucred); 1266 break; 1267 1268 case SCM_TIMESTAMP: 1269 if (datalen != sizeof(struct timeval)) { 1270 error = EMSGSIZE; 1271 goto bad; 1272 } 1273 ftmvl = (struct timeval *)data; 1274 ltmvl.tv_sec = ftmvl->tv_sec; 1275 ltmvl.tv_usec = ftmvl->tv_usec; 1276 data = <mvl; 1277 datalen = sizeof(ltmvl); 1278 break; 1279 } 1280 1281 if (outlen + LINUX_CMSG_LEN(datalen) > maxlen) { 1282 if (outlen == 0) { 1283 error = EMSGSIZE; 1284 goto bad; 1285 } else { 1286 linux_msg.msg_flags |= LINUX_MSG_CTRUNC; 1287 m_dispose_extcontrolm(control); 1288 goto out; 1289 } 1290 } 1291 1292 linux_cmsg->cmsg_len = LINUX_CMSG_LEN(datalen); 1293 1294 error = copyout(linux_cmsg, outbuf, L_CMSG_HDRSZ); 1295 if (error != 0) 1296 goto bad; 1297 outbuf += L_CMSG_HDRSZ; 1298 1299 error = copyout(data, outbuf, datalen); 1300 if (error != 0) 1301 goto bad; 1302 1303 outbuf += LINUX_CMSG_ALIGN(datalen); 1304 outlen += LINUX_CMSG_LEN(datalen); 1305 1306 cm = CMSG_NXTHDR(msg, cm); 1307 } 1308 linux_msg.msg_controllen = outlen; 1309 } 1310 1311 out: 1312 error = copyout(&linux_msg, msghdr, sizeof(linux_msg)); 1313 1314 bad: 1315 if (control != NULL) { 1316 if (error != 0) 1317 m_dispose_extcontrolm(control); 1318 m_freem(control); 1319 } 1320 free(iov, M_IOV); 1321 free(linux_cmsg, M_LINUX); 1322 free(sa, M_SONAME); 1323 1324 return (error); 1325 } 1326 1327 int 1328 linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) 1329 { 1330 struct msghdr bsd_msg; 1331 1332 return (linux_recvmsg_common(td, args->s, PTRIN(args->msg), 1333 args->flags, &bsd_msg)); 1334 } 1335 1336 int 1337 linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args) 1338 { 1339 struct l_mmsghdr *msg; 1340 struct msghdr bsd_msg; 1341 struct l_timespec lts; 1342 struct timespec ts, tts; 1343 l_uint retval; 1344 int error, datagrams; 1345 1346 if (args->timeout) { 1347 error = copyin(args->timeout, <s, sizeof(struct l_timespec)); 1348 if (error != 0) 1349 return (error); 1350 error = linux_to_native_timespec(&ts, <s); 1351 if (error != 0) 1352 return (error); 1353 getnanotime(&tts); 1354 timespecadd(&tts, &ts, &tts); 1355 } 1356 1357 msg = PTRIN(args->msg); 1358 datagrams = 0; 1359 while (datagrams < args->vlen) { 1360 error = linux_recvmsg_common(td, args->s, &msg->msg_hdr, 1361 args->flags & ~LINUX_MSG_WAITFORONE, &bsd_msg); 1362 if (error != 0) 1363 break; 1364 1365 retval = td->td_retval[0]; 1366 error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len)); 1367 if (error != 0) 1368 break; 1369 ++msg; 1370 ++datagrams; 1371 1372 /* 1373 * MSG_WAITFORONE turns on MSG_DONTWAIT after one packet. 1374 */ 1375 if (args->flags & LINUX_MSG_WAITFORONE) 1376 args->flags |= LINUX_MSG_DONTWAIT; 1377 1378 /* 1379 * See BUGS section of recvmmsg(2). 1380 */ 1381 if (args->timeout) { 1382 getnanotime(&ts); 1383 timespecsub(&ts, &tts, &ts); 1384 if (!timespecisset(&ts) || ts.tv_sec > 0) 1385 break; 1386 } 1387 /* Out of band data, return right away. */ 1388 if (bsd_msg.msg_flags & MSG_OOB) 1389 break; 1390 } 1391 if (error == 0) 1392 td->td_retval[0] = datagrams; 1393 return (error); 1394 } 1395 1396 int 1397 linux_shutdown(struct thread *td, struct linux_shutdown_args *args) 1398 { 1399 1400 return (kern_shutdown(td, args->s, args->how)); 1401 } 1402 1403 int 1404 linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) 1405 { 1406 l_timeval linux_tv; 1407 struct sockaddr *sa; 1408 struct timeval tv; 1409 socklen_t len; 1410 int error, level, name; 1411 1412 level = linux_to_bsd_sockopt_level(args->level); 1413 switch (level) { 1414 case SOL_SOCKET: 1415 name = linux_to_bsd_so_sockopt(args->optname); 1416 switch (name) { 1417 case SO_RCVTIMEO: 1418 /* FALLTHROUGH */ 1419 case SO_SNDTIMEO: 1420 error = copyin(PTRIN(args->optval), &linux_tv, 1421 sizeof(linux_tv)); 1422 if (error != 0) 1423 return (error); 1424 tv.tv_sec = linux_tv.tv_sec; 1425 tv.tv_usec = linux_tv.tv_usec; 1426 return (kern_setsockopt(td, args->s, level, 1427 name, &tv, UIO_SYSSPACE, sizeof(tv))); 1428 /* NOTREACHED */ 1429 default: 1430 break; 1431 } 1432 break; 1433 case IPPROTO_IP: 1434 if (args->optname == LINUX_IP_RECVERR && 1435 linux_ignore_ip_recverr) { 1436 /* 1437 * XXX: This is a hack to unbreak DNS resolution 1438 * with glibc 2.30 and above. 1439 */ 1440 return (0); 1441 } 1442 name = linux_to_bsd_ip_sockopt(args->optname); 1443 break; 1444 case IPPROTO_IPV6: 1445 name = linux_to_bsd_ip6_sockopt(args->optname); 1446 break; 1447 case IPPROTO_TCP: 1448 name = linux_to_bsd_tcp_sockopt(args->optname); 1449 break; 1450 default: 1451 name = -1; 1452 break; 1453 } 1454 if (name == -1) { 1455 linux_msg(curthread, 1456 "unsupported setsockopt level %d optname %d", 1457 args->level, args->optname); 1458 return (ENOPROTOOPT); 1459 } 1460 1461 if (name == IPV6_NEXTHOP) { 1462 len = args->optlen; 1463 error = linux_to_bsd_sockaddr(PTRIN(args->optval), &sa, &len); 1464 if (error != 0) 1465 return (error); 1466 1467 error = kern_setsockopt(td, args->s, level, 1468 name, sa, UIO_SYSSPACE, len); 1469 free(sa, M_SONAME); 1470 } else { 1471 error = kern_setsockopt(td, args->s, level, 1472 name, PTRIN(args->optval), UIO_USERSPACE, args->optlen); 1473 } 1474 1475 return (error); 1476 } 1477 1478 int 1479 linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) 1480 { 1481 l_timeval linux_tv; 1482 struct timeval tv; 1483 socklen_t tv_len, xulen, len; 1484 struct l_sockaddr *lsa; 1485 struct sockaddr *sa; 1486 struct xucred xu; 1487 struct l_ucred lxu; 1488 int error, level, name, newval; 1489 1490 level = linux_to_bsd_sockopt_level(args->level); 1491 switch (level) { 1492 case SOL_SOCKET: 1493 name = linux_to_bsd_so_sockopt(args->optname); 1494 switch (name) { 1495 case SO_RCVTIMEO: 1496 /* FALLTHROUGH */ 1497 case SO_SNDTIMEO: 1498 tv_len = sizeof(tv); 1499 error = kern_getsockopt(td, args->s, level, 1500 name, &tv, UIO_SYSSPACE, &tv_len); 1501 if (error != 0) 1502 return (error); 1503 linux_tv.tv_sec = tv.tv_sec; 1504 linux_tv.tv_usec = tv.tv_usec; 1505 return (copyout(&linux_tv, PTRIN(args->optval), 1506 sizeof(linux_tv))); 1507 /* NOTREACHED */ 1508 case LOCAL_PEERCRED: 1509 if (args->optlen < sizeof(lxu)) 1510 return (EINVAL); 1511 /* 1512 * LOCAL_PEERCRED is not served at the SOL_SOCKET level, 1513 * but by the Unix socket's level 0. 1514 */ 1515 level = 0; 1516 xulen = sizeof(xu); 1517 error = kern_getsockopt(td, args->s, level, 1518 name, &xu, UIO_SYSSPACE, &xulen); 1519 if (error != 0) 1520 return (error); 1521 lxu.pid = xu.cr_pid; 1522 lxu.uid = xu.cr_uid; 1523 lxu.gid = xu.cr_gid; 1524 return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu))); 1525 /* NOTREACHED */ 1526 case SO_ERROR: 1527 len = sizeof(newval); 1528 error = kern_getsockopt(td, args->s, level, 1529 name, &newval, UIO_SYSSPACE, &len); 1530 if (error != 0) 1531 return (error); 1532 newval = -SV_ABI_ERRNO(td->td_proc, newval); 1533 return (copyout(&newval, PTRIN(args->optval), len)); 1534 /* NOTREACHED */ 1535 default: 1536 break; 1537 } 1538 break; 1539 case IPPROTO_IP: 1540 name = linux_to_bsd_ip_sockopt(args->optname); 1541 break; 1542 case IPPROTO_IPV6: 1543 name = linux_to_bsd_ip6_sockopt(args->optname); 1544 break; 1545 case IPPROTO_TCP: 1546 name = linux_to_bsd_tcp_sockopt(args->optname); 1547 break; 1548 default: 1549 name = -1; 1550 break; 1551 } 1552 if (name == -1) { 1553 linux_msg(curthread, 1554 "unsupported getsockopt level %d optname %d", 1555 args->level, args->optname); 1556 return (EINVAL); 1557 } 1558 1559 if (name == IPV6_NEXTHOP) { 1560 error = copyin(PTRIN(args->optlen), &len, sizeof(len)); 1561 if (error != 0) 1562 return (error); 1563 sa = malloc(len, M_SONAME, M_WAITOK); 1564 1565 error = kern_getsockopt(td, args->s, level, 1566 name, sa, UIO_SYSSPACE, &len); 1567 if (error != 0) 1568 goto out; 1569 1570 error = bsd_to_linux_sockaddr(sa, &lsa, len); 1571 if (error == 0) 1572 error = copyout(lsa, PTRIN(args->optval), len); 1573 free(lsa, M_SONAME); 1574 if (error == 0) 1575 error = copyout(&len, PTRIN(args->optlen), 1576 sizeof(len)); 1577 out: 1578 free(sa, M_SONAME); 1579 } else { 1580 if (args->optval) { 1581 error = copyin(PTRIN(args->optlen), &len, sizeof(len)); 1582 if (error != 0) 1583 return (error); 1584 } 1585 error = kern_getsockopt(td, args->s, level, 1586 name, PTRIN(args->optval), UIO_USERSPACE, &len); 1587 if (error == 0) 1588 error = copyout(&len, PTRIN(args->optlen), 1589 sizeof(len)); 1590 } 1591 1592 return (error); 1593 } 1594 1595 static int 1596 linux_sendfile_common(struct thread *td, l_int out, l_int in, 1597 l_loff_t *offset, l_size_t count) 1598 { 1599 off_t bytes_read; 1600 int error; 1601 l_loff_t current_offset; 1602 struct file *fp; 1603 1604 AUDIT_ARG_FD(in); 1605 error = fget_read(td, in, &cap_pread_rights, &fp); 1606 if (error != 0) 1607 return (error); 1608 1609 if (offset != NULL) { 1610 current_offset = *offset; 1611 } else { 1612 error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ? 1613 fo_seek(fp, 0, SEEK_CUR, td) : ESPIPE; 1614 if (error != 0) 1615 goto drop; 1616 current_offset = td->td_uretoff.tdu_off; 1617 } 1618 1619 bytes_read = 0; 1620 1621 /* Linux cannot have 0 count. */ 1622 if (count <= 0 || current_offset < 0) { 1623 error = EINVAL; 1624 goto drop; 1625 } 1626 1627 error = fo_sendfile(fp, out, NULL, NULL, current_offset, count, 1628 &bytes_read, 0, td); 1629 if (error != 0) 1630 goto drop; 1631 current_offset += bytes_read; 1632 1633 if (offset != NULL) { 1634 *offset = current_offset; 1635 } else { 1636 error = fo_seek(fp, current_offset, SEEK_SET, td); 1637 if (error != 0) 1638 goto drop; 1639 } 1640 1641 td->td_retval[0] = (ssize_t)bytes_read; 1642 drop: 1643 fdrop(fp, td); 1644 return (error); 1645 } 1646 1647 int 1648 linux_sendfile(struct thread *td, struct linux_sendfile_args *arg) 1649 { 1650 /* 1651 * Differences between FreeBSD and Linux sendfile: 1652 * - Linux doesn't send anything when count is 0 (FreeBSD uses 0 to 1653 * mean send the whole file.) In linux_sendfile given fds are still 1654 * checked for validity when the count is 0. 1655 * - Linux can send to any fd whereas FreeBSD only supports sockets. 1656 * The same restriction follows for linux_sendfile. 1657 * - Linux doesn't have an equivalent for FreeBSD's flags and sf_hdtr. 1658 * - Linux takes an offset pointer and updates it to the read location. 1659 * FreeBSD takes in an offset and a 'bytes read' parameter which is 1660 * only filled if it isn't NULL. We use this parameter to update the 1661 * offset pointer if it exists. 1662 * - Linux sendfile returns bytes read on success while FreeBSD 1663 * returns 0. We use the 'bytes read' parameter to get this value. 1664 */ 1665 1666 l_loff_t offset64; 1667 l_long offset; 1668 int ret; 1669 int error; 1670 1671 if (arg->offset != NULL) { 1672 error = copyin(arg->offset, &offset, sizeof(offset)); 1673 if (error != 0) 1674 return (error); 1675 offset64 = (l_loff_t)offset; 1676 } 1677 1678 ret = linux_sendfile_common(td, arg->out, arg->in, 1679 arg->offset != NULL ? &offset64 : NULL, arg->count); 1680 1681 if (arg->offset != NULL) { 1682 #if defined(__i386__) || defined(__arm__) || \ 1683 (defined(__amd64__) && defined(COMPAT_LINUX32)) 1684 if (offset64 > INT32_MAX) 1685 return (EOVERFLOW); 1686 #endif 1687 offset = (l_long)offset64; 1688 error = copyout(&offset, arg->offset, sizeof(offset)); 1689 if (error != 0) 1690 return (error); 1691 } 1692 1693 return (ret); 1694 } 1695 1696 #if defined(__i386__) || defined(__arm__) || \ 1697 (defined(__amd64__) && defined(COMPAT_LINUX32)) 1698 1699 int 1700 linux_sendfile64(struct thread *td, struct linux_sendfile64_args *arg) 1701 { 1702 l_loff_t offset; 1703 int ret; 1704 int error; 1705 1706 if (arg->offset != NULL) { 1707 error = copyin(arg->offset, &offset, sizeof(offset)); 1708 if (error != 0) 1709 return (error); 1710 } 1711 1712 ret = linux_sendfile_common(td, arg->out, arg->in, 1713 arg->offset != NULL ? &offset : NULL, arg->count); 1714 1715 if (arg->offset != NULL) { 1716 error = copyout(&offset, arg->offset, sizeof(offset)); 1717 if (error != 0) 1718 return (error); 1719 } 1720 1721 return (ret); 1722 } 1723 1724 /* Argument list sizes for linux_socketcall */ 1725 static const unsigned char lxs_args_cnt[] = { 1726 0 /* unused*/, 3 /* socket */, 1727 3 /* bind */, 3 /* connect */, 1728 2 /* listen */, 3 /* accept */, 1729 3 /* getsockname */, 3 /* getpeername */, 1730 4 /* socketpair */, 4 /* send */, 1731 4 /* recv */, 6 /* sendto */, 1732 6 /* recvfrom */, 2 /* shutdown */, 1733 5 /* setsockopt */, 5 /* getsockopt */, 1734 3 /* sendmsg */, 3 /* recvmsg */, 1735 4 /* accept4 */, 5 /* recvmmsg */, 1736 4 /* sendmmsg */, 4 /* sendfile */ 1737 }; 1738 #define LINUX_ARGS_CNT (nitems(lxs_args_cnt) - 1) 1739 #define LINUX_ARG_SIZE(x) (lxs_args_cnt[x] * sizeof(l_ulong)) 1740 1741 int 1742 linux_socketcall(struct thread *td, struct linux_socketcall_args *args) 1743 { 1744 l_ulong a[6]; 1745 #if defined(__amd64__) && defined(COMPAT_LINUX32) 1746 register_t l_args[6]; 1747 #endif 1748 void *arg; 1749 int error; 1750 1751 if (args->what < LINUX_SOCKET || args->what > LINUX_ARGS_CNT) 1752 return (EINVAL); 1753 error = copyin(PTRIN(args->args), a, LINUX_ARG_SIZE(args->what)); 1754 if (error != 0) 1755 return (error); 1756 1757 #if defined(__amd64__) && defined(COMPAT_LINUX32) 1758 for (int i = 0; i < lxs_args_cnt[args->what]; ++i) 1759 l_args[i] = a[i]; 1760 arg = l_args; 1761 #else 1762 arg = a; 1763 #endif 1764 switch (args->what) { 1765 case LINUX_SOCKET: 1766 return (linux_socket(td, arg)); 1767 case LINUX_BIND: 1768 return (linux_bind(td, arg)); 1769 case LINUX_CONNECT: 1770 return (linux_connect(td, arg)); 1771 case LINUX_LISTEN: 1772 return (linux_listen(td, arg)); 1773 case LINUX_ACCEPT: 1774 return (linux_accept(td, arg)); 1775 case LINUX_GETSOCKNAME: 1776 return (linux_getsockname(td, arg)); 1777 case LINUX_GETPEERNAME: 1778 return (linux_getpeername(td, arg)); 1779 case LINUX_SOCKETPAIR: 1780 return (linux_socketpair(td, arg)); 1781 case LINUX_SEND: 1782 return (linux_send(td, arg)); 1783 case LINUX_RECV: 1784 return (linux_recv(td, arg)); 1785 case LINUX_SENDTO: 1786 return (linux_sendto(td, arg)); 1787 case LINUX_RECVFROM: 1788 return (linux_recvfrom(td, arg)); 1789 case LINUX_SHUTDOWN: 1790 return (linux_shutdown(td, arg)); 1791 case LINUX_SETSOCKOPT: 1792 return (linux_setsockopt(td, arg)); 1793 case LINUX_GETSOCKOPT: 1794 return (linux_getsockopt(td, arg)); 1795 case LINUX_SENDMSG: 1796 return (linux_sendmsg(td, arg)); 1797 case LINUX_RECVMSG: 1798 return (linux_recvmsg(td, arg)); 1799 case LINUX_ACCEPT4: 1800 return (linux_accept4(td, arg)); 1801 case LINUX_RECVMMSG: 1802 return (linux_recvmmsg(td, arg)); 1803 case LINUX_SENDMMSG: 1804 return (linux_sendmmsg(td, arg)); 1805 case LINUX_SENDFILE: 1806 return (linux_sendfile(td, arg)); 1807 } 1808 1809 uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); 1810 return (ENOSYS); 1811 } 1812 #endif /* __i386__ || __arm__ || (__amd64__ && COMPAT_LINUX32) */ 1813