1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 1995 Søren Schmidt 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include "opt_inet6.h" 33 34 #include <sys/param.h> 35 #include <sys/proc.h> 36 #include <sys/systm.h> 37 #include <sys/sysproto.h> 38 #include <sys/capsicum.h> 39 #include <sys/fcntl.h> 40 #include <sys/file.h> 41 #include <sys/filedesc.h> 42 #include <sys/limits.h> 43 #include <sys/lock.h> 44 #include <sys/malloc.h> 45 #include <sys/mutex.h> 46 #include <sys/mbuf.h> 47 #include <sys/socket.h> 48 #include <sys/socketvar.h> 49 #include <sys/syscallsubr.h> 50 #include <sys/stat.h> 51 #include <sys/syslog.h> 52 #include <sys/un.h> 53 #include <sys/unistd.h> 54 55 #include <security/audit/audit.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_common.h> 76 #include <compat/linux/linux_emul.h> 77 #include <compat/linux/linux_file.h> 78 #include <compat/linux/linux_mib.h> 79 #include <compat/linux/linux_socket.h> 80 #include <compat/linux/linux_timer.h> 81 #include <compat/linux/linux_util.h> 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_ip_origdstaddr(socklen_t *datalen, void **data, void **udata) 1702 { 1703 struct l_sockaddr *lsa; 1704 int error; 1705 1706 error = bsd_to_linux_sockaddr(*data, &lsa, *datalen); 1707 if (error == 0) { 1708 *data = *udata = lsa; 1709 *datalen = sizeof(*lsa); 1710 } 1711 return (error); 1712 } 1713 1714 static int 1715 linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, 1716 l_uint flags, struct msghdr *msg) 1717 { 1718 struct proc *p = td->td_proc; 1719 struct cmsghdr *cm; 1720 struct l_cmsghdr *lcm = NULL; 1721 socklen_t datalen, maxlen, outlen; 1722 struct l_msghdr l_msghdr; 1723 struct iovec *iov, *uiov; 1724 struct mbuf *m, *control = NULL; 1725 struct mbuf **controlp; 1726 struct sockaddr *sa; 1727 caddr_t outbuf; 1728 void *data, *udata; 1729 int error; 1730 1731 error = copyin(msghdr, &l_msghdr, sizeof(l_msghdr)); 1732 if (error != 0) 1733 return (error); 1734 1735 /* 1736 * Pass user-supplied recvmsg() flags in msg_flags field, 1737 * following sys_recvmsg() convention. 1738 */ 1739 l_msghdr.msg_flags = flags; 1740 1741 error = linux_to_bsd_msghdr(msg, &l_msghdr); 1742 if (error != 0) 1743 return (error); 1744 1745 #ifdef COMPAT_LINUX32 1746 error = linux32_copyiniov(PTRIN(msg->msg_iov), msg->msg_iovlen, 1747 &iov, EMSGSIZE); 1748 #else 1749 error = copyiniov(msg->msg_iov, msg->msg_iovlen, &iov, EMSGSIZE); 1750 #endif 1751 if (error != 0) 1752 return (error); 1753 1754 if (msg->msg_name != NULL && msg->msg_namelen > 0) { 1755 msg->msg_namelen = min(msg->msg_namelen, SOCK_MAXADDRLEN); 1756 sa = malloc(msg->msg_namelen, M_SONAME, M_WAITOK); 1757 msg->msg_name = sa; 1758 } else { 1759 sa = NULL; 1760 msg->msg_name = NULL; 1761 } 1762 1763 uiov = msg->msg_iov; 1764 msg->msg_iov = iov; 1765 controlp = (msg->msg_control != NULL) ? &control : NULL; 1766 error = kern_recvit(td, s, msg, UIO_SYSSPACE, controlp); 1767 msg->msg_iov = uiov; 1768 if (error != 0) 1769 goto bad; 1770 1771 /* 1772 * Note that kern_recvit() updates msg->msg_namelen. 1773 */ 1774 if (msg->msg_name != NULL && msg->msg_namelen > 0) { 1775 msg->msg_name = PTRIN(l_msghdr.msg_name); 1776 error = linux_copyout_sockaddr(sa, msg->msg_name, 1777 msg->msg_namelen); 1778 if (error != 0) 1779 goto bad; 1780 } 1781 1782 error = bsd_to_linux_msghdr(msg, &l_msghdr); 1783 if (error != 0) 1784 goto bad; 1785 1786 maxlen = l_msghdr.msg_controllen; 1787 l_msghdr.msg_controllen = 0; 1788 if (control == NULL) 1789 goto out; 1790 1791 lcm = malloc(L_CMSG_HDRSZ, M_LINUX, M_WAITOK | M_ZERO); 1792 msg->msg_control = mtod(control, struct cmsghdr *); 1793 msg->msg_controllen = control->m_len; 1794 outbuf = PTRIN(l_msghdr.msg_control); 1795 outlen = 0; 1796 for (m = control; m != NULL; m = m->m_next) { 1797 cm = mtod(m, struct cmsghdr *); 1798 lcm->cmsg_type = bsd_to_linux_cmsg_type(p, cm->cmsg_type, 1799 cm->cmsg_level); 1800 lcm->cmsg_level = bsd_to_linux_sockopt_level(cm->cmsg_level); 1801 1802 data = CMSG_DATA(cm); 1803 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1804 udata = NULL; 1805 error = 0; 1806 1807 /* Process non SOL_SOCKET types. */ 1808 if (cm->cmsg_level == IPPROTO_IP && 1809 lcm->cmsg_type == LINUX_IP_ORIGDSTADDR) { 1810 error = recvmsg_scm_ip_origdstaddr(&datalen, &data, &udata); 1811 goto cont; 1812 } 1813 1814 if (lcm->cmsg_type == -1 || 1815 cm->cmsg_level != SOL_SOCKET) { 1816 LINUX_RATELIMIT_MSG_OPT2( 1817 "unsupported recvmsg cmsg level %d type %d", 1818 cm->cmsg_level, cm->cmsg_type); 1819 error = EINVAL; 1820 goto bad; 1821 } 1822 1823 1824 switch (cm->cmsg_type) { 1825 case SCM_RIGHTS: 1826 error = recvmsg_scm_rights(td, flags, 1827 &datalen, &data, &udata); 1828 break; 1829 case SCM_CREDS: 1830 error = recvmsg_scm_creds(&datalen, 1831 &data, &udata); 1832 break; 1833 case SCM_CREDS2: 1834 error = recvmsg_scm_creds2(&datalen, 1835 &data, &udata); 1836 break; 1837 case SCM_TIMESTAMP: 1838 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 1839 error = recvmsg_scm_timestamp(lcm->cmsg_type, 1840 &datalen, &data, &udata); 1841 #endif 1842 break; 1843 case SCM_BINTIME: 1844 error = recvmsg_scm_timestampns(lcm->cmsg_type, 1845 &datalen, &data, &udata); 1846 break; 1847 } 1848 1849 cont: 1850 if (error != 0) 1851 goto bad; 1852 1853 if (outlen + LINUX_CMSG_LEN(datalen) > maxlen) { 1854 if (outlen == 0) { 1855 error = EMSGSIZE; 1856 goto err; 1857 } else { 1858 l_msghdr.msg_flags |= LINUX_MSG_CTRUNC; 1859 m_dispose_extcontrolm(control); 1860 free(udata, M_LINUX); 1861 goto out; 1862 } 1863 } 1864 1865 lcm->cmsg_len = LINUX_CMSG_LEN(datalen); 1866 error = copyout(lcm, outbuf, L_CMSG_HDRSZ); 1867 if (error == 0) { 1868 outbuf += L_CMSG_HDRSZ; 1869 error = copyout(data, outbuf, datalen); 1870 if (error == 0) { 1871 outbuf += LINUX_CMSG_ALIGN(datalen); 1872 outlen += LINUX_CMSG_LEN(datalen); 1873 } 1874 } 1875 err: 1876 free(udata, M_LINUX); 1877 if (error != 0) 1878 goto bad; 1879 } 1880 l_msghdr.msg_controllen = outlen; 1881 1882 out: 1883 error = copyout(&l_msghdr, msghdr, sizeof(l_msghdr)); 1884 1885 bad: 1886 if (control != NULL) { 1887 if (error != 0) 1888 m_dispose_extcontrolm(control); 1889 m_freem(control); 1890 } 1891 free(iov, M_IOV); 1892 free(lcm, M_LINUX); 1893 free(sa, M_SONAME); 1894 1895 return (error); 1896 } 1897 1898 int 1899 linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) 1900 { 1901 struct msghdr bsd_msg; 1902 struct file *fp; 1903 int error; 1904 1905 error = getsock(td, args->s, &cap_recv_rights, &fp); 1906 if (error != 0) 1907 return (error); 1908 fdrop(fp, td); 1909 return (linux_recvmsg_common(td, args->s, PTRIN(args->msg), 1910 args->flags, &bsd_msg)); 1911 } 1912 1913 static int 1914 linux_recvmmsg_common(struct thread *td, l_int s, struct l_mmsghdr *msg, 1915 l_uint vlen, l_uint flags, struct timespec *tts) 1916 { 1917 struct msghdr bsd_msg; 1918 struct timespec ts; 1919 struct file *fp; 1920 l_uint retval; 1921 int error, datagrams; 1922 1923 error = getsock(td, s, &cap_recv_rights, &fp); 1924 if (error != 0) 1925 return (error); 1926 datagrams = 0; 1927 while (datagrams < vlen) { 1928 error = linux_recvmsg_common(td, s, &msg->msg_hdr, 1929 flags & ~LINUX_MSG_WAITFORONE, &bsd_msg); 1930 if (error != 0) 1931 break; 1932 1933 retval = td->td_retval[0]; 1934 error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len)); 1935 if (error != 0) 1936 break; 1937 ++msg; 1938 ++datagrams; 1939 1940 /* 1941 * MSG_WAITFORONE turns on MSG_DONTWAIT after one packet. 1942 */ 1943 if (flags & LINUX_MSG_WAITFORONE) 1944 flags |= LINUX_MSG_DONTWAIT; 1945 1946 /* 1947 * See BUGS section of recvmmsg(2). 1948 */ 1949 if (tts) { 1950 getnanotime(&ts); 1951 timespecsub(&ts, tts, &ts); 1952 if (!timespecisset(&ts) || ts.tv_sec > 0) 1953 break; 1954 } 1955 /* Out of band data, return right away. */ 1956 if (bsd_msg.msg_flags & MSG_OOB) 1957 break; 1958 } 1959 if (error == 0) 1960 td->td_retval[0] = datagrams; 1961 fdrop(fp, td); 1962 return (error); 1963 } 1964 1965 int 1966 linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args) 1967 { 1968 struct timespec ts, tts, *ptts; 1969 int error; 1970 1971 if (args->timeout) { 1972 error = linux_get_timespec(&ts, args->timeout); 1973 if (error != 0) 1974 return (error); 1975 getnanotime(&tts); 1976 timespecadd(&tts, &ts, &tts); 1977 ptts = &tts; 1978 } 1979 else ptts = NULL; 1980 1981 return (linux_recvmmsg_common(td, args->s, PTRIN(args->msg), 1982 args->vlen, args->flags, ptts)); 1983 } 1984 1985 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 1986 int 1987 linux_recvmmsg_time64(struct thread *td, struct linux_recvmmsg_time64_args *args) 1988 { 1989 struct timespec ts, tts, *ptts; 1990 int error; 1991 1992 if (args->timeout) { 1993 error = linux_get_timespec64(&ts, args->timeout); 1994 if (error != 0) 1995 return (error); 1996 getnanotime(&tts); 1997 timespecadd(&tts, &ts, &tts); 1998 ptts = &tts; 1999 } 2000 else ptts = NULL; 2001 2002 return (linux_recvmmsg_common(td, args->s, PTRIN(args->msg), 2003 args->vlen, args->flags, ptts)); 2004 } 2005 #endif 2006 2007 int 2008 linux_shutdown(struct thread *td, struct linux_shutdown_args *args) 2009 { 2010 2011 return (kern_shutdown(td, args->s, args->how)); 2012 } 2013 2014 int 2015 linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) 2016 { 2017 struct proc *p = td->td_proc; 2018 struct linux_pemuldata *pem; 2019 l_timeval linux_tv; 2020 struct sockaddr *sa; 2021 struct timeval tv; 2022 socklen_t len; 2023 int error, level, name, val; 2024 2025 level = linux_to_bsd_sockopt_level(args->level); 2026 switch (level) { 2027 case SOL_SOCKET: 2028 name = linux_to_bsd_so_sockopt(args->optname); 2029 switch (name) { 2030 case LOCAL_CREDS_PERSISTENT: 2031 level = SOL_LOCAL; 2032 break; 2033 case SO_RCVTIMEO: 2034 /* FALLTHROUGH */ 2035 case SO_SNDTIMEO: 2036 error = copyin(PTRIN(args->optval), &linux_tv, 2037 sizeof(linux_tv)); 2038 if (error != 0) 2039 return (error); 2040 tv.tv_sec = linux_tv.tv_sec; 2041 tv.tv_usec = linux_tv.tv_usec; 2042 return (kern_setsockopt(td, args->s, level, 2043 name, &tv, UIO_SYSSPACE, sizeof(tv))); 2044 /* NOTREACHED */ 2045 case SO_TIMESTAMP: 2046 /* overwrite SO_BINTIME */ 2047 val = 0; 2048 error = kern_setsockopt(td, args->s, level, 2049 SO_BINTIME, &val, UIO_SYSSPACE, sizeof(val)); 2050 if (error != 0) 2051 return (error); 2052 pem = pem_find(p); 2053 pem->so_timestamp = args->optname; 2054 break; 2055 case SO_BINTIME: 2056 /* overwrite SO_TIMESTAMP */ 2057 val = 0; 2058 error = kern_setsockopt(td, args->s, level, 2059 SO_TIMESTAMP, &val, UIO_SYSSPACE, sizeof(val)); 2060 if (error != 0) 2061 return (error); 2062 pem = pem_find(p); 2063 pem->so_timestampns = args->optname; 2064 break; 2065 default: 2066 break; 2067 } 2068 break; 2069 case IPPROTO_IP: 2070 if (args->optname == LINUX_IP_RECVERR && 2071 linux_ignore_ip_recverr) { 2072 /* 2073 * XXX: This is a hack to unbreak DNS resolution 2074 * with glibc 2.30 and above. 2075 */ 2076 return (0); 2077 } 2078 name = linux_to_bsd_ip_sockopt(args->optname); 2079 break; 2080 case IPPROTO_IPV6: 2081 name = linux_to_bsd_ip6_sockopt(args->optname); 2082 break; 2083 case IPPROTO_TCP: 2084 name = linux_to_bsd_tcp_sockopt(args->optname); 2085 break; 2086 case SOL_NETLINK: 2087 level = SOL_SOCKET; 2088 name = args->optname; 2089 break; 2090 default: 2091 name = -1; 2092 break; 2093 } 2094 if (name < 0) { 2095 if (name == -1) 2096 linux_msg(curthread, 2097 "unsupported setsockopt level %d optname %d", 2098 args->level, args->optname); 2099 return (ENOPROTOOPT); 2100 } 2101 2102 if (name == IPV6_NEXTHOP) { 2103 len = args->optlen; 2104 error = linux_to_bsd_sockaddr(PTRIN(args->optval), &sa, &len); 2105 if (error != 0) 2106 return (error); 2107 2108 error = kern_setsockopt(td, args->s, level, 2109 name, sa, UIO_SYSSPACE, len); 2110 free(sa, M_SONAME); 2111 } else { 2112 error = kern_setsockopt(td, args->s, level, 2113 name, PTRIN(args->optval), UIO_USERSPACE, args->optlen); 2114 } 2115 2116 return (error); 2117 } 2118 2119 static int 2120 linux_sockopt_copyout(struct thread *td, void *val, socklen_t len, 2121 struct linux_getsockopt_args *args) 2122 { 2123 int error; 2124 2125 error = copyout(val, PTRIN(args->optval), len); 2126 if (error == 0) 2127 error = copyout(&len, PTRIN(args->optlen), sizeof(len)); 2128 return (error); 2129 } 2130 2131 static int 2132 linux_getsockopt_so_peergroups(struct thread *td, 2133 struct linux_getsockopt_args *args) 2134 { 2135 struct xucred xu; 2136 socklen_t xulen, len; 2137 int error, i; 2138 2139 xulen = sizeof(xu); 2140 error = kern_getsockopt(td, args->s, 0, 2141 LOCAL_PEERCRED, &xu, UIO_SYSSPACE, &xulen); 2142 if (error != 0) 2143 return (error); 2144 2145 len = xu.cr_ngroups * sizeof(l_gid_t); 2146 if (args->optlen < len) { 2147 error = copyout(&len, PTRIN(args->optlen), sizeof(len)); 2148 if (error == 0) 2149 error = ERANGE; 2150 return (error); 2151 } 2152 2153 /* 2154 * "- 1" to skip the primary group. 2155 */ 2156 for (i = 0; i < xu.cr_ngroups - 1; i++) { 2157 error = copyout(xu.cr_groups + i + 1, 2158 (void *)(args->optval + i * sizeof(l_gid_t)), 2159 sizeof(l_gid_t)); 2160 if (error != 0) 2161 return (error); 2162 } 2163 2164 error = copyout(&len, PTRIN(args->optlen), sizeof(len)); 2165 return (error); 2166 } 2167 2168 static int 2169 linux_getsockopt_so_peersec(struct thread *td, 2170 struct linux_getsockopt_args *args) 2171 { 2172 socklen_t len; 2173 int error; 2174 2175 len = sizeof(SECURITY_CONTEXT_STRING); 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 return (linux_sockopt_copyout(td, SECURITY_CONTEXT_STRING, 2184 len, args)); 2185 } 2186 2187 static int 2188 linux_getsockopt_so_linger(struct thread *td, 2189 struct linux_getsockopt_args *args) 2190 { 2191 struct linger ling; 2192 socklen_t len; 2193 int error; 2194 2195 len = sizeof(ling); 2196 error = kern_getsockopt(td, args->s, SOL_SOCKET, 2197 SO_LINGER, &ling, UIO_SYSSPACE, &len); 2198 if (error != 0) 2199 return (error); 2200 ling.l_onoff = ((ling.l_onoff & SO_LINGER) != 0); 2201 return (linux_sockopt_copyout(td, &ling, len, args)); 2202 } 2203 2204 int 2205 linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) 2206 { 2207 l_timeval linux_tv; 2208 struct timeval tv; 2209 socklen_t tv_len, xulen, len; 2210 struct sockaddr *sa; 2211 struct xucred xu; 2212 struct l_ucred lxu; 2213 int error, level, name, newval; 2214 2215 level = linux_to_bsd_sockopt_level(args->level); 2216 switch (level) { 2217 case SOL_SOCKET: 2218 switch (args->optname) { 2219 case LINUX_SO_PEERGROUPS: 2220 return (linux_getsockopt_so_peergroups(td, args)); 2221 case LINUX_SO_PEERSEC: 2222 return (linux_getsockopt_so_peersec(td, args)); 2223 default: 2224 break; 2225 } 2226 2227 name = linux_to_bsd_so_sockopt(args->optname); 2228 switch (name) { 2229 case LOCAL_CREDS_PERSISTENT: 2230 level = SOL_LOCAL; 2231 break; 2232 case SO_RCVTIMEO: 2233 /* FALLTHROUGH */ 2234 case SO_SNDTIMEO: 2235 tv_len = sizeof(tv); 2236 error = kern_getsockopt(td, args->s, level, 2237 name, &tv, UIO_SYSSPACE, &tv_len); 2238 if (error != 0) 2239 return (error); 2240 linux_tv.tv_sec = tv.tv_sec; 2241 linux_tv.tv_usec = tv.tv_usec; 2242 return (linux_sockopt_copyout(td, &linux_tv, 2243 sizeof(linux_tv), args)); 2244 /* NOTREACHED */ 2245 case LOCAL_PEERCRED: 2246 if (args->optlen < sizeof(lxu)) 2247 return (EINVAL); 2248 /* 2249 * LOCAL_PEERCRED is not served at the SOL_SOCKET level, 2250 * but by the Unix socket's level 0. 2251 */ 2252 level = 0; 2253 xulen = sizeof(xu); 2254 error = kern_getsockopt(td, args->s, level, 2255 name, &xu, UIO_SYSSPACE, &xulen); 2256 if (error != 0) 2257 return (error); 2258 lxu.pid = xu.cr_pid; 2259 lxu.uid = xu.cr_uid; 2260 lxu.gid = xu.cr_gid; 2261 return (linux_sockopt_copyout(td, &lxu, 2262 sizeof(lxu), args)); 2263 /* NOTREACHED */ 2264 case SO_ERROR: 2265 len = sizeof(newval); 2266 error = kern_getsockopt(td, args->s, level, 2267 name, &newval, UIO_SYSSPACE, &len); 2268 if (error != 0) 2269 return (error); 2270 newval = -bsd_to_linux_errno(newval); 2271 return (linux_sockopt_copyout(td, &newval, 2272 len, args)); 2273 /* NOTREACHED */ 2274 case SO_DOMAIN: 2275 len = sizeof(newval); 2276 error = kern_getsockopt(td, args->s, level, 2277 name, &newval, UIO_SYSSPACE, &len); 2278 if (error != 0) 2279 return (error); 2280 newval = bsd_to_linux_domain(newval); 2281 if (newval == -1) 2282 return (ENOPROTOOPT); 2283 return (linux_sockopt_copyout(td, &newval, 2284 len, args)); 2285 /* NOTREACHED */ 2286 case SO_LINGER: 2287 return (linux_getsockopt_so_linger(td, args)); 2288 /* NOTREACHED */ 2289 default: 2290 break; 2291 } 2292 break; 2293 case IPPROTO_IP: 2294 name = linux_to_bsd_ip_sockopt(args->optname); 2295 break; 2296 case IPPROTO_IPV6: 2297 name = linux_to_bsd_ip6_sockopt(args->optname); 2298 break; 2299 case IPPROTO_TCP: 2300 name = linux_to_bsd_tcp_sockopt(args->optname); 2301 break; 2302 default: 2303 name = -1; 2304 break; 2305 } 2306 if (name < 0) { 2307 if (name == -1) 2308 linux_msg(curthread, 2309 "unsupported getsockopt level %d optname %d", 2310 args->level, args->optname); 2311 return (EINVAL); 2312 } 2313 2314 if (name == IPV6_NEXTHOP) { 2315 error = copyin(PTRIN(args->optlen), &len, sizeof(len)); 2316 if (error != 0) 2317 return (error); 2318 sa = malloc(len, M_SONAME, M_WAITOK); 2319 2320 error = kern_getsockopt(td, args->s, level, 2321 name, sa, UIO_SYSSPACE, &len); 2322 if (error != 0) 2323 goto out; 2324 2325 error = linux_copyout_sockaddr(sa, PTRIN(args->optval), len); 2326 if (error == 0) 2327 error = copyout(&len, PTRIN(args->optlen), 2328 sizeof(len)); 2329 out: 2330 free(sa, M_SONAME); 2331 } else { 2332 if (args->optval) { 2333 error = copyin(PTRIN(args->optlen), &len, sizeof(len)); 2334 if (error != 0) 2335 return (error); 2336 } 2337 error = kern_getsockopt(td, args->s, level, 2338 name, PTRIN(args->optval), UIO_USERSPACE, &len); 2339 if (error == 0) 2340 error = copyout(&len, PTRIN(args->optlen), 2341 sizeof(len)); 2342 } 2343 2344 return (error); 2345 } 2346 2347 static int 2348 linux_sendfile_common(struct thread *td, l_int out, l_int in, 2349 l_loff_t *offset, l_size_t count) 2350 { 2351 off_t bytes_read; 2352 int error; 2353 l_loff_t current_offset; 2354 struct file *fp; 2355 2356 AUDIT_ARG_FD(in); 2357 error = fget_read(td, in, &cap_pread_rights, &fp); 2358 if (error != 0) 2359 return (error); 2360 2361 if (offset != NULL) { 2362 current_offset = *offset; 2363 } else { 2364 error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ? 2365 fo_seek(fp, 0, SEEK_CUR, td) : ESPIPE; 2366 if (error != 0) 2367 goto drop; 2368 current_offset = td->td_uretoff.tdu_off; 2369 } 2370 2371 bytes_read = 0; 2372 2373 /* Linux cannot have 0 count. */ 2374 if (count <= 0 || current_offset < 0) { 2375 error = EINVAL; 2376 goto drop; 2377 } 2378 2379 error = fo_sendfile(fp, out, NULL, NULL, current_offset, count, 2380 &bytes_read, 0, td); 2381 if (error != 0) 2382 goto drop; 2383 current_offset += bytes_read; 2384 2385 if (offset != NULL) { 2386 *offset = current_offset; 2387 } else { 2388 error = fo_seek(fp, current_offset, SEEK_SET, td); 2389 if (error != 0) 2390 goto drop; 2391 } 2392 2393 td->td_retval[0] = (ssize_t)bytes_read; 2394 drop: 2395 fdrop(fp, td); 2396 if (error == ENOTSOCK) 2397 error = EINVAL; 2398 return (error); 2399 } 2400 2401 int 2402 linux_sendfile(struct thread *td, struct linux_sendfile_args *arg) 2403 { 2404 /* 2405 * Differences between FreeBSD and Linux sendfile: 2406 * - Linux doesn't send anything when count is 0 (FreeBSD uses 0 to 2407 * mean send the whole file.) In linux_sendfile given fds are still 2408 * checked for validity when the count is 0. 2409 * - Linux can send to any fd whereas FreeBSD only supports sockets. 2410 * The same restriction follows for linux_sendfile. 2411 * - Linux doesn't have an equivalent for FreeBSD's flags and sf_hdtr. 2412 * - Linux takes an offset pointer and updates it to the read location. 2413 * FreeBSD takes in an offset and a 'bytes read' parameter which is 2414 * only filled if it isn't NULL. We use this parameter to update the 2415 * offset pointer if it exists. 2416 * - Linux sendfile returns bytes read on success while FreeBSD 2417 * returns 0. We use the 'bytes read' parameter to get this value. 2418 */ 2419 2420 l_loff_t offset64; 2421 l_long offset; 2422 int ret; 2423 int error; 2424 2425 if (arg->offset != NULL) { 2426 error = copyin(arg->offset, &offset, sizeof(offset)); 2427 if (error != 0) 2428 return (error); 2429 offset64 = (l_loff_t)offset; 2430 } 2431 2432 ret = linux_sendfile_common(td, arg->out, arg->in, 2433 arg->offset != NULL ? &offset64 : NULL, arg->count); 2434 2435 if (arg->offset != NULL) { 2436 #if defined(__i386__) || defined(__arm__) || \ 2437 (defined(__amd64__) && defined(COMPAT_LINUX32)) 2438 if (offset64 > INT32_MAX) 2439 return (EOVERFLOW); 2440 #endif 2441 offset = (l_long)offset64; 2442 error = copyout(&offset, arg->offset, sizeof(offset)); 2443 if (error != 0) 2444 return (error); 2445 } 2446 2447 return (ret); 2448 } 2449 2450 #if defined(__i386__) || defined(__arm__) || \ 2451 (defined(__amd64__) && defined(COMPAT_LINUX32)) 2452 2453 int 2454 linux_sendfile64(struct thread *td, struct linux_sendfile64_args *arg) 2455 { 2456 l_loff_t offset; 2457 int ret; 2458 int error; 2459 2460 if (arg->offset != NULL) { 2461 error = copyin(arg->offset, &offset, sizeof(offset)); 2462 if (error != 0) 2463 return (error); 2464 } 2465 2466 ret = linux_sendfile_common(td, arg->out, arg->in, 2467 arg->offset != NULL ? &offset : NULL, arg->count); 2468 2469 if (arg->offset != NULL) { 2470 error = copyout(&offset, arg->offset, sizeof(offset)); 2471 if (error != 0) 2472 return (error); 2473 } 2474 2475 return (ret); 2476 } 2477 2478 /* Argument list sizes for linux_socketcall */ 2479 static const unsigned char lxs_args_cnt[] = { 2480 0 /* unused*/, 3 /* socket */, 2481 3 /* bind */, 3 /* connect */, 2482 2 /* listen */, 3 /* accept */, 2483 3 /* getsockname */, 3 /* getpeername */, 2484 4 /* socketpair */, 4 /* send */, 2485 4 /* recv */, 6 /* sendto */, 2486 6 /* recvfrom */, 2 /* shutdown */, 2487 5 /* setsockopt */, 5 /* getsockopt */, 2488 3 /* sendmsg */, 3 /* recvmsg */, 2489 4 /* accept4 */, 5 /* recvmmsg */, 2490 4 /* sendmmsg */, 4 /* sendfile */ 2491 }; 2492 #define LINUX_ARGS_CNT (nitems(lxs_args_cnt) - 1) 2493 #define LINUX_ARG_SIZE(x) (lxs_args_cnt[x] * sizeof(l_ulong)) 2494 2495 int 2496 linux_socketcall(struct thread *td, struct linux_socketcall_args *args) 2497 { 2498 l_ulong a[6]; 2499 #if defined(__amd64__) && defined(COMPAT_LINUX32) 2500 register_t l_args[6]; 2501 #endif 2502 void *arg; 2503 int error; 2504 2505 if (args->what < LINUX_SOCKET || args->what > LINUX_ARGS_CNT) 2506 return (EINVAL); 2507 error = copyin(PTRIN(args->args), a, LINUX_ARG_SIZE(args->what)); 2508 if (error != 0) 2509 return (error); 2510 2511 #if defined(__amd64__) && defined(COMPAT_LINUX32) 2512 for (int i = 0; i < lxs_args_cnt[args->what]; ++i) 2513 l_args[i] = a[i]; 2514 arg = l_args; 2515 #else 2516 arg = a; 2517 #endif 2518 switch (args->what) { 2519 case LINUX_SOCKET: 2520 return (linux_socket(td, arg)); 2521 case LINUX_BIND: 2522 return (linux_bind(td, arg)); 2523 case LINUX_CONNECT: 2524 return (linux_connect(td, arg)); 2525 case LINUX_LISTEN: 2526 return (linux_listen(td, arg)); 2527 case LINUX_ACCEPT: 2528 return (linux_accept(td, arg)); 2529 case LINUX_GETSOCKNAME: 2530 return (linux_getsockname(td, arg)); 2531 case LINUX_GETPEERNAME: 2532 return (linux_getpeername(td, arg)); 2533 case LINUX_SOCKETPAIR: 2534 return (linux_socketpair(td, arg)); 2535 case LINUX_SEND: 2536 return (linux_send(td, arg)); 2537 case LINUX_RECV: 2538 return (linux_recv(td, arg)); 2539 case LINUX_SENDTO: 2540 return (linux_sendto(td, arg)); 2541 case LINUX_RECVFROM: 2542 return (linux_recvfrom(td, arg)); 2543 case LINUX_SHUTDOWN: 2544 return (linux_shutdown(td, arg)); 2545 case LINUX_SETSOCKOPT: 2546 return (linux_setsockopt(td, arg)); 2547 case LINUX_GETSOCKOPT: 2548 return (linux_getsockopt(td, arg)); 2549 case LINUX_SENDMSG: 2550 return (linux_sendmsg(td, arg)); 2551 case LINUX_RECVMSG: 2552 return (linux_recvmsg(td, arg)); 2553 case LINUX_ACCEPT4: 2554 return (linux_accept4(td, arg)); 2555 case LINUX_RECVMMSG: 2556 return (linux_recvmmsg(td, arg)); 2557 case LINUX_SENDMMSG: 2558 return (linux_sendmmsg(td, arg)); 2559 case LINUX_SENDFILE: 2560 return (linux_sendfile(td, arg)); 2561 } 2562 2563 linux_msg(td, "socket type %d not implemented", args->what); 2564 return (ENOSYS); 2565 } 2566 #endif /* __i386__ || __arm__ || (__amd64__ && COMPAT_LINUX32) */ 2567