1 /* $NetBSD: linux_socket.c,v 1.98 2008/08/06 15:01:23 plunky Exp $ */ 2 3 /*- 4 * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Frank van der Linden and Eric Haszlakiewicz. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Functions in multiarch: 34 * linux_sys_socketcall : linux_socketcall.c 35 */ 36 37 #include <sys/cdefs.h> 38 __KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.98 2008/08/06 15:01:23 plunky Exp $"); 39 40 #if defined(_KERNEL_OPT) 41 #include "opt_inet.h" 42 #endif /* defined(_KERNEL_OPT) */ 43 44 #include <sys/param.h> 45 #include <sys/kernel.h> 46 #include <sys/systm.h> 47 #include <sys/buf.h> 48 #include <sys/malloc.h> 49 #include <sys/ioctl.h> 50 #include <sys/tty.h> 51 #include <sys/file.h> 52 #include <sys/filedesc.h> 53 #include <sys/select.h> 54 #include <sys/socket.h> 55 #include <sys/socketvar.h> 56 #include <sys/domain.h> 57 #include <net/if.h> 58 #include <net/if_dl.h> 59 #include <net/if_types.h> 60 #include <netinet/in.h> 61 #include <netinet/tcp.h> 62 #include <sys/mount.h> 63 #include <sys/proc.h> 64 #include <sys/vnode.h> 65 #include <sys/device.h> 66 #include <sys/protosw.h> 67 #include <sys/mbuf.h> 68 #include <sys/syslog.h> 69 #include <sys/exec.h> 70 #include <sys/kauth.h> 71 #include <sys/syscallargs.h> 72 #include <sys/ktrace.h> 73 74 #include <lib/libkern/libkern.h> 75 76 #ifdef INET6 77 #include <netinet/ip6.h> 78 #include <netinet6/ip6_var.h> 79 #endif 80 81 #include <compat/sys/socket.h> 82 #include <compat/sys/sockio.h> 83 84 #include <compat/linux/common/linux_types.h> 85 #include <compat/linux/common/linux_util.h> 86 #include <compat/linux/common/linux_signal.h> 87 #include <compat/linux/common/linux_ioctl.h> 88 #include <compat/linux/common/linux_socket.h> 89 #if !defined(__alpha__) && !defined(__amd64__) 90 #include <compat/linux/common/linux_socketcall.h> 91 #endif 92 #include <compat/linux/common/linux_sockio.h> 93 #include <compat/linux/common/linux_ipc.h> 94 #include <compat/linux/common/linux_sem.h> 95 96 #include <compat/linux/linux_syscallargs.h> 97 98 #ifdef DEBUG_LINUX 99 #define DPRINTF(a) uprintf a 100 #else 101 #define DPRINTF(a) 102 #endif 103 104 /* 105 * The calls in this file are entered either via the linux_socketcall() 106 * interface or, on the Alpha, as individual syscalls. The 107 * linux_socketcall function does any massaging of arguments so that all 108 * the calls in here need not think that they are anything other 109 * than a normal syscall. 110 */ 111 112 static int linux_to_bsd_domain(int); 113 static int bsd_to_linux_domain(int); 114 int linux_to_bsd_sopt_level(int); 115 int linux_to_bsd_so_sockopt(int); 116 int linux_to_bsd_ip_sockopt(int); 117 int linux_to_bsd_tcp_sockopt(int); 118 int linux_to_bsd_udp_sockopt(int); 119 int linux_getifconf(struct lwp *, register_t *, void *); 120 int linux_getifhwaddr(struct lwp *, register_t *, u_int, void *); 121 static int linux_get_sa(struct lwp *, int, struct mbuf **, 122 const struct osockaddr *, unsigned int); 123 static int linux_sa_put(struct osockaddr *osa); 124 static int linux_to_bsd_msg_flags(int); 125 static int bsd_to_linux_msg_flags(int); 126 127 static const int linux_to_bsd_domain_[LINUX_AF_MAX] = { 128 AF_UNSPEC, 129 AF_UNIX, 130 AF_INET, 131 AF_CCITT, /* LINUX_AF_AX25 */ 132 AF_IPX, 133 AF_APPLETALK, 134 -1, /* LINUX_AF_NETROM */ 135 -1, /* LINUX_AF_BRIDGE */ 136 -1, /* LINUX_AF_ATMPVC */ 137 AF_CCITT, /* LINUX_AF_X25 */ 138 AF_INET6, 139 -1, /* LINUX_AF_ROSE */ 140 AF_DECnet, 141 -1, /* LINUX_AF_NETBEUI */ 142 -1, /* LINUX_AF_SECURITY */ 143 pseudo_AF_KEY, 144 AF_ROUTE, /* LINUX_AF_NETLINK */ 145 -1, /* LINUX_AF_PACKET */ 146 -1, /* LINUX_AF_ASH */ 147 -1, /* LINUX_AF_ECONET */ 148 -1, /* LINUX_AF_ATMSVC */ 149 AF_SNA, 150 /* rest up to LINUX_AF_MAX-1 is not allocated */ 151 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 152 }; 153 154 static const int bsd_to_linux_domain_[AF_MAX] = { 155 LINUX_AF_UNSPEC, 156 LINUX_AF_UNIX, 157 LINUX_AF_INET, 158 -1, /* AF_IMPLINK */ 159 -1, /* AF_PUP */ 160 -1, /* AF_CHAOS */ 161 -1, /* AF_NS */ 162 -1, /* AF_ISO */ 163 -1, /* AF_ECMA */ 164 -1, /* AF_DATAKIT */ 165 LINUX_AF_AX25, /* AF_CCITT */ 166 LINUX_AF_SNA, 167 LINUX_AF_DECnet, 168 -1, /* AF_DLI */ 169 -1, /* AF_LAT */ 170 -1, /* AF_HYLINK */ 171 LINUX_AF_APPLETALK, 172 LINUX_AF_NETLINK, 173 -1, /* AF_LINK */ 174 -1, /* AF_XTP */ 175 -1, /* AF_COIP */ 176 -1, /* AF_CNT */ 177 -1, /* pseudo_AF_RTIP */ 178 LINUX_AF_IPX, 179 LINUX_AF_INET6, 180 -1, /* pseudo_AF_PIP */ 181 -1, /* AF_ISDN */ 182 -1, /* AF_NATM */ 183 -1, /* AF_ARP */ 184 LINUX_pseudo_AF_KEY, 185 -1, /* pseudo_AF_HDRCMPLT */ 186 }; 187 188 static const struct { 189 int bfl; 190 int lfl; 191 } bsd_to_linux_msg_flags_[] = { 192 {MSG_OOB, LINUX_MSG_OOB}, 193 {MSG_PEEK, LINUX_MSG_PEEK}, 194 {MSG_DONTROUTE, LINUX_MSG_DONTROUTE}, 195 {MSG_EOR, LINUX_MSG_EOR}, 196 {MSG_TRUNC, LINUX_MSG_TRUNC}, 197 {MSG_CTRUNC, LINUX_MSG_CTRUNC}, 198 {MSG_WAITALL, LINUX_MSG_WAITALL}, 199 {MSG_DONTWAIT, LINUX_MSG_DONTWAIT}, 200 {MSG_BCAST, 0}, /* not supported, clear */ 201 {MSG_MCAST, 0}, /* not supported, clear */ 202 {-1, /* not supp */ LINUX_MSG_PROBE}, 203 {-1, /* not supp */ LINUX_MSG_FIN}, 204 {-1, /* not supp */ LINUX_MSG_SYN}, 205 {-1, /* not supp */ LINUX_MSG_CONFIRM}, 206 {-1, /* not supp */ LINUX_MSG_RST}, 207 {-1, /* not supp */ LINUX_MSG_ERRQUEUE}, 208 {-1, /* not supp */ LINUX_MSG_NOSIGNAL}, 209 {-1, /* not supp */ LINUX_MSG_MORE}, 210 }; 211 212 /* 213 * Convert between Linux and BSD socket domain values 214 */ 215 static int 216 linux_to_bsd_domain(int ldom) 217 { 218 if (ldom < 0 || ldom >= LINUX_AF_MAX) 219 return (-1); 220 221 return linux_to_bsd_domain_[ldom]; 222 } 223 224 /* 225 * Convert between BSD and Linux socket domain values 226 */ 227 static int 228 bsd_to_linux_domain(int bdom) 229 { 230 if (bdom < 0 || bdom >= AF_MAX) 231 return (-1); 232 233 return bsd_to_linux_domain_[bdom]; 234 } 235 236 static int 237 linux_to_bsd_msg_flags(int lflag) 238 { 239 int i, lfl, bfl; 240 int bflag = 0; 241 242 if (lflag == 0) 243 return (0); 244 245 for(i = 0; i < __arraycount(bsd_to_linux_msg_flags_); i++) { 246 bfl = bsd_to_linux_msg_flags_[i].bfl; 247 lfl = bsd_to_linux_msg_flags_[i].lfl; 248 249 if (lfl == 0) 250 continue; 251 252 if (lflag & lfl) { 253 if (bfl < 0) 254 return (-1); 255 256 bflag |= bfl; 257 } 258 } 259 260 return (bflag); 261 } 262 263 static int 264 bsd_to_linux_msg_flags(int bflag) 265 { 266 int i, lfl, bfl; 267 int lflag = 0; 268 269 if (bflag == 0) 270 return (0); 271 272 for(i = 0; i < __arraycount(bsd_to_linux_msg_flags_); i++) { 273 bfl = bsd_to_linux_msg_flags_[i].bfl; 274 lfl = bsd_to_linux_msg_flags_[i].lfl; 275 276 if (bfl <= 0) 277 continue; 278 279 if (bflag & bfl) { 280 if (lfl < 0) 281 return (-1); 282 283 lflag |= lfl; 284 } 285 } 286 287 return (lflag); 288 } 289 290 int 291 linux_sys_socket(struct lwp *l, const struct linux_sys_socket_args *uap, register_t *retval) 292 { 293 /* { 294 syscallarg(int) domain; 295 syscallarg(int) type; 296 syscallarg(int) protocol; 297 } */ 298 struct sys___socket30_args bsa; 299 int error; 300 301 SCARG(&bsa, protocol) = SCARG(uap, protocol); 302 SCARG(&bsa, type) = SCARG(uap, type); 303 SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain)); 304 if (SCARG(&bsa, domain) == -1) 305 return EINVAL; 306 error = sys___socket30(l, &bsa, retval); 307 308 #ifdef INET6 309 /* 310 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by 311 * default and some apps depend on this. So, set V6ONLY to 0 312 * for Linux apps if the sysctl value is set to 1. 313 */ 314 if (!error && ip6_v6only && SCARG(&bsa, domain) == PF_INET6) { 315 struct socket *so; 316 317 if (fd_getsock(*retval, &so) == 0) { 318 int val = 0; 319 320 /* ignore error */ 321 (void)so_setsockopt(l, so, IPPROTO_IPV6, IPV6_V6ONLY, 322 &val, sizeof(val)); 323 324 fd_putfile(*retval); 325 } 326 } 327 #endif 328 329 return (error); 330 } 331 332 int 333 linux_sys_socketpair(struct lwp *l, const struct linux_sys_socketpair_args *uap, register_t *retval) 334 { 335 /* { 336 syscallarg(int) domain; 337 syscallarg(int) type; 338 syscallarg(int) protocol; 339 syscallarg(int *) rsv; 340 } */ 341 struct sys_socketpair_args bsa; 342 343 SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain)); 344 if (SCARG(&bsa, domain) == -1) 345 return EINVAL; 346 SCARG(&bsa, type) = SCARG(uap, type); 347 SCARG(&bsa, protocol) = SCARG(uap, protocol); 348 SCARG(&bsa, rsv) = SCARG(uap, rsv); 349 350 return sys_socketpair(l, &bsa, retval); 351 } 352 353 int 354 linux_sys_sendto(struct lwp *l, const struct linux_sys_sendto_args *uap, register_t *retval) 355 { 356 /* { 357 syscallarg(int) s; 358 syscallarg(void *) msg; 359 syscallarg(int) len; 360 syscallarg(int) flags; 361 syscallarg(struct osockaddr *) to; 362 syscallarg(int) tolen; 363 } */ 364 struct msghdr msg; 365 struct iovec aiov; 366 struct mbuf *nam; 367 int bflags; 368 int error; 369 370 /* Translate message flags. */ 371 bflags = linux_to_bsd_msg_flags(SCARG(uap, flags)); 372 if (bflags < 0) 373 /* Some supported flag */ 374 return EINVAL; 375 376 msg.msg_flags = 0; 377 msg.msg_name = NULL; 378 msg.msg_control = NULL; 379 380 if (SCARG(uap, tolen)) { 381 /* Read in and convert the sockaddr */ 382 error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, to), 383 SCARG(uap, tolen)); 384 if (error) 385 return (error); 386 msg.msg_flags |= MSG_NAMEMBUF; 387 msg.msg_name = nam; 388 msg.msg_namelen = SCARG(uap, tolen); 389 } 390 391 msg.msg_iov = &aiov; 392 msg.msg_iovlen = 1; 393 aiov.iov_base = __UNCONST(SCARG(uap, msg)); 394 aiov.iov_len = SCARG(uap, len); 395 396 return do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval); 397 } 398 399 int 400 linux_sys_sendmsg(struct lwp *l, const struct linux_sys_sendmsg_args *uap, register_t *retval) 401 { 402 /* { 403 syscallarg(int) s; 404 syscallarg(struct msghdr *) msg; 405 syscallarg(u_int) flags; 406 } */ 407 struct msghdr msg; 408 int error; 409 int bflags; 410 struct mbuf *nam; 411 u_int8_t *control; 412 struct mbuf *ctl_mbuf = NULL; 413 414 msg.msg_flags = MSG_IOVUSRSPACE; 415 416 /* 417 * Translate message flags. 418 */ 419 bflags = linux_to_bsd_msg_flags(SCARG(uap, flags)); 420 if (bflags < 0) 421 /* Some supported flag */ 422 return EINVAL; 423 424 if (msg.msg_name) { 425 /* Read in and convert the sockaddr */ 426 error = linux_get_sa(l, SCARG(uap, s), &nam, msg.msg_name, 427 msg.msg_namelen); 428 if (error) 429 return (error); 430 msg.msg_flags |= MSG_NAMEMBUF; 431 msg.msg_name = nam; 432 } 433 434 /* 435 * Handle cmsg if there is any. 436 */ 437 if (CMSG_FIRSTHDR(&msg)) { 438 struct linux_cmsghdr l_cmsg, *l_cc; 439 struct cmsghdr *cmsg; 440 ssize_t resid = msg.msg_controllen; 441 size_t clen, cidx = 0, cspace; 442 443 ctl_mbuf = m_get(M_WAIT, MT_CONTROL); 444 clen = MLEN; 445 control = mtod(ctl_mbuf, void *); 446 447 l_cc = LINUX_CMSG_FIRSTHDR(&msg); 448 do { 449 error = copyin(l_cc, &l_cmsg, sizeof(l_cmsg)); 450 if (error) 451 goto done; 452 453 /* 454 * Sanity check the control message length. 455 */ 456 if (l_cmsg.cmsg_len > resid 457 || l_cmsg.cmsg_len < sizeof l_cmsg) { 458 error = EINVAL; 459 goto done; 460 } 461 462 /* 463 * Refuse unsupported control messages, and 464 * translate fields as appropriate. 465 */ 466 switch (l_cmsg.cmsg_level) { 467 case LINUX_SOL_SOCKET: 468 /* It only differs on some archs */ 469 if (LINUX_SOL_SOCKET != SOL_SOCKET) 470 l_cmsg.cmsg_level = SOL_SOCKET; 471 472 switch(l_cmsg.cmsg_type) { 473 case LINUX_SCM_RIGHTS: 474 /* Linux SCM_RIGHTS is same as NetBSD */ 475 break; 476 477 default: 478 /* other types not supported */ 479 error = EINVAL; 480 goto done; 481 } 482 break; 483 default: 484 /* pray and leave intact */ 485 break; 486 } 487 488 cspace = CMSG_SPACE(l_cmsg.cmsg_len - sizeof(l_cmsg)); 489 490 /* Check the buffer is big enough */ 491 if (__predict_false(cidx + cspace > clen)) { 492 u_int8_t *nc; 493 494 clen = cidx + cspace; 495 if (clen >= PAGE_SIZE) { 496 error = EINVAL; 497 goto done; 498 } 499 nc = realloc(clen <= MLEN ? NULL : control, 500 clen, M_TEMP, M_WAITOK); 501 if (!nc) { 502 error = ENOMEM; 503 goto done; 504 } 505 if (cidx <= MLEN) 506 /* Old buffer was in mbuf... */ 507 memcpy(nc, control, cidx); 508 control = nc; 509 } 510 511 /* Copy header */ 512 cmsg = (void *)&control[cidx]; 513 cmsg->cmsg_len = l_cmsg.cmsg_len + LINUX_CMSG_ALIGN_DELTA; 514 cmsg->cmsg_level = l_cmsg.cmsg_level; 515 cmsg->cmsg_type = l_cmsg.cmsg_type; 516 517 /* Zero are between header and data */ 518 memset(cmsg + 1, 0, 519 CMSG_ALIGN(sizeof(cmsg)) - sizeof(cmsg)); 520 521 /* Copyin the data */ 522 error = copyin(LINUX_CMSG_DATA(l_cc), 523 CMSG_DATA(control), 524 l_cmsg.cmsg_len - sizeof(l_cmsg)); 525 if (error) 526 goto done; 527 528 resid -= LINUX_CMSG_ALIGN(l_cmsg.cmsg_len); 529 cidx += cspace; 530 } while ((l_cc = LINUX_CMSG_NXTHDR(&msg, l_cc)) && resid > 0); 531 532 /* If we allocated a buffer, attach to mbuf */ 533 if (cidx > MLEN) { 534 MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL); 535 ctl_mbuf->m_flags |= M_EXT_RW; 536 } 537 control = NULL; 538 ctl_mbuf->m_len = cidx; 539 540 msg.msg_control = ctl_mbuf; 541 msg.msg_flags |= MSG_CONTROLMBUF; 542 } 543 544 error = do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval); 545 /* Freed internally */ 546 ctl_mbuf = NULL; 547 548 done: 549 if (ctl_mbuf != NULL) { 550 if (control != NULL && control != mtod(ctl_mbuf, void *)) 551 free(control, M_MBUF); 552 m_free(ctl_mbuf); 553 } 554 return (error); 555 } 556 557 int 558 linux_sys_recvfrom(struct lwp *l, const struct linux_sys_recvfrom_args *uap, register_t *retval) 559 { 560 /* { 561 syscallarg(int) s; 562 syscallarg(void *) buf; 563 syscallarg(int) len; 564 syscallarg(int) flags; 565 syscallarg(struct osockaddr *) from; 566 syscallarg(int *) fromlenaddr; 567 } */ 568 int error; 569 struct sys_recvfrom_args bra; 570 571 SCARG(&bra, s) = SCARG(uap, s); 572 SCARG(&bra, buf) = SCARG(uap, buf); 573 SCARG(&bra, len) = SCARG(uap, len); 574 SCARG(&bra, flags) = SCARG(uap, flags); 575 SCARG(&bra, from) = (struct sockaddr *) SCARG(uap, from); 576 SCARG(&bra, fromlenaddr) = (socklen_t *)SCARG(uap, fromlenaddr); 577 578 if ((error = sys_recvfrom(l, &bra, retval))) 579 return (error); 580 581 if (SCARG(uap, from) && (error = linux_sa_put(SCARG(uap, from)))) 582 return (error); 583 584 return (0); 585 } 586 587 static int 588 linux_copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control) 589 { 590 int dlen, error = 0; 591 struct cmsghdr *cmsg; 592 struct linux_cmsghdr linux_cmsg; 593 struct mbuf *m; 594 char *q, *q_end; 595 596 if (mp->msg_controllen <= 0 || control == 0) { 597 mp->msg_controllen = 0; 598 free_control_mbuf(l, control, control); 599 return 0; 600 } 601 602 q = (char *)mp->msg_control; 603 q_end = q + mp->msg_controllen; 604 605 for (m = control; m != NULL; ) { 606 cmsg = mtod(m, struct cmsghdr *); 607 608 /* 609 * Fixup cmsg. We handle two things: 610 * 0. different sizeof cmsg_len. 611 * 1. different values for level/type on some archs 612 * 2. different alignment of CMSG_DATA on some archs 613 */ 614 linux_cmsg.cmsg_len = cmsg->cmsg_len - LINUX_CMSG_ALIGN_DELTA; 615 linux_cmsg.cmsg_level = cmsg->cmsg_level; 616 linux_cmsg.cmsg_type = cmsg->cmsg_type; 617 618 dlen = q_end - q; 619 if (linux_cmsg.cmsg_len > dlen) { 620 /* Not enough room for the parameter */ 621 dlen -= sizeof linux_cmsg; 622 if (dlen <= 0) 623 /* Discard if header wont fit */ 624 break; 625 mp->msg_flags |= MSG_CTRUNC; 626 if (linux_cmsg.cmsg_level == SOL_SOCKET 627 && linux_cmsg.cmsg_type == SCM_RIGHTS) 628 /* Do not truncate me ... */ 629 break; 630 } else 631 dlen = linux_cmsg.cmsg_len - sizeof linux_cmsg; 632 633 switch (linux_cmsg.cmsg_level) { 634 case SOL_SOCKET: 635 linux_cmsg.cmsg_level = LINUX_SOL_SOCKET; 636 switch (linux_cmsg.cmsg_type) { 637 case SCM_RIGHTS: 638 /* Linux SCM_RIGHTS is same as NetBSD */ 639 break; 640 641 default: 642 /* other types not supported */ 643 error = EINVAL; 644 goto done; 645 } 646 /* machine dependant ! */ 647 break; 648 default: 649 /* pray and leave intact */ 650 break; 651 } 652 653 /* There can be padding between the header and data... */ 654 error = copyout(&linux_cmsg, q, sizeof *cmsg); 655 if (error != 0) { 656 error = copyout(CCMSG_DATA(cmsg), q + sizeof linux_cmsg, 657 dlen); 658 } 659 if (error != 0) { 660 /* We must free all the SCM_RIGHTS */ 661 m = control; 662 break; 663 } 664 m = m->m_next; 665 if (m == NULL || q + LINUX_CMSG_ALIGN(dlen) > q_end) { 666 q += dlen; 667 break; 668 } 669 q += LINUX_CMSG_ALIGN(dlen); 670 } 671 672 done: 673 free_control_mbuf(l, control, m); 674 675 mp->msg_controllen = q - (char *)mp->msg_control; 676 return error; 677 } 678 679 int 680 linux_sys_recvmsg(struct lwp *l, const struct linux_sys_recvmsg_args *uap, register_t *retval) 681 { 682 /* { 683 syscallarg(int) s; 684 syscallarg(struct msghdr *) msg; 685 syscallarg(u_int) flags; 686 } */ 687 struct msghdr msg; 688 int error; 689 struct mbuf *from, *control; 690 691 error = copyin(SCARG(uap, msg), &msg, sizeof(msg)); 692 if (error) 693 return (error); 694 695 msg.msg_flags = linux_to_bsd_msg_flags(SCARG(uap, flags)); 696 if (msg.msg_flags < 0) { 697 /* Some unsupported flag */ 698 return (EINVAL); 699 } 700 msg.msg_flags |= MSG_IOVUSRSPACE; 701 702 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, 703 msg.msg_control != NULL ? &control : NULL, retval); 704 if (error != 0) 705 return error; 706 707 if (msg.msg_control != NULL) 708 error = linux_copyout_msg_control(l, &msg, control); 709 710 if (error == 0 && from != 0) { 711 mtod(from, struct osockaddr *)->sa_family = 712 bsd_to_linux_domain(mtod(from, struct sockaddr *)->sa_family); 713 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0, 714 from); 715 } else 716 msg.msg_namelen = 0; 717 718 if (from != NULL) 719 m_free(from); 720 721 if (error == 0) { 722 msg.msg_flags = bsd_to_linux_msg_flags(msg.msg_flags); 723 if (msg.msg_flags < 0) 724 /* Some flag unsupported by Linux */ 725 error = EINVAL; 726 else 727 error = copyout(&msg, SCARG(uap, msg), sizeof(msg)); 728 } 729 730 return (error); 731 } 732 733 /* 734 * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET 735 * is different, the rest matches IPPROTO_* on both systems. 736 */ 737 int 738 linux_to_bsd_sopt_level(int llevel) 739 { 740 741 switch (llevel) { 742 case LINUX_SOL_SOCKET: 743 return SOL_SOCKET; 744 case LINUX_SOL_IP: 745 return IPPROTO_IP; 746 case LINUX_SOL_TCP: 747 return IPPROTO_TCP; 748 case LINUX_SOL_UDP: 749 return IPPROTO_UDP; 750 default: 751 return -1; 752 } 753 } 754 755 /* 756 * Convert Linux socket level socket option numbers to NetBSD values. 757 */ 758 int 759 linux_to_bsd_so_sockopt(int lopt) 760 { 761 762 switch (lopt) { 763 case LINUX_SO_DEBUG: 764 return SO_DEBUG; 765 case LINUX_SO_REUSEADDR: 766 /* 767 * Linux does not implement SO_REUSEPORT, but allows reuse of a 768 * host:port pair through SO_REUSEADDR even if the address is not a 769 * multicast-address. Effectively, this means that we should use 770 * SO_REUSEPORT to allow Linux applications to not exit with 771 * EADDRINUSE 772 */ 773 return SO_REUSEPORT; 774 case LINUX_SO_TYPE: 775 return SO_TYPE; 776 case LINUX_SO_ERROR: 777 return SO_ERROR; 778 case LINUX_SO_DONTROUTE: 779 return SO_DONTROUTE; 780 case LINUX_SO_BROADCAST: 781 return SO_BROADCAST; 782 case LINUX_SO_SNDBUF: 783 return SO_SNDBUF; 784 case LINUX_SO_RCVBUF: 785 return SO_RCVBUF; 786 case LINUX_SO_KEEPALIVE: 787 return SO_KEEPALIVE; 788 case LINUX_SO_OOBINLINE: 789 return SO_OOBINLINE; 790 case LINUX_SO_LINGER: 791 return SO_LINGER; 792 case LINUX_SO_PRIORITY: 793 case LINUX_SO_NO_CHECK: 794 default: 795 return -1; 796 } 797 } 798 799 /* 800 * Convert Linux IP level socket option number to NetBSD values. 801 */ 802 int 803 linux_to_bsd_ip_sockopt(int lopt) 804 { 805 806 switch (lopt) { 807 case LINUX_IP_TOS: 808 return IP_TOS; 809 case LINUX_IP_TTL: 810 return IP_TTL; 811 case LINUX_IP_MULTICAST_TTL: 812 return IP_MULTICAST_TTL; 813 case LINUX_IP_MULTICAST_LOOP: 814 return IP_MULTICAST_LOOP; 815 case LINUX_IP_MULTICAST_IF: 816 return IP_MULTICAST_IF; 817 case LINUX_IP_ADD_MEMBERSHIP: 818 return IP_ADD_MEMBERSHIP; 819 case LINUX_IP_DROP_MEMBERSHIP: 820 return IP_DROP_MEMBERSHIP; 821 default: 822 return -1; 823 } 824 } 825 826 /* 827 * Convert Linux TCP level socket option number to NetBSD values. 828 */ 829 int 830 linux_to_bsd_tcp_sockopt(int lopt) 831 { 832 833 switch (lopt) { 834 case LINUX_TCP_NODELAY: 835 return TCP_NODELAY; 836 case LINUX_TCP_MAXSEG: 837 return TCP_MAXSEG; 838 default: 839 return -1; 840 } 841 } 842 843 /* 844 * Convert Linux UDP level socket option number to NetBSD values. 845 */ 846 int 847 linux_to_bsd_udp_sockopt(int lopt) 848 { 849 850 switch (lopt) { 851 default: 852 return -1; 853 } 854 } 855 856 /* 857 * Another reasonably straightforward function: setsockopt(2). 858 * The level and option numbers are converted; the values passed 859 * are not (yet) converted, the ones currently implemented don't 860 * need conversion, as they are the same on both systems. 861 */ 862 int 863 linux_sys_setsockopt(struct lwp *l, const struct linux_sys_setsockopt_args *uap, register_t *retval) 864 { 865 /* { 866 syscallarg(int) s; 867 syscallarg(int) level; 868 syscallarg(int) optname; 869 syscallarg(void *) optval; 870 syscallarg(int) optlen; 871 } */ 872 struct sys_setsockopt_args bsa; 873 int name; 874 875 SCARG(&bsa, s) = SCARG(uap, s); 876 SCARG(&bsa, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 877 SCARG(&bsa, val) = SCARG(uap, optval); 878 SCARG(&bsa, valsize) = SCARG(uap, optlen); 879 880 /* 881 * Linux supports only SOL_SOCKET for AF_LOCAL domain sockets 882 * and returns EOPNOTSUPP for other levels 883 */ 884 if (SCARG(&bsa, level) != SOL_SOCKET) { 885 struct socket *so; 886 int error, family; 887 888 /* fd_getsock() will use the descriptor for us */ 889 if ((error = fd_getsock(SCARG(&bsa, s), &so)) != 0) 890 return error; 891 family = so->so_proto->pr_domain->dom_family; 892 fd_putfile(SCARG(&bsa, s)); 893 894 if (family == AF_LOCAL) 895 return EOPNOTSUPP; 896 } 897 898 switch (SCARG(&bsa, level)) { 899 case SOL_SOCKET: 900 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 901 break; 902 case IPPROTO_IP: 903 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 904 break; 905 case IPPROTO_TCP: 906 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 907 break; 908 case IPPROTO_UDP: 909 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 910 break; 911 default: 912 return EINVAL; 913 } 914 915 if (name == -1) 916 return EINVAL; 917 SCARG(&bsa, name) = name; 918 919 return sys_setsockopt(l, &bsa, retval); 920 } 921 922 /* 923 * getsockopt(2) is very much the same as setsockopt(2) (see above) 924 */ 925 int 926 linux_sys_getsockopt(struct lwp *l, const struct linux_sys_getsockopt_args *uap, register_t *retval) 927 { 928 /* { 929 syscallarg(int) s; 930 syscallarg(int) level; 931 syscallarg(int) optname; 932 syscallarg(void *) optval; 933 syscallarg(int *) optlen; 934 } */ 935 struct sys_getsockopt_args bga; 936 int name; 937 938 SCARG(&bga, s) = SCARG(uap, s); 939 SCARG(&bga, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 940 SCARG(&bga, val) = SCARG(uap, optval); 941 SCARG(&bga, avalsize) = (socklen_t *)SCARG(uap, optlen); 942 943 switch (SCARG(&bga, level)) { 944 case SOL_SOCKET: 945 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 946 break; 947 case IPPROTO_IP: 948 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 949 break; 950 case IPPROTO_TCP: 951 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 952 break; 953 case IPPROTO_UDP: 954 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 955 break; 956 default: 957 return EINVAL; 958 } 959 960 if (name == -1) 961 return EINVAL; 962 SCARG(&bga, name) = name; 963 964 return sys_getsockopt(l, &bga, retval); 965 } 966 967 int 968 linux_getifconf(struct lwp *l, register_t *retval, void *data) 969 { 970 struct linux_ifreq ifr, *ifrp; 971 struct ifconf *ifc = data; 972 struct ifnet *ifp; 973 struct ifaddr *ifa; 974 struct sockaddr *sa; 975 struct osockaddr *osa; 976 int space, error = 0; 977 const int sz = (int)sizeof(ifr); 978 979 ifrp = (struct linux_ifreq *)ifc->ifc_req; 980 if (ifrp == NULL) 981 space = 0; 982 else 983 space = ifc->ifc_len; 984 985 IFNET_FOREACH(ifp) { 986 (void)strncpy(ifr.ifr_name, ifp->if_xname, 987 sizeof(ifr.ifr_name)); 988 if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0') 989 return ENAMETOOLONG; 990 if (IFADDR_EMPTY(ifp)) 991 continue; 992 IFADDR_FOREACH(ifa, ifp) { 993 sa = ifa->ifa_addr; 994 if (sa->sa_family != AF_INET || 995 sa->sa_len > sizeof(*osa)) 996 continue; 997 memcpy(&ifr.ifr_addr, sa, sa->sa_len); 998 osa = (struct osockaddr *)&ifr.ifr_addr; 999 osa->sa_family = sa->sa_family; 1000 if (space >= sz) { 1001 error = copyout(&ifr, ifrp, sz); 1002 if (error != 0) 1003 return error; 1004 ifrp++; 1005 } 1006 space -= sz; 1007 } 1008 } 1009 1010 if (ifrp != NULL) 1011 ifc->ifc_len -= space; 1012 else 1013 ifc->ifc_len = -space; 1014 1015 return 0; 1016 } 1017 1018 int 1019 linux_getifhwaddr(struct lwp *l, register_t *retval, u_int fd, 1020 void *data) 1021 { 1022 /* Not the full structure, just enough to map what we do here */ 1023 struct linux_ifreq lreq; 1024 file_t *fp; 1025 struct ifaddr *ifa; 1026 struct ifnet *ifp; 1027 struct sockaddr_dl *sadl; 1028 int error, found; 1029 int index, ifnum; 1030 1031 /* 1032 * We can't emulate this ioctl by calling sys_ioctl() to run 1033 * SIOCGIFCONF, because the user buffer is not of the right 1034 * type to take those results. We can't use kernel buffers to 1035 * receive the results, as the implementation of sys_ioctl() 1036 * and ifconf() [which implements SIOCGIFCONF] use 1037 * copyin()/copyout() which will fail on kernel addresses. 1038 * 1039 * So, we must duplicate code from sys_ioctl() and ifconf(). Ugh. 1040 */ 1041 1042 if ((fp = fd_getfile(fd)) == NULL) 1043 return (EBADF); 1044 1045 KERNEL_LOCK(1, NULL); 1046 1047 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 1048 error = EBADF; 1049 goto out; 1050 } 1051 1052 error = copyin(data, &lreq, sizeof(lreq)); 1053 if (error) 1054 goto out; 1055 lreq.ifr_name[LINUX_IFNAMSIZ-1] = '\0'; /* just in case */ 1056 1057 /* 1058 * Try real interface name first, then fake "ethX" 1059 */ 1060 found = 0; 1061 IFNET_FOREACH(ifp) { 1062 if (found) 1063 break; 1064 if (strcmp(lreq.ifr_name, ifp->if_xname)) 1065 /* not this interface */ 1066 continue; 1067 found=1; 1068 if (IFADDR_EMPTY(ifp)) { 1069 error = ENODEV; 1070 goto out; 1071 } 1072 IFADDR_FOREACH(ifa, ifp) { 1073 sadl = satosdl(ifa->ifa_addr); 1074 /* only return ethernet addresses */ 1075 /* XXX what about FDDI, etc. ? */ 1076 if (sadl->sdl_family != AF_LINK || 1077 sadl->sdl_type != IFT_ETHER) 1078 continue; 1079 memcpy(&lreq.ifr_hwaddr.sa_data, CLLADDR(sadl), 1080 MIN(sadl->sdl_alen, 1081 sizeof(lreq.ifr_hwaddr.sa_data))); 1082 lreq.ifr_hwaddr.sa_family = 1083 sadl->sdl_family; 1084 error = copyout(&lreq, data, sizeof(lreq)); 1085 goto out; 1086 } 1087 } 1088 1089 if (strncmp(lreq.ifr_name, "eth", 3) == 0) { 1090 for (ifnum = 0, index = 3; 1091 lreq.ifr_name[index] != '\0' && index < LINUX_IFNAMSIZ; 1092 index++) { 1093 ifnum *= 10; 1094 ifnum += lreq.ifr_name[index] - '0'; 1095 } 1096 1097 error = EINVAL; /* in case we don't find one */ 1098 found = 0; 1099 IFNET_FOREACH(ifp) { 1100 if (found) 1101 break; 1102 memcpy(lreq.ifr_name, ifp->if_xname, 1103 MIN(LINUX_IFNAMSIZ, IFNAMSIZ)); 1104 IFADDR_FOREACH(ifa, ifp) { 1105 sadl = satosdl(ifa->ifa_addr); 1106 /* only return ethernet addresses */ 1107 /* XXX what about FDDI, etc. ? */ 1108 if (sadl->sdl_family != AF_LINK || 1109 sadl->sdl_type != IFT_ETHER) 1110 continue; 1111 if (ifnum--) 1112 /* not the reqested iface */ 1113 continue; 1114 memcpy(&lreq.ifr_hwaddr.sa_data, 1115 CLLADDR(sadl), 1116 MIN(sadl->sdl_alen, 1117 sizeof(lreq.ifr_hwaddr.sa_data))); 1118 lreq.ifr_hwaddr.sa_family = 1119 sadl->sdl_family; 1120 error = copyout(&lreq, data, sizeof(lreq)); 1121 found = 1; 1122 break; 1123 } 1124 } 1125 } else { 1126 /* unknown interface, not even an "eth*" name */ 1127 error = ENODEV; 1128 } 1129 1130 out: 1131 KERNEL_UNLOCK_ONE(NULL); 1132 fd_putfile(fd); 1133 return error; 1134 } 1135 1136 int 1137 linux_ioctl_socket(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval) 1138 { 1139 /* { 1140 syscallarg(int) fd; 1141 syscallarg(u_long) com; 1142 syscallarg(void *) data; 1143 } */ 1144 u_long com; 1145 int error = 0, isdev = 0, dosys = 1; 1146 struct sys_ioctl_args ia; 1147 file_t *fp; 1148 struct vnode *vp; 1149 int (*ioctlf)(file_t *, u_long, void *); 1150 struct ioctl_pt pt; 1151 1152 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) 1153 return (EBADF); 1154 1155 if (fp->f_type == DTYPE_VNODE) { 1156 vp = (struct vnode *)fp->f_data; 1157 isdev = vp->v_type == VCHR; 1158 } 1159 1160 /* 1161 * Don't try to interpret socket ioctl calls that are done 1162 * on a device filedescriptor, just pass them through, to 1163 * emulate Linux behaviour. Use PTIOCLINUX so that the 1164 * device will only handle these if it's prepared to do 1165 * so, to avoid unexpected things from happening. 1166 */ 1167 if (isdev) { 1168 dosys = 0; 1169 ioctlf = fp->f_ops->fo_ioctl; 1170 pt.com = SCARG(uap, com); 1171 pt.data = SCARG(uap, data); 1172 error = ioctlf(fp, PTIOCLINUX, &pt); 1173 /* 1174 * XXX hack: if the function returns EJUSTRETURN, 1175 * it has stuffed a sysctl return value in pt.data. 1176 */ 1177 if (error == EJUSTRETURN) { 1178 retval[0] = (register_t)pt.data; 1179 error = 0; 1180 } 1181 goto out; 1182 } 1183 1184 com = SCARG(uap, com); 1185 retval[0] = 0; 1186 1187 switch (com) { 1188 case LINUX_SIOCGIFCONF: 1189 error = linux_getifconf(l, retval, SCARG(uap, data)); 1190 dosys = 0; 1191 break; 1192 case LINUX_SIOCGIFFLAGS: 1193 SCARG(&ia, com) = OSIOCGIFFLAGS; 1194 break; 1195 case LINUX_SIOCSIFFLAGS: 1196 SCARG(&ia, com) = OSIOCSIFFLAGS; 1197 break; 1198 case LINUX_SIOCGIFADDR: 1199 SCARG(&ia, com) = OOSIOCGIFADDR; 1200 break; 1201 case LINUX_SIOCGIFDSTADDR: 1202 SCARG(&ia, com) = OOSIOCGIFDSTADDR; 1203 break; 1204 case LINUX_SIOCGIFBRDADDR: 1205 SCARG(&ia, com) = OOSIOCGIFBRDADDR; 1206 break; 1207 case LINUX_SIOCGIFNETMASK: 1208 SCARG(&ia, com) = OOSIOCGIFNETMASK; 1209 break; 1210 case LINUX_SIOCADDMULTI: 1211 SCARG(&ia, com) = OSIOCADDMULTI; 1212 break; 1213 case LINUX_SIOCDELMULTI: 1214 SCARG(&ia, com) = OSIOCDELMULTI; 1215 break; 1216 case LINUX_SIOCGIFHWADDR: 1217 error = linux_getifhwaddr(l, retval, SCARG(uap, fd), 1218 SCARG(uap, data)); 1219 dosys = 0; 1220 break; 1221 default: 1222 error = EINVAL; 1223 } 1224 1225 out: 1226 fd_putfile(SCARG(uap, fd)); 1227 1228 if (error ==0 && dosys) { 1229 SCARG(&ia, fd) = SCARG(uap, fd); 1230 SCARG(&ia, data) = SCARG(uap, data); 1231 error = sys_ioctl(curlwp, &ia, retval); 1232 } 1233 1234 return error; 1235 } 1236 1237 int 1238 linux_sys_connect(struct lwp *l, const struct linux_sys_connect_args *uap, register_t *retval) 1239 { 1240 /* { 1241 syscallarg(int) s; 1242 syscallarg(const struct sockaddr *) name; 1243 syscallarg(int) namelen; 1244 } */ 1245 int error; 1246 struct mbuf *nam; 1247 1248 error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, name), 1249 SCARG(uap, namelen)); 1250 if (error) 1251 return (error); 1252 1253 error = do_sys_connect(l, SCARG(uap, s), nam); 1254 1255 if (error == EISCONN) { 1256 struct socket *so; 1257 int state, prflags, nbio; 1258 1259 /* fd_getsock() will use the descriptor for us */ 1260 if (fd_getsock(SCARG(uap, s), &so) != 0) 1261 return EISCONN; 1262 1263 solock(so); 1264 state = so->so_state; 1265 nbio = so->so_nbio; 1266 prflags = so->so_proto->pr_flags; 1267 sounlock(so); 1268 fd_putfile(SCARG(uap, s)); 1269 /* 1270 * We should only let this call succeed once per 1271 * non-blocking connect; however we don't have 1272 * a convenient place to keep that state.. 1273 */ 1274 if (nbio && (state & SS_ISCONNECTED) && 1275 (prflags & PR_CONNREQUIRED)) 1276 return 0; 1277 } 1278 1279 return (error); 1280 } 1281 1282 int 1283 linux_sys_bind(struct lwp *l, const struct linux_sys_bind_args *uap, register_t *retval) 1284 { 1285 /* { 1286 syscallarg(int) s; 1287 syscallarg(const struct osockaddr *) name; 1288 syscallarg(int) namelen; 1289 } */ 1290 int error; 1291 struct mbuf *nam; 1292 1293 error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, name), 1294 SCARG(uap, namelen)); 1295 if (error) 1296 return (error); 1297 1298 return do_sys_bind(l, SCARG(uap, s), nam); 1299 } 1300 1301 int 1302 linux_sys_getsockname(struct lwp *l, const struct linux_sys_getsockname_args *uap, register_t *retval) 1303 { 1304 /* { 1305 syscallarg(int) fdes; 1306 syscallarg(void *) asa; 1307 syscallarg(int *) alen; 1308 } */ 1309 int error; 1310 1311 if ((error = sys_getsockname(l, (const void *)uap, retval)) != 0) 1312 return (error); 1313 1314 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 1315 return (error); 1316 1317 return (0); 1318 } 1319 1320 int 1321 linux_sys_getpeername(struct lwp *l, const struct linux_sys_getpeername_args *uap, register_t *retval) 1322 { 1323 /* { 1324 syscallarg(int) fdes; 1325 syscallarg(void *) asa; 1326 syscallarg(int *) alen; 1327 } */ 1328 int error; 1329 1330 if ((error = sys_getpeername(l, (const void *)uap, retval)) != 0) 1331 return (error); 1332 1333 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 1334 return (error); 1335 1336 return (0); 1337 } 1338 1339 /* 1340 * Copy the osockaddr structure pointed to by osa to mbuf, adjust 1341 * family and convert to sockaddr. 1342 */ 1343 static int 1344 linux_get_sa(struct lwp *l, int s, struct mbuf **mp, 1345 const struct osockaddr *osa, unsigned int salen) 1346 { 1347 int error, bdom; 1348 struct sockaddr *sa; 1349 struct osockaddr *kosa; 1350 struct mbuf *m; 1351 1352 if (salen == 1 || salen > UCHAR_MAX) { 1353 DPRINTF(("bad osa=%p salen=%d\n", osa, salen)); 1354 return EINVAL; 1355 } 1356 1357 /* We'll need the address in an mbuf later, so copy into one here */ 1358 m = m_get(M_WAIT, MT_SONAME); 1359 if (salen > MLEN) 1360 MEXTMALLOC(m, salen, M_WAITOK); 1361 1362 m->m_len = salen; 1363 1364 if (salen == 0) { 1365 *mp = m; 1366 return 0; 1367 } 1368 1369 kosa = mtod(m, void *); 1370 if ((error = copyin(osa, kosa, salen))) { 1371 DPRINTF(("error %d copying osa %p len %d\n", 1372 error, osa, salen)); 1373 goto bad; 1374 } 1375 1376 ktrkuser("linux sockaddr", kosa, salen); 1377 1378 bdom = linux_to_bsd_domain(kosa->sa_family); 1379 if (bdom == -1) { 1380 DPRINTF(("bad linux family=%d\n", kosa->sa_family)); 1381 error = EINVAL; 1382 goto bad; 1383 } 1384 1385 /* 1386 * If the family is unspecified, use address family of the socket. 1387 * This avoid triggering strict family checks in netinet/in_pcb.c et.al. 1388 */ 1389 if (bdom == AF_UNSPEC) { 1390 struct socket *so; 1391 1392 /* fd_getsock() will use the descriptor for us */ 1393 if ((error = fd_getsock(s, &so)) != 0) 1394 goto bad; 1395 1396 bdom = so->so_proto->pr_domain->dom_family; 1397 fd_putfile(s); 1398 1399 DPRINTF(("AF_UNSPEC family adjusted to %d\n", bdom)); 1400 } 1401 1402 #ifdef INET6 1403 /* 1404 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, 1405 * which lacks the scope id compared with RFC2553 one. If we detect 1406 * the situation, reject the address and write a message to system log. 1407 * 1408 * Still accept addresses for which the scope id is not used. 1409 */ 1410 if (bdom == AF_INET6 && salen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) { 1411 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)kosa; 1412 if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) && 1413 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 1414 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) || 1415 IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) || 1416 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 1417 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { 1418 struct proc *p = l->l_proc; 1419 int uid = l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1; 1420 1421 log(LOG_DEBUG, 1422 "pid %d (%s), uid %d: obsolete pre-RFC2553 " 1423 "sockaddr_in6 rejected", 1424 p->p_pid, p->p_comm, uid); 1425 error = EINVAL; 1426 goto bad; 1427 } 1428 salen = sizeof (struct sockaddr_in6); 1429 sin6->sin6_scope_id = 0; 1430 } 1431 #endif 1432 1433 if (bdom == AF_INET) 1434 salen = sizeof(struct sockaddr_in); 1435 1436 sa = (struct sockaddr *) kosa; 1437 sa->sa_family = bdom; 1438 sa->sa_len = salen; 1439 m->m_len = salen; 1440 ktrkuser("new sockaddr", kosa, salen); 1441 1442 #ifdef DEBUG_LINUX 1443 DPRINTF(("family %d, len = %d [ ", sa->sa_family, sa->sa_len)); 1444 for (bdom = 0; bdom < sizeof(sa->sa_data); bdom++) 1445 DPRINTF(("%02x ", (unsigned char) sa->sa_data[bdom])); 1446 DPRINTF(("\n")); 1447 #endif 1448 1449 *mp = m; 1450 return 0; 1451 1452 bad: 1453 m_free(m); 1454 return error; 1455 } 1456 1457 static int 1458 linux_sa_put(struct osockaddr *osa) 1459 { 1460 struct sockaddr sa; 1461 struct osockaddr *kosa; 1462 int error, bdom, len; 1463 1464 /* 1465 * Only read/write the sockaddr family and length part, the rest is 1466 * not changed. 1467 */ 1468 len = sizeof(sa.sa_len) + sizeof(sa.sa_family); 1469 1470 error = copyin(osa, &sa, len); 1471 if (error) 1472 return (error); 1473 1474 bdom = bsd_to_linux_domain(sa.sa_family); 1475 if (bdom == -1) 1476 return (EINVAL); 1477 1478 /* Note: we convert from sockaddr to osockaddr here, too */ 1479 kosa = (struct osockaddr *) &sa; 1480 kosa->sa_family = bdom; 1481 error = copyout(kosa, osa, len); 1482 if (error) 1483 return (error); 1484 1485 return (0); 1486 } 1487 1488 #ifndef __amd64__ 1489 int 1490 linux_sys_recv(struct lwp *l, const struct linux_sys_recv_args *uap, register_t *retval) 1491 { 1492 /* { 1493 syscallarg(int) s; 1494 syscallarg(void *) buf; 1495 syscallarg(int) len; 1496 syscallarg(int) flags; 1497 } */ 1498 struct sys_recvfrom_args bra; 1499 1500 1501 SCARG(&bra, s) = SCARG(uap, s); 1502 SCARG(&bra, buf) = SCARG(uap, buf); 1503 SCARG(&bra, len) = (size_t) SCARG(uap, len); 1504 SCARG(&bra, flags) = SCARG(uap, flags); 1505 SCARG(&bra, from) = NULL; 1506 SCARG(&bra, fromlenaddr) = NULL; 1507 1508 return (sys_recvfrom(l, &bra, retval)); 1509 } 1510 1511 int 1512 linux_sys_send(struct lwp *l, const struct linux_sys_send_args *uap, register_t *retval) 1513 { 1514 /* { 1515 syscallarg(int) s; 1516 syscallarg(void *) buf; 1517 syscallarg(int) len; 1518 syscallarg(int) flags; 1519 } */ 1520 struct sys_sendto_args bsa; 1521 1522 SCARG(&bsa, s) = SCARG(uap, s); 1523 SCARG(&bsa, buf) = SCARG(uap, buf); 1524 SCARG(&bsa, len) = SCARG(uap, len); 1525 SCARG(&bsa, flags) = SCARG(uap, flags); 1526 SCARG(&bsa, to) = NULL; 1527 SCARG(&bsa, tolen) = 0; 1528 1529 return (sys_sendto(l, &bsa, retval)); 1530 } 1531 #endif 1532 1533 int 1534 linux_sys_accept(struct lwp *l, const struct linux_sys_accept_args *uap, register_t *retval) 1535 { 1536 /* { 1537 syscallarg(int) s; 1538 syscallarg(struct osockaddr *) name; 1539 syscallarg(int *) anamelen; 1540 } */ 1541 int error; 1542 struct sys_accept_args baa; 1543 1544 SCARG(&baa, s) = SCARG(uap, s); 1545 SCARG(&baa, name) = (struct sockaddr *) SCARG(uap, name); 1546 SCARG(&baa, anamelen) = (unsigned int *) SCARG(uap, anamelen); 1547 1548 if ((error = sys_accept(l, &baa, retval))) 1549 return (error); 1550 1551 if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name)))) 1552 return (error); 1553 1554 return (0); 1555 } 1556