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