1 /* $NetBSD: netbsd32_compat_43.c,v 1.57 2019/01/27 02:08:40 pgoyette Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2001 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_43.c,v 1.57 2019/01/27 02:08:40 pgoyette Exp $"); 31 32 #if defined(_KERNEL_OPT) 33 #include "opt_compat_43.h" 34 #endif 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/module.h> 39 #include <sys/fcntl.h> 40 #include <sys/filedesc.h> 41 #include <sys/mbuf.h> 42 #include <sys/mount.h> 43 #include <sys/namei.h> 44 #include <sys/socket.h> 45 #include <sys/proc.h> 46 #include <sys/socket.h> 47 #include <sys/socketvar.h> 48 #include <sys/stat.h> 49 #include <sys/syscallvar.h> 50 #include <sys/syscallargs.h> 51 #include <sys/time.h> 52 #include <sys/ucred.h> 53 #include <sys/vfs_syscalls.h> 54 #include <uvm/uvm_extern.h> 55 #include <sys/sysctl.h> 56 #include <sys/swap.h> 57 58 #include <compat/netbsd32/netbsd32.h> 59 #include <compat/netbsd32/netbsd32_syscall.h> 60 #include <compat/netbsd32/netbsd32_syscallargs.h> 61 62 #include <compat/sys/stat.h> 63 #include <compat/sys/signal.h> 64 #include <compat/sys/signalvar.h> 65 #include <compat/sys/socket.h> 66 67 #define SYS_DEF(foo) struct foo##_args; \ 68 int foo(struct lwp *, const struct foo##_args *, register_t *) 69 70 SYS_DEF(compat_43_netbsd32_sethostid); 71 SYS_DEF(compat_43_netbsd32_killpg); 72 SYS_DEF(compat_43_netbsd32_sigblock); 73 SYS_DEF(compat_43_netbsd32_sigsetmask); 74 #undef SYS_DEF 75 76 static void 77 netbsd32_from_stat(const struct stat *sb, struct netbsd32_stat43 *sp32) 78 { 79 80 sp32->st_dev = sb->st_dev; 81 sp32->st_ino = sb->st_ino; 82 sp32->st_mode = sb->st_mode; 83 sp32->st_nlink = sb->st_nlink; 84 sp32->st_uid = sb->st_uid; 85 sp32->st_gid = sb->st_gid; 86 sp32->st_rdev = sb->st_rdev; 87 sp32->st_size = sb->st_size < (quad_t)1 << 32 ? sb->st_size : -2; 88 sp32->st_atimespec.tv_sec = sb->st_atimespec.tv_sec; 89 sp32->st_atimespec.tv_nsec = sb->st_atimespec.tv_nsec; 90 sp32->st_mtimespec.tv_sec = sb->st_mtimespec.tv_sec; 91 sp32->st_mtimespec.tv_nsec = sb->st_mtimespec.tv_nsec; 92 sp32->st_ctimespec.tv_sec = sb->st_ctimespec.tv_sec; 93 sp32->st_ctimespec.tv_nsec = sb->st_ctimespec.tv_nsec; 94 sp32->st_blksize = sb->st_blksize; 95 sp32->st_blocks = sb->st_blocks; 96 sp32->st_flags = sb->st_flags; 97 sp32->st_gen = sb->st_gen; 98 } 99 100 /* file system syscalls */ 101 int 102 compat_43_netbsd32_ocreat(struct lwp *l, const struct compat_43_netbsd32_ocreat_args *uap, register_t *retval) 103 { 104 /* { 105 syscallarg(const netbsd32_charp) path; 106 syscallarg(mode_t) mode; 107 } */ 108 struct sys_open_args ua; 109 110 NETBSD32TOP_UAP(path, const char); 111 NETBSD32TO64_UAP(mode); 112 SCARG(&ua, flags) = O_WRONLY | O_CREAT | O_TRUNC; 113 114 return (sys_open(l, &ua, retval)); 115 } 116 117 int 118 compat_43_netbsd32_olseek(struct lwp *l, const struct compat_43_netbsd32_olseek_args *uap, register_t *retval) 119 { 120 /* { 121 syscallarg(int) fd; 122 syscallarg(netbsd32_long) offset; 123 syscallarg(int) whence; 124 } */ 125 struct sys_lseek_args ua; 126 127 SCARG(&ua, fd) = SCARG(uap, fd); 128 NETBSD32TOX_UAP(offset, long); 129 NETBSD32TO64_UAP(whence); 130 /* Maybe offsets > 2^32 should generate an error ? */ 131 return sys_lseek(l, &ua, retval); 132 } 133 134 int 135 compat_43_netbsd32_stat43(struct lwp *l, const struct compat_43_netbsd32_stat43_args *uap, register_t *retval) 136 { 137 /* { 138 syscallarg(const netbsd32_charp) path; 139 syscallarg(netbsd32_stat43p_t) ub; 140 } */ 141 struct stat sb; 142 struct netbsd32_stat43 sb32; 143 int error; 144 145 error = do_sys_stat(SCARG_P32(uap, path), FOLLOW, &sb); 146 if (error == 0) { 147 netbsd32_from_stat(&sb, &sb32); 148 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 149 } 150 return error; 151 } 152 153 int 154 compat_43_netbsd32_lstat43(struct lwp *l, const struct compat_43_netbsd32_lstat43_args *uap, register_t *retval) 155 { 156 /* { 157 syscallarg(const netbsd32_charp) path; 158 syscallarg(netbsd32_stat43p_t) ub; 159 } */ 160 struct stat sb; 161 struct netbsd32_stat43 sb32; 162 int error; 163 164 error = do_sys_stat(SCARG_P32(uap, path), NOFOLLOW, &sb); 165 if (error == 0) { 166 netbsd32_from_stat(&sb, &sb32); 167 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 168 } 169 return error; 170 } 171 172 int 173 compat_43_netbsd32_fstat43(struct lwp *l, const struct compat_43_netbsd32_fstat43_args *uap, register_t *retval) 174 { 175 /* { 176 syscallarg(int) fd; 177 syscallarg(netbsd32_stat43p_t) sb; 178 } */ 179 struct stat sb; 180 struct netbsd32_stat43 sb32; 181 int error; 182 183 error = do_sys_fstat(SCARG(uap, fd), &sb); 184 if (error == 0) { 185 netbsd32_from_stat(&sb, &sb32); 186 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32)); 187 } 188 return error; 189 } 190 191 int 192 compat_43_netbsd32_otruncate(struct lwp *l, const struct compat_43_netbsd32_otruncate_args *uap, register_t *retval) 193 { 194 /* { 195 syscallarg(const netbsd32_charp) path; 196 syscallarg(netbsd32_long) length; 197 } */ 198 struct sys_truncate_args ua; 199 200 NETBSD32TOP_UAP(path, const char); 201 NETBSD32TO64_UAP(length); 202 return (sys_truncate(l, &ua, retval)); 203 } 204 205 int 206 compat_43_netbsd32_oftruncate(struct lwp *l, const struct compat_43_netbsd32_oftruncate_args *uap, register_t *retval) 207 { 208 /* { 209 syscallarg(int) fd; 210 syscallarg(netbsd32_long) length; 211 } */ 212 struct sys_ftruncate_args ua; 213 214 NETBSD32TO64_UAP(fd); 215 NETBSD32TO64_UAP(length); 216 return (sys_ftruncate(l, &ua, retval)); 217 } 218 219 int 220 compat_43_netbsd32_ogetdirentries(struct lwp *l, const struct compat_43_netbsd32_ogetdirentries_args *uap, register_t *retval) 221 { 222 /* { 223 syscallarg(int) fd; 224 syscallarg(netbsd32_charp) buf; 225 syscallarg(u_int) count; 226 syscallarg(netbsd32_longp) basep; 227 } */ 228 struct compat_43_sys_getdirentries_args ua; 229 230 NETBSD32TO64_UAP(fd); 231 NETBSD32TOP_UAP(buf, char); 232 NETBSD32TO64_UAP(count); 233 NETBSD32TOP_UAP(basep, long); 234 return (compat_43_sys_getdirentries(l, &ua, retval)); 235 } 236 237 /* kernel syscalls */ 238 int 239 compat_43_netbsd32_ogetkerninfo(struct lwp *l, const struct compat_43_netbsd32_ogetkerninfo_args *uap, register_t *retval) 240 { 241 /* { 242 syscallarg(int) op; 243 syscallarg(netbsd32_charp) where; 244 syscallarg(netbsd32_intp) size; 245 syscallarg(int) arg; 246 } */ 247 struct compat_43_sys_getkerninfo_args ua; 248 249 NETBSD32TO64_UAP(op); 250 NETBSD32TOP_UAP(where, char); 251 NETBSD32TOP_UAP(size, int); 252 NETBSD32TO64_UAP(arg); 253 return (compat_43_sys_getkerninfo(l, &ua, retval)); 254 } 255 256 int 257 compat_43_netbsd32_ogethostname(struct lwp *l, const struct compat_43_netbsd32_ogethostname_args *uap, register_t *retval) 258 { 259 /* { 260 syscallarg(netbsd32_charp) hostname; 261 syscallarg(u_int) len; 262 } */ 263 int name[2]; 264 size_t sz; 265 266 name[0] = CTL_KERN; 267 name[1] = KERN_HOSTNAME; 268 sz = SCARG(uap, len); 269 return (old_sysctl(&name[0], 2, 270 SCARG_P32(uap, hostname), &sz, 0, 0, l)); 271 } 272 273 int 274 compat_43_netbsd32_osethostname(struct lwp *l, const struct compat_43_netbsd32_osethostname_args *uap, register_t *retval) 275 { 276 /* { 277 syscallarg(netbsd32_charp) hostname; 278 syscallarg(u_int) len; 279 } */ 280 int name[2]; 281 282 name[0] = CTL_KERN; 283 name[1] = KERN_HOSTNAME; 284 return old_sysctl(&name[0], 2, 0, 0, (char *)SCARG_P32(uap, 285 hostname), SCARG(uap, len), l); 286 } 287 288 int 289 compat_43_netbsd32_sethostid(struct lwp *l, const struct compat_43_netbsd32_sethostid_args *uap, register_t *retval) 290 { 291 /* { 292 syscallarg(int32_t) hostid; 293 } */ 294 struct compat_43_sys_sethostid_args ua; 295 296 NETBSD32TO64_UAP(hostid); 297 return (compat_43_sys_sethostid(l, &ua, retval)); 298 } 299 300 int 301 compat_43_netbsd32_ogetrlimit(struct lwp *l, const struct compat_43_netbsd32_ogetrlimit_args *uap, register_t *retval) 302 { 303 /* { 304 syscallarg(int) which; 305 syscallarg(netbsd32_orlimitp_t) rlp; 306 } */ 307 struct compat_43_sys_getrlimit_args ua; 308 309 NETBSD32TO64_UAP(which); 310 NETBSD32TOP_UAP(rlp, struct orlimit); 311 return (compat_43_sys_getrlimit(l, &ua, retval)); 312 } 313 314 int 315 compat_43_netbsd32_osetrlimit(struct lwp *l, const struct compat_43_netbsd32_osetrlimit_args *uap, register_t *retval) 316 { 317 /* { 318 syscallarg(int) which; 319 syscallarg(netbsd32_orlimitp_t) rlp; 320 } */ 321 struct compat_43_sys_setrlimit_args ua; 322 323 NETBSD32TO64_UAP(which); 324 NETBSD32TOP_UAP(rlp, struct orlimit); 325 return (compat_43_sys_setrlimit(l, &ua, retval)); 326 } 327 328 int 329 compat_43_netbsd32_killpg(struct lwp *l, const struct compat_43_netbsd32_killpg_args *uap, register_t *retval) 330 { 331 /* { 332 syscallarg(int) pgid; 333 syscallarg(int) signum; 334 } */ 335 struct compat_43_sys_killpg_args ua; 336 337 NETBSD32TO64_UAP(pgid); 338 NETBSD32TO64_UAP(signum); 339 return (compat_43_sys_killpg(l, &ua, retval)); 340 } 341 342 /* virtual memory syscalls */ 343 int 344 compat_43_netbsd32_ommap(struct lwp *l, const struct compat_43_netbsd32_ommap_args *uap, register_t *retval) 345 { 346 /* { 347 syscallarg(netbsd32_voidp) addr; 348 syscallarg(netbsd32_size_t) len; 349 syscallarg(int) prot; 350 syscallarg(int) flags; 351 syscallarg(int) fd; 352 syscallarg(netbsd32_long) pos; 353 } */ 354 struct compat_43_sys_mmap_args ua; 355 356 NETBSD32TOP_UAP(addr, void *); 357 NETBSD32TOX_UAP(len, size_t); 358 NETBSD32TO64_UAP(prot); 359 NETBSD32TO64_UAP(flags); 360 NETBSD32TO64_UAP(fd); 361 NETBSD32TOX_UAP(pos, long); 362 return (compat_43_sys_mmap(l, &ua, retval)); 363 } 364 365 /* network syscalls */ 366 int 367 compat_43_netbsd32_oaccept(struct lwp *l, const struct compat_43_netbsd32_oaccept_args *uap, register_t *retval) 368 { 369 /* { 370 syscallarg(int) s; 371 syscallarg(netbsd32_voidp) name; 372 syscallarg(netbsd32_intp) anamelen; 373 } */ 374 struct compat_43_sys_accept_args ua; 375 376 NETBSD32TOX_UAP(s, int); 377 NETBSD32TOP_UAP(name, void *); 378 NETBSD32TOP_UAP(anamelen, int); 379 return (compat_43_sys_accept(l, &ua, retval)); 380 } 381 382 int 383 compat_43_netbsd32_osend(struct lwp *l, const struct compat_43_netbsd32_osend_args *uap, register_t *retval) 384 { 385 /* { 386 syscallarg(int) s; 387 syscallarg(netbsd32_voidp) buf; 388 syscallarg(int) len; 389 syscallarg(int) flags; 390 } */ 391 struct compat_43_sys_send_args ua; 392 393 NETBSD32TO64_UAP(s); 394 NETBSD32TOP_UAP(buf, void *); 395 NETBSD32TO64_UAP(len); 396 NETBSD32TO64_UAP(flags); 397 return (compat_43_sys_send(l, &ua, retval)); 398 } 399 400 int 401 compat_43_netbsd32_orecv(struct lwp *l, const struct compat_43_netbsd32_orecv_args *uap, register_t *retval) 402 { 403 /* { 404 syscallarg(int) s; 405 syscallarg(netbsd32_voidp) buf; 406 syscallarg(int) len; 407 syscallarg(int) flags; 408 } */ 409 struct compat_43_sys_recv_args ua; 410 411 NETBSD32TO64_UAP(s); 412 NETBSD32TOP_UAP(buf, void *); 413 NETBSD32TO64_UAP(len); 414 NETBSD32TO64_UAP(flags); 415 return (compat_43_sys_recv(l, &ua, retval)); 416 } 417 418 /* 419 * This is a brutal clone of compat_43_sys_recvmsg(). 420 */ 421 int 422 compat_43_netbsd32_orecvmsg(struct lwp *l, const struct compat_43_netbsd32_orecvmsg_args *uap, register_t *retval) 423 { 424 /* { 425 syscallarg(int) s; 426 syscallarg(netbsd32_omsghdrp_t) msg; 427 syscallarg(int) flags; 428 } */ 429 struct netbsd32_omsghdr omsg; 430 struct msghdr msg; 431 struct mbuf *from, *control; 432 struct iovec *iov, aiov[UIO_SMALLIOV]; 433 int error; 434 435 error = copyin(SCARG_P32(uap, msg), &omsg, sizeof (struct omsghdr)); 436 if (error) 437 return (error); 438 439 if (NETBSD32PTR64(omsg.msg_accrights) == NULL) 440 omsg.msg_accrightslen = 0; 441 /* it was this way in 4.4BSD */ 442 if (omsg.msg_accrightslen > MLEN) 443 return EINVAL; 444 445 iov = netbsd32_get_iov(NETBSD32PTR64(omsg.msg_iov), omsg.msg_iovlen, 446 aiov, __arraycount(aiov)); 447 if (iov == NULL) 448 return EFAULT; 449 450 msg.msg_name = NETBSD32PTR64(omsg.msg_name); 451 msg.msg_namelen = omsg.msg_namelen; 452 msg.msg_iovlen = omsg.msg_iovlen; 453 msg.msg_iov = iov; 454 msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS; 455 456 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, 457 NETBSD32PTR64(omsg.msg_accrights) != NULL ? &control : NULL, 458 retval); 459 if (error != 0) 460 goto out; 461 462 /* 463 * If there is any control information and it's SCM_RIGHTS, 464 * pass it back to the program. 465 * XXX: maybe there can be more than one chunk of control data? 466 */ 467 if (NETBSD32PTR64(omsg.msg_accrights) != NULL && control != NULL) { 468 struct cmsghdr *cmsg = mtod(control, void *); 469 470 if (cmsg->cmsg_level == SOL_SOCKET 471 && cmsg->cmsg_type == SCM_RIGHTS 472 && cmsg->cmsg_len < omsg.msg_accrightslen 473 && copyout(CMSG_DATA(cmsg), 474 NETBSD32PTR64(omsg.msg_accrights), 475 cmsg->cmsg_len) == 0) { 476 omsg.msg_accrightslen = cmsg->cmsg_len; 477 free_control_mbuf(l, control, control->m_next); 478 } else { 479 omsg.msg_accrightslen = 0; 480 free_control_mbuf(l, control, control); 481 } 482 } else 483 omsg.msg_accrightslen = 0; 484 485 if (from != NULL) 486 /* convert from sockaddr sa_family to osockaddr one here */ 487 mtod(from, struct osockaddr *)->sa_family = 488 mtod(from, struct sockaddr *)->sa_family; 489 490 error = copyout_sockname(NETBSD32PTR64(omsg.msg_name), 491 &omsg.msg_namelen, 0, from); 492 if (from != NULL) 493 m_free(from); 494 495 if (error != 0) 496 error = copyout(&omsg, SCARG_P32(uap, msg), sizeof(omsg)); 497 out: 498 if (iov != aiov) { 499 kmem_free(iov, omsg.msg_iovlen * sizeof(*iov)); 500 } 501 return error; 502 } 503 504 int 505 compat_43_netbsd32_osendmsg(struct lwp *l, const struct compat_43_netbsd32_osendmsg_args *uap, register_t *retval) 506 { 507 /* { 508 syscallarg(int) s; 509 syscallarg(netbsd32_voidp) msg; 510 syscallarg(int) flags; 511 } */ 512 struct iovec *iov, aiov[UIO_SMALLIOV]; 513 struct netbsd32_omsghdr omsg; 514 struct msghdr msg; 515 struct mbuf *nam; 516 struct osockaddr *osa; 517 struct sockaddr *sa; 518 int error; 519 520 error = copyin(SCARG_P32(uap, msg), &omsg, sizeof (struct omsghdr)); 521 if (error != 0) 522 return (error); 523 524 iov = netbsd32_get_iov(NETBSD32PTR64(omsg.msg_iov), omsg.msg_iovlen, 525 aiov, __arraycount(aiov)); 526 if (iov == NULL) 527 return EFAULT; 528 529 msg.msg_iovlen = omsg.msg_iovlen; 530 msg.msg_iov = iov; 531 msg.msg_flags = MSG_NAMEMBUF; 532 533 error = sockargs(&nam, NETBSD32PTR64(omsg.msg_name), omsg.msg_namelen, 534 UIO_USERSPACE, MT_SONAME); 535 if (error != 0) 536 goto out; 537 538 sa = mtod(nam, void *); 539 osa = mtod(nam, void *); 540 sa->sa_family = osa->sa_family; 541 sa->sa_len = omsg.msg_namelen; 542 543 msg.msg_name = nam; 544 msg.msg_namelen = omsg.msg_namelen; 545 error = compat43_set_accrights(&msg, NETBSD32PTR64(omsg.msg_accrights), 546 omsg.msg_accrightslen); 547 if (error != 0) { 548 m_free(nam); 549 goto out; 550 } 551 552 error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 553 retval); 554 555 out: 556 if (iov != aiov) 557 kmem_free(iov, omsg.msg_iovlen * sizeof(*iov)); 558 return (error); 559 } 560 561 int 562 compat_43_netbsd32_orecvfrom(struct lwp *l, const struct compat_43_netbsd32_orecvfrom_args *uap, register_t *retval) 563 { 564 /* { 565 syscallarg(int) s; 566 syscallarg(netbsd32_voidp) buf; 567 syscallarg(netbsd32_size_t) len; 568 syscallarg(int) flags; 569 syscallarg(netbsd32_voidp) from; 570 syscallarg(netbsd32_intp) fromlenaddr; 571 } */ 572 struct compat_43_sys_recvfrom_args ua; 573 574 NETBSD32TO64_UAP(s); 575 NETBSD32TOP_UAP(buf, void *); 576 NETBSD32TOX_UAP(len, size_t); 577 NETBSD32TO64_UAP(flags); 578 NETBSD32TOP_UAP(from, void *); 579 NETBSD32TOP_UAP(fromlenaddr, int); 580 return (compat_43_sys_recvfrom(l, &ua, retval)); 581 } 582 583 int 584 compat_43_netbsd32_ogetsockname(struct lwp *l, const struct compat_43_netbsd32_ogetsockname_args *uap, register_t *retval) 585 { 586 /* { 587 syscallarg(int) fdec; 588 syscallarg(netbsd32_voidp) asa; 589 syscallarg(netbsd32_intp) alen; 590 } */ 591 struct compat_43_sys_getsockname_args ua; 592 593 NETBSD32TO64_UAP(fdec); 594 NETBSD32TOP_UAP(asa, void *); 595 NETBSD32TOP_UAP(alen, int *); 596 return (compat_43_sys_getsockname(l, &ua, retval)); 597 } 598 599 int 600 compat_43_netbsd32_ogetpeername(struct lwp *l, const struct compat_43_netbsd32_ogetpeername_args *uap, register_t *retval) 601 { 602 /* { 603 syscallarg(int) fdes; 604 syscallarg(netbsd32_voidp) asa; 605 syscallarg(netbsd32_intp) alen; 606 } */ 607 struct compat_43_sys_getpeername_args ua; 608 609 NETBSD32TO64_UAP(fdes); 610 NETBSD32TOP_UAP(asa, void *); 611 NETBSD32TOP_UAP(alen, int *); 612 return (compat_43_sys_getpeername(l, &ua, retval)); 613 } 614 615 /* signal syscalls */ 616 int 617 compat_43_netbsd32_osigvec(struct lwp *l, const struct compat_43_netbsd32_osigvec_args *uap, register_t *retval) 618 { 619 /* { 620 syscallarg(int) signum; 621 syscallarg(netbsd32_sigvecp_t) nsv; 622 syscallarg(netbsd32_sigvecp_t) osv; 623 } */ 624 struct netbsd32_sigvec sv32; 625 struct sigaction nsa, osa; 626 int error; 627 628 if (SCARG(uap, signum) >= 32) 629 return EINVAL; 630 631 if (SCARG_P32(uap, nsv)) { 632 error = copyin(SCARG_P32(uap, nsv), &sv32, sizeof(sv32)); 633 if (error) 634 return error; 635 nsa.sa_handler = NETBSD32PTR64(sv32.sv_handler); 636 nsa.sa_mask.__bits[0] = sv32.sv_mask; 637 nsa.sa_mask.__bits[1] = 0; 638 nsa.sa_mask.__bits[2] = 0; 639 nsa.sa_mask.__bits[3] = 0; 640 nsa.sa_flags = sv32.sv_flags ^ SA_RESTART; 641 error = sigaction1(l, SCARG(uap, signum), &nsa, &osa, NULL, 0); 642 } else 643 error = sigaction1(l, SCARG(uap, signum), NULL, &osa, NULL, 0); 644 if (error) 645 return error; 646 647 if (SCARG_P32(uap, osv)) { 648 NETBSD32PTR32(sv32.sv_handler, osa.sa_handler); 649 sv32.sv_mask = osa.sa_mask.__bits[0]; 650 sv32.sv_flags = osa.sa_flags ^ SA_RESTART; 651 error = copyout(&sv32, SCARG_P32(uap, osv), sizeof(sv32)); 652 } 653 654 return error; 655 } 656 657 int 658 compat_43_netbsd32_sigblock(struct lwp *l, const struct compat_43_netbsd32_sigblock_args *uap, register_t *retval) 659 { 660 /* { 661 syscallarg(int) mask; 662 } */ 663 struct compat_43_sys_sigblock_args ua; 664 665 NETBSD32TO64_UAP(mask); 666 return (compat_43_sys_sigblock(l, &ua, retval)); 667 } 668 669 int 670 compat_43_netbsd32_sigsetmask(struct lwp *l, const struct compat_43_netbsd32_sigsetmask_args *uap, register_t *retval) 671 { 672 /* { 673 syscallarg(int) mask; 674 } */ 675 struct compat_43_sys_sigsetmask_args ua; 676 677 NETBSD32TO64_UAP(mask); 678 return (compat_43_sys_sigsetmask(l, &ua, retval)); 679 } 680 681 int 682 compat_43_netbsd32_osigstack(struct lwp *l, const struct compat_43_netbsd32_osigstack_args *uap, register_t *retval) 683 { 684 /* { 685 syscallarg(netbsd32_sigstackp_t) nss; 686 syscallarg(netbsd32_sigstackp_t) oss; 687 } */ 688 struct netbsd32_sigstack ss32; 689 struct sigaltstack nsa, osa; 690 int error; 691 692 if (SCARG_P32(uap, nss)) { 693 error = copyin(SCARG_P32(uap, nss), &ss32, sizeof(ss32)); 694 if (error) 695 return error; 696 nsa.ss_sp = NETBSD32PTR64(ss32.ss_sp); 697 nsa.ss_size = SIGSTKSZ; /* Use the recommended size */ 698 nsa.ss_flags = ss32.ss_onstack ? SS_ONSTACK : 0; 699 error = sigaltstack1(l, &nsa, &osa); 700 } else 701 error = sigaltstack1(l, NULL, &osa); 702 if (error) 703 return error; 704 705 if (SCARG_P32(uap, oss)) { 706 NETBSD32PTR32(ss32.ss_sp, osa.ss_sp); 707 ss32.ss_onstack = (osa.ss_flags & SS_ONSTACK) != 0; 708 error = copyout(&ss32, SCARG_P32(uap, oss), sizeof(ss32)); 709 } 710 711 return error; 712 } 713 714 static struct syscall_package compat_netbsd32_43_syscalls[] = { 715 { NETBSD32_SYS_compat_43_netbsd32_ocreat, 0, 716 (sy_call_t *)compat_43_netbsd32_ocreat }, 717 { NETBSD32_SYS_compat_43_netbsd32_olseek, 0, 718 (sy_call_t *)compat_43_netbsd32_olseek }, 719 { NETBSD32_SYS_compat_43_netbsd32_stat43, 0, 720 (sy_call_t *)compat_43_netbsd32_stat43 }, 721 { NETBSD32_SYS_compat_43_netbsd32_lstat43, 0, 722 (sy_call_t *)compat_43_netbsd32_lstat43 }, 723 { NETBSD32_SYS_compat_43_netbsd32_fstat43, 0, 724 (sy_call_t *)compat_43_netbsd32_fstat43 }, 725 { NETBSD32_SYS_compat_43_netbsd32_otruncate, 0, 726 (sy_call_t *)compat_43_netbsd32_otruncate }, 727 { NETBSD32_SYS_compat_43_netbsd32_oftruncate, 0, 728 (sy_call_t *)compat_43_netbsd32_oftruncate }, 729 { NETBSD32_SYS_compat_43_netbsd32_ogetdirentries, 0, 730 (sy_call_t *)compat_43_netbsd32_ogetdirentries }, 731 { NETBSD32_SYS_compat_43_netbsd32_ogetkerninfo, 0, 732 (sy_call_t *)compat_43_netbsd32_ogetkerninfo }, 733 { NETBSD32_SYS_compat_43_netbsd32_ogethostname, 0, 734 (sy_call_t *)compat_43_netbsd32_ogethostname }, 735 { NETBSD32_SYS_compat_43_netbsd32_osethostname, 0, 736 (sy_call_t *)compat_43_netbsd32_osethostname }, 737 { NETBSD32_SYS_compat_43_netbsd32_sethostid, 0, 738 (sy_call_t *)compat_43_netbsd32_sethostid }, 739 { NETBSD32_SYS_compat_43_netbsd32_ogetrlimit, 0, 740 (sy_call_t *)compat_43_netbsd32_ogetrlimit }, 741 { NETBSD32_SYS_compat_43_netbsd32_osetrlimit, 0, 742 (sy_call_t *)compat_43_netbsd32_osetrlimit }, 743 { NETBSD32_SYS_compat_43_netbsd32_killpg, 0, 744 (sy_call_t *)compat_43_netbsd32_killpg }, 745 { NETBSD32_SYS_compat_43_netbsd32_ommap, 0, 746 (sy_call_t *)compat_43_netbsd32_ommap }, 747 { NETBSD32_SYS_compat_43_netbsd32_oaccept, 0, 748 (sy_call_t *)compat_43_netbsd32_oaccept }, 749 { NETBSD32_SYS_compat_43_netbsd32_osend, 0, 750 (sy_call_t *)compat_43_netbsd32_osend }, 751 { NETBSD32_SYS_compat_43_netbsd32_orecv, 0, 752 (sy_call_t *)compat_43_netbsd32_orecv }, 753 { NETBSD32_SYS_compat_43_netbsd32_orecvmsg, 0, 754 (sy_call_t *)compat_43_netbsd32_orecvmsg }, 755 { NETBSD32_SYS_compat_43_netbsd32_osendmsg, 0, 756 (sy_call_t *)compat_43_netbsd32_osendmsg }, 757 { NETBSD32_SYS_compat_43_netbsd32_orecvfrom, 0, 758 (sy_call_t *)compat_43_netbsd32_orecvfrom }, 759 { NETBSD32_SYS_compat_43_netbsd32_ogetsockname, 0, 760 (sy_call_t *)compat_43_netbsd32_ogetsockname }, 761 { NETBSD32_SYS_compat_43_netbsd32_ogetpeername, 0, 762 (sy_call_t *)compat_43_netbsd32_ogetpeername }, 763 { NETBSD32_SYS_compat_43_netbsd32_osigvec, 0, 764 (sy_call_t *)compat_43_netbsd32_osigvec }, 765 { NETBSD32_SYS_compat_43_netbsd32_sigblock, 0, 766 (sy_call_t *)compat_43_netbsd32_sigblock }, 767 { NETBSD32_SYS_compat_43_netbsd32_sigsetmask, 0, 768 (sy_call_t *)compat_43_netbsd32_sigsetmask }, 769 { NETBSD32_SYS_compat_43_netbsd32_osigstack, 0, 770 (sy_call_t *)compat_43_netbsd32_osigstack }, 771 { 0, 0, NULL } 772 }; 773 774 MODULE(MODULE_CLASS_EXEC, compat_netbsd32_43, "compat_netbsd32,compat_43"); 775 776 static int 777 compat_netbsd32_43_modcmd(modcmd_t cmd, void *arg) 778 { 779 780 switch (cmd) { 781 case MODULE_CMD_INIT: 782 return syscall_establish(&emul_netbsd32, 783 compat_netbsd32_43_syscalls); 784 785 case MODULE_CMD_FINI: 786 return syscall_disestablish(&emul_netbsd32, 787 compat_netbsd32_43_syscalls); 788 789 default: 790 return ENOTTY; 791 } 792 } 793