Home | History | Annotate | Line # | Download | only in common
      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, &lts, sizeof(lts));
    266 		if (error != 0)
    267 			return (error);
    268 		linux32_to_native_timespec(&uts, &lts);
    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(&lts, &uts);
    300 		error = copyout(&lts, 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), &lts, sizeof(lts));
    512 		if (error != 0)
    513 			return error;
    514 		linux32_to_native_timespec(&ts[0], &lts[0]);
    515 		linux32_to_native_timespec(&ts[1], &lts[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