1 /* $NetBSD: linux32_unistd.c,v 1.44 2021/11/27 21:15:07 ryo Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Emmanuel Dreyfus 17 * 4. The name of the author may not be used to endorse or promote 18 * products derived from this software without specific prior written 19 * permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 36 __KERNEL_RCSID(0, "$NetBSD: linux32_unistd.c,v 1.44 2021/11/27 21:15:07 ryo Exp $"); 37 38 #include <sys/types.h> 39 #include <sys/param.h> 40 #include <sys/fstypes.h> 41 #include <sys/signal.h> 42 #include <sys/dirent.h> 43 #include <sys/kernel.h> 44 #include <sys/fcntl.h> 45 #include <sys/select.h> 46 #include <sys/proc.h> 47 #include <sys/ucred.h> 48 #include <sys/swap.h> 49 #include <sys/kauth.h> 50 #include <sys/filedesc.h> 51 #include <sys/vfs_syscalls.h> 52 53 #include <machine/types.h> 54 55 #include <sys/syscallargs.h> 56 57 #include <compat/netbsd32/netbsd32.h> 58 #include <compat/netbsd32/netbsd32_conv.h> 59 60 #include <compat/linux/common/linux_types.h> 61 #include <compat/linux/common/linux_signal.h> 62 #include <compat/linux/common/linux_machdep.h> 63 #include <compat/linux/common/linux_misc.h> 64 #include <compat/linux/common/linux_oldolduname.h> 65 #include <compat/linux/common/linux_ipc.h> 66 #include <compat/linux/common/linux_sem.h> 67 #include <compat/linux/common/linux_fcntl.h> 68 #include <compat/linux/linux_syscallargs.h> 69 70 #include <compat/linux32/common/linux32_types.h> 71 #include <compat/linux32/common/linux32_signal.h> 72 #include <compat/linux32/common/linux32_machdep.h> 73 #include <compat/linux32/common/linux32_sched.h> 74 #include <compat/linux32/common/linux32_sysctl.h> 75 #include <compat/linux32/common/linux32_socketcall.h> 76 #include <compat/linux32/linux32_syscall.h> 77 #include <compat/linux32/linux32_syscallargs.h> 78 79 static int linux32_select1(struct lwp *, register_t *, 80 int, fd_set *, fd_set *, fd_set *, struct timeval *); 81 82 int 83 linux32_sys_brk(struct lwp *l, const struct linux32_sys_brk_args *uap, register_t *retval) 84 { 85 /* { 86 syscallarg(netbsd32_charp) nsize; 87 } */ 88 struct linux_sys_brk_args ua; 89 90 NETBSD32TOP_UAP(nsize, char); 91 return linux_sys_brk(l, &ua, retval); 92 } 93 94 int 95 linux32_sys_llseek(struct lwp *l, const struct linux32_sys_llseek_args *uap, register_t *retval) 96 { 97 /* { 98 syscallarg(int) fd; 99 syscallarg(u_int32_t) ohigh; 100 syscallarg(u_int32_t) olow; 101 syscallarg(netbsd32_voidp) res; 102 syscallarg(int) whence; 103 } */ 104 struct linux_sys_llseek_args ua; 105 106 NETBSD32TO64_UAP(fd); 107 NETBSD32TO64_UAP(ohigh); 108 NETBSD32TO64_UAP(olow); 109 NETBSD32TOP_UAP(res, void); 110 NETBSD32TO64_UAP(whence); 111 112 return linux_sys_llseek(l, &ua, retval); 113 } 114 115 int 116 linux32_sys_select(struct lwp *l, const struct linux32_sys_select_args *uap, register_t *retval) 117 { 118 /* { 119 syscallarg(int) nfds; 120 syscallarg(netbsd32_fd_setp_t) readfds; 121 syscallarg(netbsd32_fd_setp_t) writefds; 122 syscallarg(netbsd32_fd_setp_t) exceptfds; 123 syscallarg(netbsd32_timeval50p_t) timeout; 124 } */ 125 126 return linux32_select1(l, retval, SCARG(uap, nfds), 127 SCARG_P32(uap, readfds), 128 SCARG_P32(uap, writefds), 129 SCARG_P32(uap, exceptfds), 130 SCARG_P32(uap, timeout)); 131 } 132 133 int 134 linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval) 135 { 136 /* { 137 syscallarg(linux32_oldselectp_t) lsp; 138 } */ 139 struct linux32_oldselect lsp32; 140 int error; 141 142 if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0) 143 return error; 144 145 return linux32_select1(l, retval, lsp32.nfds, 146 NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), 147 NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); 148 } 149 150 static int 151 linux32_select1(struct lwp *l, register_t *retval, int nfds, 152 fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 153 struct timeval *timeout) 154 { 155 struct timespec ts0, ts1, uts, *ts = NULL; 156 struct netbsd32_timeval50 utv32; 157 int error; 158 159 160 /* 161 * Store current time for computation of the amount of 162 * time left. 163 */ 164 if (timeout) { 165 if ((error = copyin(timeout, &utv32, sizeof(utv32)))) 166 return error; 167 168 uts.tv_sec = utv32.tv_sec; 169 uts.tv_nsec = (long)((unsigned long)utv32.tv_usec * 1000); 170 171 if (itimespecfix(&uts)) { 172 /* 173 * The timeval was invalid. Convert it to something 174 * valid that will act as it does under Linux. 175 */ 176 uts.tv_sec += uts.tv_nsec / 1000000000; 177 uts.tv_nsec %= 1000000000; 178 if (uts.tv_nsec < 0) { 179 uts.tv_sec -= 1; 180 uts.tv_nsec += 1000000000; 181 } 182 if (uts.tv_sec < 0) 183 timespecclear(&uts); 184 } 185 nanotime(&ts0); 186 ts = &uts; 187 } else 188 timespecclear(&uts); /* XXX GCC4 */ 189 190 error = selcommon(retval, nfds, readfds, writefds, exceptfds, ts, NULL); 191 192 if (error) { 193 /* 194 * See fs/select.c in the Linux kernel. Without this, 195 * Maelstrom doesn't work. 196 */ 197 if (error == ERESTART) 198 error = EINTR; 199 return error; 200 } 201 202 if (timeout) { 203 if (*retval) { 204 /* 205 * Compute how much time was left of the timeout, 206 * by subtracting the current time and the time 207 * before we started the call, and subtracting 208 * that result from the user-supplied value. 209 */ 210 nanotime(&ts1); 211 timespecsub(&ts1, &ts0, &ts1); 212 timespecsub(&uts, &ts1, &uts); 213 if (uts.tv_sec < 0) 214 timespecclear(&uts); 215 } else { 216 timespecclear(&uts); 217 } 218 219 utv32.tv_sec = uts.tv_sec; 220 utv32.tv_usec = uts.tv_nsec / 1000; 221 222 if ((error = copyout(&utv32, timeout, sizeof(utv32)))) 223 return error; 224 } 225 226 return 0; 227 } 228 229 int 230 linux32_sys_pselect6(struct lwp *l, const struct linux32_sys_pselect6_args *uap, 231 register_t *retval) 232 { 233 /* { 234 syscallarg(int) nfds; 235 syscallarg(netbsd32_fd_setp_t) readfds; 236 syscallarg(netbsd32_fd_setp_t) writefds; 237 syscallarg(netbsd32_fd_setp_t) exceptfds; 238 syscallarg(linux32_timespecp_t) timeout; 239 syscallarg(linux32_sized_sigsetp_t) ss; 240 } */ 241 struct timespec uts, ts0, ts1, *tsp; 242 linux32_sized_sigset_t lsss; 243 struct linux32_timespec lts; 244 linux32_sigset_t lss; 245 sigset_t *ssp; 246 sigset_t ss; 247 int error; 248 void *p; 249 250 ssp = NULL; 251 if ((p = SCARG_P32(uap, ss)) != NULL) { 252 if ((error = copyin(p, &lsss, sizeof(lsss))) != 0) 253 return (error); 254 if (lsss.ss_len != sizeof(lss)) 255 return (EINVAL); 256 if ((p = NETBSD32PTR64(lsss.ss)) != NULL) { 257 if ((error = copyin(p, &lss, sizeof(lss))) != 0) 258 return (error); 259 linux32_to_native_sigset(&ss, &lss); 260 ssp = &ss; 261 } 262 } 263 264 if ((p = SCARG_P32(uap, timeout)) != NULL) { 265 error = copyin(p, <s, sizeof(lts)); 266 if (error != 0) 267 return (error); 268 linux32_to_native_timespec(&uts, <s); 269 270 if (itimespecfix(&uts)) 271 return (EINVAL); 272 273 nanotime(&ts0); 274 tsp = &uts; 275 } else { 276 tsp = NULL; 277 } 278 279 error = selcommon(retval, SCARG(uap, nfds), SCARG_P32(uap, readfds), 280 SCARG_P32(uap, writefds), SCARG_P32(uap, exceptfds), tsp, ssp); 281 282 if (error == 0 && tsp != NULL) { 283 if (retval != 0) { 284 /* 285 * Compute how much time was left of the timeout, 286 * by subtracting the current time and the time 287 * before we started the call, and subtracting 288 * that result from the user-supplied value. 289 */ 290 nanotime(&ts1); 291 timespecsub(&ts1, &ts0, &ts1); 292 timespecsub(&uts, &ts1, &uts); 293 if (uts.tv_sec < 0) 294 timespecclear(&uts); 295 } else { 296 timespecclear(&uts); 297 } 298 299 native_to_linux32_timespec(<s, &uts); 300 error = copyout(<s, SCARG_P32(uap, timeout), sizeof(lts)); 301 } 302 303 return (error); 304 } 305 306 int 307 linux32_sys_pipe(struct lwp *l, const struct linux32_sys_pipe_args *uap, 308 register_t *retval) 309 { 310 /* { 311 syscallarg(netbsd32_intp) fd; 312 } */ 313 int f[2], error; 314 315 if ((error = pipe1(l, f, 0))) 316 return error; 317 318 if ((error = copyout(f, SCARG_P32(uap, fd), sizeof(f))) != 0) 319 return error; 320 retval[0] = 0; 321 return 0; 322 } 323 324 int 325 linux32_sys_pipe2(struct lwp *l, const struct linux32_sys_pipe2_args *uap, 326 register_t *retval) 327 { 328 /* { 329 syscallarg(netbsd32_intp) fd; 330 } */ 331 int f[2], flags, error; 332 333 flags = linux_to_bsd_ioflags(SCARG(uap, flags)); 334 if ((flags & ~(O_CLOEXEC|O_NONBLOCK)) != 0) 335 return EINVAL; 336 337 if ((error = pipe1(l, f, flags))) 338 return error; 339 340 if ((error = copyout(f, SCARG_P32(uap, fd), sizeof(f))) != 0) 341 return error; 342 retval[0] = 0; 343 return 0; 344 } 345 346 int 347 linux32_sys_dup3(struct lwp *l, const struct linux32_sys_dup3_args *uap, 348 register_t *retval) 349 { 350 /* { 351 syscallarg(int) from; 352 syscallarg(int) to; 353 syscallarg(int) flags; 354 } */ 355 struct linux_sys_dup3_args ua; 356 357 NETBSD32TO64_UAP(from); 358 NETBSD32TO64_UAP(to); 359 NETBSD32TO64_UAP(flags); 360 361 return linux_sys_dup3(l, &ua, retval); 362 } 363 364 365 int 366 linux32_sys_openat(struct lwp *l, const struct linux32_sys_openat_args *uap, register_t *retval) 367 { 368 /* { 369 syscallarg(int) fd; 370 syscallarg(const netbsd32_charp) path; 371 syscallarg(int) flags; 372 syscallarg(int) mode; 373 } */ 374 struct linux_sys_openat_args ua; 375 376 NETBSD32TO64_UAP(fd); 377 NETBSD32TOP_UAP(path, const char); 378 NETBSD32TO64_UAP(flags); 379 NETBSD32TO64_UAP(mode); 380 381 return linux_sys_openat(l, &ua, retval); 382 } 383 384 int 385 linux32_sys_mknodat(struct lwp *l, const struct linux32_sys_mknodat_args *uap, register_t *retval) 386 { 387 /* { 388 syscallarg(int) fd; 389 syscallarg(const netbsd32_charp) path; 390 syscallarg(linux_umode_t) mode; 391 syscallarg(unsigned) dev; 392 } */ 393 struct linux_sys_mknodat_args ua; 394 395 NETBSD32TO64_UAP(fd); 396 NETBSD32TOP_UAP(path, const char); 397 NETBSD32TO64_UAP(mode); 398 NETBSD32TO64_UAP(dev); 399 400 return linux_sys_mknodat(l, &ua, retval); 401 } 402 403 int 404 linux32_sys_linkat(struct lwp *l, const struct linux32_sys_linkat_args *uap, register_t *retval) 405 { 406 /* { 407 syscallarg(int) fd1; 408 syscallarg(netbsd32_charp) name1; 409 syscallarg(int) fd2; 410 syscallarg(netbsd32_charp) name2; 411 syscallarg(int) flags; 412 } */ 413 int fd1 = SCARG(uap, fd1); 414 const char *name1 = SCARG_P32(uap, name1); 415 int fd2 = SCARG(uap, fd2); 416 const char *name2 = SCARG_P32(uap, name2); 417 int follow; 418 419 follow = SCARG(uap, flags) & LINUX_AT_SYMLINK_FOLLOW; 420 421 return do_sys_linkat(l, fd1, name1, fd2, name2, follow, retval); 422 } 423 424 int 425 linux32_sys_unlink(struct lwp *l, const struct linux32_sys_unlink_args *uap, register_t *retval) 426 { 427 /* { 428 syscallarg(const netbsd32_charp) path; 429 } */ 430 struct linux_sys_unlink_args ua; 431 432 NETBSD32TOP_UAP(path, const char); 433 434 return linux_sys_unlink(l, &ua, retval); 435 } 436 437 int 438 linux32_sys_unlinkat(struct lwp *l, const struct linux32_sys_unlinkat_args *uap, register_t *retval) 439 { 440 /* { 441 syscallarg(int) fd; 442 syscallarg(const netbsd32_charp) path; 443 syscallarg(int) flag; 444 } */ 445 struct linux_sys_unlinkat_args ua; 446 447 NETBSD32TO64_UAP(fd); 448 NETBSD32TOP_UAP(path, const char); 449 NETBSD32TO64_UAP(flag); 450 451 return linux_sys_unlinkat(l, &ua, retval); 452 } 453 454 int 455 linux32_sys_fchmodat(struct lwp *l, const struct linux32_sys_fchmodat_args *uap, register_t *retval) 456 { 457 /* { 458 syscallarg(int) fd; 459 syscallarg(netbsd_charp) path; 460 syscallarg(linux_umode_t) mode; 461 } */ 462 463 return do_sys_chmodat(l, SCARG(uap, fd), SCARG_P32(uap, path), 464 SCARG(uap, mode), AT_SYMLINK_FOLLOW); 465 } 466 467 int 468 linux32_sys_fchownat(struct lwp *l, const struct linux32_sys_fchownat_args *uap, register_t *retval) 469 { 470 /* { 471 syscallarg(int) fd; 472 syscallarg(netbsd_charp) path; 473 syscallarg(uid_t) owner; 474 syscallarg(gid_t) group; 475 syscallarg(int) flag; 476 } */ 477 int flag; 478 479 flag = linux_to_bsd_atflags(SCARG(uap, flag)); 480 return do_sys_chownat(l, SCARG(uap, fd), SCARG_P32(uap, path), 481 SCARG(uap, owner), SCARG(uap, group), flag); 482 } 483 484 int 485 linux32_sys_faccessat(struct lwp *l, const struct linux32_sys_faccessat_args *uap, register_t *retval) 486 { 487 /* { 488 syscallarg(int) fd; 489 syscallarg(netbsd_charp) path; 490 syscallarg(int) amode; 491 } */ 492 493 return do_sys_accessat(l, SCARG(uap, fd), SCARG_P32(uap, path), 494 SCARG(uap, amode), AT_SYMLINK_FOLLOW); 495 } 496 497 int 498 linux32_sys_utimensat(struct lwp *l, const struct linux32_sys_utimensat_args *uap, register_t *retval) 499 { 500 /* { 501 syscallarg(int) fd; 502 syscallarg(const netbsd32_charp) path; 503 syscallarg(const linux32_timespecp_t) times; 504 syscallarg(int) flags; 505 } */ 506 int error; 507 struct linux32_timespec lts[2]; 508 struct timespec *tsp = NULL, ts[2]; 509 510 if (SCARG_P32(uap, times)) { 511 error = copyin(SCARG_P32(uap, times), <s, sizeof(lts)); 512 if (error != 0) 513 return error; 514 linux32_to_native_timespec(&ts[0], <s[0]); 515 linux32_to_native_timespec(&ts[1], <s[1]); 516 tsp = ts; 517 } 518 519 return linux_do_sys_utimensat(l, SCARG(uap, fd), SCARG_P32(uap, path), 520 tsp, SCARG(uap, flag), retval); 521 } 522 523 int 524 linux32_sys_creat(struct lwp *l, const struct linux32_sys_creat_args *uap, register_t *retval) 525 { 526 /* { 527 syscallarg(const netbsd32_charp) path; 528 syscallarg(int) mode; 529 } */ 530 struct sys_open_args ua; 531 532 NETBSD32TOP_UAP(path, const char); 533 SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; 534 NETBSD32TO64_UAP(mode); 535 536 return sys_open(l, &ua, retval); 537 } 538 539 int 540 linux32_sys_mknod(struct lwp *l, const struct linux32_sys_mknod_args *uap, register_t *retval) 541 { 542 /* { 543 syscallarg(const netbsd32_charp) path; 544 syscallarg(int) mode; 545 syscallarg(int) dev; 546 } */ 547 struct linux_sys_mknod_args ua; 548 549 NETBSD32TOP_UAP(path, const char); 550 NETBSD32TO64_UAP(mode); 551 NETBSD32TO64_UAP(dev); 552 553 return linux_sys_mknod(l, &ua, retval); 554 } 555 556 #ifdef LINUX32_SYS_break 557 int 558 linux32_sys_break(struct lwp *l, const struct linux32_sys_break_args *uap, register_t *retval) 559 { 560 #if 0 561 /* { 562 syscallarg(const netbsd32_charp) nsize; 563 } */ 564 #endif 565 566 return ENOSYS; 567 } 568 #endif 569 570 int 571 linux32_sys_swapon(struct lwp *l, const struct linux32_sys_swapon_args *uap, register_t *retval) 572 { 573 /* { 574 syscallarg(const netbsd32_charp) name; 575 } */ 576 struct sys_swapctl_args ua; 577 578 SCARG(&ua, cmd) = SWAP_ON; 579 SCARG(&ua, arg) = SCARG_P32(uap, name); 580 SCARG(&ua, misc) = 0; /* priority */ 581 return (sys_swapctl(l, &ua, retval)); 582 } 583 584 int 585 linux32_sys_swapoff(struct lwp *l, const struct linux32_sys_swapoff_args *uap, register_t *retval) 586 { 587 /* { 588 syscallarg(const netbsd32_charp) path; 589 } */ 590 struct sys_swapctl_args ua; 591 592 SCARG(&ua, cmd) = SWAP_OFF; 593 SCARG(&ua, arg) = SCARG_P32(uap, path); 594 SCARG(&ua, misc) = 0; /* priority */ 595 return (sys_swapctl(l, &ua, retval)); 596 } 597 598 599 int 600 linux32_sys_reboot(struct lwp *l, const struct linux32_sys_reboot_args *uap, register_t *retval) 601 { 602 /* { 603 syscallarg(int) magic1; 604 syscallarg(int) magic2; 605 syscallarg(int) cmd; 606 syscallarg(netbsd32_voidp) arg; 607 } */ 608 struct linux_sys_reboot_args ua; 609 610 NETBSD32TO64_UAP(magic1); 611 NETBSD32TO64_UAP(magic2); 612 NETBSD32TO64_UAP(cmd); 613 NETBSD32TOP_UAP(arg, void); 614 615 return linux_sys_reboot(l, &ua, retval); 616 } 617 618 int 619 linux32_sys_setresuid(struct lwp *l, const struct linux32_sys_setresuid_args *uap, register_t *retval) 620 { 621 /* { 622 syscallarg(uid_t) ruid; 623 syscallarg(uid_t) euid; 624 syscallarg(uid_t) suid; 625 } */ 626 struct linux_sys_setresuid_args ua; 627 628 NETBSD32TO64_UAP(ruid); 629 NETBSD32TO64_UAP(euid); 630 NETBSD32TO64_UAP(suid); 631 632 return linux_sys_setresuid(l, &ua, retval); 633 } 634 635 int 636 linux32_sys_getresuid(struct lwp *l, const struct linux32_sys_getresuid_args *uap, register_t *retval) 637 { 638 /* { 639 syscallarg(linux32_uidp_t) ruid; 640 syscallarg(linux32_uidp_t) euid; 641 syscallarg(linux32_uidp_t) suid; 642 } */ 643 kauth_cred_t pc = l->l_cred; 644 int error; 645 uid_t uid; 646 647 uid = kauth_cred_getuid(pc); 648 if ((error = copyout(&uid, SCARG_P32(uap, ruid), sizeof(uid_t))) != 0) 649 return error; 650 651 uid = kauth_cred_geteuid(pc); 652 if ((error = copyout(&uid, SCARG_P32(uap, euid), sizeof(uid_t))) != 0) 653 return error; 654 655 uid = kauth_cred_getsvuid(pc); 656 return copyout(&uid, SCARG_P32(uap, suid), sizeof(uid_t)); 657 } 658 659 int 660 linux32_sys_setresgid(struct lwp *l, const struct linux32_sys_setresgid_args *uap, register_t *retval) 661 { 662 /* { 663 syscallarg(gid_t) rgid; 664 syscallarg(gid_t) egid; 665 syscallarg(gid_t) sgid; 666 } */ 667 struct linux_sys_setresgid_args ua; 668 669 NETBSD32TO64_UAP(rgid); 670 NETBSD32TO64_UAP(egid); 671 NETBSD32TO64_UAP(sgid); 672 673 return linux_sys_setresgid(l, &ua, retval); 674 } 675 676 int 677 linux32_sys_getresgid(struct lwp *l, const struct linux32_sys_getresgid_args *uap, register_t *retval) 678 { 679 /* { 680 syscallarg(linux32_gidp_t) rgid; 681 syscallarg(linux32_gidp_t) egid; 682 syscallarg(linux32_gidp_t) sgid; 683 } */ 684 kauth_cred_t pc = l->l_cred; 685 int error; 686 gid_t gid; 687 688 gid = kauth_cred_getgid(pc); 689 if ((error = copyout(&gid, SCARG_P32(uap, rgid), sizeof(gid_t))) != 0) 690 return error; 691 692 gid = kauth_cred_getegid(pc); 693 if ((error = copyout(&gid, SCARG_P32(uap, egid), sizeof(gid_t))) != 0) 694 return error; 695 696 gid = kauth_cred_getsvgid(pc); 697 return copyout(&gid, SCARG_P32(uap, sgid), sizeof(gid_t)); 698 } 699 700 int 701 linux32_sys_nice(struct lwp *l, const struct linux32_sys_nice_args *uap, register_t *retval) 702 { 703 /* { 704 syscallarg(int) incr; 705 } */ 706 struct proc *p = l->l_proc; 707 struct sys_setpriority_args bsa; 708 int error; 709 710 SCARG(&bsa, which) = PRIO_PROCESS; 711 SCARG(&bsa, who) = 0; 712 SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr); 713 714 error = sys_setpriority(l, &bsa, retval); 715 return (error) ? EPERM : 0; 716 } 717 718 int 719 linux32_sys_alarm(struct lwp *l, const struct linux32_sys_alarm_args *uap, register_t *retval) 720 { 721 /* { 722 syscallarg(unsigned int) secs; 723 } */ 724 struct linux_sys_alarm_args ua; 725 726 NETBSD32TO64_UAP(secs); 727 728 return linux_sys_alarm(l, &ua, retval); 729 } 730 731 int 732 linux32_sys_fdatasync(struct lwp *l, const struct linux32_sys_fdatasync_args *uap, register_t *retval) 733 { 734 /* { 735 syscallarg(int) fd; 736 } */ 737 struct linux_sys_fdatasync_args ua; 738 739 NETBSD32TO64_UAP(fd); 740 741 return linux_sys_fdatasync(l, &ua, retval); 742 } 743 744 int 745 linux32_sys_setfsuid(struct lwp *l, const struct linux32_sys_setfsuid_args *uap, register_t *retval) 746 { 747 /* { 748 syscallarg(uid_t) uid; 749 } */ 750 struct linux_sys_setfsuid_args ua; 751 752 NETBSD32TO64_UAP(uid); 753 754 return linux_sys_setfsuid(l, &ua, retval); 755 } 756 757 int 758 linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval) 759 { 760 /* { 761 syscallarg(gid_t) gid; 762 } */ 763 struct linux_sys_setfsgid_args ua; 764 765 NETBSD32TO64_UAP(gid); 766 767 return linux_sys_setfsgid(l, &ua, retval); 768 } 769 770 /* 771 * pread(2). 772 */ 773 int 774 linux32_sys_pread(struct lwp *l, 775 const struct linux32_sys_pread_args *uap, register_t *retval) 776 { 777 /* { 778 syscallarg(int) fd; 779 syscallarg(netbsd32_voidp) buf; 780 syscallarg(netbsd32_size_t) nbyte; 781 syscallarg(netbsd32_off_t) offset; 782 } */ 783 struct sys_pread_args pra; 784 785 SCARG(&pra, fd) = SCARG(uap, fd); 786 SCARG(&pra, buf) = SCARG_P32(uap, buf); 787 SCARG(&pra, nbyte) = SCARG(uap, nbyte); 788 SCARG(&pra, PAD) = 0; 789 SCARG(&pra, offset) = SCARG(uap, offset); 790 791 return sys_pread(l, &pra, retval); 792 } 793 794 /* 795 * pwrite(2). 796 */ 797 int 798 linux32_sys_pwrite(struct lwp *l, 799 const struct linux32_sys_pwrite_args *uap, register_t *retval) 800 { 801 /* { 802 syscallarg(int) fd; 803 syscallarg(const netbsd32_voidp) buf; 804 syscallarg(netbsd32_size_t) nbyte; 805 syscallarg(netbsd32_off_t) offset; 806 } */ 807 struct sys_pwrite_args pra; 808 809 SCARG(&pra, fd) = SCARG(uap, fd); 810 SCARG(&pra, buf) = SCARG_P32(uap, buf); 811 SCARG(&pra, nbyte) = SCARG(uap, nbyte); 812 SCARG(&pra, PAD) = 0; 813 SCARG(&pra, offset) = SCARG(uap, offset); 814 815 return sys_pwrite(l, &pra, retval); 816 } 817 818 /* 819 * fallocate(2) 820 */ 821 int 822 linux32_sys_fallocate(struct lwp *l, 823 const struct linux32_sys_fallocate_args *uap, register_t *retval) 824 { 825 /* 826 * For now just return EOPNOTSUPP, this makes glibc posix_fallocate() 827 * to fallback to emulation. 828 * XXX Right now no filesystem actually implements fallocate support, 829 * so no need for mapping. 830 */ 831 return EOPNOTSUPP; 832 } 833