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