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