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