1 /* $NetBSD: linux_socket.c,v 1.104 2009/06/17 14:18:51 njoly 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.104 2009/06/17 14:18:51 njoly 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_getifconf(struct lwp *, register_t *, void *); 118 int linux_getifhwaddr(struct lwp *, register_t *, u_int, void *); 119 static int linux_get_sa(struct lwp *, int, struct mbuf **, 120 const struct osockaddr *, unsigned int); 121 static int linux_sa_put(struct osockaddr *osa); 122 static int linux_to_bsd_msg_flags(int); 123 static int bsd_to_linux_msg_flags(int); 124 static void linux_to_bsd_msghdr(struct linux_msghdr *, struct msghdr *); 125 static void bsd_to_linux_msghdr(struct msghdr *, struct linux_msghdr *); 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 static void 400 linux_to_bsd_msghdr(struct linux_msghdr *lmsg, struct msghdr *bmsg) 401 { 402 bmsg->msg_name = lmsg->msg_name; 403 bmsg->msg_namelen = lmsg->msg_namelen; 404 bmsg->msg_iov = lmsg->msg_iov; 405 bmsg->msg_iovlen = lmsg->msg_iovlen; 406 bmsg->msg_control = lmsg->msg_control; 407 bmsg->msg_controllen = lmsg->msg_controllen; 408 bmsg->msg_flags = lmsg->msg_flags; 409 } 410 411 static void 412 bsd_to_linux_msghdr(struct msghdr *bmsg, struct linux_msghdr *lmsg) 413 { 414 lmsg->msg_name = bmsg->msg_name; 415 lmsg->msg_namelen = bmsg->msg_namelen; 416 lmsg->msg_iov = bmsg->msg_iov; 417 lmsg->msg_iovlen = bmsg->msg_iovlen; 418 lmsg->msg_control = bmsg->msg_control; 419 lmsg->msg_controllen = bmsg->msg_controllen; 420 lmsg->msg_flags = bmsg->msg_flags; 421 } 422 423 int 424 linux_sys_sendmsg(struct lwp *l, const struct linux_sys_sendmsg_args *uap, register_t *retval) 425 { 426 /* { 427 syscallarg(int) s; 428 syscallarg(struct linux_msghdr *) msg; 429 syscallarg(u_int) flags; 430 } */ 431 struct msghdr msg; 432 struct linux_msghdr lmsg; 433 int error; 434 int bflags; 435 struct mbuf *nam; 436 u_int8_t *control; 437 struct mbuf *ctl_mbuf = NULL; 438 439 error = copyin(SCARG(uap, msg), &lmsg, sizeof(lmsg)); 440 if (error) 441 return error; 442 linux_to_bsd_msghdr(&lmsg, &msg); 443 444 msg.msg_flags = MSG_IOVUSRSPACE; 445 446 /* 447 * Translate message flags. 448 */ 449 bflags = linux_to_bsd_msg_flags(SCARG(uap, flags)); 450 if (bflags < 0) 451 /* Some supported flag */ 452 return EINVAL; 453 454 if (lmsg.msg_name) { 455 /* Read in and convert the sockaddr */ 456 error = linux_get_sa(l, SCARG(uap, s), &nam, msg.msg_name, 457 msg.msg_namelen); 458 if (error) 459 return (error); 460 msg.msg_flags |= MSG_NAMEMBUF; 461 msg.msg_name = nam; 462 } 463 464 /* 465 * Handle cmsg if there is any. 466 */ 467 if (LINUX_CMSG_FIRSTHDR(&lmsg)) { 468 struct linux_cmsghdr l_cmsg, *l_cc; 469 struct cmsghdr *cmsg; 470 ssize_t resid = msg.msg_controllen; 471 size_t clen, cidx = 0, cspace; 472 473 ctl_mbuf = m_get(M_WAIT, MT_CONTROL); 474 clen = MLEN; 475 control = mtod(ctl_mbuf, void *); 476 477 l_cc = LINUX_CMSG_FIRSTHDR(&lmsg); 478 do { 479 error = copyin(l_cc, &l_cmsg, sizeof(l_cmsg)); 480 if (error) 481 goto done; 482 483 /* 484 * Sanity check the control message length. 485 */ 486 if (l_cmsg.cmsg_len > resid 487 || l_cmsg.cmsg_len < sizeof l_cmsg) { 488 error = EINVAL; 489 goto done; 490 } 491 492 /* 493 * Refuse unsupported control messages, and 494 * translate fields as appropriate. 495 */ 496 switch (l_cmsg.cmsg_level) { 497 case LINUX_SOL_SOCKET: 498 /* It only differs on some archs */ 499 if (LINUX_SOL_SOCKET != SOL_SOCKET) 500 l_cmsg.cmsg_level = SOL_SOCKET; 501 502 switch(l_cmsg.cmsg_type) { 503 case LINUX_SCM_RIGHTS: 504 /* Linux SCM_RIGHTS is same as NetBSD */ 505 break; 506 507 default: 508 /* other types not supported */ 509 error = EINVAL; 510 goto done; 511 } 512 break; 513 default: 514 /* pray and leave intact */ 515 break; 516 } 517 518 cspace = CMSG_SPACE(l_cmsg.cmsg_len - sizeof(l_cmsg)); 519 520 /* Check the buffer is big enough */ 521 if (__predict_false(cidx + cspace > clen)) { 522 u_int8_t *nc; 523 524 clen = cidx + cspace; 525 if (clen >= PAGE_SIZE) { 526 error = EINVAL; 527 goto done; 528 } 529 nc = realloc(clen <= MLEN ? NULL : control, 530 clen, M_TEMP, M_WAITOK); 531 if (!nc) { 532 error = ENOMEM; 533 goto done; 534 } 535 if (cidx <= MLEN) 536 /* Old buffer was in mbuf... */ 537 memcpy(nc, control, cidx); 538 control = nc; 539 } 540 541 /* Copy header */ 542 cmsg = (void *)&control[cidx]; 543 cmsg->cmsg_len = l_cmsg.cmsg_len + LINUX_CMSG_ALIGN_DELTA; 544 cmsg->cmsg_level = l_cmsg.cmsg_level; 545 cmsg->cmsg_type = l_cmsg.cmsg_type; 546 547 /* Zero are between header and data */ 548 memset(cmsg + 1, 0, 549 CMSG_ALIGN(sizeof(cmsg)) - sizeof(cmsg)); 550 551 /* Copyin the data */ 552 error = copyin(LINUX_CMSG_DATA(l_cc), 553 CMSG_DATA(control), 554 l_cmsg.cmsg_len - sizeof(l_cmsg)); 555 if (error) 556 goto done; 557 558 resid -= LINUX_CMSG_ALIGN(l_cmsg.cmsg_len); 559 cidx += cspace; 560 } while ((l_cc = LINUX_CMSG_NXTHDR(&msg, l_cc)) && resid > 0); 561 562 /* If we allocated a buffer, attach to mbuf */ 563 if (cidx > MLEN) { 564 MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL); 565 ctl_mbuf->m_flags |= M_EXT_RW; 566 } 567 control = NULL; 568 ctl_mbuf->m_len = cidx; 569 570 msg.msg_control = ctl_mbuf; 571 msg.msg_flags |= MSG_CONTROLMBUF; 572 573 ktrkuser("msgcontrol", mtod(ctl_mbuf, void *), 574 msg.msg_controllen); 575 } 576 577 error = do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval); 578 /* Freed internally */ 579 ctl_mbuf = NULL; 580 581 done: 582 if (ctl_mbuf != NULL) { 583 if (control != NULL && control != mtod(ctl_mbuf, void *)) 584 free(control, M_MBUF); 585 m_free(ctl_mbuf); 586 } 587 return (error); 588 } 589 590 int 591 linux_sys_recvfrom(struct lwp *l, const struct linux_sys_recvfrom_args *uap, register_t *retval) 592 { 593 /* { 594 syscallarg(int) s; 595 syscallarg(void *) buf; 596 syscallarg(int) len; 597 syscallarg(int) flags; 598 syscallarg(struct osockaddr *) from; 599 syscallarg(int *) fromlenaddr; 600 } */ 601 int error; 602 struct sys_recvfrom_args bra; 603 604 SCARG(&bra, s) = SCARG(uap, s); 605 SCARG(&bra, buf) = SCARG(uap, buf); 606 SCARG(&bra, len) = SCARG(uap, len); 607 SCARG(&bra, flags) = SCARG(uap, flags); 608 SCARG(&bra, from) = (struct sockaddr *) SCARG(uap, from); 609 SCARG(&bra, fromlenaddr) = (socklen_t *)SCARG(uap, fromlenaddr); 610 611 if ((error = sys_recvfrom(l, &bra, retval))) 612 return (error); 613 614 if (SCARG(uap, from) && (error = linux_sa_put(SCARG(uap, from)))) 615 return (error); 616 617 return (0); 618 } 619 620 static int 621 linux_copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control) 622 { 623 int dlen, error = 0; 624 struct cmsghdr *cmsg; 625 struct linux_cmsghdr linux_cmsg; 626 struct mbuf *m; 627 char *q, *q_end; 628 629 if (mp->msg_controllen <= 0 || control == 0) { 630 mp->msg_controllen = 0; 631 free_control_mbuf(l, control, control); 632 return 0; 633 } 634 635 ktrkuser("msgcontrol", mtod(control, void *), mp->msg_controllen); 636 637 q = (char *)mp->msg_control; 638 q_end = q + mp->msg_controllen; 639 640 for (m = control; m != NULL; ) { 641 cmsg = mtod(m, struct cmsghdr *); 642 643 /* 644 * Fixup cmsg. We handle two things: 645 * 0. different sizeof cmsg_len. 646 * 1. different values for level/type on some archs 647 * 2. different alignment of CMSG_DATA on some archs 648 */ 649 linux_cmsg.cmsg_len = cmsg->cmsg_len - LINUX_CMSG_ALIGN_DELTA; 650 linux_cmsg.cmsg_level = cmsg->cmsg_level; 651 linux_cmsg.cmsg_type = cmsg->cmsg_type; 652 653 dlen = q_end - q; 654 if (linux_cmsg.cmsg_len > dlen) { 655 /* Not enough room for the parameter */ 656 dlen -= sizeof linux_cmsg; 657 if (dlen <= 0) 658 /* Discard if header wont fit */ 659 break; 660 mp->msg_flags |= MSG_CTRUNC; 661 if (linux_cmsg.cmsg_level == SOL_SOCKET 662 && linux_cmsg.cmsg_type == SCM_RIGHTS) 663 /* Do not truncate me ... */ 664 break; 665 } else 666 dlen = linux_cmsg.cmsg_len - sizeof linux_cmsg; 667 668 switch (linux_cmsg.cmsg_level) { 669 case SOL_SOCKET: 670 linux_cmsg.cmsg_level = LINUX_SOL_SOCKET; 671 switch (linux_cmsg.cmsg_type) { 672 case SCM_RIGHTS: 673 /* Linux SCM_RIGHTS is same as NetBSD */ 674 break; 675 676 default: 677 /* other types not supported */ 678 error = EINVAL; 679 goto done; 680 } 681 /* machine dependant ! */ 682 break; 683 default: 684 /* pray and leave intact */ 685 break; 686 } 687 688 /* There can be padding between the header and data... */ 689 error = copyout(&linux_cmsg, q, sizeof linux_cmsg); 690 if (error != 0) { 691 error = copyout(CCMSG_DATA(cmsg), q + sizeof linux_cmsg, 692 dlen); 693 } 694 if (error != 0) { 695 /* We must free all the SCM_RIGHTS */ 696 m = control; 697 break; 698 } 699 m = m->m_next; 700 if (m == NULL || q + LINUX_CMSG_SPACE(dlen) > q_end) { 701 q += LINUX_CMSG_LEN(dlen); 702 break; 703 } 704 q += LINUX_CMSG_SPACE(dlen); 705 } 706 707 done: 708 free_control_mbuf(l, control, m); 709 710 mp->msg_controllen = q - (char *)mp->msg_control; 711 return error; 712 } 713 714 int 715 linux_sys_recvmsg(struct lwp *l, const struct linux_sys_recvmsg_args *uap, register_t *retval) 716 { 717 /* { 718 syscallarg(int) s; 719 syscallarg(struct linux_msghdr *) msg; 720 syscallarg(u_int) flags; 721 } */ 722 struct msghdr msg; 723 struct linux_msghdr lmsg; 724 int error; 725 struct mbuf *from, *control; 726 727 error = copyin(SCARG(uap, msg), &lmsg, sizeof(lmsg)); 728 if (error) 729 return (error); 730 linux_to_bsd_msghdr(&lmsg, &msg); 731 732 msg.msg_flags = linux_to_bsd_msg_flags(SCARG(uap, flags)); 733 if (msg.msg_flags < 0) { 734 /* Some unsupported flag */ 735 return (EINVAL); 736 } 737 msg.msg_flags |= MSG_IOVUSRSPACE; 738 739 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, 740 msg.msg_control != NULL ? &control : NULL, retval); 741 if (error != 0) 742 return error; 743 744 if (msg.msg_control != NULL) 745 error = linux_copyout_msg_control(l, &msg, control); 746 747 if (error == 0 && from != 0) { 748 mtod(from, struct osockaddr *)->sa_family = 749 bsd_to_linux_domain(mtod(from, struct sockaddr *)->sa_family); 750 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0, 751 from); 752 } else 753 msg.msg_namelen = 0; 754 755 if (from != NULL) 756 m_free(from); 757 758 if (error == 0) { 759 msg.msg_flags = bsd_to_linux_msg_flags(msg.msg_flags); 760 if (msg.msg_flags < 0) 761 /* Some flag unsupported by Linux */ 762 error = EINVAL; 763 else { 764 ktrkuser("msghdr", &msg, sizeof(msg)); 765 bsd_to_linux_msghdr(&msg, &lmsg); 766 error = copyout(&lmsg, SCARG(uap, msg), sizeof(lmsg)); 767 } 768 } 769 770 return (error); 771 } 772 773 /* 774 * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET 775 * is different, the rest matches IPPROTO_* on both systems. 776 */ 777 int 778 linux_to_bsd_sopt_level(int llevel) 779 { 780 781 switch (llevel) { 782 case LINUX_SOL_SOCKET: 783 return SOL_SOCKET; 784 case LINUX_SOL_IP: 785 return IPPROTO_IP; 786 case LINUX_SOL_TCP: 787 return IPPROTO_TCP; 788 case LINUX_SOL_UDP: 789 return IPPROTO_UDP; 790 default: 791 return -1; 792 } 793 } 794 795 /* 796 * Convert Linux socket level socket option numbers to NetBSD values. 797 */ 798 int 799 linux_to_bsd_so_sockopt(int lopt) 800 { 801 802 switch (lopt) { 803 case LINUX_SO_DEBUG: 804 return SO_DEBUG; 805 case LINUX_SO_REUSEADDR: 806 /* 807 * Linux does not implement SO_REUSEPORT, but allows reuse of a 808 * host:port pair through SO_REUSEADDR even if the address is not a 809 * multicast-address. Effectively, this means that we should use 810 * SO_REUSEPORT to allow Linux applications to not exit with 811 * EADDRINUSE 812 */ 813 return SO_REUSEPORT; 814 case LINUX_SO_TYPE: 815 return SO_TYPE; 816 case LINUX_SO_ERROR: 817 return SO_ERROR; 818 case LINUX_SO_DONTROUTE: 819 return SO_DONTROUTE; 820 case LINUX_SO_BROADCAST: 821 return SO_BROADCAST; 822 case LINUX_SO_SNDBUF: 823 return SO_SNDBUF; 824 case LINUX_SO_RCVBUF: 825 return SO_RCVBUF; 826 case LINUX_SO_KEEPALIVE: 827 return SO_KEEPALIVE; 828 case LINUX_SO_OOBINLINE: 829 return SO_OOBINLINE; 830 case LINUX_SO_LINGER: 831 return SO_LINGER; 832 case LINUX_SO_PRIORITY: 833 case LINUX_SO_NO_CHECK: 834 default: 835 return -1; 836 } 837 } 838 839 /* 840 * Convert Linux IP level socket option number to NetBSD values. 841 */ 842 int 843 linux_to_bsd_ip_sockopt(int lopt) 844 { 845 846 switch (lopt) { 847 case LINUX_IP_TOS: 848 return IP_TOS; 849 case LINUX_IP_TTL: 850 return IP_TTL; 851 case LINUX_IP_MULTICAST_TTL: 852 return IP_MULTICAST_TTL; 853 case LINUX_IP_MULTICAST_LOOP: 854 return IP_MULTICAST_LOOP; 855 case LINUX_IP_MULTICAST_IF: 856 return IP_MULTICAST_IF; 857 case LINUX_IP_ADD_MEMBERSHIP: 858 return IP_ADD_MEMBERSHIP; 859 case LINUX_IP_DROP_MEMBERSHIP: 860 return IP_DROP_MEMBERSHIP; 861 default: 862 return -1; 863 } 864 } 865 866 /* 867 * Convert Linux TCP level socket option number to NetBSD values. 868 */ 869 int 870 linux_to_bsd_tcp_sockopt(int lopt) 871 { 872 873 switch (lopt) { 874 case LINUX_TCP_NODELAY: 875 return TCP_NODELAY; 876 case LINUX_TCP_MAXSEG: 877 return TCP_MAXSEG; 878 default: 879 return -1; 880 } 881 } 882 883 /* 884 * Convert Linux UDP level socket option number to NetBSD values. 885 */ 886 int 887 linux_to_bsd_udp_sockopt(int lopt) 888 { 889 890 switch (lopt) { 891 default: 892 return -1; 893 } 894 } 895 896 /* 897 * Another reasonably straightforward function: setsockopt(2). 898 * The level and option numbers are converted; the values passed 899 * are not (yet) converted, the ones currently implemented don't 900 * need conversion, as they are the same on both systems. 901 */ 902 int 903 linux_sys_setsockopt(struct lwp *l, const struct linux_sys_setsockopt_args *uap, register_t *retval) 904 { 905 /* { 906 syscallarg(int) s; 907 syscallarg(int) level; 908 syscallarg(int) optname; 909 syscallarg(void *) optval; 910 syscallarg(int) optlen; 911 } */ 912 struct sys_setsockopt_args bsa; 913 int name; 914 915 SCARG(&bsa, s) = SCARG(uap, s); 916 SCARG(&bsa, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 917 SCARG(&bsa, val) = SCARG(uap, optval); 918 SCARG(&bsa, valsize) = SCARG(uap, optlen); 919 920 /* 921 * Linux supports only SOL_SOCKET for AF_LOCAL domain sockets 922 * and returns EOPNOTSUPP for other levels 923 */ 924 if (SCARG(&bsa, level) != SOL_SOCKET) { 925 struct socket *so; 926 int error, family; 927 928 /* fd_getsock() will use the descriptor for us */ 929 if ((error = fd_getsock(SCARG(&bsa, s), &so)) != 0) 930 return error; 931 family = so->so_proto->pr_domain->dom_family; 932 fd_putfile(SCARG(&bsa, s)); 933 934 if (family == AF_LOCAL) 935 return EOPNOTSUPP; 936 } 937 938 switch (SCARG(&bsa, level)) { 939 case SOL_SOCKET: 940 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 941 break; 942 case IPPROTO_IP: 943 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 944 break; 945 case IPPROTO_TCP: 946 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 947 break; 948 case IPPROTO_UDP: 949 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 950 break; 951 default: 952 return EINVAL; 953 } 954 955 if (name == -1) 956 return EINVAL; 957 SCARG(&bsa, name) = name; 958 959 return sys_setsockopt(l, &bsa, retval); 960 } 961 962 /* 963 * getsockopt(2) is very much the same as setsockopt(2) (see above) 964 */ 965 int 966 linux_sys_getsockopt(struct lwp *l, const struct linux_sys_getsockopt_args *uap, register_t *retval) 967 { 968 /* { 969 syscallarg(int) s; 970 syscallarg(int) level; 971 syscallarg(int) optname; 972 syscallarg(void *) optval; 973 syscallarg(int *) optlen; 974 } */ 975 struct sys_getsockopt_args bga; 976 int name; 977 978 SCARG(&bga, s) = SCARG(uap, s); 979 SCARG(&bga, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 980 SCARG(&bga, val) = SCARG(uap, optval); 981 SCARG(&bga, avalsize) = (socklen_t *)SCARG(uap, optlen); 982 983 switch (SCARG(&bga, level)) { 984 case SOL_SOCKET: 985 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 986 break; 987 case IPPROTO_IP: 988 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 989 break; 990 case IPPROTO_TCP: 991 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 992 break; 993 case IPPROTO_UDP: 994 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 995 break; 996 default: 997 return EINVAL; 998 } 999 1000 if (name == -1) 1001 return EINVAL; 1002 SCARG(&bga, name) = name; 1003 1004 return sys_getsockopt(l, &bga, retval); 1005 } 1006 1007 int 1008 linux_getifconf(struct lwp *l, register_t *retval, void *data) 1009 { 1010 struct linux_ifreq ifr, *ifrp; 1011 struct ifconf *ifc = data; 1012 struct ifnet *ifp; 1013 struct ifaddr *ifa; 1014 struct sockaddr *sa; 1015 struct osockaddr *osa; 1016 int space, error = 0; 1017 const int sz = (int)sizeof(ifr); 1018 1019 ifrp = (struct linux_ifreq *)ifc->ifc_req; 1020 if (ifrp == NULL) 1021 space = 0; 1022 else 1023 space = ifc->ifc_len; 1024 1025 IFNET_FOREACH(ifp) { 1026 (void)strncpy(ifr.ifr_name, ifp->if_xname, 1027 sizeof(ifr.ifr_name)); 1028 if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0') 1029 return ENAMETOOLONG; 1030 if (IFADDR_EMPTY(ifp)) 1031 continue; 1032 IFADDR_FOREACH(ifa, ifp) { 1033 sa = ifa->ifa_addr; 1034 if (sa->sa_family != AF_INET || 1035 sa->sa_len > sizeof(*osa)) 1036 continue; 1037 memcpy(&ifr.ifr_addr, sa, sa->sa_len); 1038 osa = (struct osockaddr *)&ifr.ifr_addr; 1039 osa->sa_family = sa->sa_family; 1040 if (space >= sz) { 1041 error = copyout(&ifr, ifrp, sz); 1042 if (error != 0) 1043 return error; 1044 ifrp++; 1045 } 1046 space -= sz; 1047 } 1048 } 1049 1050 if (ifrp != NULL) 1051 ifc->ifc_len -= space; 1052 else 1053 ifc->ifc_len = -space; 1054 1055 return 0; 1056 } 1057 1058 int 1059 linux_getifhwaddr(struct lwp *l, register_t *retval, u_int fd, 1060 void *data) 1061 { 1062 /* Not the full structure, just enough to map what we do here */ 1063 struct linux_ifreq lreq; 1064 file_t *fp; 1065 struct ifaddr *ifa; 1066 struct ifnet *ifp; 1067 struct sockaddr_dl *sadl; 1068 int error, found; 1069 int index, ifnum; 1070 1071 /* 1072 * We can't emulate this ioctl by calling sys_ioctl() to run 1073 * SIOCGIFCONF, because the user buffer is not of the right 1074 * type to take those results. We can't use kernel buffers to 1075 * receive the results, as the implementation of sys_ioctl() 1076 * and ifconf() [which implements SIOCGIFCONF] use 1077 * copyin()/copyout() which will fail on kernel addresses. 1078 * 1079 * So, we must duplicate code from sys_ioctl() and ifconf(). Ugh. 1080 */ 1081 1082 if ((fp = fd_getfile(fd)) == NULL) 1083 return (EBADF); 1084 1085 KERNEL_LOCK(1, NULL); 1086 1087 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 1088 error = EBADF; 1089 goto out; 1090 } 1091 1092 error = copyin(data, &lreq, sizeof(lreq)); 1093 if (error) 1094 goto out; 1095 lreq.ifr_name[LINUX_IFNAMSIZ-1] = '\0'; /* just in case */ 1096 1097 /* 1098 * Try real interface name first, then fake "ethX" 1099 */ 1100 found = 0; 1101 IFNET_FOREACH(ifp) { 1102 if (found) 1103 break; 1104 if (strcmp(lreq.ifr_name, ifp->if_xname)) 1105 /* not this interface */ 1106 continue; 1107 found=1; 1108 if (IFADDR_EMPTY(ifp)) { 1109 error = ENODEV; 1110 goto out; 1111 } 1112 IFADDR_FOREACH(ifa, ifp) { 1113 sadl = satosdl(ifa->ifa_addr); 1114 /* only return ethernet addresses */ 1115 /* XXX what about FDDI, etc. ? */ 1116 if (sadl->sdl_family != AF_LINK || 1117 sadl->sdl_type != IFT_ETHER) 1118 continue; 1119 memcpy(&lreq.ifr_hwaddr.sa_data, CLLADDR(sadl), 1120 MIN(sadl->sdl_alen, 1121 sizeof(lreq.ifr_hwaddr.sa_data))); 1122 lreq.ifr_hwaddr.sa_family = 1123 sadl->sdl_family; 1124 error = copyout(&lreq, data, sizeof(lreq)); 1125 goto out; 1126 } 1127 } 1128 1129 if (strncmp(lreq.ifr_name, "eth", 3) == 0) { 1130 for (ifnum = 0, index = 3; 1131 lreq.ifr_name[index] != '\0' && index < LINUX_IFNAMSIZ; 1132 index++) { 1133 ifnum *= 10; 1134 ifnum += lreq.ifr_name[index] - '0'; 1135 } 1136 1137 error = EINVAL; /* in case we don't find one */ 1138 found = 0; 1139 IFNET_FOREACH(ifp) { 1140 if (found) 1141 break; 1142 memcpy(lreq.ifr_name, ifp->if_xname, 1143 MIN(LINUX_IFNAMSIZ, IFNAMSIZ)); 1144 IFADDR_FOREACH(ifa, ifp) { 1145 sadl = satosdl(ifa->ifa_addr); 1146 /* only return ethernet addresses */ 1147 /* XXX what about FDDI, etc. ? */ 1148 if (sadl->sdl_family != AF_LINK || 1149 sadl->sdl_type != IFT_ETHER) 1150 continue; 1151 if (ifnum--) 1152 /* not the reqested iface */ 1153 continue; 1154 memcpy(&lreq.ifr_hwaddr.sa_data, 1155 CLLADDR(sadl), 1156 MIN(sadl->sdl_alen, 1157 sizeof(lreq.ifr_hwaddr.sa_data))); 1158 lreq.ifr_hwaddr.sa_family = 1159 sadl->sdl_family; 1160 error = copyout(&lreq, data, sizeof(lreq)); 1161 found = 1; 1162 break; 1163 } 1164 } 1165 } else { 1166 /* unknown interface, not even an "eth*" name */ 1167 error = ENODEV; 1168 } 1169 1170 out: 1171 KERNEL_UNLOCK_ONE(NULL); 1172 fd_putfile(fd); 1173 return error; 1174 } 1175 1176 int 1177 linux_ioctl_socket(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval) 1178 { 1179 /* { 1180 syscallarg(int) fd; 1181 syscallarg(u_long) com; 1182 syscallarg(void *) data; 1183 } */ 1184 u_long com; 1185 int error = 0, isdev = 0, dosys = 1; 1186 struct sys_ioctl_args ia; 1187 file_t *fp; 1188 struct vnode *vp; 1189 int (*ioctlf)(file_t *, u_long, void *); 1190 struct ioctl_pt pt; 1191 1192 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) 1193 return (EBADF); 1194 1195 if (fp->f_type == DTYPE_VNODE) { 1196 vp = (struct vnode *)fp->f_data; 1197 isdev = vp->v_type == VCHR; 1198 } 1199 1200 /* 1201 * Don't try to interpret socket ioctl calls that are done 1202 * on a device filedescriptor, just pass them through, to 1203 * emulate Linux behaviour. Use PTIOCLINUX so that the 1204 * device will only handle these if it's prepared to do 1205 * so, to avoid unexpected things from happening. 1206 */ 1207 if (isdev) { 1208 dosys = 0; 1209 ioctlf = fp->f_ops->fo_ioctl; 1210 pt.com = SCARG(uap, com); 1211 pt.data = SCARG(uap, data); 1212 error = ioctlf(fp, PTIOCLINUX, &pt); 1213 /* 1214 * XXX hack: if the function returns EJUSTRETURN, 1215 * it has stuffed a sysctl return value in pt.data. 1216 */ 1217 if (error == EJUSTRETURN) { 1218 retval[0] = (register_t)pt.data; 1219 error = 0; 1220 } 1221 goto out; 1222 } 1223 1224 com = SCARG(uap, com); 1225 retval[0] = 0; 1226 1227 switch (com) { 1228 case LINUX_SIOCGIFCONF: 1229 error = linux_getifconf(l, retval, SCARG(uap, data)); 1230 dosys = 0; 1231 break; 1232 case LINUX_SIOCGIFFLAGS: 1233 SCARG(&ia, com) = OSIOCGIFFLAGS; 1234 break; 1235 case LINUX_SIOCSIFFLAGS: 1236 SCARG(&ia, com) = OSIOCSIFFLAGS; 1237 break; 1238 case LINUX_SIOCGIFADDR: 1239 SCARG(&ia, com) = OOSIOCGIFADDR; 1240 break; 1241 case LINUX_SIOCGIFDSTADDR: 1242 SCARG(&ia, com) = OOSIOCGIFDSTADDR; 1243 break; 1244 case LINUX_SIOCGIFBRDADDR: 1245 SCARG(&ia, com) = OOSIOCGIFBRDADDR; 1246 break; 1247 case LINUX_SIOCGIFNETMASK: 1248 SCARG(&ia, com) = OOSIOCGIFNETMASK; 1249 break; 1250 case LINUX_SIOCADDMULTI: 1251 SCARG(&ia, com) = OSIOCADDMULTI; 1252 break; 1253 case LINUX_SIOCDELMULTI: 1254 SCARG(&ia, com) = OSIOCDELMULTI; 1255 break; 1256 case LINUX_SIOCGIFHWADDR: 1257 error = linux_getifhwaddr(l, retval, SCARG(uap, fd), 1258 SCARG(uap, data)); 1259 dosys = 0; 1260 break; 1261 default: 1262 error = EINVAL; 1263 } 1264 1265 out: 1266 fd_putfile(SCARG(uap, fd)); 1267 1268 if (error ==0 && dosys) { 1269 SCARG(&ia, fd) = SCARG(uap, fd); 1270 SCARG(&ia, data) = SCARG(uap, data); 1271 error = sys_ioctl(curlwp, &ia, retval); 1272 } 1273 1274 return error; 1275 } 1276 1277 int 1278 linux_sys_connect(struct lwp *l, const struct linux_sys_connect_args *uap, register_t *retval) 1279 { 1280 /* { 1281 syscallarg(int) s; 1282 syscallarg(const struct sockaddr *) name; 1283 syscallarg(int) namelen; 1284 } */ 1285 int error; 1286 struct mbuf *nam; 1287 1288 error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, name), 1289 SCARG(uap, namelen)); 1290 if (error) 1291 return (error); 1292 1293 error = do_sys_connect(l, SCARG(uap, s), nam); 1294 1295 if (error == EISCONN) { 1296 struct socket *so; 1297 int state, prflags, nbio; 1298 1299 /* fd_getsock() will use the descriptor for us */ 1300 if (fd_getsock(SCARG(uap, s), &so) != 0) 1301 return EISCONN; 1302 1303 solock(so); 1304 state = so->so_state; 1305 nbio = so->so_nbio; 1306 prflags = so->so_proto->pr_flags; 1307 sounlock(so); 1308 fd_putfile(SCARG(uap, s)); 1309 /* 1310 * We should only let this call succeed once per 1311 * non-blocking connect; however we don't have 1312 * a convenient place to keep that state.. 1313 */ 1314 if (nbio && (state & SS_ISCONNECTED) && 1315 (prflags & PR_CONNREQUIRED)) 1316 return 0; 1317 } 1318 1319 return (error); 1320 } 1321 1322 int 1323 linux_sys_bind(struct lwp *l, const struct linux_sys_bind_args *uap, register_t *retval) 1324 { 1325 /* { 1326 syscallarg(int) s; 1327 syscallarg(const struct osockaddr *) name; 1328 syscallarg(int) namelen; 1329 } */ 1330 int error; 1331 struct mbuf *nam; 1332 1333 error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, name), 1334 SCARG(uap, namelen)); 1335 if (error) 1336 return (error); 1337 1338 return do_sys_bind(l, SCARG(uap, s), nam); 1339 } 1340 1341 int 1342 linux_sys_getsockname(struct lwp *l, const struct linux_sys_getsockname_args *uap, register_t *retval) 1343 { 1344 /* { 1345 syscallarg(int) fdes; 1346 syscallarg(void *) asa; 1347 syscallarg(int *) alen; 1348 } */ 1349 int error; 1350 1351 if ((error = sys_getsockname(l, (const void *)uap, retval)) != 0) 1352 return (error); 1353 1354 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 1355 return (error); 1356 1357 return (0); 1358 } 1359 1360 int 1361 linux_sys_getpeername(struct lwp *l, const struct linux_sys_getpeername_args *uap, register_t *retval) 1362 { 1363 /* { 1364 syscallarg(int) fdes; 1365 syscallarg(void *) asa; 1366 syscallarg(int *) alen; 1367 } */ 1368 int error; 1369 1370 if ((error = sys_getpeername(l, (const void *)uap, retval)) != 0) 1371 return (error); 1372 1373 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 1374 return (error); 1375 1376 return (0); 1377 } 1378 1379 /* 1380 * Copy the osockaddr structure pointed to by osa to mbuf, adjust 1381 * family and convert to sockaddr. 1382 */ 1383 static int 1384 linux_get_sa(struct lwp *l, int s, struct mbuf **mp, 1385 const struct osockaddr *osa, unsigned int salen) 1386 { 1387 int error, bdom; 1388 struct sockaddr *sa; 1389 struct osockaddr *kosa; 1390 struct mbuf *m; 1391 1392 if (salen == 1 || salen > UCHAR_MAX) { 1393 DPRINTF(("bad osa=%p salen=%d\n", osa, salen)); 1394 return EINVAL; 1395 } 1396 1397 /* We'll need the address in an mbuf later, so copy into one here */ 1398 m = m_get(M_WAIT, MT_SONAME); 1399 if (salen > MLEN) 1400 MEXTMALLOC(m, salen, M_WAITOK); 1401 1402 m->m_len = salen; 1403 1404 if (salen == 0) { 1405 *mp = m; 1406 return 0; 1407 } 1408 1409 kosa = mtod(m, void *); 1410 if ((error = copyin(osa, kosa, salen))) { 1411 DPRINTF(("error %d copying osa %p len %d\n", 1412 error, osa, salen)); 1413 goto bad; 1414 } 1415 1416 ktrkuser("linux sockaddr", kosa, salen); 1417 1418 bdom = linux_to_bsd_domain(kosa->sa_family); 1419 if (bdom == -1) { 1420 DPRINTF(("bad linux family=%d\n", kosa->sa_family)); 1421 error = EINVAL; 1422 goto bad; 1423 } 1424 1425 /* 1426 * If the family is unspecified, use address family of the socket. 1427 * This avoid triggering strict family checks in netinet/in_pcb.c et.al. 1428 */ 1429 if (bdom == AF_UNSPEC) { 1430 struct socket *so; 1431 1432 /* fd_getsock() will use the descriptor for us */ 1433 if ((error = fd_getsock(s, &so)) != 0) 1434 goto bad; 1435 1436 bdom = so->so_proto->pr_domain->dom_family; 1437 fd_putfile(s); 1438 1439 DPRINTF(("AF_UNSPEC family adjusted to %d\n", bdom)); 1440 } 1441 1442 /* 1443 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, 1444 * which lacks the scope id compared with RFC2553 one. If we detect 1445 * the situation, reject the address and write a message to system log. 1446 * 1447 * Still accept addresses for which the scope id is not used. 1448 */ 1449 if (bdom == AF_INET6 && salen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) { 1450 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)kosa; 1451 if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) && 1452 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 1453 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) || 1454 IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) || 1455 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 1456 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { 1457 struct proc *p = l->l_proc; 1458 int uid = l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1; 1459 1460 log(LOG_DEBUG, 1461 "pid %d (%s), uid %d: obsolete pre-RFC2553 " 1462 "sockaddr_in6 rejected", 1463 p->p_pid, p->p_comm, uid); 1464 error = EINVAL; 1465 goto bad; 1466 } 1467 salen = sizeof (struct sockaddr_in6); 1468 sin6->sin6_scope_id = 0; 1469 } 1470 1471 if (bdom == AF_INET) 1472 salen = sizeof(struct sockaddr_in); 1473 1474 sa = (struct sockaddr *) kosa; 1475 sa->sa_family = bdom; 1476 sa->sa_len = salen; 1477 m->m_len = salen; 1478 ktrkuser("new sockaddr", kosa, salen); 1479 1480 #ifdef DEBUG_LINUX 1481 DPRINTF(("family %d, len = %d [ ", sa->sa_family, sa->sa_len)); 1482 for (bdom = 0; bdom < sizeof(sa->sa_data); bdom++) 1483 DPRINTF(("%02x ", (unsigned char) sa->sa_data[bdom])); 1484 DPRINTF(("\n")); 1485 #endif 1486 1487 *mp = m; 1488 return 0; 1489 1490 bad: 1491 m_free(m); 1492 return error; 1493 } 1494 1495 static int 1496 linux_sa_put(struct osockaddr *osa) 1497 { 1498 struct sockaddr sa; 1499 struct osockaddr *kosa; 1500 int error, bdom, len; 1501 1502 /* 1503 * Only read/write the sockaddr family and length part, the rest is 1504 * not changed. 1505 */ 1506 len = sizeof(sa.sa_len) + sizeof(sa.sa_family); 1507 1508 error = copyin(osa, &sa, len); 1509 if (error) 1510 return (error); 1511 1512 bdom = bsd_to_linux_domain(sa.sa_family); 1513 if (bdom == -1) 1514 return (EINVAL); 1515 1516 /* Note: we convert from sockaddr to osockaddr here, too */ 1517 kosa = (struct osockaddr *) &sa; 1518 kosa->sa_family = bdom; 1519 error = copyout(kosa, osa, len); 1520 if (error) 1521 return (error); 1522 1523 return (0); 1524 } 1525 1526 #ifndef __amd64__ 1527 int 1528 linux_sys_recv(struct lwp *l, const struct linux_sys_recv_args *uap, register_t *retval) 1529 { 1530 /* { 1531 syscallarg(int) s; 1532 syscallarg(void *) buf; 1533 syscallarg(int) len; 1534 syscallarg(int) flags; 1535 } */ 1536 struct sys_recvfrom_args bra; 1537 1538 1539 SCARG(&bra, s) = SCARG(uap, s); 1540 SCARG(&bra, buf) = SCARG(uap, buf); 1541 SCARG(&bra, len) = (size_t) SCARG(uap, len); 1542 SCARG(&bra, flags) = SCARG(uap, flags); 1543 SCARG(&bra, from) = NULL; 1544 SCARG(&bra, fromlenaddr) = NULL; 1545 1546 return (sys_recvfrom(l, &bra, retval)); 1547 } 1548 1549 int 1550 linux_sys_send(struct lwp *l, const struct linux_sys_send_args *uap, register_t *retval) 1551 { 1552 /* { 1553 syscallarg(int) s; 1554 syscallarg(void *) buf; 1555 syscallarg(int) len; 1556 syscallarg(int) flags; 1557 } */ 1558 struct sys_sendto_args bsa; 1559 1560 SCARG(&bsa, s) = SCARG(uap, s); 1561 SCARG(&bsa, buf) = SCARG(uap, buf); 1562 SCARG(&bsa, len) = SCARG(uap, len); 1563 SCARG(&bsa, flags) = SCARG(uap, flags); 1564 SCARG(&bsa, to) = NULL; 1565 SCARG(&bsa, tolen) = 0; 1566 1567 return (sys_sendto(l, &bsa, retval)); 1568 } 1569 #endif 1570 1571 int 1572 linux_sys_accept(struct lwp *l, const struct linux_sys_accept_args *uap, register_t *retval) 1573 { 1574 /* { 1575 syscallarg(int) s; 1576 syscallarg(struct osockaddr *) name; 1577 syscallarg(int *) anamelen; 1578 } */ 1579 int error; 1580 struct sys_accept_args baa; 1581 1582 SCARG(&baa, s) = SCARG(uap, s); 1583 SCARG(&baa, name) = (struct sockaddr *) SCARG(uap, name); 1584 SCARG(&baa, anamelen) = (unsigned int *) SCARG(uap, anamelen); 1585 1586 if ((error = sys_accept(l, &baa, retval))) 1587 return (error); 1588 1589 if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name)))) 1590 return (error); 1591 1592 return (0); 1593 } 1594