1 /* $NetBSD: linux32_unistd.c,v 1.45 2026/09/20 13:43:52 riastradh 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.45 2026/09/20 13:43:52 riastradh 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 memset(&ua, 0, sizeof(ua)); 91 NETBSD32TOP_UAP(nsize, char); 92 return linux_sys_brk(l, &ua, retval); 93 } 94 95 int 96 linux32_sys_llseek(struct lwp *l, const struct linux32_sys_llseek_args *uap, register_t *retval) 97 { 98 /* { 99 syscallarg(int) fd; 100 syscallarg(u_int32_t) ohigh; 101 syscallarg(u_int32_t) olow; 102 syscallarg(netbsd32_voidp) res; 103 syscallarg(int) whence; 104 } */ 105 struct linux_sys_llseek_args ua; 106 107 memset(&ua, 0, sizeof(ua)); 108 NETBSD32TO64_UAP(fd); 109 NETBSD32TO64_UAP(ohigh); 110 NETBSD32TO64_UAP(olow); 111 NETBSD32TOP_UAP(res, void); 112 NETBSD32TO64_UAP(whence); 113 114 return linux_sys_llseek(l, &ua, retval); 115 } 116 117 int 118 linux32_sys_select(struct lwp *l, const struct linux32_sys_select_args *uap, register_t *retval) 119 { 120 /* { 121 syscallarg(int) nfds; 122 syscallarg(netbsd32_fd_setp_t) readfds; 123 syscallarg(netbsd32_fd_setp_t) writefds; 124 syscallarg(netbsd32_fd_setp_t) exceptfds; 125 syscallarg(netbsd32_timeval50p_t) timeout; 126 } */ 127 128 return linux32_select1(l, retval, SCARG(uap, nfds), 129 SCARG_P32(uap, readfds), 130 SCARG_P32(uap, writefds), 131 SCARG_P32(uap, exceptfds), 132 SCARG_P32(uap, timeout)); 133 } 134 135 int 136 linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval) 137 { 138 /* { 139 syscallarg(linux32_oldselectp_t) lsp; 140 } */ 141 struct linux32_oldselect lsp32; 142 int error; 143 144 if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0) 145 return error; 146 147 return linux32_select1(l, retval, lsp32.nfds, 148 NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), 149 NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); 150 } 151 152 static int 153 linux32_select1(struct lwp *l, register_t *retval, int nfds, 154 fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 155 struct timeval *timeout) 156 { 157 struct timespec ts0, ts1, uts, *ts = NULL; 158 struct netbsd32_timeval50 utv32; 159 int error; 160 161 162 /* 163 * Store current time for computation of the amount of 164 * time left. 165 */ 166 if (timeout) { 167 if ((error = copyin(timeout, &utv32, sizeof(utv32)))) 168 return error; 169 170 uts.tv_sec = utv32.tv_sec; 171 uts.tv_nsec = (long)((unsigned long)utv32.tv_usec * 1000); 172 173 if (itimespecfix(&uts)) { 174 /* 175 * The timeval was invalid. Convert it to something 176 * valid that will act as it does under Linux. 177 */ 178 uts.tv_sec += uts.tv_nsec / 1000000000; 179 uts.tv_nsec %= 1000000000; 180 if (uts.tv_nsec < 0) { 181 uts.tv_sec -= 1; 182 uts.tv_nsec += 1000000000; 183 } 184 if (uts.tv_sec < 0) 185 timespecclear(&uts); 186 } 187 nanotime(&ts0); 188 ts = &uts; 189 } else 190 timespecclear(&uts); /* XXX GCC4 */ 191 192 error = selcommon(retval, nfds, readfds, writefds, exceptfds, ts, NULL); 193 194 if (error) { 195 /* 196 * See fs/select.c in the Linux kernel. Without this, 197 * Maelstrom doesn't work. 198 */ 199 if (error == ERESTART) 200 error = EINTR; 201 return error; 202 } 203 204 if (timeout) { 205 if (*retval) { 206 /* 207 * Compute how much time was left of the timeout, 208 * by subtracting the current time and the time 209 * before we started the call, and subtracting 210 * that result from the user-supplied value. 211 */ 212 nanotime(&ts1); 213 timespecsub(&ts1, &ts0, &ts1); 214 timespecsub(&uts, &ts1, &uts); 215 if (uts.tv_sec < 0) 216 timespecclear(&uts); 217 } else { 218 timespecclear(&uts); 219 } 220 221 utv32.tv_sec = uts.tv_sec; 222 utv32.tv_usec = uts.tv_nsec / 1000; 223 224 if ((error = copyout(&utv32, timeout, sizeof(utv32)))) 225 return error; 226 } 227 228 return 0; 229 } 230 231 int 232 linux32_sys_pselect6(struct lwp *l, const struct linux32_sys_pselect6_args *uap, 233 register_t *retval) 234 { 235 /* { 236 syscallarg(int) nfds; 237 syscallarg(netbsd32_fd_setp_t) readfds; 238 syscallarg(netbsd32_fd_setp_t) writefds; 239 syscallarg(netbsd32_fd_setp_t) exceptfds; 240 syscallarg(linux32_timespecp_t) timeout; 241 syscallarg(linux32_sized_sigsetp_t) ss; 242 } */ 243 struct timespec uts, ts0, ts1, *tsp; 244 linux32_sized_sigset_t lsss; 245 struct linux32_timespec lts; 246 linux32_sigset_t lss; 247 sigset_t *ssp; 248 sigset_t ss; 249 int error; 250 void *p; 251 252 ssp = NULL; 253 if ((p = SCARG_P32(uap, ss)) != NULL) { 254 if ((error = copyin(p, &lsss, sizeof(lsss))) != 0) 255 return (error); 256 if (lsss.ss_len != sizeof(lss)) 257 return (EINVAL); 258 if ((p = NETBSD32PTR64(lsss.ss)) != NULL) { 259 if ((error = copyin(p, &lss, sizeof(lss))) != 0) 260 return (error); 261 linux32_to_native_sigset(&ss, &lss); 262 ssp = &ss; 263 } 264 } 265 266 if ((p = SCARG_P32(uap, timeout)) != NULL) { 267 error = copyin(p, <s, sizeof(lts)); 268 if (error != 0) 269 return (error); 270 linux32_to_native_timespec(&uts, <s); 271 272 if (itimespecfix(&uts)) 273 return (EINVAL); 274 275 nanotime(&ts0); 276 tsp = &uts; 277 } else { 278 tsp = NULL; 279 } 280 281 error = selcommon(retval, SCARG(uap, nfds), SCARG_P32(uap, readfds), 282 SCARG_P32(uap, writefds), SCARG_P32(uap, exceptfds), tsp, ssp); 283 284 if (error == 0 && tsp != NULL) { 285 if (retval != 0) { 286 /* 287 * Compute how much time was left of the timeout, 288 * by subtracting the current time and the time 289 * before we started the call, and subtracting 290 * that result from the user-supplied value. 291 */ 292 nanotime(&ts1); 293 timespecsub(&ts1, &ts0, &ts1); 294 timespecsub(&uts, &ts1, &uts); 295 if (uts.tv_sec < 0) 296 timespecclear(&uts); 297 } else { 298 timespecclear(&uts); 299 } 300 301 native_to_linux32_timespec(<s, &uts); 302 error = copyout(<s, SCARG_P32(uap, timeout), sizeof(lts)); 303 } 304 305 return (error); 306 } 307 308 int 309 linux32_sys_pipe(struct lwp *l, const struct linux32_sys_pipe_args *uap, 310 register_t *retval) 311 { 312 /* { 313 syscallarg(netbsd32_intp) fd; 314 } */ 315 int f[2], error; 316 317 if ((error = pipe1(l, f, 0))) 318 return error; 319 320 if ((error = copyout(f, SCARG_P32(uap, fd), sizeof(f))) != 0) 321 return error; 322 retval[0] = 0; 323 return 0; 324 } 325 326 int 327 linux32_sys_pipe2(struct lwp *l, const struct linux32_sys_pipe2_args *uap, 328 register_t *retval) 329 { 330 /* { 331 syscallarg(netbsd32_intp) fd; 332 } */ 333 int f[2], flags, error; 334 335 flags = linux_to_bsd_ioflags(SCARG(uap, flags)); 336 if ((flags & ~(O_CLOEXEC|O_NONBLOCK)) != 0) 337 return EINVAL; 338 339 if ((error = pipe1(l, f, flags))) 340 return error; 341 342 if ((error = copyout(f, SCARG_P32(uap, fd), sizeof(f))) != 0) 343 return error; 344 retval[0] = 0; 345 return 0; 346 } 347 348 int 349 linux32_sys_dup3(struct lwp *l, const struct linux32_sys_dup3_args *uap, 350 register_t *retval) 351 { 352 /* { 353 syscallarg(int) from; 354 syscallarg(int) to; 355 syscallarg(int) flags; 356 } */ 357 struct linux_sys_dup3_args ua; 358 359 memset(&ua, 0, sizeof(ua)); 360 NETBSD32TO64_UAP(from); 361 NETBSD32TO64_UAP(to); 362 NETBSD32TO64_UAP(flags); 363 364 return linux_sys_dup3(l, &ua, retval); 365 } 366 367 368 int 369 linux32_sys_openat(struct lwp *l, const struct linux32_sys_openat_args *uap, register_t *retval) 370 { 371 /* { 372 syscallarg(int) fd; 373 syscallarg(const netbsd32_charp) path; 374 syscallarg(int) flags; 375 syscallarg(int) mode; 376 } */ 377 struct linux_sys_openat_args ua; 378 379 memset(&ua, 0, sizeof(ua)); 380 NETBSD32TO64_UAP(fd); 381 NETBSD32TOP_UAP(path, const char); 382 NETBSD32TO64_UAP(flags); 383 NETBSD32TO64_UAP(mode); 384 385 return linux_sys_openat(l, &ua, retval); 386 } 387 388 int 389 linux32_sys_mknodat(struct lwp *l, const struct linux32_sys_mknodat_args *uap, register_t *retval) 390 { 391 /* { 392 syscallarg(int) fd; 393 syscallarg(const netbsd32_charp) path; 394 syscallarg(linux_umode_t) mode; 395 syscallarg(unsigned) dev; 396 } */ 397 struct linux_sys_mknodat_args ua; 398 399 memset(&ua, 0, sizeof(ua)); 400 NETBSD32TO64_UAP(fd); 401 NETBSD32TOP_UAP(path, const char); 402 NETBSD32TO64_UAP(mode); 403 NETBSD32TO64_UAP(dev); 404 405 return linux_sys_mknodat(l, &ua, retval); 406 } 407 408 int 409 linux32_sys_linkat(struct lwp *l, const struct linux32_sys_linkat_args *uap, register_t *retval) 410 { 411 /* { 412 syscallarg(int) fd1; 413 syscallarg(netbsd32_charp) name1; 414 syscallarg(int) fd2; 415 syscallarg(netbsd32_charp) name2; 416 syscallarg(int) flags; 417 } */ 418 int fd1 = SCARG(uap, fd1); 419 const char *name1 = SCARG_P32(uap, name1); 420 int fd2 = SCARG(uap, fd2); 421 const char *name2 = SCARG_P32(uap, name2); 422 int follow; 423 424 follow = SCARG(uap, flags) & LINUX_AT_SYMLINK_FOLLOW; 425 426 return do_sys_linkat(l, fd1, name1, fd2, name2, follow, retval); 427 } 428 429 int 430 linux32_sys_unlink(struct lwp *l, const struct linux32_sys_unlink_args *uap, register_t *retval) 431 { 432 /* { 433 syscallarg(const netbsd32_charp) path; 434 } */ 435 struct linux_sys_unlink_args ua; 436 437 memset(&ua, 0, sizeof(ua)); 438 NETBSD32TOP_UAP(path, const char); 439 440 return linux_sys_unlink(l, &ua, retval); 441 } 442 443 int 444 linux32_sys_unlinkat(struct lwp *l, const struct linux32_sys_unlinkat_args *uap, register_t *retval) 445 { 446 /* { 447 syscallarg(int) fd; 448 syscallarg(const netbsd32_charp) path; 449 syscallarg(int) flag; 450 } */ 451 struct linux_sys_unlinkat_args ua; 452 453 memset(&ua, 0, sizeof(ua)); 454 NETBSD32TO64_UAP(fd); 455 NETBSD32TOP_UAP(path, const char); 456 NETBSD32TO64_UAP(flag); 457 458 return linux_sys_unlinkat(l, &ua, retval); 459 } 460 461 int 462 linux32_sys_fchmodat(struct lwp *l, const struct linux32_sys_fchmodat_args *uap, register_t *retval) 463 { 464 /* { 465 syscallarg(int) fd; 466 syscallarg(netbsd_charp) path; 467 syscallarg(linux_umode_t) mode; 468 } */ 469 470 return do_sys_chmodat(l, SCARG(uap, fd), SCARG_P32(uap, path), 471 SCARG(uap, mode), AT_SYMLINK_FOLLOW); 472 } 473 474 int 475 linux32_sys_fchownat(struct lwp *l, const struct linux32_sys_fchownat_args *uap, register_t *retval) 476 { 477 /* { 478 syscallarg(int) fd; 479 syscallarg(netbsd_charp) path; 480 syscallarg(uid_t) owner; 481 syscallarg(gid_t) group; 482 syscallarg(int) flag; 483 } */ 484 int flag; 485 486 flag = linux_to_bsd_atflags(SCARG(uap, flag)); 487 return do_sys_chownat(l, SCARG(uap, fd), SCARG_P32(uap, path), 488 SCARG(uap, owner), SCARG(uap, group), flag); 489 } 490 491 int 492 linux32_sys_faccessat(struct lwp *l, const struct linux32_sys_faccessat_args *uap, register_t *retval) 493 { 494 /* { 495 syscallarg(int) fd; 496 syscallarg(netbsd_charp) path; 497 syscallarg(int) amode; 498 } */ 499 500 return do_sys_accessat(l, SCARG(uap, fd), SCARG_P32(uap, path), 501 SCARG(uap, amode), AT_SYMLINK_FOLLOW); 502 } 503 504 int 505 linux32_sys_utimensat(struct lwp *l, const struct linux32_sys_utimensat_args *uap, register_t *retval) 506 { 507 /* { 508 syscallarg(int) fd; 509 syscallarg(const netbsd32_charp) path; 510 syscallarg(const linux32_timespecp_t) times; 511 syscallarg(int) flags; 512 } */ 513 int error; 514 struct linux32_timespec lts[2]; 515 struct timespec *tsp = NULL, ts[2]; 516 517 if (SCARG_P32(uap, times)) { 518 error = copyin(SCARG_P32(uap, times), <s, sizeof(lts)); 519 if (error != 0) 520 return error; 521 linux32_to_native_timespec(&ts[0], <s[0]); 522 linux32_to_native_timespec(&ts[1], <s[1]); 523 tsp = ts; 524 } 525 526 return linux_do_sys_utimensat(l, SCARG(uap, fd), SCARG_P32(uap, path), 527 tsp, SCARG(uap, flag), retval); 528 } 529 530 int 531 linux32_sys_creat(struct lwp *l, const struct linux32_sys_creat_args *uap, register_t *retval) 532 { 533 /* { 534 syscallarg(const netbsd32_charp) path; 535 syscallarg(int) mode; 536 } */ 537 struct sys_open_args ua; 538 539 memset(&ua, 0, sizeof(ua)); 540 NETBSD32TOP_UAP(path, const char); 541 SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; 542 NETBSD32TO64_UAP(mode); 543 544 return sys_open(l, &ua, retval); 545 } 546 547 int 548 linux32_sys_mknod(struct lwp *l, const struct linux32_sys_mknod_args *uap, register_t *retval) 549 { 550 /* { 551 syscallarg(const netbsd32_charp) path; 552 syscallarg(int) mode; 553 syscallarg(int) dev; 554 } */ 555 struct linux_sys_mknod_args ua; 556 557 memset(&ua, 0, sizeof(ua)); 558 NETBSD32TOP_UAP(path, const char); 559 NETBSD32TO64_UAP(mode); 560 NETBSD32TO64_UAP(dev); 561 562 return linux_sys_mknod(l, &ua, retval); 563 } 564 565 #ifdef LINUX32_SYS_break 566 int 567 linux32_sys_break(struct lwp *l, const struct linux32_sys_break_args *uap, register_t *retval) 568 { 569 #if 0 570 /* { 571 syscallarg(const netbsd32_charp) nsize; 572 } */ 573 #endif 574 575 return ENOSYS; 576 } 577 #endif 578 579 int 580 linux32_sys_swapon(struct lwp *l, const struct linux32_sys_swapon_args *uap, register_t *retval) 581 { 582 /* { 583 syscallarg(const netbsd32_charp) name; 584 } */ 585 struct sys_swapctl_args ua; 586 587 memset(&ua, 0, sizeof(ua)); 588 SCARG(&ua, cmd) = SWAP_ON; 589 SCARG(&ua, arg) = SCARG_P32(uap, name); 590 SCARG(&ua, misc) = 0; /* priority */ 591 return (sys_swapctl(l, &ua, retval)); 592 } 593 594 int 595 linux32_sys_swapoff(struct lwp *l, const struct linux32_sys_swapoff_args *uap, register_t *retval) 596 { 597 /* { 598 syscallarg(const netbsd32_charp) path; 599 } */ 600 struct sys_swapctl_args ua; 601 602 memset(&ua, 0, sizeof(ua)); 603 SCARG(&ua, cmd) = SWAP_OFF; 604 SCARG(&ua, arg) = SCARG_P32(uap, path); 605 SCARG(&ua, misc) = 0; /* priority */ 606 return (sys_swapctl(l, &ua, retval)); 607 } 608 609 610 int 611 linux32_sys_reboot(struct lwp *l, const struct linux32_sys_reboot_args *uap, register_t *retval) 612 { 613 /* { 614 syscallarg(int) magic1; 615 syscallarg(int) magic2; 616 syscallarg(int) cmd; 617 syscallarg(netbsd32_voidp) arg; 618 } */ 619 struct linux_sys_reboot_args ua; 620 621 memset(&ua, 0, sizeof(ua)); 622 NETBSD32TO64_UAP(magic1); 623 NETBSD32TO64_UAP(magic2); 624 NETBSD32TO64_UAP(cmd); 625 NETBSD32TOP_UAP(arg, void); 626 627 return linux_sys_reboot(l, &ua, retval); 628 } 629 630 int 631 linux32_sys_setresuid(struct lwp *l, const struct linux32_sys_setresuid_args *uap, register_t *retval) 632 { 633 /* { 634 syscallarg(uid_t) ruid; 635 syscallarg(uid_t) euid; 636 syscallarg(uid_t) suid; 637 } */ 638 struct linux_sys_setresuid_args ua; 639 640 memset(&ua, 0, sizeof(ua)); 641 NETBSD32TO64_UAP(ruid); 642 NETBSD32TO64_UAP(euid); 643 NETBSD32TO64_UAP(suid); 644 645 return linux_sys_setresuid(l, &ua, retval); 646 } 647 648 int 649 linux32_sys_getresuid(struct lwp *l, const struct linux32_sys_getresuid_args *uap, register_t *retval) 650 { 651 /* { 652 syscallarg(linux32_uidp_t) ruid; 653 syscallarg(linux32_uidp_t) euid; 654 syscallarg(linux32_uidp_t) suid; 655 } */ 656 kauth_cred_t pc = l->l_cred; 657 int error; 658 uid_t uid; 659 660 uid = kauth_cred_getuid(pc); 661 if ((error = copyout(&uid, SCARG_P32(uap, ruid), sizeof(uid_t))) != 0) 662 return error; 663 664 uid = kauth_cred_geteuid(pc); 665 if ((error = copyout(&uid, SCARG_P32(uap, euid), sizeof(uid_t))) != 0) 666 return error; 667 668 uid = kauth_cred_getsvuid(pc); 669 return copyout(&uid, SCARG_P32(uap, suid), sizeof(uid_t)); 670 } 671 672 int 673 linux32_sys_setresgid(struct lwp *l, const struct linux32_sys_setresgid_args *uap, register_t *retval) 674 { 675 /* { 676 syscallarg(gid_t) rgid; 677 syscallarg(gid_t) egid; 678 syscallarg(gid_t) sgid; 679 } */ 680 struct linux_sys_setresgid_args ua; 681 682 memset(&ua, 0, sizeof(ua)); 683 NETBSD32TO64_UAP(rgid); 684 NETBSD32TO64_UAP(egid); 685 NETBSD32TO64_UAP(sgid); 686 687 return linux_sys_setresgid(l, &ua, retval); 688 } 689 690 int 691 linux32_sys_getresgid(struct lwp *l, const struct linux32_sys_getresgid_args *uap, register_t *retval) 692 { 693 /* { 694 syscallarg(linux32_gidp_t) rgid; 695 syscallarg(linux32_gidp_t) egid; 696 syscallarg(linux32_gidp_t) sgid; 697 } */ 698 kauth_cred_t pc = l->l_cred; 699 int error; 700 gid_t gid; 701 702 gid = kauth_cred_getgid(pc); 703 if ((error = copyout(&gid, SCARG_P32(uap, rgid), sizeof(gid_t))) != 0) 704 return error; 705 706 gid = kauth_cred_getegid(pc); 707 if ((error = copyout(&gid, SCARG_P32(uap, egid), sizeof(gid_t))) != 0) 708 return error; 709 710 gid = kauth_cred_getsvgid(pc); 711 return copyout(&gid, SCARG_P32(uap, sgid), sizeof(gid_t)); 712 } 713 714 int 715 linux32_sys_nice(struct lwp *l, const struct linux32_sys_nice_args *uap, register_t *retval) 716 { 717 /* { 718 syscallarg(int) incr; 719 } */ 720 struct proc *p = l->l_proc; 721 struct sys_setpriority_args bsa; 722 int error; 723 724 memset(&bsa, 0, sizeof(bsa)); 725 SCARG(&bsa, which) = PRIO_PROCESS; 726 SCARG(&bsa, who) = 0; 727 SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr); 728 729 error = sys_setpriority(l, &bsa, retval); 730 return (error) ? EPERM : 0; 731 } 732 733 int 734 linux32_sys_alarm(struct lwp *l, const struct linux32_sys_alarm_args *uap, register_t *retval) 735 { 736 /* { 737 syscallarg(unsigned int) secs; 738 } */ 739 struct linux_sys_alarm_args ua; 740 741 memset(&ua, 0, sizeof(ua)); 742 NETBSD32TO64_UAP(secs); 743 744 return linux_sys_alarm(l, &ua, retval); 745 } 746 747 int 748 linux32_sys_fdatasync(struct lwp *l, const struct linux32_sys_fdatasync_args *uap, register_t *retval) 749 { 750 /* { 751 syscallarg(int) fd; 752 } */ 753 struct linux_sys_fdatasync_args ua; 754 755 memset(&ua, 0, sizeof(ua)); 756 NETBSD32TO64_UAP(fd); 757 758 return linux_sys_fdatasync(l, &ua, retval); 759 } 760 761 int 762 linux32_sys_setfsuid(struct lwp *l, const struct linux32_sys_setfsuid_args *uap, register_t *retval) 763 { 764 /* { 765 syscallarg(uid_t) uid; 766 } */ 767 struct linux_sys_setfsuid_args ua; 768 769 memset(&ua, 0, sizeof(ua)); 770 NETBSD32TO64_UAP(uid); 771 772 return linux_sys_setfsuid(l, &ua, retval); 773 } 774 775 int 776 linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval) 777 { 778 /* { 779 syscallarg(gid_t) gid; 780 } */ 781 struct linux_sys_setfsgid_args ua; 782 783 memset(&ua, 0, sizeof(ua)); 784 NETBSD32TO64_UAP(gid); 785 786 return linux_sys_setfsgid(l, &ua, retval); 787 } 788 789 /* 790 * pread(2). 791 */ 792 int 793 linux32_sys_pread(struct lwp *l, 794 const struct linux32_sys_pread_args *uap, register_t *retval) 795 { 796 /* { 797 syscallarg(int) fd; 798 syscallarg(netbsd32_voidp) buf; 799 syscallarg(netbsd32_size_t) nbyte; 800 syscallarg(netbsd32_off_t) offset; 801 } */ 802 struct sys_pread_args pra; 803 804 memset(&pra, 0, sizeof(pra)); 805 SCARG(&pra, fd) = SCARG(uap, fd); 806 SCARG(&pra, buf) = SCARG_P32(uap, buf); 807 SCARG(&pra, nbyte) = SCARG(uap, nbyte); 808 SCARG(&pra, PAD) = 0; 809 SCARG(&pra, offset) = SCARG(uap, offset); 810 811 return sys_pread(l, &pra, retval); 812 } 813 814 /* 815 * pwrite(2). 816 */ 817 int 818 linux32_sys_pwrite(struct lwp *l, 819 const struct linux32_sys_pwrite_args *uap, register_t *retval) 820 { 821 /* { 822 syscallarg(int) fd; 823 syscallarg(const netbsd32_voidp) buf; 824 syscallarg(netbsd32_size_t) nbyte; 825 syscallarg(netbsd32_off_t) offset; 826 } */ 827 struct sys_pwrite_args pra; 828 829 memset(&pra, 0, sizeof(pra)); 830 SCARG(&pra, fd) = SCARG(uap, fd); 831 SCARG(&pra, buf) = SCARG_P32(uap, buf); 832 SCARG(&pra, nbyte) = SCARG(uap, nbyte); 833 SCARG(&pra, PAD) = 0; 834 SCARG(&pra, offset) = SCARG(uap, offset); 835 836 return sys_pwrite(l, &pra, retval); 837 } 838 839 /* 840 * fallocate(2) 841 */ 842 int 843 linux32_sys_fallocate(struct lwp *l, 844 const struct linux32_sys_fallocate_args *uap, register_t *retval) 845 { 846 /* 847 * For now just return EOPNOTSUPP, this makes glibc posix_fallocate() 848 * to fallback to emulation. 849 * XXX Right now no filesystem actually implements fallocate support, 850 * so no need for mapping. 851 */ 852 return EOPNOTSUPP; 853 } 854