1 /* $NetBSD: netbsd32_compat_50.c,v 1.51 2021/02/18 12:54:03 simonb Exp $ */ 2 3 /*- 4 * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas. 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 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_50.c,v 1.51 2021/02/18 12:54:03 simonb Exp $"); 33 34 #if defined(_KERNEL_OPT) 35 #include "opt_compat_netbsd.h" 36 #include "opt_compat_netbsd32.h" 37 #include "opt_ntp.h" 38 #include "opt_quota.h" 39 #endif 40 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/module.h> 45 #include <sys/mount.h> 46 #include <sys/socket.h> 47 #include <sys/socketvar.h> 48 #include <sys/stat.h> 49 #include <sys/time.h> 50 #include <sys/ktrace.h> 51 #include <sys/eventvar.h> 52 #include <sys/resourcevar.h> 53 #include <sys/vnode.h> 54 #include <sys/file.h> 55 #include <sys/filedesc.h> 56 #include <sys/poll.h> 57 #include <sys/namei.h> 58 #include <sys/statvfs.h> 59 #include <sys/syscallargs.h> 60 #include <sys/syscallvar.h> 61 #include <sys/proc.h> 62 #include <sys/dirent.h> 63 #include <sys/kauth.h> 64 #include <sys/vfs_syscalls.h> 65 #include <sys/compat_stub.h> 66 #include <sys/module_hook.h> 67 68 #include <compat/netbsd32/netbsd32.h> 69 #include <compat/netbsd32/netbsd32_syscall.h> 70 #include <compat/netbsd32/netbsd32_syscallargs.h> 71 #include <compat/netbsd32/netbsd32_conv.h> 72 #include <compat/sys/mount.h> 73 #include <compat/sys/time.h> 74 #include <compat/sys/rnd.h> 75 76 #if defined(COMPAT_50) 77 78 /* 79 * Common routine to set access and modification times given a vnode. 80 */ 81 static int 82 get_utimes32(const netbsd32_timeval50p_t *tptr, struct timeval *tv, 83 struct timeval **tvp) 84 { 85 int error; 86 struct netbsd32_timeval50 tv32[2]; 87 88 if (tptr == NULL) { 89 *tvp = NULL; 90 return 0; 91 } 92 93 error = copyin(tptr, tv32, sizeof(tv32)); 94 if (error) 95 return error; 96 netbsd32_to_timeval50(&tv32[0], &tv[0]); 97 netbsd32_to_timeval50(&tv32[1], &tv[1]); 98 99 *tvp = tv; 100 return 0; 101 } 102 103 int 104 compat_50_netbsd32_mknod(struct lwp *l, 105 const struct compat_50_netbsd32_mknod_args *uap, register_t *retval) 106 { 107 /* { 108 syscallarg(netbsd32_charp) path; 109 syscallarg(mode_t) mode; 110 syscallarg(uint32_t) dev; 111 } */ 112 return do_sys_mknod(l, SCARG_P32(uap, path), SCARG(uap, mode), 113 SCARG(uap, dev), UIO_USERSPACE); 114 } 115 116 int 117 compat_50_netbsd32_select(struct lwp *l, 118 const struct compat_50_netbsd32_select_args *uap, register_t *retval) 119 { 120 /* { 121 syscallarg(int) nd; 122 syscallarg(netbsd32_fd_setp_t) in; 123 syscallarg(netbsd32_fd_setp_t) ou; 124 syscallarg(netbsd32_fd_setp_t) ex; 125 syscallarg(netbsd32_timeval50p_t) tv; 126 } */ 127 int error; 128 struct netbsd32_timeval50 tv32; 129 struct timespec ats, *ts = NULL; 130 131 if (SCARG_P32(uap, tv)) { 132 error = copyin(SCARG_P32(uap, tv), &tv32, sizeof(tv32)); 133 if (error != 0) 134 return error; 135 136 if (tv32.tv_usec < 0 || tv32.tv_usec >= 1000000) 137 return EINVAL; 138 139 ats.tv_sec = tv32.tv_sec; 140 ats.tv_nsec = tv32.tv_usec * 1000; 141 ts = &ats; 142 } 143 144 return selcommon(retval, SCARG(uap, nd), SCARG_P32(uap, in), 145 SCARG_P32(uap, ou), SCARG_P32(uap, ex), ts, NULL); 146 } 147 148 int 149 compat_50_netbsd32_gettimeofday(struct lwp *l, 150 const struct compat_50_netbsd32_gettimeofday_args *uap, register_t *retval) 151 { 152 /* { 153 syscallarg(netbsd32_timeval50p_t) tp; 154 syscallarg(netbsd32_timezonep_t) tzp; 155 } */ 156 struct timeval atv; 157 struct netbsd32_timeval50 tv32; 158 int error = 0; 159 struct netbsd32_timezone tzfake; 160 161 if (SCARG_P32(uap, tp)) { 162 microtime(&atv); 163 netbsd32_from_timeval50(&atv, &tv32); 164 error = copyout(&tv32, SCARG_P32(uap, tp), sizeof(tv32)); 165 if (error) 166 return error; 167 } 168 if (SCARG_P32(uap, tzp)) { 169 /* 170 * NetBSD has no kernel notion of time zone, so we just 171 * fake up a timezone struct and return it if demanded. 172 */ 173 tzfake.tz_minuteswest = 0; 174 tzfake.tz_dsttime = 0; 175 error = copyout(&tzfake, SCARG_P32(uap, tzp), sizeof(tzfake)); 176 } 177 return error; 178 } 179 180 int 181 compat_50_netbsd32_settimeofday(struct lwp *l, 182 const struct compat_50_netbsd32_settimeofday_args *uap, register_t *retval) 183 { 184 /* { 185 syscallarg(const netbsd32_timeval50p_t) tv; 186 syscallarg(const netbsd32_timezonep_t) tzp; 187 } */ 188 struct netbsd32_timeval50 atv32; 189 struct timeval atv; 190 struct timespec ats; 191 int error; 192 struct proc *p = l->l_proc; 193 194 /* Verify all parameters before changing time. */ 195 196 /* 197 * NetBSD has no kernel notion of time zone, and only an 198 * obsolete program would try to set it, so we log a warning. 199 */ 200 if (SCARG_P32(uap, tzp)) 201 printf("pid %d attempted to set the " 202 "(obsolete) kernel time zone\n", p->p_pid); 203 204 if (SCARG_P32(uap, tv) == 0) 205 return 0; 206 207 if ((error = copyin(SCARG_P32(uap, tv), &atv32, sizeof(atv32))) != 0) 208 return error; 209 210 netbsd32_to_timeval50(&atv32, &atv); 211 212 if (atv.tv_usec < 0 || atv.tv_usec >= 1000000) 213 return EINVAL; 214 215 TIMEVAL_TO_TIMESPEC(&atv, &ats); 216 return settime(p, &ats); 217 } 218 219 int 220 compat_50_netbsd32_utimes(struct lwp *l, 221 const struct compat_50_netbsd32_utimes_args *uap, register_t *retval) 222 { 223 /* { 224 syscallarg(const netbsd32_charp) path; 225 syscallarg(const netbsd32_timeval50p_t) tptr; 226 } */ 227 int error; 228 struct timeval tv[2], *tvp; 229 230 error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp); 231 if (error != 0) 232 return error; 233 234 return do_sys_utimes(l, NULL, SCARG_P32(uap, path), FOLLOW, 235 tvp, UIO_SYSSPACE); 236 } 237 238 int 239 compat_50_netbsd32_adjtime(struct lwp *l, 240 const struct compat_50_netbsd32_adjtime_args *uap, register_t *retval) 241 { 242 /* { 243 syscallarg(const netbsd32_timeval50p_t) delta; 244 syscallarg(netbsd32_timeval50p_t) olddelta; 245 } */ 246 struct netbsd32_timeval50 atv; 247 int error; 248 249 extern int time_adjusted; /* in kern_ntptime.c */ 250 extern int64_t time_adjtime; /* in kern_ntptime.c */ 251 252 if ((error = kauth_authorize_system(l->l_cred, 253 KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL, 254 NULL)) != 0) 255 return error; 256 257 if (SCARG_P32(uap, olddelta)) { 258 mutex_spin_enter(&timecounter_lock); 259 atv.tv_sec = time_adjtime / 1000000; 260 atv.tv_usec = time_adjtime % 1000000; 261 if (atv.tv_usec < 0) { 262 atv.tv_usec += 1000000; 263 atv.tv_sec--; 264 } 265 mutex_spin_exit(&timecounter_lock); 266 267 error = copyout(&atv, SCARG_P32(uap, olddelta), sizeof(atv)); 268 if (error) 269 return error; 270 } 271 272 if (SCARG_P32(uap, delta)) { 273 error = copyin(SCARG_P32(uap, delta), &atv, sizeof(atv)); 274 if (error) 275 return error; 276 277 mutex_spin_enter(&timecounter_lock); 278 time_adjtime = (int64_t)atv.tv_sec * 1000000 + atv.tv_usec; 279 if (time_adjtime) 280 /* We need to save the system time during shutdown */ 281 time_adjusted |= 1; 282 mutex_spin_exit(&timecounter_lock); 283 } 284 285 return 0; 286 } 287 288 int 289 compat_50_netbsd32_futimes(struct lwp *l, 290 const struct compat_50_netbsd32_futimes_args *uap, register_t *retval) 291 { 292 /* { 293 syscallarg(int) fd; 294 syscallarg(const netbsd32_timeval50p_t) tptr; 295 } */ 296 int error; 297 file_t *fp; 298 struct timeval tv[2], *tvp; 299 300 error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp); 301 if (error != 0) 302 return error; 303 304 /* fd_getvnode() will use the descriptor for us */ 305 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 306 return error; 307 308 error = do_sys_utimes(l, fp->f_vnode, NULL, 0, tvp, UIO_SYSSPACE); 309 310 fd_putfile(SCARG(uap, fd)); 311 return error; 312 } 313 314 int 315 compat_50_netbsd32_clock_gettime(struct lwp *l, 316 const struct compat_50_netbsd32_clock_gettime_args *uap, register_t *retval) 317 { 318 /* { 319 syscallarg(netbsd32_clockid_t) clock_id; 320 syscallarg(netbsd32_timespec50p_t) tp; 321 } */ 322 int error; 323 struct timespec ats; 324 struct netbsd32_timespec50 ts32; 325 326 error = clock_gettime1(SCARG(uap, clock_id), &ats); 327 if (error != 0) 328 return error; 329 330 netbsd32_from_timespec50(&ats, &ts32); 331 return copyout(&ts32, SCARG_P32(uap, tp), sizeof(ts32)); 332 } 333 334 int 335 compat_50_netbsd32_clock_settime(struct lwp *l, 336 const struct compat_50_netbsd32_clock_settime_args *uap, register_t *retval) 337 { 338 /* { 339 syscallarg(netbsd32_clockid_t) clock_id; 340 syscallarg(const netbsd32_timespec50p_t) tp; 341 } */ 342 struct netbsd32_timespec50 ts32; 343 struct timespec ats; 344 int error; 345 346 if ((error = copyin(SCARG_P32(uap, tp), &ts32, sizeof(ts32))) != 0) 347 return error; 348 349 netbsd32_to_timespec50(&ts32, &ats); 350 return clock_settime1(l->l_proc, SCARG(uap, clock_id), &ats, true); 351 } 352 353 int 354 compat_50_netbsd32_clock_getres(struct lwp *l, 355 const struct compat_50_netbsd32_clock_getres_args *uap, register_t *retval) 356 { 357 /* { 358 syscallarg(netbsd32_clockid_t) clock_id; 359 syscallarg(netbsd32_timespec50p_t) tp; 360 } */ 361 struct netbsd32_timespec50 ts32; 362 struct timespec ts; 363 int error; 364 365 error = clock_getres1(SCARG(uap, clock_id), &ts); 366 if (error != 0) 367 return error; 368 369 if (SCARG_P32(uap, tp)) { 370 netbsd32_from_timespec50(&ts, &ts32); 371 error = copyout(&ts32, SCARG_P32(uap, tp), sizeof(ts32)); 372 } 373 374 return error; 375 } 376 377 int 378 compat_50_netbsd32_timer_settime(struct lwp *l, 379 const struct compat_50_netbsd32_timer_settime_args *uap, register_t *retval) 380 { 381 /* { 382 syscallarg(netbsd32_timer_t) timerid; 383 syscallarg(int) flags; 384 syscallarg(const netbsd32_itimerspec50p_t) value; 385 syscallarg(netbsd32_itimerspec50p_t) ovalue; 386 } */ 387 int error; 388 struct itimerspec value, ovalue, *ovp = NULL; 389 struct netbsd32_itimerspec50 its32; 390 391 if ((error = copyin(SCARG_P32(uap, value), &its32, sizeof(its32))) != 0) 392 return error; 393 netbsd32_to_timespec50(&its32.it_interval, &value.it_interval); 394 netbsd32_to_timespec50(&its32.it_value, &value.it_value); 395 396 if (SCARG_P32(uap, ovalue)) 397 ovp = &ovalue; 398 399 if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp, 400 SCARG(uap, flags), l->l_proc)) != 0) 401 return error; 402 403 if (ovp) { 404 netbsd32_from_timespec50(&ovp->it_interval, &its32.it_interval); 405 netbsd32_from_timespec50(&ovp->it_value, &its32.it_value); 406 return copyout(&its32, SCARG_P32(uap, ovalue), sizeof(its32)); 407 } 408 return 0; 409 } 410 411 int 412 compat_50_netbsd32_timer_gettime(struct lwp *l, const struct compat_50_netbsd32_timer_gettime_args *uap, register_t *retval) 413 { 414 /* { 415 syscallarg(netbsd32_timer_t) timerid; 416 syscallarg(netbsd32_itimerspec50p_t) value; 417 } */ 418 int error; 419 struct itimerspec its; 420 struct netbsd32_itimerspec50 its32; 421 422 if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, 423 &its)) != 0) 424 return error; 425 426 netbsd32_from_timespec50(&its.it_interval, &its32.it_interval); 427 netbsd32_from_timespec50(&its.it_value, &its32.it_value); 428 429 return copyout(&its32, SCARG_P32(uap, value), sizeof(its32)); 430 } 431 432 int 433 compat_50_netbsd32_nanosleep(struct lwp *l, 434 const struct compat_50_netbsd32_nanosleep_args *uap, register_t *retval) 435 { 436 /* { 437 syscallarg(const netbsd32_timespec50p_t) rqtp; 438 syscallarg(netbsd32_timespecp_t) rmtp; 439 } */ 440 struct netbsd32_timespec50 ts32; 441 struct timespec rqt, rmt; 442 int error, error1; 443 444 error = copyin(SCARG_P32(uap, rqtp), &ts32, sizeof(ts32)); 445 if (error) 446 return error; 447 netbsd32_to_timespec50(&ts32, &rqt); 448 449 error = nanosleep1(l, CLOCK_MONOTONIC, 0, &rqt, 450 SCARG_P32(uap, rmtp) ? &rmt : NULL); 451 if (SCARG_P32(uap, rmtp) == NULL || (error != 0 && error != EINTR)) 452 return error; 453 454 netbsd32_from_timespec50(&rmt, &ts32); 455 error1 = copyout(&ts32, SCARG_P32(uap,rmtp), sizeof(ts32)); 456 return error1 ? error1 : error; 457 } 458 459 static int 460 compat_50_netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size) 461 { 462 const siginfo_t *info = src; 463 siginfo32_t info32; 464 465 netbsd32_si_to_si32(&info32, info); 466 467 return copyout(&info32, dst, sizeof(info32)); 468 } 469 470 static int 471 compat_50_netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size) 472 { 473 struct timespec *ts = dst; 474 struct netbsd32_timespec50 ts32; 475 int error; 476 477 error = copyin(src, &ts32, sizeof(ts32)); 478 if (error) 479 return error; 480 481 netbsd32_to_timespec50(&ts32, ts); 482 return 0; 483 } 484 485 static int 486 compat_50_netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size) 487 { 488 const struct timespec *ts = src; 489 struct netbsd32_timespec50 ts32; 490 491 netbsd32_from_timespec50(ts, &ts32); 492 493 return copyout(&ts32, dst, sizeof(ts32)); 494 } 495 496 int 497 compat_50_netbsd32___sigtimedwait(struct lwp *l, 498 const struct compat_50_netbsd32___sigtimedwait_args *uap, register_t *retval) 499 { 500 /* { 501 syscallarg(netbsd32_sigsetp_t) set; 502 syscallarg(netbsd32_siginfop_t) info; 503 syscallarg(netbsd32_timespec50p_t) timeout; 504 } */ 505 struct sys_____sigtimedwait50_args ua; 506 int res; 507 508 NETBSD32TOP_UAP(set, const sigset_t); 509 NETBSD32TOP_UAP(info, siginfo_t); 510 NETBSD32TOP_UAP(timeout, struct timespec); 511 512 res = sigtimedwait1(l, &ua, retval, 513 copyin, 514 compat_50_netbsd32_sigtimedwait_put_info, 515 compat_50_netbsd32_sigtimedwait_fetch_timeout, 516 compat_50_netbsd32_sigtimedwait_put_timeout); 517 if (!res) 518 *retval = 0; /* NetBSD<=5 was not POSIX compliant */ 519 return res; 520 } 521 522 int 523 compat_50_netbsd32_lutimes(struct lwp *l, 524 const struct compat_50_netbsd32_lutimes_args *uap, register_t *retval) 525 { 526 /* { 527 syscallarg(const netbsd32_charp) path; 528 syscallarg(const netbsd32_timeval50p_t) tptr; 529 } */ 530 int error; 531 struct timeval tv[2], *tvp; 532 533 error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp); 534 if (error != 0) 535 return error; 536 537 return do_sys_utimes(l, NULL, SCARG_P32(uap, path), NOFOLLOW, 538 tvp, UIO_SYSSPACE); 539 } 540 541 int 542 compat_50_netbsd32__lwp_park(struct lwp *l, 543 const struct compat_50_netbsd32__lwp_park_args *uap, register_t *retval) 544 { 545 /* { 546 syscallarg(const netbsd32_timespec50p) ts; 547 syscallarg(lwpid_t) unpark; 548 syscallarg(netbsd32_voidp) hint; 549 syscallarg(netbsd32_voidp) unparkhint; 550 } */ 551 struct timespec ts, *tsp; 552 struct netbsd32_timespec50 ts32; 553 int error; 554 555 if (SCARG_P32(uap, ts) == NULL) 556 tsp = NULL; 557 else { 558 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof ts32); 559 if (error != 0) 560 return error; 561 netbsd32_to_timespec50(&ts32, &ts); 562 tsp = &ts; 563 } 564 565 if (SCARG(uap, unpark) != 0) { 566 error = lwp_unpark(&SCARG(uap, unpark), 1); 567 if (error != 0) 568 return error; 569 } 570 571 return lwp_park(CLOCK_REALTIME, TIMER_ABSTIME, tsp); 572 } 573 574 static int 575 netbsd32_kevent_fetch_timeout(const void *src, void *dest, size_t length) 576 { 577 struct netbsd32_timespec50 ts32; 578 int error; 579 580 KASSERT(length == sizeof(struct timespec50)); 581 582 error = copyin(src, &ts32, sizeof(ts32)); 583 if (error) 584 return error; 585 netbsd32_to_timespec50(&ts32, (struct timespec *)dest); 586 return 0; 587 } 588 589 static int 590 netbsd32_kevent_fetch_changes(void *ctx, const struct kevent *changelist, 591 struct kevent *changes, size_t index, int n) 592 { 593 const struct netbsd32_kevent *src = 594 (const struct netbsd32_kevent *)changelist; 595 struct netbsd32_kevent *kev32, *changes32 = ctx; 596 int error, i; 597 598 error = copyin(src + index, changes32, n * sizeof(*changes32)); 599 if (error) 600 return error; 601 for (i = 0, kev32 = changes32; i < n; i++, kev32++, changes++) 602 netbsd32_to_kevent(kev32, changes); 603 return 0; 604 } 605 606 static int 607 netbsd32_kevent_put_events(void *ctx, struct kevent *events, 608 struct kevent *eventlist, size_t index, int n) 609 { 610 struct netbsd32_kevent *kev32, *events32 = ctx; 611 int i; 612 613 for (i = 0, kev32 = events32; i < n; i++, kev32++, events++) 614 netbsd32_from_kevent(events, kev32); 615 kev32 = (struct netbsd32_kevent *)eventlist; 616 return copyout(events32, kev32, n * sizeof(*events32)); 617 } 618 619 int 620 compat_50_netbsd32_kevent(struct lwp *l, 621 const struct compat_50_netbsd32_kevent_args *uap, register_t *retval) 622 { 623 /* { 624 syscallarg(int) fd; 625 syscallarg(netbsd32_keventp_t) changelist; 626 syscallarg(netbsd32_size_t) nchanges; 627 syscallarg(netbsd32_keventp_t) eventlist; 628 syscallarg(netbsd32_size_t) nevents; 629 syscallarg(netbsd32_timespec50p_t) timeout; 630 } */ 631 int error; 632 size_t maxalloc, nchanges, nevents; 633 struct kevent_ops netbsd32_kevent_ops = { 634 .keo_fetch_timeout = netbsd32_kevent_fetch_timeout, 635 .keo_fetch_changes = netbsd32_kevent_fetch_changes, 636 .keo_put_events = netbsd32_kevent_put_events, 637 }; 638 639 nchanges = SCARG(uap, nchanges); 640 nevents = SCARG(uap, nevents); 641 maxalloc = KQ_NEVENTS; 642 643 netbsd32_kevent_ops.keo_private = 644 kmem_alloc(maxalloc * sizeof(struct netbsd32_kevent), KM_SLEEP); 645 646 error = kevent1(retval, SCARG(uap, fd), 647 NETBSD32PTR64(SCARG(uap, changelist)), nchanges, 648 NETBSD32PTR64(SCARG(uap, eventlist)), nevents, 649 NETBSD32PTR64(SCARG(uap, timeout)), &netbsd32_kevent_ops); 650 651 kmem_free(netbsd32_kevent_ops.keo_private, 652 maxalloc * sizeof(struct netbsd32_kevent)); 653 return error; 654 } 655 656 int 657 compat_50_netbsd32_pselect(struct lwp *l, 658 const struct compat_50_netbsd32_pselect_args *uap, register_t *retval) 659 { 660 /* { 661 syscallarg(int) nd; 662 syscallarg(netbsd32_fd_setp_t) in; 663 syscallarg(netbsd32_fd_setp_t) ou; 664 syscallarg(netbsd32_fd_setp_t) ex; 665 syscallarg(const netbsd32_timespec50p_t) ts; 666 syscallarg(const netbsd32_sigsetp_t) mask; 667 } */ 668 int error; 669 struct netbsd32_timespec50 ts32; 670 struct timespec ats, *ts = NULL; 671 sigset_t amask, *mask = NULL; 672 673 if (SCARG_P32(uap, ts)) { 674 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32)); 675 if (error != 0) 676 return error; 677 netbsd32_to_timespec50(&ts32, &ats); 678 ts = &ats; 679 } 680 if (SCARG_P32(uap, mask)) { 681 error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask)); 682 if (error != 0) 683 return error; 684 mask = &amask; 685 } 686 687 return selcommon(retval, SCARG(uap, nd), SCARG_P32(uap, in), 688 SCARG_P32(uap, ou), SCARG_P32(uap, ex), ts, mask); 689 } 690 691 int 692 compat_50_netbsd32_pollts(struct lwp *l, 693 const struct compat_50_netbsd32_pollts_args *uap, register_t *retval) 694 { 695 /* { 696 syscallarg(struct netbsd32_pollfdp_t) fds; 697 syscallarg(u_int) nfds; 698 syscallarg(const netbsd32_timespec50p_t) ts; 699 syscallarg(const netbsd32_sigsetp_t) mask; 700 } */ 701 int error; 702 struct netbsd32_timespec50 ts32; 703 struct timespec ats, *ts = NULL; 704 sigset_t amask, *mask = NULL; 705 706 if (SCARG_P32(uap, ts)) { 707 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32)); 708 if (error != 0) 709 return error; 710 netbsd32_to_timespec50(&ts32, &ats); 711 ts = &ats; 712 } 713 if (NETBSD32PTR64( SCARG(uap, mask))) { 714 error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask)); 715 if (error != 0) 716 return error; 717 mask = &amask; 718 } 719 720 return pollcommon(retval, SCARG_P32(uap, fds), 721 SCARG(uap, nfds), ts, mask); 722 } 723 724 int 725 compat_50_netbsd32___stat30(struct lwp *l, 726 const struct compat_50_netbsd32___stat30_args *uap, register_t *retval) 727 { 728 /* { 729 syscallarg(const netbsd32_charp) path; 730 syscallarg(netbsd32_stat50p_t) ub; 731 } */ 732 struct netbsd32_stat50 sb32; 733 struct stat sb; 734 int error; 735 const char *path; 736 737 path = SCARG_P32(uap, path); 738 739 error = do_sys_stat(path, FOLLOW, &sb); 740 if (error) 741 return error; 742 netbsd32_from___stat50(&sb, &sb32); 743 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 744 return error; 745 } 746 747 int 748 compat_50_netbsd32___fstat30(struct lwp *l, 749 const struct compat_50_netbsd32___fstat30_args *uap, register_t *retval) 750 { 751 /* { 752 syscallarg(int) fd; 753 syscallarg(netbsd32_stat50p_t) sb; 754 } */ 755 struct netbsd32_stat50 sb32; 756 struct stat ub; 757 int error; 758 759 error = do_sys_fstat(SCARG(uap, fd), &ub); 760 if (error == 0) { 761 netbsd32_from___stat50(&ub, &sb32); 762 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32)); 763 } 764 return error; 765 } 766 767 int 768 compat_50_netbsd32___lstat30(struct lwp *l, 769 const struct compat_50_netbsd32___lstat30_args *uap, register_t *retval) 770 { 771 /* { 772 syscallarg(const netbsd32_charp) path; 773 syscallarg(netbsd32_stat50p_t) ub; 774 } */ 775 struct netbsd32_stat50 sb32; 776 struct stat sb; 777 int error; 778 const char *path; 779 780 path = SCARG_P32(uap, path); 781 782 error = do_sys_stat(path, NOFOLLOW, &sb); 783 if (error) 784 return error; 785 netbsd32_from___stat50(&sb, &sb32); 786 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 787 return error; 788 } 789 790 int 791 compat_50_netbsd32___fhstat40(struct lwp *l, const struct compat_50_netbsd32___fhstat40_args *uap, register_t *retval) 792 { 793 /* { 794 syscallarg(const netbsd32_pointer_t) fhp; 795 syscallarg(netbsd32_size_t) fh_size; 796 syscallarg(netbsd32_stat50p_t) sb; 797 } */ 798 struct stat sb; 799 struct netbsd32_stat50 sb32; 800 int error; 801 802 error = do_fhstat(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), &sb); 803 if (error == 0) { 804 netbsd32_from___stat50(&sb, &sb32); 805 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32)); 806 } 807 return error; 808 } 809 810 int 811 compat_50_netbsd32_wait4(struct lwp *l, const struct compat_50_netbsd32_wait4_args *uap, register_t *retval) 812 { 813 /* { 814 syscallarg(int) pid; 815 syscallarg(netbsd32_intp) status; 816 syscallarg(int) options; 817 syscallarg(netbsd32_rusage50p_t) rusage; 818 } */ 819 int error, status, pid = SCARG(uap, pid); 820 struct netbsd32_rusage50 ru32; 821 struct rusage ru; 822 823 error = do_sys_wait(&pid, &status, SCARG(uap, options), 824 SCARG_P32(uap, rusage) != NULL ? &ru : NULL); 825 826 retval[0] = pid; 827 if (pid == 0) 828 return error; 829 830 if (SCARG_P32(uap, rusage)) { 831 netbsd32_from_rusage50(&ru, &ru32); 832 error = copyout(&ru32, SCARG_P32(uap, rusage), sizeof(ru32)); 833 } 834 835 if (error == 0 && SCARG_P32(uap, status)) 836 error = copyout(&status, SCARG_P32(uap, status), sizeof(status)); 837 838 return error; 839 } 840 841 842 int 843 compat_50_netbsd32_getrusage(struct lwp *l, const struct compat_50_netbsd32_getrusage_args *uap, register_t *retval) 844 { 845 /* { 846 syscallarg(int) who; 847 syscallarg(netbsd32_rusage50p_t) rusage; 848 } */ 849 int error; 850 struct proc *p = l->l_proc; 851 struct rusage ru; 852 struct netbsd32_rusage50 ru32; 853 854 error = getrusage1(p, SCARG(uap, who), &ru); 855 if (error != 0) 856 return error; 857 858 netbsd32_from_rusage50(&ru, &ru32); 859 return copyout(&ru32, SCARG_P32(uap, rusage), sizeof(ru32)); 860 } 861 862 int 863 compat_50_netbsd32_setitimer(struct lwp *l, 864 const struct compat_50_netbsd32_setitimer_args *uap, register_t *retval) 865 { 866 /* { 867 syscallarg(int) which; 868 syscallarg(const netbsd32_itimerval50p_t) itv; 869 syscallarg(netbsd32_itimerval50p_t) oitv; 870 } */ 871 struct proc *p = l->l_proc; 872 struct netbsd32_itimerval50 s32it, *itv32; 873 int which = SCARG(uap, which); 874 struct compat_50_netbsd32_getitimer_args getargs; 875 struct itimerval aitv; 876 int error; 877 878 itv32 = SCARG_P32(uap, itv); 879 if (itv32) { 880 if ((error = copyin(itv32, &s32it, sizeof(s32it)))) 881 return error; 882 netbsd32_to_itimerval50(&s32it, &aitv); 883 } 884 if (SCARG_P32(uap, oitv) != 0) { 885 SCARG(&getargs, which) = which; 886 SCARG(&getargs, itv) = SCARG(uap, oitv); 887 if ((error = compat_50_netbsd32_getitimer(l, &getargs, retval)) != 0) 888 return error; 889 } 890 if (itv32 == 0) 891 return 0; 892 893 return dosetitimer(p, which, &aitv); 894 } 895 896 int 897 compat_50_netbsd32_getitimer(struct lwp *l, const struct compat_50_netbsd32_getitimer_args *uap, register_t *retval) 898 { 899 /* { 900 syscallarg(int) which; 901 syscallarg(netbsd32_itimerval50p_t) itv; 902 } */ 903 struct proc *p = l->l_proc; 904 struct netbsd32_itimerval50 s32it; 905 struct itimerval aitv; 906 int error; 907 908 error = dogetitimer(p, SCARG(uap, which), &aitv); 909 if (error) 910 return error; 911 912 netbsd32_from_itimerval50(&aitv, &s32it); 913 return copyout(&s32it, SCARG_P32(uap, itv), sizeof(s32it)); 914 } 915 916 #ifdef NTP 917 int 918 compat_50_netbsd32_ntp_gettime(struct lwp *l, 919 const struct compat_50_netbsd32_ntp_gettime_args *uap, register_t *retval) 920 { 921 /* { 922 syscallarg(netbsd32_ntptimeval50p_t) ntvp; 923 } */ 924 struct netbsd32_ntptimeval50 ntv32; 925 struct ntptimeval ntv; 926 int error = 0; 927 928 if (vec_ntp_gettime == NULL) 929 return EINVAL; 930 931 if (SCARG_P32(uap, ntvp)) { 932 (*vec_ntp_gettime)(&ntv); 933 934 memset(&ntv32, 0, sizeof(ntv32)); 935 ntv32.time.tv_sec = (int32_t)ntv.time.tv_sec; 936 ntv32.time.tv_nsec = ntv.time.tv_nsec; 937 ntv32.maxerror = (netbsd32_long)ntv.maxerror; 938 ntv32.esterror = (netbsd32_long)ntv.esterror; 939 ntv32.tai = (netbsd32_long)ntv.tai; 940 ntv32.time_state = ntv.time_state; 941 error = copyout(&ntv32, SCARG_P32(uap, ntvp), sizeof(ntv32)); 942 } 943 if (!error) { 944 *retval = (*vec_ntp_timestatus)(); 945 } 946 947 return error; 948 } 949 #endif 950 951 static struct syscall_package compat_netbsd32_50_syscalls[] = { 952 { NETBSD32_SYS_compat_50_netbsd32_mknod, 0, 953 (sy_call_t *)compat_50_netbsd32_mknod }, 954 { NETBSD32_SYS_compat_50_netbsd32_select, 0, 955 (sy_call_t *)compat_50_netbsd32_select }, 956 { NETBSD32_SYS_compat_50_netbsd32_gettimeofday, 0, 957 (sy_call_t *)compat_50_netbsd32_gettimeofday }, 958 { NETBSD32_SYS_compat_50_netbsd32_settimeofday, 0, 959 (sy_call_t *)compat_50_netbsd32_settimeofday }, 960 { NETBSD32_SYS_compat_50_netbsd32_utimes, 0, 961 (sy_call_t *)compat_50_netbsd32_utimes }, 962 { NETBSD32_SYS_compat_50_netbsd32_futimes, 0, 963 (sy_call_t *)compat_50_netbsd32_futimes }, 964 { NETBSD32_SYS_compat_50_netbsd32_adjtime, 0, 965 (sy_call_t *)compat_50_netbsd32_adjtime }, 966 { NETBSD32_SYS_compat_50_netbsd32_clock_gettime, 0, 967 (sy_call_t *)compat_50_netbsd32_clock_gettime }, 968 { NETBSD32_SYS_compat_50_netbsd32_clock_settime, 0, 969 (sy_call_t *)compat_50_netbsd32_clock_settime }, 970 { NETBSD32_SYS_compat_50_netbsd32_clock_getres, 0, 971 (sy_call_t *)compat_50_netbsd32_clock_getres }, 972 { NETBSD32_SYS_compat_50_netbsd32_timer_settime, 0, 973 (sy_call_t *)compat_50_netbsd32_timer_settime }, 974 { NETBSD32_SYS_compat_50_netbsd32_timer_gettime, 0, 975 (sy_call_t *)compat_50_netbsd32_timer_gettime }, 976 { NETBSD32_SYS_compat_50_netbsd32_nanosleep, 0, 977 (sy_call_t *)compat_50_netbsd32_nanosleep }, 978 { NETBSD32_SYS_compat_50_netbsd32___sigtimedwait, 0, 979 (sy_call_t *)compat_50_netbsd32___sigtimedwait }, 980 { NETBSD32_SYS_compat_50_netbsd32_lutimes, 0, 981 (sy_call_t *)compat_50_netbsd32_lutimes }, 982 { NETBSD32_SYS_compat_50_netbsd32__lwp_park, 0, 983 (sy_call_t *)compat_50_netbsd32__lwp_park }, 984 { NETBSD32_SYS_compat_50_netbsd32_kevent, 0, 985 (sy_call_t *)compat_50_netbsd32_kevent }, 986 { NETBSD32_SYS_compat_50_netbsd32_pselect, 0, 987 (sy_call_t *)compat_50_netbsd32_pselect }, 988 { NETBSD32_SYS_compat_50_netbsd32_pollts, 0, 989 (sy_call_t *)compat_50_netbsd32_pollts }, 990 { NETBSD32_SYS_compat_50_netbsd32___stat30, 0, 991 (sy_call_t *)compat_50_netbsd32___stat30 }, 992 { NETBSD32_SYS_compat_50_netbsd32___fstat30, 0, 993 (sy_call_t *)compat_50_netbsd32___fstat30 }, 994 { NETBSD32_SYS_compat_50_netbsd32___lstat30, 0, 995 (sy_call_t *)compat_50_netbsd32___lstat30 }, 996 { NETBSD32_SYS_compat_50_netbsd32___fhstat40, 0, 997 (sy_call_t *)compat_50_netbsd32___fhstat40 }, 998 { NETBSD32_SYS_compat_50_netbsd32_wait4, 0, 999 (sy_call_t *)compat_50_netbsd32_wait4 }, 1000 { NETBSD32_SYS_compat_50_netbsd32_getrusage, 0, 1001 (sy_call_t *)compat_50_netbsd32_getrusage }, 1002 { NETBSD32_SYS_compat_50_netbsd32_setitimer, 0, 1003 (sy_call_t *)compat_50_netbsd32_setitimer }, 1004 { NETBSD32_SYS_compat_50_netbsd32_getitimer, 0, 1005 (sy_call_t *)compat_50_netbsd32_getitimer }, 1006 #ifdef NTP 1007 { NETBSD32_SYS_compat_50_netbsd32_ntp_gettime, 0, 1008 (sy_call_t *)compat_50_netbsd32_ntp_gettime }, 1009 #endif 1010 { 0, 0, NULL } 1011 }; 1012 1013 MODULE(MODULE_CLASS_EXEC, compat_netbsd32_50, "compat_netbsd32_60,compat_50"); 1014 1015 static int 1016 compat_netbsd32_50_modcmd(modcmd_t cmd, void *arg) 1017 { 1018 int ret; 1019 1020 switch (cmd) { 1021 case MODULE_CMD_INIT: 1022 ret = syscall_establish(&emul_netbsd32, 1023 compat_netbsd32_50_syscalls); 1024 if (ret == 0) 1025 MODULE_HOOK_SET(rnd_ioctl32_50_hook, 1026 compat32_50_rnd_ioctl); 1027 return ret; 1028 1029 case MODULE_CMD_FINI: 1030 ret = syscall_disestablish(&emul_netbsd32, 1031 compat_netbsd32_50_syscalls); 1032 if (ret == 0) 1033 MODULE_HOOK_UNSET(rnd_ioctl32_50_hook); 1034 return ret; 1035 1036 default: 1037 return ENOTTY; 1038 } 1039 } 1040 #endif /* COMPAT_50 */ 1041