1 /*- 2 * SPDX-License-Identifier: BSD-2-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 * 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 #include "opt_inet6.h" 31 32 #include <sys/param.h> 33 #include <sys/capsicum.h> 34 #include <sys/filedesc.h> 35 #include <sys/limits.h> 36 #include <sys/malloc.h> 37 #include <sys/mbuf.h> 38 #include <sys/proc.h> 39 #include <sys/socket.h> 40 #include <sys/socketvar.h> 41 #include <sys/syscallsubr.h> 42 #include <sys/sysproto.h> 43 #include <sys/un.h> 44 #include <sys/unistd.h> 45 46 #include <security/audit/audit.h> 47 48 #include <net/if.h> 49 #include <net/vnet.h> 50 #include <netinet/in.h> 51 #include <netinet/ip.h> 52 #include <netinet/tcp.h> 53 #ifdef INET6 54 #include <netinet/ip6.h> 55 #include <netinet6/ip6_var.h> 56 #endif 57 58 #ifdef COMPAT_LINUX32 59 #include <machine/../linux32/linux.h> 60 #include <machine/../linux32/linux32_proto.h> 61 #else 62 #include <machine/../linux/linux.h> 63 #include <machine/../linux/linux_proto.h> 64 #endif 65 #include <compat/linux/linux_common.h> 66 #include <compat/linux/linux_emul.h> 67 #include <compat/linux/linux_file.h> 68 #include <compat/linux/linux_mib.h> 69 #include <compat/linux/linux_socket.h> 70 #include <compat/linux/linux_time.h> 71 #include <compat/linux/linux_util.h> 72 73 _Static_assert(offsetof(struct l_ifreq, ifr_ifru) == 74 offsetof(struct ifreq, ifr_ifru), 75 "Linux ifreq members names should be equal to FreeeBSD"); 76 _Static_assert(offsetof(struct l_ifreq, ifr_index) == 77 offsetof(struct ifreq, ifr_index), 78 "Linux ifreq members names should be equal to FreeeBSD"); 79 _Static_assert(offsetof(struct l_ifreq, ifr_name) == 80 offsetof(struct ifreq, ifr_name), 81 "Linux ifreq members names should be equal to FreeeBSD"); 82 83 #define SECURITY_CONTEXT_STRING "unconfined" 84 85 static int linux_sendmsg_common(struct thread *, l_int, struct l_msghdr *, 86 l_uint); 87 static int linux_recvmsg_common(struct thread *, l_int, struct l_msghdr *, 88 l_uint, struct msghdr *); 89 static int linux_set_socket_flags(int, int *); 90 91 #define SOL_NETLINK 270 92 93 static int 94 linux_to_bsd_sockopt_level(int level) 95 { 96 97 if (level == LINUX_SOL_SOCKET) 98 return (SOL_SOCKET); 99 /* Remaining values are RFC-defined protocol numbers. */ 100 return (level); 101 } 102 103 static int 104 bsd_to_linux_sockopt_level(int level) 105 { 106 107 if (level == SOL_SOCKET) 108 return (LINUX_SOL_SOCKET); 109 return (level); 110 } 111 112 static int 113 linux_to_bsd_ip_sockopt(int opt) 114 { 115 116 switch (opt) { 117 /* known and translated sockopts */ 118 case LINUX_IP_TOS: 119 return (IP_TOS); 120 case LINUX_IP_TTL: 121 return (IP_TTL); 122 case LINUX_IP_HDRINCL: 123 return (IP_HDRINCL); 124 case LINUX_IP_OPTIONS: 125 return (IP_OPTIONS); 126 case LINUX_IP_RECVOPTS: 127 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_RECVOPTS"); 128 return (IP_RECVOPTS); 129 case LINUX_IP_RETOPTS: 130 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_REETOPTS"); 131 return (IP_RETOPTS); 132 case LINUX_IP_RECVTTL: 133 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_RECVTTL"); 134 return (IP_RECVTTL); 135 case LINUX_IP_RECVTOS: 136 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_RECVTOS"); 137 return (IP_RECVTOS); 138 case LINUX_IP_FREEBIND: 139 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_FREEBIND"); 140 return (IP_BINDANY); 141 case LINUX_IP_IPSEC_POLICY: 142 /* we have this option, but not documented in ip(4) manpage */ 143 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_IPSEC_POLICY"); 144 return (IP_IPSEC_POLICY); 145 case LINUX_IP_MINTTL: 146 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MINTTL"); 147 return (IP_MINTTL); 148 case LINUX_IP_MULTICAST_IF: 149 return (IP_MULTICAST_IF); 150 case LINUX_IP_MULTICAST_TTL: 151 return (IP_MULTICAST_TTL); 152 case LINUX_IP_MULTICAST_LOOP: 153 return (IP_MULTICAST_LOOP); 154 case LINUX_IP_ADD_MEMBERSHIP: 155 return (IP_ADD_MEMBERSHIP); 156 case LINUX_IP_DROP_MEMBERSHIP: 157 return (IP_DROP_MEMBERSHIP); 158 case LINUX_IP_UNBLOCK_SOURCE: 159 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_UNBLOCK_SOURCE"); 160 return (IP_UNBLOCK_SOURCE); 161 case LINUX_IP_BLOCK_SOURCE: 162 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_BLOCK_SOURCE"); 163 return (IP_BLOCK_SOURCE); 164 case LINUX_IP_ADD_SOURCE_MEMBERSHIP: 165 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_ADD_SOURCE_MEMBERSHIP"); 166 return (IP_ADD_SOURCE_MEMBERSHIP); 167 case LINUX_IP_DROP_SOURCE_MEMBERSHIP: 168 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_DROP_SOURCE_MEMBERSHIP"); 169 return (IP_DROP_SOURCE_MEMBERSHIP); 170 case LINUX_MCAST_JOIN_GROUP: 171 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MCAST_JOIN_GROUP"); 172 return (MCAST_JOIN_GROUP); 173 case LINUX_MCAST_LEAVE_GROUP: 174 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MCAST_LEAVE_GROUP"); 175 return (MCAST_LEAVE_GROUP); 176 case LINUX_MCAST_JOIN_SOURCE_GROUP: 177 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MCAST_JOIN_SOURCE_GROUP"); 178 return (MCAST_JOIN_SOURCE_GROUP); 179 case LINUX_MCAST_LEAVE_SOURCE_GROUP: 180 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MCAST_LEAVE_SOURCE_GROUP"); 181 return (MCAST_LEAVE_SOURCE_GROUP); 182 case LINUX_IP_RECVORIGDSTADDR: 183 return (IP_RECVORIGDSTADDR); 184 185 /* known but not implemented sockopts */ 186 case LINUX_IP_ROUTER_ALERT: 187 LINUX_RATELIMIT_MSG_OPT1( 188 "unsupported IPv4 socket option IP_ROUTER_ALERT (%d), you can not do user-space routing from linux programs", 189 opt); 190 return (-2); 191 case LINUX_IP_PKTINFO: 192 LINUX_RATELIMIT_MSG_OPT1( 193 "unsupported IPv4 socket option IP_PKTINFO (%d), you can not get extended packet info for datagram sockets in linux programs", 194 opt); 195 return (-2); 196 case LINUX_IP_PKTOPTIONS: 197 LINUX_RATELIMIT_MSG_OPT1( 198 "unsupported IPv4 socket option IP_PKTOPTIONS (%d)", 199 opt); 200 return (-2); 201 case LINUX_IP_MTU_DISCOVER: 202 LINUX_RATELIMIT_MSG_OPT1( 203 "unsupported IPv4 socket option IP_MTU_DISCOVER (%d), your linux program can not control path-MTU discovery", 204 opt); 205 return (-2); 206 case LINUX_IP_RECVERR: 207 /* needed by steam */ 208 LINUX_RATELIMIT_MSG_OPT1( 209 "unsupported IPv4 socket option IP_RECVERR (%d), you can not get extended reliability info in linux programs", 210 opt); 211 return (-2); 212 case LINUX_IP_MTU: 213 LINUX_RATELIMIT_MSG_OPT1( 214 "unsupported IPv4 socket option IP_MTU (%d), your linux program can not control the MTU on this socket", 215 opt); 216 return (-2); 217 case LINUX_IP_XFRM_POLICY: 218 LINUX_RATELIMIT_MSG_OPT1( 219 "unsupported IPv4 socket option IP_XFRM_POLICY (%d)", 220 opt); 221 return (-2); 222 case LINUX_IP_PASSSEC: 223 /* needed by steam */ 224 LINUX_RATELIMIT_MSG_OPT1( 225 "unsupported IPv4 socket option IP_PASSSEC (%d), you can not get IPSEC related credential information associated with this socket in linux programs -- if you do not use IPSEC, you can ignore this", 226 opt); 227 return (-2); 228 case LINUX_IP_TRANSPARENT: 229 /* IP_BINDANY or more? */ 230 LINUX_RATELIMIT_MSG_OPT1( 231 "unsupported IPv4 socket option IP_TRANSPARENT (%d), you can not enable transparent proxying in linux programs -- note, IP_FREEBIND is supported, no idea if the FreeBSD IP_BINDANY is equivalent to the Linux IP_TRANSPARENT or not, any info is welcome", 232 opt); 233 return (-2); 234 case LINUX_IP_NODEFRAG: 235 LINUX_RATELIMIT_MSG_OPT1( 236 "unsupported IPv4 socket option IP_NODEFRAG (%d)", 237 opt); 238 return (-2); 239 case LINUX_IP_CHECKSUM: 240 LINUX_RATELIMIT_MSG_OPT1( 241 "unsupported IPv4 socket option IP_CHECKSUM (%d)", 242 opt); 243 return (-2); 244 case LINUX_IP_BIND_ADDRESS_NO_PORT: 245 LINUX_RATELIMIT_MSG_OPT1( 246 "unsupported IPv4 socket option IP_BIND_ADDRESS_NO_PORT (%d)", 247 opt); 248 return (-2); 249 case LINUX_IP_RECVFRAGSIZE: 250 LINUX_RATELIMIT_MSG_OPT1( 251 "unsupported IPv4 socket option IP_RECVFRAGSIZE (%d)", 252 opt); 253 return (-2); 254 case LINUX_MCAST_MSFILTER: 255 LINUX_RATELIMIT_MSG_OPT1( 256 "unsupported IPv4 socket option IP_MCAST_MSFILTER (%d)", 257 opt); 258 return (-2); 259 case LINUX_IP_MULTICAST_ALL: 260 LINUX_RATELIMIT_MSG_OPT1( 261 "unsupported IPv4 socket option IP_MULTICAST_ALL (%d), your linux program will not see all multicast groups joined by the entire system, only those the program joined itself on this socket", 262 opt); 263 return (-2); 264 case LINUX_IP_UNICAST_IF: 265 LINUX_RATELIMIT_MSG_OPT1( 266 "unsupported IPv4 socket option IP_UNICAST_IF (%d)", 267 opt); 268 return (-2); 269 270 /* unknown sockopts */ 271 default: 272 return (-1); 273 } 274 } 275 276 static int 277 linux_to_bsd_ip6_sockopt(int opt) 278 { 279 280 switch (opt) { 281 /* known and translated sockopts */ 282 case LINUX_IPV6_2292PKTINFO: 283 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292PKTINFO"); 284 return (IPV6_2292PKTINFO); 285 case LINUX_IPV6_2292HOPOPTS: 286 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292HOPOPTS"); 287 return (IPV6_2292HOPOPTS); 288 case LINUX_IPV6_2292DSTOPTS: 289 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292DSTOPTS"); 290 return (IPV6_2292DSTOPTS); 291 case LINUX_IPV6_2292RTHDR: 292 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292RTHDR"); 293 return (IPV6_2292RTHDR); 294 case LINUX_IPV6_2292PKTOPTIONS: 295 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292PKTOPTIONS"); 296 return (IPV6_2292PKTOPTIONS); 297 case LINUX_IPV6_CHECKSUM: 298 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_CHECKSUM"); 299 return (IPV6_CHECKSUM); 300 case LINUX_IPV6_2292HOPLIMIT: 301 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292HOPLIMIT"); 302 return (IPV6_2292HOPLIMIT); 303 case LINUX_IPV6_NEXTHOP: 304 return (IPV6_NEXTHOP); 305 case LINUX_IPV6_UNICAST_HOPS: 306 return (IPV6_UNICAST_HOPS); 307 case LINUX_IPV6_MULTICAST_IF: 308 return (IPV6_MULTICAST_IF); 309 case LINUX_IPV6_MULTICAST_HOPS: 310 return (IPV6_MULTICAST_HOPS); 311 case LINUX_IPV6_MULTICAST_LOOP: 312 return (IPV6_MULTICAST_LOOP); 313 case LINUX_IPV6_ADD_MEMBERSHIP: 314 return (IPV6_JOIN_GROUP); 315 case LINUX_IPV6_DROP_MEMBERSHIP: 316 return (IPV6_LEAVE_GROUP); 317 case LINUX_IPV6_V6ONLY: 318 return (IPV6_V6ONLY); 319 case LINUX_IPV6_IPSEC_POLICY: 320 /* we have this option, but not documented in ip6(4) manpage */ 321 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_IPSEC_POLICY"); 322 return (IPV6_IPSEC_POLICY); 323 case LINUX_MCAST_JOIN_GROUP: 324 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_JOIN_GROUP"); 325 return (IPV6_JOIN_GROUP); 326 case LINUX_MCAST_LEAVE_GROUP: 327 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_LEAVE_GROUP"); 328 return (IPV6_LEAVE_GROUP); 329 case LINUX_IPV6_RECVPKTINFO: 330 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVPKTINFO"); 331 return (IPV6_RECVPKTINFO); 332 case LINUX_IPV6_PKTINFO: 333 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_PKTINFO"); 334 return (IPV6_PKTINFO); 335 case LINUX_IPV6_RECVHOPLIMIT: 336 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVHOPLIMIT"); 337 return (IPV6_RECVHOPLIMIT); 338 case LINUX_IPV6_HOPLIMIT: 339 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_HOPLIMIT"); 340 return (IPV6_HOPLIMIT); 341 case LINUX_IPV6_RECVHOPOPTS: 342 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVHOPOPTS"); 343 return (IPV6_RECVHOPOPTS); 344 case LINUX_IPV6_HOPOPTS: 345 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_HOPOPTS"); 346 return (IPV6_HOPOPTS); 347 case LINUX_IPV6_RTHDRDSTOPTS: 348 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RTHDRDSTOPTS"); 349 return (IPV6_RTHDRDSTOPTS); 350 case LINUX_IPV6_RECVRTHDR: 351 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVRTHDR"); 352 return (IPV6_RECVRTHDR); 353 case LINUX_IPV6_RTHDR: 354 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RTHDR"); 355 return (IPV6_RTHDR); 356 case LINUX_IPV6_RECVDSTOPTS: 357 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVDSTOPTS"); 358 return (IPV6_RECVDSTOPTS); 359 case LINUX_IPV6_DSTOPTS: 360 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_DSTOPTS"); 361 return (IPV6_DSTOPTS); 362 case LINUX_IPV6_RECVPATHMTU: 363 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVPATHMTU"); 364 return (IPV6_RECVPATHMTU); 365 case LINUX_IPV6_PATHMTU: 366 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_PATHMTU"); 367 return (IPV6_PATHMTU); 368 case LINUX_IPV6_DONTFRAG: 369 return (IPV6_DONTFRAG); 370 case LINUX_IPV6_AUTOFLOWLABEL: 371 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_AUTOFLOWLABEL"); 372 return (IPV6_AUTOFLOWLABEL); 373 case LINUX_IPV6_ORIGDSTADDR: 374 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_ORIGDSTADDR"); 375 return (IPV6_ORIGDSTADDR); 376 case LINUX_IPV6_FREEBIND: 377 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_FREEBIND"); 378 return (IPV6_BINDANY); 379 380 /* known but not implemented sockopts */ 381 case LINUX_IPV6_ADDRFORM: 382 LINUX_RATELIMIT_MSG_OPT1( 383 "unsupported IPv6 socket option IPV6_ADDRFORM (%d), you linux program can not convert the socket to IPv4", 384 opt); 385 return (-2); 386 case LINUX_IPV6_AUTHHDR: 387 LINUX_RATELIMIT_MSG_OPT1( 388 "unsupported IPv6 socket option IPV6_AUTHHDR (%d), your linux program can not get the authentication header info of IPv6 packets", 389 opt); 390 return (-2); 391 case LINUX_IPV6_FLOWINFO: 392 LINUX_RATELIMIT_MSG_OPT1( 393 "unsupported IPv6 socket option IPV6_FLOWINFO (%d), your linux program can not get the flowid of IPv6 packets", 394 opt); 395 return (-2); 396 case LINUX_IPV6_ROUTER_ALERT: 397 LINUX_RATELIMIT_MSG_OPT1( 398 "unsupported IPv6 socket option IPV6_ROUTER_ALERT (%d), you can not do user-space routing from linux programs", 399 opt); 400 return (-2); 401 case LINUX_IPV6_MTU_DISCOVER: 402 LINUX_RATELIMIT_MSG_OPT1( 403 "unsupported IPv6 socket option IPV6_MTU_DISCOVER (%d), your linux program can not control path-MTU discovery", 404 opt); 405 return (-2); 406 case LINUX_IPV6_MTU: 407 LINUX_RATELIMIT_MSG_OPT1( 408 "unsupported IPv6 socket option IPV6_MTU (%d), your linux program can not control the MTU on this socket", 409 opt); 410 return (-2); 411 case LINUX_IPV6_JOIN_ANYCAST: 412 LINUX_RATELIMIT_MSG_OPT1( 413 "unsupported IPv6 socket option IPV6_JOIN_ANYCAST (%d)", 414 opt); 415 return (-2); 416 case LINUX_IPV6_LEAVE_ANYCAST: 417 LINUX_RATELIMIT_MSG_OPT1( 418 "unsupported IPv6 socket option IPV6_LEAVE_ANYCAST (%d)", 419 opt); 420 return (-2); 421 case LINUX_IPV6_MULTICAST_ALL: 422 LINUX_RATELIMIT_MSG_OPT1( 423 "unsupported IPv6 socket option IPV6_MULTICAST_ALL (%d)", 424 opt); 425 return (-2); 426 case LINUX_IPV6_ROUTER_ALERT_ISOLATE: 427 LINUX_RATELIMIT_MSG_OPT1( 428 "unsupported IPv6 socket option IPV6_ROUTER_ALERT_ISOLATE (%d)", 429 opt); 430 return (-2); 431 case LINUX_IPV6_FLOWLABEL_MGR: 432 LINUX_RATELIMIT_MSG_OPT1( 433 "unsupported IPv6 socket option IPV6_FLOWLABEL_MGR (%d)", 434 opt); 435 return (-2); 436 case LINUX_IPV6_FLOWINFO_SEND: 437 LINUX_RATELIMIT_MSG_OPT1( 438 "unsupported IPv6 socket option IPV6_FLOWINFO_SEND (%d)", 439 opt); 440 return (-2); 441 case LINUX_IPV6_XFRM_POLICY: 442 LINUX_RATELIMIT_MSG_OPT1( 443 "unsupported IPv6 socket option IPV6_XFRM_POLICY (%d)", 444 opt); 445 return (-2); 446 case LINUX_IPV6_HDRINCL: 447 LINUX_RATELIMIT_MSG_OPT1( 448 "unsupported IPv6 socket option IPV6_HDRINCL (%d)", 449 opt); 450 return (-2); 451 case LINUX_MCAST_BLOCK_SOURCE: 452 LINUX_RATELIMIT_MSG_OPT1( 453 "unsupported IPv6 socket option MCAST_BLOCK_SOURCE (%d), your linux program may see more multicast stuff than it wants", 454 opt); 455 return (-2); 456 case LINUX_MCAST_UNBLOCK_SOURCE: 457 LINUX_RATELIMIT_MSG_OPT1( 458 "unsupported IPv6 socket option MCAST_UNBLOCK_SOURCE (%d), your linux program may not see all the multicast stuff it wants", 459 opt); 460 return (-2); 461 case LINUX_MCAST_JOIN_SOURCE_GROUP: 462 LINUX_RATELIMIT_MSG_OPT1( 463 "unsupported IPv6 socket option MCAST_JOIN_SOURCE_GROUP (%d), your linux program is not able to join a multicast source group", 464 opt); 465 return (-2); 466 case LINUX_MCAST_LEAVE_SOURCE_GROUP: 467 LINUX_RATELIMIT_MSG_OPT1( 468 "unsupported IPv6 socket option MCAST_LEAVE_SOURCE_GROUP (%d), your linux program is not able to leave a multicast source group -- but it was also not able to join one, so no issue", 469 opt); 470 return (-2); 471 case LINUX_MCAST_MSFILTER: 472 LINUX_RATELIMIT_MSG_OPT1( 473 "unsupported IPv6 socket option MCAST_MSFILTER (%d), your linux program can not manipulate the multicast filter, it may see more multicast data than it wants to see", 474 opt); 475 return (-2); 476 case LINUX_IPV6_ADDR_PREFERENCES: 477 LINUX_RATELIMIT_MSG_OPT1( 478 "unsupported IPv6 socket option IPV6_ADDR_PREFERENCES (%d)", 479 opt); 480 return (-2); 481 case LINUX_IPV6_MINHOPCOUNT: 482 LINUX_RATELIMIT_MSG_OPT1( 483 "unsupported IPv6 socket option IPV6_MINHOPCOUNT (%d)", 484 opt); 485 return (-2); 486 case LINUX_IPV6_TRANSPARENT: 487 /* IP_BINDANY or more? */ 488 LINUX_RATELIMIT_MSG_OPT1( 489 "unsupported IPv6 socket option IPV6_TRANSPARENT (%d), you can not enable transparent proxying in linux programs -- note, IP_FREEBIND is supported, no idea if the FreeBSD IP_BINDANY is equivalent to the Linux IP_TRANSPARENT or not, any info is welcome", 490 opt); 491 return (-2); 492 case LINUX_IPV6_UNICAST_IF: 493 LINUX_RATELIMIT_MSG_OPT1( 494 "unsupported IPv6 socket option IPV6_UNICAST_IF (%d)", 495 opt); 496 return (-2); 497 case LINUX_IPV6_RECVFRAGSIZE: 498 LINUX_RATELIMIT_MSG_OPT1( 499 "unsupported IPv6 socket option IPV6_RECVFRAGSIZE (%d)", 500 opt); 501 return (-2); 502 503 /* unknown sockopts */ 504 default: 505 return (-1); 506 } 507 } 508 509 static int 510 linux_to_bsd_so_sockopt(int opt) 511 { 512 513 switch (opt) { 514 case LINUX_SO_DEBUG: 515 return (SO_DEBUG); 516 case LINUX_SO_REUSEADDR: 517 return (SO_REUSEADDR); 518 case LINUX_SO_TYPE: 519 return (SO_TYPE); 520 case LINUX_SO_ERROR: 521 return (SO_ERROR); 522 case LINUX_SO_DONTROUTE: 523 return (SO_DONTROUTE); 524 case LINUX_SO_BROADCAST: 525 return (SO_BROADCAST); 526 case LINUX_SO_SNDBUF: 527 case LINUX_SO_SNDBUFFORCE: 528 return (SO_SNDBUF); 529 case LINUX_SO_RCVBUF: 530 case LINUX_SO_RCVBUFFORCE: 531 return (SO_RCVBUF); 532 case LINUX_SO_KEEPALIVE: 533 return (SO_KEEPALIVE); 534 case LINUX_SO_OOBINLINE: 535 return (SO_OOBINLINE); 536 case LINUX_SO_LINGER: 537 return (SO_LINGER); 538 case LINUX_SO_REUSEPORT: 539 return (SO_REUSEPORT_LB); 540 case LINUX_SO_PASSCRED: 541 return (LOCAL_CREDS_PERSISTENT); 542 case LINUX_SO_PEERCRED: 543 return (LOCAL_PEERCRED); 544 case LINUX_SO_RCVLOWAT: 545 return (SO_RCVLOWAT); 546 case LINUX_SO_SNDLOWAT: 547 return (SO_SNDLOWAT); 548 case LINUX_SO_RCVTIMEO: 549 return (SO_RCVTIMEO); 550 case LINUX_SO_SNDTIMEO: 551 return (SO_SNDTIMEO); 552 case LINUX_SO_TIMESTAMPO: 553 case LINUX_SO_TIMESTAMPN: 554 return (SO_TIMESTAMP); 555 case LINUX_SO_TIMESTAMPNSO: 556 case LINUX_SO_TIMESTAMPNSN: 557 return (SO_BINTIME); 558 case LINUX_SO_ACCEPTCONN: 559 return (SO_ACCEPTCONN); 560 case LINUX_SO_PROTOCOL: 561 return (SO_PROTOCOL); 562 case LINUX_SO_DOMAIN: 563 return (SO_DOMAIN); 564 } 565 return (-1); 566 } 567 568 static int 569 linux_to_bsd_tcp_sockopt(int opt) 570 { 571 572 switch (opt) { 573 case LINUX_TCP_NODELAY: 574 return (TCP_NODELAY); 575 case LINUX_TCP_MAXSEG: 576 return (TCP_MAXSEG); 577 case LINUX_TCP_CORK: 578 return (TCP_NOPUSH); 579 case LINUX_TCP_KEEPIDLE: 580 return (TCP_KEEPIDLE); 581 case LINUX_TCP_KEEPINTVL: 582 return (TCP_KEEPINTVL); 583 case LINUX_TCP_KEEPCNT: 584 return (TCP_KEEPCNT); 585 case LINUX_TCP_INFO: 586 LINUX_RATELIMIT_MSG_OPT1( 587 "unsupported TCP socket option TCP_INFO (%d)", opt); 588 return (-2); 589 case LINUX_TCP_MD5SIG: 590 return (TCP_MD5SIG); 591 } 592 return (-1); 593 } 594 595 static int 596 linux_to_bsd_msg_flags(int flags) 597 { 598 int ret_flags = 0; 599 600 if (flags & LINUX_MSG_OOB) 601 ret_flags |= MSG_OOB; 602 if (flags & LINUX_MSG_PEEK) 603 ret_flags |= MSG_PEEK; 604 if (flags & LINUX_MSG_DONTROUTE) 605 ret_flags |= MSG_DONTROUTE; 606 if (flags & LINUX_MSG_CTRUNC) 607 ret_flags |= MSG_CTRUNC; 608 if (flags & LINUX_MSG_TRUNC) 609 ret_flags |= MSG_TRUNC; 610 if (flags & LINUX_MSG_DONTWAIT) 611 ret_flags |= MSG_DONTWAIT; 612 if (flags & LINUX_MSG_EOR) 613 ret_flags |= MSG_EOR; 614 if (flags & LINUX_MSG_WAITALL) 615 ret_flags |= MSG_WAITALL; 616 if (flags & LINUX_MSG_NOSIGNAL) 617 ret_flags |= MSG_NOSIGNAL; 618 if (flags & LINUX_MSG_PROXY) 619 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_PROXY (%d) not handled", 620 LINUX_MSG_PROXY); 621 if (flags & LINUX_MSG_FIN) 622 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_FIN (%d) not handled", 623 LINUX_MSG_FIN); 624 if (flags & LINUX_MSG_SYN) 625 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_SYN (%d) not handled", 626 LINUX_MSG_SYN); 627 if (flags & LINUX_MSG_CONFIRM) 628 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_CONFIRM (%d) not handled", 629 LINUX_MSG_CONFIRM); 630 if (flags & LINUX_MSG_RST) 631 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_RST (%d) not handled", 632 LINUX_MSG_RST); 633 if (flags & LINUX_MSG_ERRQUEUE) 634 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_ERRQUEUE (%d) not handled", 635 LINUX_MSG_ERRQUEUE); 636 return (ret_flags); 637 } 638 639 static int 640 linux_to_bsd_cmsg_type(int cmsg_type) 641 { 642 643 switch (cmsg_type) { 644 case LINUX_SCM_RIGHTS: 645 return (SCM_RIGHTS); 646 case LINUX_SCM_CREDENTIALS: 647 return (SCM_CREDS); 648 } 649 return (-1); 650 } 651 652 static int 653 bsd_to_linux_ip_cmsg_type(int cmsg_type) 654 { 655 656 switch (cmsg_type) { 657 case IP_RECVORIGDSTADDR: 658 return (LINUX_IP_RECVORIGDSTADDR); 659 } 660 return (-1); 661 } 662 663 static int 664 bsd_to_linux_cmsg_type(struct proc *p, int cmsg_type, int cmsg_level) 665 { 666 struct linux_pemuldata *pem; 667 668 if (cmsg_level == IPPROTO_IP) 669 return (bsd_to_linux_ip_cmsg_type(cmsg_type)); 670 if (cmsg_level != SOL_SOCKET) 671 return (-1); 672 673 pem = pem_find(p); 674 675 switch (cmsg_type) { 676 case SCM_RIGHTS: 677 return (LINUX_SCM_RIGHTS); 678 case SCM_CREDS: 679 return (LINUX_SCM_CREDENTIALS); 680 case SCM_CREDS2: 681 return (LINUX_SCM_CREDENTIALS); 682 case SCM_TIMESTAMP: 683 return (pem->so_timestamp); 684 case SCM_BINTIME: 685 return (pem->so_timestampns); 686 } 687 return (-1); 688 } 689 690 static int 691 linux_to_bsd_msghdr(struct msghdr *bhdr, const struct l_msghdr *lhdr) 692 { 693 if (lhdr->msg_controllen > INT_MAX) 694 return (ENOBUFS); 695 696 bhdr->msg_name = PTRIN(lhdr->msg_name); 697 bhdr->msg_namelen = lhdr->msg_namelen; 698 bhdr->msg_iov = PTRIN(lhdr->msg_iov); 699 bhdr->msg_iovlen = lhdr->msg_iovlen; 700 bhdr->msg_control = PTRIN(lhdr->msg_control); 701 702 /* 703 * msg_controllen is skipped since BSD and LINUX control messages 704 * are potentially different sizes (e.g. the cred structure used 705 * by SCM_CREDS is different between the two operating system). 706 * 707 * The caller can set it (if necessary) after converting all the 708 * control messages. 709 */ 710 711 bhdr->msg_flags = linux_to_bsd_msg_flags(lhdr->msg_flags); 712 return (0); 713 } 714 715 static int 716 bsd_to_linux_msghdr(const struct msghdr *bhdr, struct l_msghdr *lhdr) 717 { 718 lhdr->msg_name = PTROUT(bhdr->msg_name); 719 lhdr->msg_namelen = bhdr->msg_namelen; 720 lhdr->msg_iov = PTROUT(bhdr->msg_iov); 721 lhdr->msg_iovlen = bhdr->msg_iovlen; 722 lhdr->msg_control = PTROUT(bhdr->msg_control); 723 724 /* 725 * msg_controllen is skipped since BSD and LINUX control messages 726 * are potentially different sizes (e.g. the cred structure used 727 * by SCM_CREDS is different between the two operating system). 728 * 729 * The caller can set it (if necessary) after converting all the 730 * control messages. 731 */ 732 733 /* msg_flags skipped */ 734 return (0); 735 } 736 737 static int 738 linux_set_socket_flags(int lflags, int *flags) 739 { 740 741 if (lflags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) 742 return (EINVAL); 743 if (lflags & LINUX_SOCK_NONBLOCK) 744 *flags |= SOCK_NONBLOCK; 745 if (lflags & LINUX_SOCK_CLOEXEC) 746 *flags |= SOCK_CLOEXEC; 747 return (0); 748 } 749 750 static int 751 linux_copyout_sockaddr(const struct sockaddr *sa, void *uaddr, size_t len) 752 { 753 struct l_sockaddr *lsa; 754 int error; 755 756 error = bsd_to_linux_sockaddr(sa, &lsa, len); 757 if (error != 0) 758 return (error); 759 760 error = copyout(lsa, uaddr, len); 761 free(lsa, M_LINUX); 762 763 return (error); 764 } 765 766 static int 767 linux_sendit(struct thread *td, int s, struct msghdr *mp, int flags, 768 struct mbuf *control, enum uio_seg segflg) 769 { 770 struct sockaddr *to; 771 int error, len; 772 773 if (mp->msg_name != NULL) { 774 len = mp->msg_namelen; 775 error = linux_to_bsd_sockaddr(mp->msg_name, &to, &len); 776 if (error != 0) 777 return (error); 778 mp->msg_name = to; 779 } else 780 to = NULL; 781 782 error = kern_sendit(td, s, mp, linux_to_bsd_msg_flags(flags), control, 783 segflg); 784 785 if (to) 786 free(to, M_SONAME); 787 return (error); 788 } 789 790 /* Return 0 if IP_HDRINCL is set for the given socket. */ 791 static int 792 linux_check_hdrincl(struct thread *td, int s) 793 { 794 int error, optval; 795 socklen_t size_val; 796 797 size_val = sizeof(optval); 798 error = kern_getsockopt(td, s, IPPROTO_IP, IP_HDRINCL, 799 &optval, UIO_SYSSPACE, &size_val); 800 if (error != 0) 801 return (error); 802 803 return (optval == 0); 804 } 805 806 /* 807 * Updated sendto() when IP_HDRINCL is set: 808 * tweak endian-dependent fields in the IP packet. 809 */ 810 static int 811 linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args) 812 { 813 /* 814 * linux_ip_copysize defines how many bytes we should copy 815 * from the beginning of the IP packet before we customize it for BSD. 816 * It should include all the fields we modify (ip_len and ip_off). 817 */ 818 #define linux_ip_copysize 8 819 820 struct ip *packet; 821 struct msghdr msg; 822 struct iovec aiov[1]; 823 int error; 824 825 /* Check that the packet isn't too big or too small. */ 826 if (linux_args->len < linux_ip_copysize || 827 linux_args->len > IP_MAXPACKET) 828 return (EINVAL); 829 830 packet = (struct ip *)malloc(linux_args->len, M_LINUX, M_WAITOK); 831 832 /* Make kernel copy of the packet to be sent */ 833 if ((error = copyin(PTRIN(linux_args->msg), packet, 834 linux_args->len))) 835 goto goout; 836 837 /* Convert fields from Linux to BSD raw IP socket format */ 838 packet->ip_len = linux_args->len; 839 packet->ip_off = ntohs(packet->ip_off); 840 841 /* Prepare the msghdr and iovec structures describing the new packet */ 842 msg.msg_name = PTRIN(linux_args->to); 843 msg.msg_namelen = linux_args->tolen; 844 msg.msg_iov = aiov; 845 msg.msg_iovlen = 1; 846 msg.msg_control = NULL; 847 msg.msg_flags = 0; 848 aiov[0].iov_base = (char *)packet; 849 aiov[0].iov_len = linux_args->len; 850 error = linux_sendit(td, linux_args->s, &msg, linux_args->flags, 851 NULL, UIO_SYSSPACE); 852 goout: 853 free(packet, M_LINUX); 854 return (error); 855 } 856 857 static const char *linux_netlink_names[] = { 858 [LINUX_NETLINK_ROUTE] = "ROUTE", 859 [LINUX_NETLINK_SOCK_DIAG] = "SOCK_DIAG", 860 [LINUX_NETLINK_NFLOG] = "NFLOG", 861 [LINUX_NETLINK_SELINUX] = "SELINUX", 862 [LINUX_NETLINK_AUDIT] = "AUDIT", 863 [LINUX_NETLINK_FIB_LOOKUP] = "FIB_LOOKUP", 864 [LINUX_NETLINK_NETFILTER] = "NETFILTER", 865 [LINUX_NETLINK_KOBJECT_UEVENT] = "KOBJECT_UEVENT", 866 }; 867 868 int 869 linux_socket(struct thread *td, struct linux_socket_args *args) 870 { 871 int domain, retval_socket, type; 872 873 type = args->type & LINUX_SOCK_TYPE_MASK; 874 if (type < 0 || type > LINUX_SOCK_MAX) 875 return (EINVAL); 876 retval_socket = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK, 877 &type); 878 if (retval_socket != 0) 879 return (retval_socket); 880 domain = linux_to_bsd_domain(args->domain); 881 if (domain == -1) { 882 /* Mask off SOCK_NONBLOCK / CLOEXEC for error messages. */ 883 type = args->type & LINUX_SOCK_TYPE_MASK; 884 if (args->domain == LINUX_AF_NETLINK && 885 args->protocol == LINUX_NETLINK_AUDIT) { 886 ; /* Do nothing, quietly. */ 887 } else if (args->domain == LINUX_AF_NETLINK) { 888 const char *nl_name; 889 890 if (args->protocol >= 0 && 891 args->protocol < nitems(linux_netlink_names)) 892 nl_name = linux_netlink_names[args->protocol]; 893 else 894 nl_name = NULL; 895 if (nl_name != NULL) 896 linux_msg(curthread, 897 "unsupported socket(AF_NETLINK, %d, " 898 "NETLINK_%s)", type, nl_name); 899 else 900 linux_msg(curthread, 901 "unsupported socket(AF_NETLINK, %d, %d)", 902 type, args->protocol); 903 } else { 904 linux_msg(curthread, "unsupported socket domain %d, " 905 "type %d, protocol %d", args->domain, type, 906 args->protocol); 907 } 908 return (EAFNOSUPPORT); 909 } 910 911 retval_socket = kern_socket(td, domain, type, args->protocol); 912 if (retval_socket) 913 return (retval_socket); 914 915 if (type == SOCK_RAW 916 && (args->protocol == IPPROTO_RAW || args->protocol == 0) 917 && domain == PF_INET) { 918 /* It's a raw IP socket: set the IP_HDRINCL option. */ 919 int hdrincl; 920 921 hdrincl = 1; 922 /* We ignore any error returned by kern_setsockopt() */ 923 kern_setsockopt(td, td->td_retval[0], IPPROTO_IP, IP_HDRINCL, 924 &hdrincl, UIO_SYSSPACE, sizeof(hdrincl)); 925 } 926 #ifdef INET6 927 /* 928 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by default 929 * and some apps depend on this. So, set V6ONLY to 0 for Linux apps. 930 * For simplicity we do this unconditionally of the net.inet6.ip6.v6only 931 * sysctl value. 932 */ 933 if (domain == PF_INET6) { 934 int v6only; 935 936 v6only = 0; 937 /* We ignore any error returned by setsockopt() */ 938 kern_setsockopt(td, td->td_retval[0], IPPROTO_IPV6, IPV6_V6ONLY, 939 &v6only, UIO_SYSSPACE, sizeof(v6only)); 940 } 941 #endif 942 943 return (retval_socket); 944 } 945 946 int 947 linux_bind(struct thread *td, struct linux_bind_args *args) 948 { 949 struct sockaddr *sa; 950 int error; 951 952 error = linux_to_bsd_sockaddr(PTRIN(args->name), &sa, 953 &args->namelen); 954 if (error != 0) 955 return (error); 956 957 error = kern_bindat(td, AT_FDCWD, args->s, sa); 958 free(sa, M_SONAME); 959 960 /* XXX */ 961 if (error == EADDRNOTAVAIL && args->namelen != sizeof(struct sockaddr_in)) 962 return (EINVAL); 963 return (error); 964 } 965 966 int 967 linux_connect(struct thread *td, struct linux_connect_args *args) 968 { 969 struct socket *so; 970 struct sockaddr *sa; 971 struct file *fp; 972 int error; 973 974 error = linux_to_bsd_sockaddr(PTRIN(args->name), &sa, 975 &args->namelen); 976 if (error != 0) 977 return (error); 978 979 error = kern_connectat(td, AT_FDCWD, args->s, sa); 980 free(sa, M_SONAME); 981 if (error != EISCONN) 982 return (error); 983 984 /* 985 * Linux doesn't return EISCONN the first time it occurs, 986 * when on a non-blocking socket. Instead it returns the 987 * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. 988 */ 989 error = getsock(td, args->s, &cap_connect_rights, &fp); 990 if (error != 0) 991 return (error); 992 993 error = EISCONN; 994 so = fp->f_data; 995 if (atomic_load_int(&fp->f_flag) & FNONBLOCK) { 996 SOCK_LOCK(so); 997 if (so->so_emuldata == 0) 998 error = so->so_error; 999 so->so_emuldata = (void *)1; 1000 SOCK_UNLOCK(so); 1001 } 1002 fdrop(fp, td); 1003 1004 return (error); 1005 } 1006 1007 int 1008 linux_listen(struct thread *td, struct linux_listen_args *args) 1009 { 1010 1011 return (kern_listen(td, args->s, args->backlog)); 1012 } 1013 1014 static int 1015 linux_accept_common(struct thread *td, int s, l_uintptr_t addr, 1016 l_uintptr_t namelen, int flags) 1017 { 1018 struct sockaddr *sa; 1019 struct file *fp, *fp1; 1020 int bflags, len; 1021 struct socket *so; 1022 int error, error1; 1023 1024 bflags = 0; 1025 fp = NULL; 1026 sa = NULL; 1027 1028 error = linux_set_socket_flags(flags, &bflags); 1029 if (error != 0) 1030 return (error); 1031 1032 if (PTRIN(addr) == NULL) { 1033 len = 0; 1034 error = kern_accept4(td, s, NULL, NULL, bflags, NULL); 1035 } else { 1036 error = copyin(PTRIN(namelen), &len, sizeof(len)); 1037 if (error != 0) 1038 return (error); 1039 if (len < 0) 1040 return (EINVAL); 1041 error = kern_accept4(td, s, &sa, &len, bflags, &fp); 1042 } 1043 1044 /* 1045 * Translate errno values into ones used by Linux. 1046 */ 1047 if (error != 0) { 1048 /* 1049 * XXX. This is wrong, different sockaddr structures 1050 * have different sizes. 1051 */ 1052 switch (error) { 1053 case EFAULT: 1054 if (namelen != sizeof(struct sockaddr_in)) 1055 error = EINVAL; 1056 break; 1057 case EINVAL: 1058 error1 = getsock(td, s, &cap_accept_rights, &fp1); 1059 if (error1 != 0) { 1060 error = error1; 1061 break; 1062 } 1063 so = fp1->f_data; 1064 if (so->so_type == SOCK_DGRAM) 1065 error = EOPNOTSUPP; 1066 fdrop(fp1, td); 1067 break; 1068 } 1069 return (error); 1070 } 1071 1072 if (len != 0) { 1073 error = linux_copyout_sockaddr(sa, PTRIN(addr), len); 1074 if (error == 0) 1075 error = copyout(&len, PTRIN(namelen), 1076 sizeof(len)); 1077 if (error != 0) { 1078 fdclose(td, fp, td->td_retval[0]); 1079 td->td_retval[0] = 0; 1080 } 1081 } 1082 if (fp != NULL) 1083 fdrop(fp, td); 1084 free(sa, M_SONAME); 1085 return (error); 1086 } 1087 1088 int 1089 linux_accept(struct thread *td, struct linux_accept_args *args) 1090 { 1091 1092 return (linux_accept_common(td, args->s, args->addr, 1093 args->namelen, 0)); 1094 } 1095 1096 int 1097 linux_accept4(struct thread *td, struct linux_accept4_args *args) 1098 { 1099 1100 return (linux_accept_common(td, args->s, args->addr, 1101 args->namelen, args->flags)); 1102 } 1103 1104 int 1105 linux_getsockname(struct thread *td, struct linux_getsockname_args *args) 1106 { 1107 struct sockaddr *sa; 1108 int len, error; 1109 1110 error = copyin(PTRIN(args->namelen), &len, sizeof(len)); 1111 if (error != 0) 1112 return (error); 1113 1114 error = kern_getsockname(td, args->s, &sa, &len); 1115 if (error != 0) 1116 return (error); 1117 1118 if (len != 0) 1119 error = linux_copyout_sockaddr(sa, PTRIN(args->addr), len); 1120 1121 free(sa, M_SONAME); 1122 if (error == 0) 1123 error = copyout(&len, PTRIN(args->namelen), sizeof(len)); 1124 return (error); 1125 } 1126 1127 int 1128 linux_getpeername(struct thread *td, struct linux_getpeername_args *args) 1129 { 1130 struct sockaddr *sa; 1131 int len, error; 1132 1133 error = copyin(PTRIN(args->namelen), &len, sizeof(len)); 1134 if (error != 0) 1135 return (error); 1136 if (len < 0) 1137 return (EINVAL); 1138 1139 error = kern_getpeername(td, args->s, &sa, &len); 1140 if (error != 0) 1141 return (error); 1142 1143 if (len != 0) 1144 error = linux_copyout_sockaddr(sa, PTRIN(args->addr), len); 1145 1146 free(sa, M_SONAME); 1147 if (error == 0) 1148 error = copyout(&len, PTRIN(args->namelen), sizeof(len)); 1149 return (error); 1150 } 1151 1152 int 1153 linux_socketpair(struct thread *td, struct linux_socketpair_args *args) 1154 { 1155 int domain, error, sv[2], type; 1156 1157 domain = linux_to_bsd_domain(args->domain); 1158 if (domain != PF_LOCAL) 1159 return (EAFNOSUPPORT); 1160 type = args->type & LINUX_SOCK_TYPE_MASK; 1161 if (type < 0 || type > LINUX_SOCK_MAX) 1162 return (EINVAL); 1163 error = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK, 1164 &type); 1165 if (error != 0) 1166 return (error); 1167 if (args->protocol != 0 && args->protocol != PF_UNIX) { 1168 /* 1169 * Use of PF_UNIX as protocol argument is not right, 1170 * but Linux does it. 1171 * Do not map PF_UNIX as its Linux value is identical 1172 * to FreeBSD one. 1173 */ 1174 return (EPROTONOSUPPORT); 1175 } 1176 error = kern_socketpair(td, domain, type, 0, sv); 1177 if (error != 0) 1178 return (error); 1179 error = copyout(sv, PTRIN(args->rsv), 2 * sizeof(int)); 1180 if (error != 0) { 1181 (void)kern_close(td, sv[0]); 1182 (void)kern_close(td, sv[1]); 1183 } 1184 return (error); 1185 } 1186 1187 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 1188 struct linux_send_args { 1189 register_t s; 1190 register_t msg; 1191 register_t len; 1192 register_t flags; 1193 }; 1194 1195 static int 1196 linux_send(struct thread *td, struct linux_send_args *args) 1197 { 1198 struct sendto_args /* { 1199 int s; 1200 caddr_t buf; 1201 int len; 1202 int flags; 1203 caddr_t to; 1204 int tolen; 1205 } */ bsd_args; 1206 struct file *fp; 1207 int error; 1208 1209 bsd_args.s = args->s; 1210 bsd_args.buf = (caddr_t)PTRIN(args->msg); 1211 bsd_args.len = args->len; 1212 bsd_args.flags = linux_to_bsd_msg_flags(args->flags); 1213 bsd_args.to = NULL; 1214 bsd_args.tolen = 0; 1215 error = sys_sendto(td, &bsd_args); 1216 if (error == ENOTCONN) { 1217 /* 1218 * Linux doesn't return ENOTCONN for non-blocking sockets. 1219 * Instead it returns the EAGAIN. 1220 */ 1221 error = getsock(td, args->s, &cap_send_rights, &fp); 1222 if (error == 0) { 1223 if (atomic_load_int(&fp->f_flag) & FNONBLOCK) 1224 error = EAGAIN; 1225 fdrop(fp, td); 1226 } 1227 } 1228 return (error); 1229 } 1230 1231 struct linux_recv_args { 1232 register_t s; 1233 register_t msg; 1234 register_t len; 1235 register_t flags; 1236 }; 1237 1238 static int 1239 linux_recv(struct thread *td, struct linux_recv_args *args) 1240 { 1241 struct recvfrom_args /* { 1242 int s; 1243 caddr_t buf; 1244 int len; 1245 int flags; 1246 struct sockaddr *from; 1247 socklen_t fromlenaddr; 1248 } */ bsd_args; 1249 1250 bsd_args.s = args->s; 1251 bsd_args.buf = (caddr_t)PTRIN(args->msg); 1252 bsd_args.len = args->len; 1253 bsd_args.flags = linux_to_bsd_msg_flags(args->flags); 1254 bsd_args.from = NULL; 1255 bsd_args.fromlenaddr = 0; 1256 return (sys_recvfrom(td, &bsd_args)); 1257 } 1258 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 1259 1260 int 1261 linux_sendto(struct thread *td, struct linux_sendto_args *args) 1262 { 1263 struct msghdr msg; 1264 struct iovec aiov; 1265 struct socket *so; 1266 struct file *fp; 1267 int error; 1268 1269 if (linux_check_hdrincl(td, args->s) == 0) 1270 /* IP_HDRINCL set, tweak the packet before sending */ 1271 return (linux_sendto_hdrincl(td, args)); 1272 1273 bzero(&msg, sizeof(msg)); 1274 error = getsock(td, args->s, &cap_send_connect_rights, &fp); 1275 if (error != 0) 1276 return (error); 1277 so = fp->f_data; 1278 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0) { 1279 msg.msg_name = PTRIN(args->to); 1280 msg.msg_namelen = args->tolen; 1281 } 1282 msg.msg_iov = &aiov; 1283 msg.msg_iovlen = 1; 1284 aiov.iov_base = PTRIN(args->msg); 1285 aiov.iov_len = args->len; 1286 fdrop(fp, td); 1287 return (linux_sendit(td, args->s, &msg, args->flags, NULL, 1288 UIO_USERSPACE)); 1289 } 1290 1291 int 1292 linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) 1293 { 1294 struct sockaddr *sa; 1295 struct msghdr msg; 1296 struct iovec aiov; 1297 int error, fromlen; 1298 1299 if (PTRIN(args->fromlen) != NULL) { 1300 error = copyin(PTRIN(args->fromlen), &fromlen, 1301 sizeof(fromlen)); 1302 if (error != 0) 1303 return (error); 1304 if (fromlen < 0) 1305 return (EINVAL); 1306 fromlen = min(fromlen, SOCK_MAXADDRLEN); 1307 sa = malloc(fromlen, M_SONAME, M_WAITOK); 1308 } else { 1309 fromlen = 0; 1310 sa = NULL; 1311 } 1312 1313 msg.msg_name = sa; 1314 msg.msg_namelen = fromlen; 1315 msg.msg_iov = &aiov; 1316 msg.msg_iovlen = 1; 1317 aiov.iov_base = PTRIN(args->buf); 1318 aiov.iov_len = args->len; 1319 msg.msg_control = 0; 1320 msg.msg_flags = linux_to_bsd_msg_flags(args->flags); 1321 1322 error = kern_recvit(td, args->s, &msg, UIO_SYSSPACE, NULL); 1323 if (error != 0) 1324 goto out; 1325 1326 /* 1327 * XXX. Seems that FreeBSD is different from Linux here. Linux 1328 * fill source address if underlying protocol provides it, while 1329 * FreeBSD fill it if underlying protocol is not connection-oriented. 1330 * So, kern_recvit() set msg.msg_namelen to 0 if protocol pr_flags 1331 * does not contains PR_ADDR flag. 1332 */ 1333 if (PTRIN(args->from) != NULL && msg.msg_namelen != 0) 1334 error = linux_copyout_sockaddr(sa, PTRIN(args->from), 1335 msg.msg_namelen); 1336 1337 if (error == 0 && PTRIN(args->fromlen) != NULL) 1338 error = copyout(&msg.msg_namelen, PTRIN(args->fromlen), 1339 sizeof(msg.msg_namelen)); 1340 out: 1341 free(sa, M_SONAME); 1342 return (error); 1343 } 1344 1345 static int 1346 linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, 1347 l_uint flags) 1348 { 1349 struct cmsghdr *cmsg; 1350 struct mbuf *control; 1351 struct msghdr msg; 1352 struct l_cmsghdr linux_cmsg; 1353 struct l_cmsghdr *ptr_cmsg; 1354 struct l_msghdr linux_msghdr; 1355 struct iovec *iov; 1356 socklen_t datalen; 1357 struct sockaddr *sa; 1358 struct socket *so; 1359 sa_family_t sa_family; 1360 struct file *fp; 1361 void *data; 1362 l_size_t len; 1363 l_size_t clen; 1364 int error; 1365 1366 error = copyin(msghdr, &linux_msghdr, sizeof(linux_msghdr)); 1367 if (error != 0) 1368 return (error); 1369 1370 /* 1371 * Some Linux applications (ping) define a non-NULL control data 1372 * pointer, but a msg_controllen of 0, which is not allowed in the 1373 * FreeBSD system call interface. NULL the msg_control pointer in 1374 * order to handle this case. This should be checked, but allows the 1375 * Linux ping to work. 1376 */ 1377 if (PTRIN(linux_msghdr.msg_control) != NULL && 1378 linux_msghdr.msg_controllen == 0) 1379 linux_msghdr.msg_control = PTROUT(NULL); 1380 1381 error = linux_to_bsd_msghdr(&msg, &linux_msghdr); 1382 if (error != 0) 1383 return (error); 1384 1385 #ifdef COMPAT_LINUX32 1386 error = linux32_copyiniov(PTRIN(msg.msg_iov), msg.msg_iovlen, 1387 &iov, EMSGSIZE); 1388 #else 1389 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); 1390 #endif 1391 if (error != 0) 1392 return (error); 1393 1394 control = NULL; 1395 1396 error = kern_getsockname(td, s, &sa, &datalen); 1397 if (error != 0) 1398 goto bad; 1399 sa_family = sa->sa_family; 1400 free(sa, M_SONAME); 1401 1402 if (flags & LINUX_MSG_OOB) { 1403 error = EOPNOTSUPP; 1404 if (sa_family == AF_UNIX) 1405 goto bad; 1406 1407 error = getsock(td, s, &cap_send_rights, &fp); 1408 if (error != 0) 1409 goto bad; 1410 so = fp->f_data; 1411 if (so->so_type != SOCK_STREAM) 1412 error = EOPNOTSUPP; 1413 fdrop(fp, td); 1414 if (error != 0) 1415 goto bad; 1416 } 1417 1418 if (linux_msghdr.msg_controllen >= sizeof(struct l_cmsghdr)) { 1419 error = ENOBUFS; 1420 control = m_get(M_WAITOK, MT_CONTROL); 1421 MCLGET(control, M_WAITOK); 1422 data = mtod(control, void *); 1423 datalen = 0; 1424 1425 ptr_cmsg = PTRIN(linux_msghdr.msg_control); 1426 clen = linux_msghdr.msg_controllen; 1427 do { 1428 error = copyin(ptr_cmsg, &linux_cmsg, 1429 sizeof(struct l_cmsghdr)); 1430 if (error != 0) 1431 goto bad; 1432 1433 error = EINVAL; 1434 if (linux_cmsg.cmsg_len < sizeof(struct l_cmsghdr) || 1435 linux_cmsg.cmsg_len > clen) 1436 goto bad; 1437 1438 if (datalen + CMSG_HDRSZ > MCLBYTES) 1439 goto bad; 1440 1441 /* 1442 * Now we support only SCM_RIGHTS and SCM_CRED, 1443 * so return EINVAL in any other cmsg_type 1444 */ 1445 cmsg = data; 1446 cmsg->cmsg_type = 1447 linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type); 1448 cmsg->cmsg_level = 1449 linux_to_bsd_sockopt_level(linux_cmsg.cmsg_level); 1450 if (cmsg->cmsg_type == -1 1451 || cmsg->cmsg_level != SOL_SOCKET) { 1452 linux_msg(curthread, 1453 "unsupported sendmsg cmsg level %d type %d", 1454 linux_cmsg.cmsg_level, linux_cmsg.cmsg_type); 1455 goto bad; 1456 } 1457 1458 /* 1459 * Some applications (e.g. pulseaudio) attempt to 1460 * send ancillary data even if the underlying protocol 1461 * doesn't support it which is not allowed in the 1462 * FreeBSD system call interface. 1463 */ 1464 if (sa_family != AF_UNIX) 1465 goto next; 1466 1467 if (cmsg->cmsg_type == SCM_CREDS) { 1468 len = sizeof(struct cmsgcred); 1469 if (datalen + CMSG_SPACE(len) > MCLBYTES) 1470 goto bad; 1471 1472 /* 1473 * The lower levels will fill in the structure 1474 */ 1475 memset(CMSG_DATA(data), 0, len); 1476 } else { 1477 len = linux_cmsg.cmsg_len - L_CMSG_HDRSZ; 1478 if (datalen + CMSG_SPACE(len) < datalen || 1479 datalen + CMSG_SPACE(len) > MCLBYTES) 1480 goto bad; 1481 1482 error = copyin(LINUX_CMSG_DATA(ptr_cmsg), 1483 CMSG_DATA(data), len); 1484 if (error != 0) 1485 goto bad; 1486 } 1487 1488 cmsg->cmsg_len = CMSG_LEN(len); 1489 data = (char *)data + CMSG_SPACE(len); 1490 datalen += CMSG_SPACE(len); 1491 1492 next: 1493 if (clen <= LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len)) 1494 break; 1495 1496 clen -= LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len); 1497 ptr_cmsg = (struct l_cmsghdr *)((char *)ptr_cmsg + 1498 LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len)); 1499 } while(clen >= sizeof(struct l_cmsghdr)); 1500 1501 control->m_len = datalen; 1502 if (datalen == 0) { 1503 m_freem(control); 1504 control = NULL; 1505 } 1506 } 1507 1508 msg.msg_iov = iov; 1509 msg.msg_flags = 0; 1510 error = linux_sendit(td, s, &msg, flags, control, UIO_USERSPACE); 1511 control = NULL; 1512 1513 bad: 1514 m_freem(control); 1515 free(iov, M_IOV); 1516 return (error); 1517 } 1518 1519 int 1520 linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) 1521 { 1522 1523 return (linux_sendmsg_common(td, args->s, PTRIN(args->msg), 1524 args->flags)); 1525 } 1526 1527 int 1528 linux_sendmmsg(struct thread *td, struct linux_sendmmsg_args *args) 1529 { 1530 struct l_mmsghdr *msg; 1531 l_uint retval; 1532 int error, datagrams; 1533 1534 if (args->vlen > UIO_MAXIOV) 1535 args->vlen = UIO_MAXIOV; 1536 1537 msg = PTRIN(args->msg); 1538 datagrams = 0; 1539 while (datagrams < args->vlen) { 1540 error = linux_sendmsg_common(td, args->s, &msg->msg_hdr, 1541 args->flags); 1542 if (error != 0) 1543 break; 1544 1545 retval = td->td_retval[0]; 1546 error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len)); 1547 if (error != 0) 1548 break; 1549 ++msg; 1550 ++datagrams; 1551 } 1552 if (error == 0) 1553 td->td_retval[0] = datagrams; 1554 return (error); 1555 } 1556 1557 static int 1558 recvmsg_scm_rights(struct thread *td, l_uint flags, socklen_t *datalen, 1559 void **data, void **udata) 1560 { 1561 int i, fd, fds, *fdp; 1562 1563 if (flags & LINUX_MSG_CMSG_CLOEXEC) { 1564 fds = *datalen / sizeof(int); 1565 fdp = *data; 1566 for (i = 0; i < fds; i++) { 1567 fd = *fdp++; 1568 (void)kern_fcntl(td, fd, F_SETFD, FD_CLOEXEC); 1569 } 1570 } 1571 return (0); 1572 } 1573 1574 1575 static int 1576 recvmsg_scm_creds(socklen_t *datalen, void **data, void **udata) 1577 { 1578 struct cmsgcred *cmcred; 1579 struct l_ucred lu; 1580 1581 cmcred = *data; 1582 lu.pid = cmcred->cmcred_pid; 1583 lu.uid = cmcred->cmcred_uid; 1584 lu.gid = cmcred->cmcred_gid; 1585 memmove(*data, &lu, sizeof(lu)); 1586 *datalen = sizeof(lu); 1587 return (0); 1588 } 1589 _Static_assert(sizeof(struct cmsgcred) >= sizeof(struct l_ucred), 1590 "scm_creds sizeof l_ucred"); 1591 1592 static int 1593 recvmsg_scm_creds2(socklen_t *datalen, void **data, void **udata) 1594 { 1595 struct sockcred2 *scred; 1596 struct l_ucred lu; 1597 1598 scred = *data; 1599 lu.pid = scred->sc_pid; 1600 lu.uid = scred->sc_uid; 1601 lu.gid = scred->sc_gid; 1602 memmove(*data, &lu, sizeof(lu)); 1603 *datalen = sizeof(lu); 1604 return (0); 1605 } 1606 _Static_assert(sizeof(struct sockcred2) >= sizeof(struct l_ucred), 1607 "scm_creds2 sizeof l_ucred"); 1608 1609 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 1610 static int 1611 recvmsg_scm_timestamp(l_int msg_type, socklen_t *datalen, void **data, 1612 void **udata) 1613 { 1614 l_sock_timeval ltv64; 1615 l_timeval ltv; 1616 struct timeval *tv; 1617 socklen_t len; 1618 void *buf; 1619 1620 if (*datalen != sizeof(struct timeval)) 1621 return (EMSGSIZE); 1622 1623 tv = *data; 1624 #if defined(COMPAT_LINUX32) 1625 if (msg_type == LINUX_SCM_TIMESTAMPO && 1626 (tv->tv_sec > INT_MAX || tv->tv_sec < INT_MIN)) 1627 return (EOVERFLOW); 1628 #endif 1629 if (msg_type == LINUX_SCM_TIMESTAMPN) 1630 len = sizeof(ltv64); 1631 else 1632 len = sizeof(ltv); 1633 1634 buf = malloc(len, M_LINUX, M_WAITOK); 1635 if (msg_type == LINUX_SCM_TIMESTAMPN) { 1636 ltv64.tv_sec = tv->tv_sec; 1637 ltv64.tv_usec = tv->tv_usec; 1638 memmove(buf, <v64, len); 1639 } else { 1640 ltv.tv_sec = tv->tv_sec; 1641 ltv.tv_usec = tv->tv_usec; 1642 memmove(buf, <v, len); 1643 } 1644 *data = *udata = buf; 1645 *datalen = len; 1646 return (0); 1647 } 1648 #else 1649 _Static_assert(sizeof(struct timeval) == sizeof(l_timeval), 1650 "scm_timestamp sizeof l_timeval"); 1651 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 1652 1653 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 1654 static int 1655 recvmsg_scm_timestampns(l_int msg_type, socklen_t *datalen, void **data, 1656 void **udata) 1657 { 1658 struct l_timespec64 ts64; 1659 struct l_timespec ts32; 1660 struct timespec ts; 1661 socklen_t len; 1662 void *buf; 1663 1664 if (msg_type == LINUX_SCM_TIMESTAMPNSO) 1665 len = sizeof(ts32); 1666 else 1667 len = sizeof(ts64); 1668 1669 buf = malloc(len, M_LINUX, M_WAITOK); 1670 bintime2timespec(*data, &ts); 1671 if (msg_type == LINUX_SCM_TIMESTAMPNSO) { 1672 ts32.tv_sec = ts.tv_sec; 1673 ts32.tv_nsec = ts.tv_nsec; 1674 memmove(buf, &ts32, len); 1675 } else { 1676 ts64.tv_sec = ts.tv_sec; 1677 ts64.tv_nsec = ts.tv_nsec; 1678 memmove(buf, &ts64, len); 1679 } 1680 *data = *udata = buf; 1681 *datalen = len; 1682 return (0); 1683 } 1684 #else 1685 static int 1686 recvmsg_scm_timestampns(l_int msg_type, socklen_t *datalen, void **data, 1687 void **udata) 1688 { 1689 struct timespec ts; 1690 1691 bintime2timespec(*data, &ts); 1692 memmove(*data, &ts, sizeof(struct timespec)); 1693 *datalen = sizeof(struct timespec); 1694 return (0); 1695 } 1696 _Static_assert(sizeof(struct bintime) >= sizeof(struct timespec), 1697 "scm_timestampns sizeof timespec"); 1698 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 1699 1700 static int 1701 recvmsg_scm_sol_socket(struct thread *td, l_int msg_type, l_int lmsg_type, 1702 l_uint flags, socklen_t *datalen, void **data, void **udata) 1703 { 1704 int error; 1705 1706 error = 0; 1707 switch (msg_type) { 1708 case SCM_RIGHTS: 1709 error = recvmsg_scm_rights(td, flags, datalen, 1710 data, udata); 1711 break; 1712 case SCM_CREDS: 1713 error = recvmsg_scm_creds(datalen, data, udata); 1714 break; 1715 case SCM_CREDS2: 1716 error = recvmsg_scm_creds2(datalen, data, udata); 1717 break; 1718 case SCM_TIMESTAMP: 1719 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 1720 error = recvmsg_scm_timestamp(lmsg_type, datalen, 1721 data, udata); 1722 #endif 1723 break; 1724 case SCM_BINTIME: 1725 error = recvmsg_scm_timestampns(lmsg_type, datalen, 1726 data, udata); 1727 break; 1728 } 1729 1730 return (error); 1731 } 1732 1733 static int 1734 recvmsg_scm_ip_origdstaddr(socklen_t *datalen, void **data, void **udata) 1735 { 1736 struct l_sockaddr *lsa; 1737 int error; 1738 1739 error = bsd_to_linux_sockaddr(*data, &lsa, *datalen); 1740 if (error == 0) { 1741 *data = *udata = lsa; 1742 *datalen = sizeof(*lsa); 1743 } 1744 return (error); 1745 } 1746 1747 static int 1748 recvmsg_scm_ipproto_ip(l_int msg_type, l_int lmsg_type, socklen_t *datalen, 1749 void **data, void **udata) 1750 { 1751 int error; 1752 1753 error = 0; 1754 switch (msg_type) { 1755 case IP_ORIGDSTADDR: 1756 error = recvmsg_scm_ip_origdstaddr(datalen, data, 1757 udata); 1758 break; 1759 } 1760 1761 return (error); 1762 } 1763 1764 static int 1765 linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, 1766 l_uint flags, struct msghdr *msg) 1767 { 1768 struct proc *p = td->td_proc; 1769 struct cmsghdr *cm; 1770 struct l_cmsghdr *lcm = NULL; 1771 socklen_t datalen, maxlen, outlen; 1772 struct l_msghdr l_msghdr; 1773 struct iovec *iov, *uiov; 1774 struct mbuf *m, *control = NULL; 1775 struct mbuf **controlp; 1776 struct sockaddr *sa; 1777 caddr_t outbuf; 1778 void *data, *udata; 1779 int error, skiped; 1780 1781 error = copyin(msghdr, &l_msghdr, sizeof(l_msghdr)); 1782 if (error != 0) 1783 return (error); 1784 1785 /* 1786 * Pass user-supplied recvmsg() flags in msg_flags field, 1787 * following sys_recvmsg() convention. 1788 */ 1789 l_msghdr.msg_flags = flags; 1790 1791 error = linux_to_bsd_msghdr(msg, &l_msghdr); 1792 if (error != 0) 1793 return (error); 1794 1795 #ifdef COMPAT_LINUX32 1796 error = linux32_copyiniov(PTRIN(msg->msg_iov), msg->msg_iovlen, 1797 &iov, EMSGSIZE); 1798 #else 1799 error = copyiniov(msg->msg_iov, msg->msg_iovlen, &iov, EMSGSIZE); 1800 #endif 1801 if (error != 0) 1802 return (error); 1803 1804 if (msg->msg_name != NULL && msg->msg_namelen > 0) { 1805 msg->msg_namelen = min(msg->msg_namelen, SOCK_MAXADDRLEN); 1806 sa = malloc(msg->msg_namelen, M_SONAME, M_WAITOK); 1807 msg->msg_name = sa; 1808 } else { 1809 sa = NULL; 1810 msg->msg_name = NULL; 1811 } 1812 1813 uiov = msg->msg_iov; 1814 msg->msg_iov = iov; 1815 controlp = (msg->msg_control != NULL) ? &control : NULL; 1816 error = kern_recvit(td, s, msg, UIO_SYSSPACE, controlp); 1817 msg->msg_iov = uiov; 1818 if (error != 0) 1819 goto bad; 1820 1821 /* 1822 * Note that kern_recvit() updates msg->msg_namelen. 1823 */ 1824 if (msg->msg_name != NULL && msg->msg_namelen > 0) { 1825 msg->msg_name = PTRIN(l_msghdr.msg_name); 1826 error = linux_copyout_sockaddr(sa, msg->msg_name, 1827 msg->msg_namelen); 1828 if (error != 0) 1829 goto bad; 1830 } 1831 1832 error = bsd_to_linux_msghdr(msg, &l_msghdr); 1833 if (error != 0) 1834 goto bad; 1835 1836 skiped = outlen = 0; 1837 maxlen = l_msghdr.msg_controllen; 1838 if (control == NULL) 1839 goto out; 1840 1841 lcm = malloc(L_CMSG_HDRSZ, M_LINUX, M_WAITOK | M_ZERO); 1842 msg->msg_control = mtod(control, struct cmsghdr *); 1843 msg->msg_controllen = control->m_len; 1844 outbuf = PTRIN(l_msghdr.msg_control); 1845 for (m = control; m != NULL; m = m->m_next) { 1846 cm = mtod(m, struct cmsghdr *); 1847 lcm->cmsg_type = bsd_to_linux_cmsg_type(p, cm->cmsg_type, 1848 cm->cmsg_level); 1849 lcm->cmsg_level = bsd_to_linux_sockopt_level(cm->cmsg_level); 1850 1851 if (lcm->cmsg_type == -1 || 1852 cm->cmsg_level == -1) { 1853 LINUX_RATELIMIT_MSG_OPT2( 1854 "unsupported recvmsg cmsg level %d type %d", 1855 cm->cmsg_level, cm->cmsg_type); 1856 /* Skip unsupported messages */ 1857 skiped++; 1858 continue; 1859 } 1860 data = CMSG_DATA(cm); 1861 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1862 udata = NULL; 1863 error = 0; 1864 1865 switch (cm->cmsg_level) { 1866 case IPPROTO_IP: 1867 error = recvmsg_scm_ipproto_ip(cm->cmsg_type, 1868 lcm->cmsg_type, &datalen, &data, &udata); 1869 break; 1870 case SOL_SOCKET: 1871 error = recvmsg_scm_sol_socket(td, cm->cmsg_type, 1872 lcm->cmsg_type, flags, &datalen, &data, &udata); 1873 break; 1874 } 1875 1876 /* The recvmsg_scm_ is responsible to free udata on error. */ 1877 if (error != 0) 1878 goto bad; 1879 1880 if (outlen + LINUX_CMSG_LEN(datalen) > maxlen) { 1881 if (outlen == 0) { 1882 error = EMSGSIZE; 1883 goto err; 1884 } else { 1885 l_msghdr.msg_flags |= LINUX_MSG_CTRUNC; 1886 m_dispose_extcontrolm(control); 1887 free(udata, M_LINUX); 1888 goto out; 1889 } 1890 } 1891 1892 lcm->cmsg_len = LINUX_CMSG_LEN(datalen); 1893 error = copyout(lcm, outbuf, L_CMSG_HDRSZ); 1894 if (error == 0) { 1895 error = copyout(data, LINUX_CMSG_DATA(outbuf), datalen); 1896 if (error == 0) { 1897 outbuf += LINUX_CMSG_SPACE(datalen); 1898 outlen += LINUX_CMSG_SPACE(datalen); 1899 } 1900 } 1901 err: 1902 free(udata, M_LINUX); 1903 if (error != 0) 1904 goto bad; 1905 } 1906 if (outlen == 0 && skiped > 0) { 1907 error = EINVAL; 1908 goto bad; 1909 } 1910 1911 out: 1912 l_msghdr.msg_controllen = outlen; 1913 error = copyout(&l_msghdr, msghdr, sizeof(l_msghdr)); 1914 1915 bad: 1916 if (control != NULL) { 1917 if (error != 0) 1918 m_dispose_extcontrolm(control); 1919 m_freem(control); 1920 } 1921 free(iov, M_IOV); 1922 free(lcm, M_LINUX); 1923 free(sa, M_SONAME); 1924 1925 return (error); 1926 } 1927 1928 int 1929 linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) 1930 { 1931 struct msghdr bsd_msg; 1932 struct file *fp; 1933 int error; 1934 1935 error = getsock(td, args->s, &cap_recv_rights, &fp); 1936 if (error != 0) 1937 return (error); 1938 fdrop(fp, td); 1939 return (linux_recvmsg_common(td, args->s, PTRIN(args->msg), 1940 args->flags, &bsd_msg)); 1941 } 1942 1943 static int 1944 linux_recvmmsg_common(struct thread *td, l_int s, struct l_mmsghdr *msg, 1945 l_uint vlen, l_uint flags, struct timespec *tts) 1946 { 1947 struct msghdr bsd_msg; 1948 struct timespec ts; 1949 struct file *fp; 1950 l_uint retval; 1951 int error, datagrams; 1952 1953 error = getsock(td, s, &cap_recv_rights, &fp); 1954 if (error != 0) 1955 return (error); 1956 datagrams = 0; 1957 while (datagrams < vlen) { 1958 error = linux_recvmsg_common(td, s, &msg->msg_hdr, 1959 flags & ~LINUX_MSG_WAITFORONE, &bsd_msg); 1960 if (error != 0) 1961 break; 1962 1963 retval = td->td_retval[0]; 1964 error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len)); 1965 if (error != 0) 1966 break; 1967 ++msg; 1968 ++datagrams; 1969 1970 /* 1971 * MSG_WAITFORONE turns on MSG_DONTWAIT after one packet. 1972 */ 1973 if (flags & LINUX_MSG_WAITFORONE) 1974 flags |= LINUX_MSG_DONTWAIT; 1975 1976 /* 1977 * See BUGS section of recvmmsg(2). 1978 */ 1979 if (tts) { 1980 getnanotime(&ts); 1981 timespecsub(&ts, tts, &ts); 1982 if (!timespecisset(&ts) || ts.tv_sec > 0) 1983 break; 1984 } 1985 /* Out of band data, return right away. */ 1986 if (bsd_msg.msg_flags & MSG_OOB) 1987 break; 1988 } 1989 if (error == 0) 1990 td->td_retval[0] = datagrams; 1991 fdrop(fp, td); 1992 return (error); 1993 } 1994 1995 int 1996 linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args) 1997 { 1998 struct timespec ts, tts, *ptts; 1999 int error; 2000 2001 if (args->timeout) { 2002 error = linux_get_timespec(&ts, args->timeout); 2003 if (error != 0) 2004 return (error); 2005 getnanotime(&tts); 2006 timespecadd(&tts, &ts, &tts); 2007 ptts = &tts; 2008 } 2009 else ptts = NULL; 2010 2011 return (linux_recvmmsg_common(td, args->s, PTRIN(args->msg), 2012 args->vlen, args->flags, ptts)); 2013 } 2014 2015 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 2016 int 2017 linux_recvmmsg_time64(struct thread *td, struct linux_recvmmsg_time64_args *args) 2018 { 2019 struct timespec ts, tts, *ptts; 2020 int error; 2021 2022 if (args->timeout) { 2023 error = linux_get_timespec64(&ts, args->timeout); 2024 if (error != 0) 2025 return (error); 2026 getnanotime(&tts); 2027 timespecadd(&tts, &ts, &tts); 2028 ptts = &tts; 2029 } 2030 else ptts = NULL; 2031 2032 return (linux_recvmmsg_common(td, args->s, PTRIN(args->msg), 2033 args->vlen, args->flags, ptts)); 2034 } 2035 #endif 2036 2037 int 2038 linux_shutdown(struct thread *td, struct linux_shutdown_args *args) 2039 { 2040 2041 return (kern_shutdown(td, args->s, args->how)); 2042 } 2043 2044 int 2045 linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) 2046 { 2047 struct proc *p = td->td_proc; 2048 struct linux_pemuldata *pem; 2049 l_timeval linux_tv; 2050 struct sockaddr *sa; 2051 struct timeval tv; 2052 socklen_t len; 2053 int error, level, name, val; 2054 2055 level = linux_to_bsd_sockopt_level(args->level); 2056 switch (level) { 2057 case SOL_SOCKET: 2058 name = linux_to_bsd_so_sockopt(args->optname); 2059 switch (name) { 2060 case LOCAL_CREDS_PERSISTENT: 2061 level = SOL_LOCAL; 2062 break; 2063 case SO_RCVTIMEO: 2064 /* FALLTHROUGH */ 2065 case SO_SNDTIMEO: 2066 error = copyin(PTRIN(args->optval), &linux_tv, 2067 sizeof(linux_tv)); 2068 if (error != 0) 2069 return (error); 2070 tv.tv_sec = linux_tv.tv_sec; 2071 tv.tv_usec = linux_tv.tv_usec; 2072 return (kern_setsockopt(td, args->s, level, 2073 name, &tv, UIO_SYSSPACE, sizeof(tv))); 2074 /* NOTREACHED */ 2075 case SO_TIMESTAMP: 2076 /* overwrite SO_BINTIME */ 2077 val = 0; 2078 error = kern_setsockopt(td, args->s, level, 2079 SO_BINTIME, &val, UIO_SYSSPACE, sizeof(val)); 2080 if (error != 0) 2081 return (error); 2082 pem = pem_find(p); 2083 pem->so_timestamp = args->optname; 2084 break; 2085 case SO_BINTIME: 2086 /* overwrite SO_TIMESTAMP */ 2087 val = 0; 2088 error = kern_setsockopt(td, args->s, level, 2089 SO_TIMESTAMP, &val, UIO_SYSSPACE, sizeof(val)); 2090 if (error != 0) 2091 return (error); 2092 pem = pem_find(p); 2093 pem->so_timestampns = args->optname; 2094 break; 2095 default: 2096 break; 2097 } 2098 break; 2099 case IPPROTO_IP: 2100 if (args->optname == LINUX_IP_RECVERR && 2101 linux_ignore_ip_recverr) { 2102 /* 2103 * XXX: This is a hack to unbreak DNS resolution 2104 * with glibc 2.30 and above. 2105 */ 2106 return (0); 2107 } 2108 name = linux_to_bsd_ip_sockopt(args->optname); 2109 break; 2110 case IPPROTO_IPV6: 2111 name = linux_to_bsd_ip6_sockopt(args->optname); 2112 break; 2113 case IPPROTO_TCP: 2114 name = linux_to_bsd_tcp_sockopt(args->optname); 2115 break; 2116 case SOL_NETLINK: 2117 level = SOL_SOCKET; 2118 name = args->optname; 2119 break; 2120 default: 2121 name = -1; 2122 break; 2123 } 2124 if (name < 0) { 2125 if (name == -1) 2126 linux_msg(curthread, 2127 "unsupported setsockopt level %d optname %d", 2128 args->level, args->optname); 2129 return (ENOPROTOOPT); 2130 } 2131 2132 if (name == IPV6_NEXTHOP) { 2133 len = args->optlen; 2134 error = linux_to_bsd_sockaddr(PTRIN(args->optval), &sa, &len); 2135 if (error != 0) 2136 return (error); 2137 2138 error = kern_setsockopt(td, args->s, level, 2139 name, sa, UIO_SYSSPACE, len); 2140 free(sa, M_SONAME); 2141 } else { 2142 error = kern_setsockopt(td, args->s, level, 2143 name, PTRIN(args->optval), UIO_USERSPACE, args->optlen); 2144 } 2145 2146 return (error); 2147 } 2148 2149 static int 2150 linux_sockopt_copyout(struct thread *td, void *val, socklen_t len, 2151 struct linux_getsockopt_args *args) 2152 { 2153 int error; 2154 2155 error = copyout(val, PTRIN(args->optval), len); 2156 if (error == 0) 2157 error = copyout(&len, PTRIN(args->optlen), sizeof(len)); 2158 return (error); 2159 } 2160 2161 static int 2162 linux_getsockopt_so_peergroups(struct thread *td, 2163 struct linux_getsockopt_args *args) 2164 { 2165 struct xucred xu; 2166 socklen_t xulen, len; 2167 int error, i; 2168 2169 xulen = sizeof(xu); 2170 error = kern_getsockopt(td, args->s, 0, 2171 LOCAL_PEERCRED, &xu, UIO_SYSSPACE, &xulen); 2172 if (error != 0) 2173 return (error); 2174 2175 len = xu.cr_ngroups * sizeof(l_gid_t); 2176 if (args->optlen < len) { 2177 error = copyout(&len, PTRIN(args->optlen), sizeof(len)); 2178 if (error == 0) 2179 error = ERANGE; 2180 return (error); 2181 } 2182 2183 /* 2184 * "- 1" to skip the primary group. 2185 */ 2186 for (i = 0; i < xu.cr_ngroups - 1; i++) { 2187 error = copyout(xu.cr_groups + i + 1, 2188 (void *)(args->optval + i * sizeof(l_gid_t)), 2189 sizeof(l_gid_t)); 2190 if (error != 0) 2191 return (error); 2192 } 2193 2194 error = copyout(&len, PTRIN(args->optlen), sizeof(len)); 2195 return (error); 2196 } 2197 2198 static int 2199 linux_getsockopt_so_peersec(struct thread *td, 2200 struct linux_getsockopt_args *args) 2201 { 2202 socklen_t len; 2203 int error; 2204 2205 len = sizeof(SECURITY_CONTEXT_STRING); 2206 if (args->optlen < len) { 2207 error = copyout(&len, PTRIN(args->optlen), sizeof(len)); 2208 if (error == 0) 2209 error = ERANGE; 2210 return (error); 2211 } 2212 2213 return (linux_sockopt_copyout(td, SECURITY_CONTEXT_STRING, 2214 len, args)); 2215 } 2216 2217 static int 2218 linux_getsockopt_so_linger(struct thread *td, 2219 struct linux_getsockopt_args *args) 2220 { 2221 struct linger ling; 2222 socklen_t len; 2223 int error; 2224 2225 len = sizeof(ling); 2226 error = kern_getsockopt(td, args->s, SOL_SOCKET, 2227 SO_LINGER, &ling, UIO_SYSSPACE, &len); 2228 if (error != 0) 2229 return (error); 2230 ling.l_onoff = ((ling.l_onoff & SO_LINGER) != 0); 2231 return (linux_sockopt_copyout(td, &ling, len, args)); 2232 } 2233 2234 int 2235 linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) 2236 { 2237 l_timeval linux_tv; 2238 struct timeval tv; 2239 socklen_t tv_len, xulen, len; 2240 struct sockaddr *sa; 2241 struct xucred xu; 2242 struct l_ucred lxu; 2243 int error, level, name, newval; 2244 2245 level = linux_to_bsd_sockopt_level(args->level); 2246 switch (level) { 2247 case SOL_SOCKET: 2248 switch (args->optname) { 2249 case LINUX_SO_PEERGROUPS: 2250 return (linux_getsockopt_so_peergroups(td, args)); 2251 case LINUX_SO_PEERSEC: 2252 return (linux_getsockopt_so_peersec(td, args)); 2253 default: 2254 break; 2255 } 2256 2257 name = linux_to_bsd_so_sockopt(args->optname); 2258 switch (name) { 2259 case LOCAL_CREDS_PERSISTENT: 2260 level = SOL_LOCAL; 2261 break; 2262 case SO_RCVTIMEO: 2263 /* FALLTHROUGH */ 2264 case SO_SNDTIMEO: 2265 tv_len = sizeof(tv); 2266 error = kern_getsockopt(td, args->s, level, 2267 name, &tv, UIO_SYSSPACE, &tv_len); 2268 if (error != 0) 2269 return (error); 2270 linux_tv.tv_sec = tv.tv_sec; 2271 linux_tv.tv_usec = tv.tv_usec; 2272 return (linux_sockopt_copyout(td, &linux_tv, 2273 sizeof(linux_tv), args)); 2274 /* NOTREACHED */ 2275 case LOCAL_PEERCRED: 2276 if (args->optlen < sizeof(lxu)) 2277 return (EINVAL); 2278 /* 2279 * LOCAL_PEERCRED is not served at the SOL_SOCKET level, 2280 * but by the Unix socket's level 0. 2281 */ 2282 level = 0; 2283 xulen = sizeof(xu); 2284 error = kern_getsockopt(td, args->s, level, 2285 name, &xu, UIO_SYSSPACE, &xulen); 2286 if (error != 0) 2287 return (error); 2288 lxu.pid = xu.cr_pid; 2289 lxu.uid = xu.cr_uid; 2290 lxu.gid = xu.cr_gid; 2291 return (linux_sockopt_copyout(td, &lxu, 2292 sizeof(lxu), args)); 2293 /* NOTREACHED */ 2294 case SO_ERROR: 2295 len = sizeof(newval); 2296 error = kern_getsockopt(td, args->s, level, 2297 name, &newval, UIO_SYSSPACE, &len); 2298 if (error != 0) 2299 return (error); 2300 newval = -bsd_to_linux_errno(newval); 2301 return (linux_sockopt_copyout(td, &newval, 2302 len, args)); 2303 /* NOTREACHED */ 2304 case SO_DOMAIN: 2305 len = sizeof(newval); 2306 error = kern_getsockopt(td, args->s, level, 2307 name, &newval, UIO_SYSSPACE, &len); 2308 if (error != 0) 2309 return (error); 2310 newval = bsd_to_linux_domain(newval); 2311 if (newval == -1) 2312 return (ENOPROTOOPT); 2313 return (linux_sockopt_copyout(td, &newval, 2314 len, args)); 2315 /* NOTREACHED */ 2316 case SO_LINGER: 2317 return (linux_getsockopt_so_linger(td, args)); 2318 /* NOTREACHED */ 2319 default: 2320 break; 2321 } 2322 break; 2323 case IPPROTO_IP: 2324 name = linux_to_bsd_ip_sockopt(args->optname); 2325 break; 2326 case IPPROTO_IPV6: 2327 name = linux_to_bsd_ip6_sockopt(args->optname); 2328 break; 2329 case IPPROTO_TCP: 2330 name = linux_to_bsd_tcp_sockopt(args->optname); 2331 break; 2332 default: 2333 name = -1; 2334 break; 2335 } 2336 if (name < 0) { 2337 if (name == -1) 2338 linux_msg(curthread, 2339 "unsupported getsockopt level %d optname %d", 2340 args->level, args->optname); 2341 return (EINVAL); 2342 } 2343 2344 if (name == IPV6_NEXTHOP) { 2345 error = copyin(PTRIN(args->optlen), &len, sizeof(len)); 2346 if (error != 0) 2347 return (error); 2348 sa = malloc(len, M_SONAME, M_WAITOK); 2349 2350 error = kern_getsockopt(td, args->s, level, 2351 name, sa, UIO_SYSSPACE, &len); 2352 if (error != 0) 2353 goto out; 2354 2355 error = linux_copyout_sockaddr(sa, PTRIN(args->optval), len); 2356 if (error == 0) 2357 error = copyout(&len, PTRIN(args->optlen), 2358 sizeof(len)); 2359 out: 2360 free(sa, M_SONAME); 2361 } else { 2362 if (args->optval) { 2363 error = copyin(PTRIN(args->optlen), &len, sizeof(len)); 2364 if (error != 0) 2365 return (error); 2366 } 2367 error = kern_getsockopt(td, args->s, level, 2368 name, PTRIN(args->optval), UIO_USERSPACE, &len); 2369 if (error == 0) 2370 error = copyout(&len, PTRIN(args->optlen), 2371 sizeof(len)); 2372 } 2373 2374 return (error); 2375 } 2376 2377 static int 2378 linux_sendfile_common(struct thread *td, l_int out, l_int in, 2379 l_loff_t *offset, l_size_t count) 2380 { 2381 off_t bytes_read; 2382 int error; 2383 l_loff_t current_offset; 2384 struct file *fp; 2385 2386 AUDIT_ARG_FD(in); 2387 error = fget_read(td, in, &cap_pread_rights, &fp); 2388 if (error != 0) 2389 return (error); 2390 2391 if (offset != NULL) { 2392 current_offset = *offset; 2393 } else { 2394 error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ? 2395 fo_seek(fp, 0, SEEK_CUR, td) : ESPIPE; 2396 if (error != 0) 2397 goto drop; 2398 current_offset = td->td_uretoff.tdu_off; 2399 } 2400 2401 bytes_read = 0; 2402 2403 /* Linux cannot have 0 count. */ 2404 if (count <= 0 || current_offset < 0) { 2405 error = EINVAL; 2406 goto drop; 2407 } 2408 2409 error = fo_sendfile(fp, out, NULL, NULL, current_offset, count, 2410 &bytes_read, 0, td); 2411 if (error != 0) 2412 goto drop; 2413 current_offset += bytes_read; 2414 2415 if (offset != NULL) { 2416 *offset = current_offset; 2417 } else { 2418 error = fo_seek(fp, current_offset, SEEK_SET, td); 2419 if (error != 0) 2420 goto drop; 2421 } 2422 2423 td->td_retval[0] = (ssize_t)bytes_read; 2424 drop: 2425 fdrop(fp, td); 2426 if (error == ENOTSOCK) 2427 error = EINVAL; 2428 return (error); 2429 } 2430 2431 int 2432 linux_sendfile(struct thread *td, struct linux_sendfile_args *arg) 2433 { 2434 /* 2435 * Differences between FreeBSD and Linux sendfile: 2436 * - Linux doesn't send anything when count is 0 (FreeBSD uses 0 to 2437 * mean send the whole file.) In linux_sendfile given fds are still 2438 * checked for validity when the count is 0. 2439 * - Linux can send to any fd whereas FreeBSD only supports sockets. 2440 * The same restriction follows for linux_sendfile. 2441 * - Linux doesn't have an equivalent for FreeBSD's flags and sf_hdtr. 2442 * - Linux takes an offset pointer and updates it to the read location. 2443 * FreeBSD takes in an offset and a 'bytes read' parameter which is 2444 * only filled if it isn't NULL. We use this parameter to update the 2445 * offset pointer if it exists. 2446 * - Linux sendfile returns bytes read on success while FreeBSD 2447 * returns 0. We use the 'bytes read' parameter to get this value. 2448 */ 2449 2450 l_loff_t offset64; 2451 l_long offset; 2452 int ret; 2453 int error; 2454 2455 if (arg->offset != NULL) { 2456 error = copyin(arg->offset, &offset, sizeof(offset)); 2457 if (error != 0) 2458 return (error); 2459 offset64 = (l_loff_t)offset; 2460 } 2461 2462 ret = linux_sendfile_common(td, arg->out, arg->in, 2463 arg->offset != NULL ? &offset64 : NULL, arg->count); 2464 2465 if (arg->offset != NULL) { 2466 #if defined(__i386__) || defined(__arm__) || \ 2467 (defined(__amd64__) && defined(COMPAT_LINUX32)) 2468 if (offset64 > INT32_MAX) 2469 return (EOVERFLOW); 2470 #endif 2471 offset = (l_long)offset64; 2472 error = copyout(&offset, arg->offset, sizeof(offset)); 2473 if (error != 0) 2474 return (error); 2475 } 2476 2477 return (ret); 2478 } 2479 2480 #if defined(__i386__) || defined(__arm__) || \ 2481 (defined(__amd64__) && defined(COMPAT_LINUX32)) 2482 2483 int 2484 linux_sendfile64(struct thread *td, struct linux_sendfile64_args *arg) 2485 { 2486 l_loff_t offset; 2487 int ret; 2488 int error; 2489 2490 if (arg->offset != NULL) { 2491 error = copyin(arg->offset, &offset, sizeof(offset)); 2492 if (error != 0) 2493 return (error); 2494 } 2495 2496 ret = linux_sendfile_common(td, arg->out, arg->in, 2497 arg->offset != NULL ? &offset : NULL, arg->count); 2498 2499 if (arg->offset != NULL) { 2500 error = copyout(&offset, arg->offset, sizeof(offset)); 2501 if (error != 0) 2502 return (error); 2503 } 2504 2505 return (ret); 2506 } 2507 2508 /* Argument list sizes for linux_socketcall */ 2509 static const unsigned char lxs_args_cnt[] = { 2510 0 /* unused*/, 3 /* socket */, 2511 3 /* bind */, 3 /* connect */, 2512 2 /* listen */, 3 /* accept */, 2513 3 /* getsockname */, 3 /* getpeername */, 2514 4 /* socketpair */, 4 /* send */, 2515 4 /* recv */, 6 /* sendto */, 2516 6 /* recvfrom */, 2 /* shutdown */, 2517 5 /* setsockopt */, 5 /* getsockopt */, 2518 3 /* sendmsg */, 3 /* recvmsg */, 2519 4 /* accept4 */, 5 /* recvmmsg */, 2520 4 /* sendmmsg */, 4 /* sendfile */ 2521 }; 2522 #define LINUX_ARGS_CNT (nitems(lxs_args_cnt) - 1) 2523 #define LINUX_ARG_SIZE(x) (lxs_args_cnt[x] * sizeof(l_ulong)) 2524 2525 int 2526 linux_socketcall(struct thread *td, struct linux_socketcall_args *args) 2527 { 2528 l_ulong a[6]; 2529 #if defined(__amd64__) && defined(COMPAT_LINUX32) 2530 register_t l_args[6]; 2531 #endif 2532 void *arg; 2533 int error; 2534 2535 if (args->what < LINUX_SOCKET || args->what > LINUX_ARGS_CNT) 2536 return (EINVAL); 2537 error = copyin(PTRIN(args->args), a, LINUX_ARG_SIZE(args->what)); 2538 if (error != 0) 2539 return (error); 2540 2541 #if defined(__amd64__) && defined(COMPAT_LINUX32) 2542 for (int i = 0; i < lxs_args_cnt[args->what]; ++i) 2543 l_args[i] = a[i]; 2544 arg = l_args; 2545 #else 2546 arg = a; 2547 #endif 2548 switch (args->what) { 2549 case LINUX_SOCKET: 2550 return (linux_socket(td, arg)); 2551 case LINUX_BIND: 2552 return (linux_bind(td, arg)); 2553 case LINUX_CONNECT: 2554 return (linux_connect(td, arg)); 2555 case LINUX_LISTEN: 2556 return (linux_listen(td, arg)); 2557 case LINUX_ACCEPT: 2558 return (linux_accept(td, arg)); 2559 case LINUX_GETSOCKNAME: 2560 return (linux_getsockname(td, arg)); 2561 case LINUX_GETPEERNAME: 2562 return (linux_getpeername(td, arg)); 2563 case LINUX_SOCKETPAIR: 2564 return (linux_socketpair(td, arg)); 2565 case LINUX_SEND: 2566 return (linux_send(td, arg)); 2567 case LINUX_RECV: 2568 return (linux_recv(td, arg)); 2569 case LINUX_SENDTO: 2570 return (linux_sendto(td, arg)); 2571 case LINUX_RECVFROM: 2572 return (linux_recvfrom(td, arg)); 2573 case LINUX_SHUTDOWN: 2574 return (linux_shutdown(td, arg)); 2575 case LINUX_SETSOCKOPT: 2576 return (linux_setsockopt(td, arg)); 2577 case LINUX_GETSOCKOPT: 2578 return (linux_getsockopt(td, arg)); 2579 case LINUX_SENDMSG: 2580 return (linux_sendmsg(td, arg)); 2581 case LINUX_RECVMSG: 2582 return (linux_recvmsg(td, arg)); 2583 case LINUX_ACCEPT4: 2584 return (linux_accept4(td, arg)); 2585 case LINUX_RECVMMSG: 2586 return (linux_recvmmsg(td, arg)); 2587 case LINUX_SENDMMSG: 2588 return (linux_sendmmsg(td, arg)); 2589 case LINUX_SENDFILE: 2590 return (linux_sendfile(td, arg)); 2591 } 2592 2593 linux_msg(td, "socket type %d not implemented", args->what); 2594 return (ENOSYS); 2595 } 2596 #endif /* __i386__ || __arm__ || (__amd64__ && COMPAT_LINUX32) */ 2597