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