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