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
linux32_sys_brk(struct lwp * l,const struct linux32_sys_brk_args * uap,register_t * retval)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
linux32_sys_llseek(struct lwp * l,const struct linux32_sys_llseek_args * uap,register_t * retval)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
linux32_sys_select(struct lwp * l,const struct linux32_sys_select_args * uap,register_t * retval)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
linux32_sys_oldselect(struct lwp * l,const struct linux32_sys_oldselect_args * uap,register_t * retval)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
linux32_select1(struct lwp * l,register_t * retval,int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout)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
linux32_sys_pselect6(struct lwp * l,const struct linux32_sys_pselect6_args * uap,register_t * retval)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
linux32_sys_pipe(struct lwp * l,const struct linux32_sys_pipe_args * uap,register_t * retval)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
linux32_sys_pipe2(struct lwp * l,const struct linux32_sys_pipe2_args * uap,register_t * retval)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
linux32_sys_dup3(struct lwp * l,const struct linux32_sys_dup3_args * uap,register_t * retval)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
linux32_sys_openat(struct lwp * l,const struct linux32_sys_openat_args * uap,register_t * retval)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
linux32_sys_mknodat(struct lwp * l,const struct linux32_sys_mknodat_args * uap,register_t * retval)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
linux32_sys_linkat(struct lwp * l,const struct linux32_sys_linkat_args * uap,register_t * retval)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
linux32_sys_unlink(struct lwp * l,const struct linux32_sys_unlink_args * uap,register_t * retval)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
linux32_sys_unlinkat(struct lwp * l,const struct linux32_sys_unlinkat_args * uap,register_t * retval)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
linux32_sys_fchmodat(struct lwp * l,const struct linux32_sys_fchmodat_args * uap,register_t * retval)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
linux32_sys_fchownat(struct lwp * l,const struct linux32_sys_fchownat_args * uap,register_t * retval)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
linux32_sys_faccessat(struct lwp * l,const struct linux32_sys_faccessat_args * uap,register_t * retval)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
linux32_sys_utimensat(struct lwp * l,const struct linux32_sys_utimensat_args * uap,register_t * retval)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
linux32_sys_creat(struct lwp * l,const struct linux32_sys_creat_args * uap,register_t * retval)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
linux32_sys_mknod(struct lwp * l,const struct linux32_sys_mknod_args * uap,register_t * retval)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
linux32_sys_break(struct lwp * l,const struct linux32_sys_break_args * uap,register_t * retval)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
linux32_sys_swapon(struct lwp * l,const struct linux32_sys_swapon_args * uap,register_t * retval)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
linux32_sys_swapoff(struct lwp * l,const struct linux32_sys_swapoff_args * uap,register_t * retval)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
linux32_sys_reboot(struct lwp * l,const struct linux32_sys_reboot_args * uap,register_t * retval)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
linux32_sys_setresuid(struct lwp * l,const struct linux32_sys_setresuid_args * uap,register_t * retval)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
linux32_sys_getresuid(struct lwp * l,const struct linux32_sys_getresuid_args * uap,register_t * retval)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
linux32_sys_setresgid(struct lwp * l,const struct linux32_sys_setresgid_args * uap,register_t * retval)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
linux32_sys_getresgid(struct lwp * l,const struct linux32_sys_getresgid_args * uap,register_t * retval)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
linux32_sys_nice(struct lwp * l,const struct linux32_sys_nice_args * uap,register_t * retval)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
linux32_sys_alarm(struct lwp * l,const struct linux32_sys_alarm_args * uap,register_t * retval)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
linux32_sys_fdatasync(struct lwp * l,const struct linux32_sys_fdatasync_args * uap,register_t * retval)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
linux32_sys_setfsuid(struct lwp * l,const struct linux32_sys_setfsuid_args * uap,register_t * retval)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
linux32_sys_setfsgid(struct lwp * l,const struct linux32_sys_setfsgid_args * uap,register_t * retval)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
linux32_sys_pread(struct lwp * l,const struct linux32_sys_pread_args * uap,register_t * retval)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
linux32_sys_pwrite(struct lwp * l,const struct linux32_sys_pwrite_args * uap,register_t * retval)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
linux32_sys_fallocate(struct lwp * l,const struct linux32_sys_fallocate_args * uap,register_t * retval)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