Bug Summary

File:compat/freebsd32/freebsd32_misc.c
Warning:line 2199, column 11
Copies out a struct with untouched element(s): ,

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-freebsd11.2 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name freebsd32_misc.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model static -mthread-model posix -mdisable-fp-elim -relaxed-aliasing -masm-verbose -mconstructor-aliases -ffreestanding -mcode-model kernel -target-cpu x86-64 -target-feature -mmx -target-feature -sse -target-feature -aes -target-feature -avx -disable-red-zone -no-implicit-float -dwarf-column-info -debugger-tuning=gdb -nostdsysteminc -nobuiltininc -resource-dir /root/kernel-uninitialized-memory-checker/build/lib/clang/8.0.0 -include opt_global.h -I . -I /root/freebsd/sys -I /root/freebsd/sys/contrib/ck/include -I /root/freebsd/sys/contrib/libfdt -D _KERNEL -D HAVE_KERNEL_OPTION_HEADERS -D __printf__=__freebsd_kprintf__ -O2 -Wno-pointer-sign -Wno-unknown-pragmas -Wno-error-tautological-compare -Wno-error-empty-body -Wno-error-parentheses-equality -Wno-error-unused-function -Wno-error-pointer-sign -Wno-error-shift-negative-value -Wno-address-of-packed-member -std=iso9899:1999 -fdebug-compilation-dir /usr/obj/root/freebsd/amd64.amd64/sys/GENERIC -ferror-limit 19 -fmessage-length 0 -fwrapv -stack-protector 1 -fobjc-runtime=gnustep -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker alpha.security.KernelMemoryDisclosure -analyzer-disable-checker core,unix,deadcode,nullability -analyzer-output=html -o /root/analyzer/2018-12-28-044519-76292-1 -x c /root/freebsd/sys/compat/freebsd32/freebsd32_misc.c -faddrsig
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2002 Doug Rabson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD$")__asm__(".ident\t\"" "$FreeBSD$" "\"");
31
32#include "opt_inet.h"
33#include "opt_inet6.h"
34#include "opt_ktrace.h"
35
36#define __ELF_WORD_SIZE32 32
37
38#ifdef COMPAT_FREEBSD111
39#define _WANT_FREEBSD11_KEVENT
40#endif
41
42#include <sys/param.h>
43#include <sys/bus.h>
44#include <sys/capsicum.h>
45#include <sys/clock.h>
46#include <sys/exec.h>
47#include <sys/fcntl.h>
48#include <sys/filedesc.h>
49#include <sys/imgact.h>
50#include <sys/jail.h>
51#include <sys/kernel.h>
52#include <sys/limits.h>
53#include <sys/linker.h>
54#include <sys/lock.h>
55#include <sys/malloc.h>
56#include <sys/file.h> /* Must come after sys/malloc.h */
57#include <sys/imgact.h>
58#include <sys/mbuf.h>
59#include <sys/mman.h>
60#include <sys/module.h>
61#include <sys/mount.h>
62#include <sys/mutex.h>
63#include <sys/namei.h>
64#include <sys/proc.h>
65#include <sys/procctl.h>
66#include <sys/reboot.h>
67#include <sys/resource.h>
68#include <sys/resourcevar.h>
69#include <sys/selinfo.h>
70#include <sys/eventvar.h> /* Must come after sys/selinfo.h */
71#include <sys/pipe.h> /* Must come after sys/selinfo.h */
72#include <sys/signal.h>
73#include <sys/signalvar.h>
74#include <sys/socket.h>
75#include <sys/socketvar.h>
76#include <sys/stat.h>
77#include <sys/syscall.h>
78#include <sys/syscallsubr.h>
79#include <sys/sysctl.h>
80#include <sys/sysent.h>
81#include <sys/sysproto.h>
82#include <sys/systm.h>
83#include <sys/thr.h>
84#include <sys/unistd.h>
85#include <sys/ucontext.h>
86#include <sys/vnode.h>
87#include <sys/wait.h>
88#include <sys/ipc.h>
89#include <sys/msg.h>
90#include <sys/sem.h>
91#include <sys/shm.h>
92#ifdef KTRACE1
93#include <sys/ktrace.h>
94#endif
95
96#ifdef INET1
97#include <netinet/in.h>
98#endif
99
100#include <vm/vm.h>
101#include <vm/vm_param.h>
102#include <vm/pmap.h>
103#include <vm/vm_map.h>
104#include <vm/vm_object.h>
105#include <vm/vm_extern.h>
106
107#include <machine/cpu.h>
108#include <machine/elf.h>
109
110#include <security/audit/audit.h>
111
112#include <compat/freebsd32/freebsd32_util.h>
113#include <compat/freebsd32/freebsd32.h>
114#include <compat/freebsd32/freebsd32_ipc.h>
115#include <compat/freebsd32/freebsd32_misc.h>
116#include <compat/freebsd32/freebsd32_signal.h>
117#include <compat/freebsd32/freebsd32_proto.h>
118
119FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD")static struct sysctl_oid sysctl___kern_features_compat_freebsd_32bit
= { .oid_parent = ((&(&sysctl___kern_features)->oid_children
)), .oid_children = { ((void *)0) }, .oid_number = ((-1)), .oid_kind
= (2 | 0x00040000 | (0x80000000 | 0x00008000)), .oid_arg1 = (
((int *)((void *)0))), .oid_arg2 = (1), .oid_name = ("compat_freebsd_32bit"
), .oid_handler = (sysctl_handle_int), .oid_fmt = ("I"), .oid_descr
= "Compatible with 32-bit FreeBSD", .oid_label = ("feature")
, }; __asm__(".globl " "__start_set_sysctl_set"); __asm__(".globl "
"__stop_set_sysctl_set"); static void const * const __set_sysctl_set_sym_sysctl___kern_features_compat_freebsd_32bit
__attribute__((__section__("set_" "sysctl_set"))) __attribute__
((__used__)) = &(sysctl___kern_features_compat_freebsd_32bit
); _Static_assert((((0x80000000 | 0x00008000) & 0xf) == 0
|| ((0x80000000 | 0x00008000) & 0) == 2) && sizeof
(int) == sizeof(*(((int *)((void *)0)))), "compile-time assertion failed"
)
;
120
121#ifdef __amd64__1
122CTASSERT(sizeof(struct timeval32) == 8)_Static_assert(sizeof(struct timeval32) == 8, "compile-time assertion failed"
)
;
123CTASSERT(sizeof(struct timespec32) == 8)_Static_assert(sizeof(struct timespec32) == 8, "compile-time assertion failed"
)
;
124CTASSERT(sizeof(struct itimerval32) == 16)_Static_assert(sizeof(struct itimerval32) == 16, "compile-time assertion failed"
)
;
125CTASSERT(sizeof(struct bintime32) == 12)_Static_assert(sizeof(struct bintime32) == 12, "compile-time assertion failed"
)
;
126#endif
127CTASSERT(sizeof(struct statfs32) == 256)_Static_assert(sizeof(struct statfs32) == 256, "compile-time assertion failed"
)
;
128#ifdef __amd64__1
129CTASSERT(sizeof(struct rusage32) == 72)_Static_assert(sizeof(struct rusage32) == 72, "compile-time assertion failed"
)
;
130#endif
131CTASSERT(sizeof(struct sigaltstack32) == 12)_Static_assert(sizeof(struct sigaltstack32) == 12, "compile-time assertion failed"
)
;
132#ifdef __amd64__1
133CTASSERT(sizeof(struct kevent32) == 56)_Static_assert(sizeof(struct kevent32) == 56, "compile-time assertion failed"
)
;
134#else
135CTASSERT(sizeof(struct kevent32) == 64)_Static_assert(sizeof(struct kevent32) == 64, "compile-time assertion failed"
)
;
136#endif
137CTASSERT(sizeof(struct iovec32) == 8)_Static_assert(sizeof(struct iovec32) == 8, "compile-time assertion failed"
)
;
138CTASSERT(sizeof(struct msghdr32) == 28)_Static_assert(sizeof(struct msghdr32) == 28, "compile-time assertion failed"
)
;
139#ifdef __amd64__1
140CTASSERT(sizeof(struct stat32) == 208)_Static_assert(sizeof(struct stat32) == 208, "compile-time assertion failed"
)
;
141CTASSERT(sizeof(struct freebsd11_stat32) == 96)_Static_assert(sizeof(struct freebsd11_stat32) == 96, "compile-time assertion failed"
)
;
142#endif
143CTASSERT(sizeof(struct sigaction32) == 24)_Static_assert(sizeof(struct sigaction32) == 24, "compile-time assertion failed"
)
;
144
145static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
146static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
147static int freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
148 int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp);
149
150void
151freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32)
152{
153
154 TV_CP(*s, *s32, ru_utime)do { do { ((*s32).ru_utime).tv_sec = ((*s).ru_utime).tv_sec; }
while (0); do { ((*s32).ru_utime).tv_usec = ((*s).ru_utime).
tv_usec; } while (0); } while (0)
;
155 TV_CP(*s, *s32, ru_stime)do { do { ((*s32).ru_stime).tv_sec = ((*s).ru_stime).tv_sec; }
while (0); do { ((*s32).ru_stime).tv_usec = ((*s).ru_stime).
tv_usec; } while (0); } while (0)
;
156 CP(*s, *s32, ru_maxrss)do { (*s32).ru_maxrss = (*s).ru_maxrss; } while (0);
157 CP(*s, *s32, ru_ixrss)do { (*s32).ru_ixrss = (*s).ru_ixrss; } while (0);
158 CP(*s, *s32, ru_idrss)do { (*s32).ru_idrss = (*s).ru_idrss; } while (0);
159 CP(*s, *s32, ru_isrss)do { (*s32).ru_isrss = (*s).ru_isrss; } while (0);
160 CP(*s, *s32, ru_minflt)do { (*s32).ru_minflt = (*s).ru_minflt; } while (0);
161 CP(*s, *s32, ru_majflt)do { (*s32).ru_majflt = (*s).ru_majflt; } while (0);
162 CP(*s, *s32, ru_nswap)do { (*s32).ru_nswap = (*s).ru_nswap; } while (0);
163 CP(*s, *s32, ru_inblock)do { (*s32).ru_inblock = (*s).ru_inblock; } while (0);
164 CP(*s, *s32, ru_oublock)do { (*s32).ru_oublock = (*s).ru_oublock; } while (0);
165 CP(*s, *s32, ru_msgsnd)do { (*s32).ru_msgsnd = (*s).ru_msgsnd; } while (0);
166 CP(*s, *s32, ru_msgrcv)do { (*s32).ru_msgrcv = (*s).ru_msgrcv; } while (0);
167 CP(*s, *s32, ru_nsignals)do { (*s32).ru_nsignals = (*s).ru_nsignals; } while (0);
168 CP(*s, *s32, ru_nvcsw)do { (*s32).ru_nvcsw = (*s).ru_nvcsw; } while (0);
169 CP(*s, *s32, ru_nivcsw)do { (*s32).ru_nivcsw = (*s).ru_nivcsw; } while (0);
170}
171
172int
173freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
174{
175 int error, status;
176 struct rusage32 ru32;
177 struct rusage ru, *rup;
178
179 if (uap->rusage != NULL((void *)0))
180 rup = &ru;
181 else
182 rup = NULL((void *)0);
183 error = kern_wait(td, uap->pid, &status, uap->options, rup);
184 if (error)
185 return (error);
186 if (uap->status != NULL((void *)0))
187 error = copyout(&status, uap->status, sizeof(status));
188 if (uap->rusage != NULL((void *)0) && error == 0) {
189 freebsd32_rusage_out(&ru, &ru32);
190 error = copyout(&ru32, uap->rusage, sizeof(ru32));
191 }
192 return (error);
193}
194
195int
196freebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap)
197{
198 struct wrusage32 wru32;
199 struct __wrusage wru, *wrup;
200 struct siginfo32 si32;
201 struct __siginfo si, *sip;
202 int error, status;
203
204 if (uap->wrusage != NULL((void *)0))
205 wrup = &wru;
206 else
207 wrup = NULL((void *)0);
208 if (uap->info != NULL((void *)0)) {
209 sip = &si;
210 bzero(sip, sizeof(*sip))__builtin_memset((sip), 0, (sizeof(*sip)));
211 } else
212 sip = NULL((void *)0);
213 error = kern_wait6(td, uap->idtype, PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)),
214 &status, uap->options, wrup, sip);
215 if (error != 0)
216 return (error);
217 if (uap->status != NULL((void *)0))
218 error = copyout(&status, uap->status, sizeof(status));
219 if (uap->wrusage != NULL((void *)0) && error == 0) {
220 freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self);
221 freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children);
222 error = copyout(&wru32, uap->wrusage, sizeof(wru32));
223 }
224 if (uap->info != NULL((void *)0) && error == 0) {
225 siginfo_to_siginfo32 (&si, &si32);
226 error = copyout(&si32, uap->info, sizeof(si32));
227 }
228 return (error);
229}
230
231#ifdef COMPAT_FREEBSD41
232static void
233copy_statfs(struct statfs *in, struct statfs32 *out)
234{
235
236 statfs_scale_blocks(in, INT32_MAX0x7fffffff);
237 bzero(out, sizeof(*out))__builtin_memset((out), 0, (sizeof(*out)));
238 CP(*in, *out, f_bsize)do { (*out).f_bsize = (*in).f_bsize; } while (0);
239 out->f_iosize = MIN(in->f_iosize, INT32_MAX)(((in->f_iosize)<(0x7fffffff))?(in->f_iosize):(0x7fffffff
))
;
240 CP(*in, *out, f_blocks)do { (*out).f_blocks = (*in).f_blocks; } while (0);
241 CP(*in, *out, f_bfree)do { (*out).f_bfree = (*in).f_bfree; } while (0);
242 CP(*in, *out, f_bavail)do { (*out).f_bavail = (*in).f_bavail; } while (0);
243 out->f_files = MIN(in->f_files, INT32_MAX)(((in->f_files)<(0x7fffffff))?(in->f_files):(0x7fffffff
))
;
244 out->f_ffree = MIN(in->f_ffree, INT32_MAX)(((in->f_ffree)<(0x7fffffff))?(in->f_ffree):(0x7fffffff
))
;
245 CP(*in, *out, f_fsid)do { (*out).f_fsid = (*in).f_fsid; } while (0);
246 CP(*in, *out, f_owner)do { (*out).f_owner = (*in).f_owner; } while (0);
247 CP(*in, *out, f_type)do { (*out).f_type = (*in).f_type; } while (0);
248 CP(*in, *out, f_flags)do { (*out).f_flags = (*in).f_flags; } while (0);
249 out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX)(((in->f_syncwrites)<(0x7fffffff))?(in->f_syncwrites
):(0x7fffffff))
;
250 out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX)(((in->f_asyncwrites)<(0x7fffffff))?(in->f_asyncwrites
):(0x7fffffff))
;
251 strlcpy(out->f_fstypename,
252 in->f_fstypename, MFSNAMELEN16);
253 strlcpy(out->f_mntonname,
254 in->f_mntonname, min(MNAMELEN1024, FREEBSD4_MNAMELEN(88 - 2 * sizeof(int32_t))));
255 out->f_syncreads = MIN(in->f_syncreads, INT32_MAX)(((in->f_syncreads)<(0x7fffffff))?(in->f_syncreads):
(0x7fffffff))
;
256 out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX)(((in->f_asyncreads)<(0x7fffffff))?(in->f_asyncreads
):(0x7fffffff))
;
257 strlcpy(out->f_mntfromname,
258 in->f_mntfromname, min(MNAMELEN1024, FREEBSD4_MNAMELEN(88 - 2 * sizeof(int32_t))));
259}
260#endif
261
262#ifdef COMPAT_FREEBSD41
263int
264freebsd4_freebsd32_getfsstat(struct thread *td,
265 struct freebsd4_freebsd32_getfsstat_args *uap)
266{
267 struct statfs *buf, *sp;
268 struct statfs32 stat32;
269 size_t count, size, copycount;
270 int error;
271
272 count = uap->bufsize / sizeof(struct statfs32);
273 size = count * sizeof(struct statfs);
274 error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->mode);
275 if (size > 0) {
276 sp = buf;
277 copycount = count;
278 while (copycount > 0 && error == 0) {
279 copy_statfs(sp, &stat32);
280 error = copyout(&stat32, uap->buf, sizeof(stat32));
281 sp++;
282 uap->buf++;
283 copycount--;
284 }
285 free(buf, M_STATFS);
286 }
287 if (error == 0)
288 td->td_retvaltd_uretoff.tdu_retval[0] = count;
289 return (error);
290}
291#endif
292
293#ifdef COMPAT_FREEBSD101
294int
295freebsd10_freebsd32_pipe(struct thread *td,
296 struct freebsd10_freebsd32_pipe_args *uap) {
297
298 return (freebsd10_pipe(td, (struct freebsd10_pipe_args*)uap));
299}
300#endif
301
302int
303freebsd32_sigaltstack(struct thread *td,
304 struct freebsd32_sigaltstack_args *uap)
305{
306 struct sigaltstack32 s32;
307 struct sigaltstack ss, oss, *ssp;
308 int error;
309
310 if (uap->ss != NULL((void *)0)) {
311 error = copyin(uap->ss, &s32, sizeof(s32));
312 if (error)
313 return (error);
314 PTRIN_CP(s32, ss, ss_sp)do { (ss).ss_sp = (void *)(uintptr_t) ((s32).ss_sp); } while (
0)
;
315 CP(s32, ss, ss_size)do { (ss).ss_size = (s32).ss_size; } while (0);
316 CP(s32, ss, ss_flags)do { (ss).ss_flags = (s32).ss_flags; } while (0);
317 ssp = &ss;
318 } else
319 ssp = NULL((void *)0);
320 error = kern_sigaltstack(td, ssp, &oss);
321 if (error == 0 && uap->oss != NULL((void *)0)) {
322 PTROUT_CP(oss, s32, ss_sp)do { (s32).ss_sp = (u_int32_t)(uintptr_t) ((oss).ss_sp); } while
(0)
;
323 CP(oss, s32, ss_size)do { (s32).ss_size = (oss).ss_size; } while (0);
324 CP(oss, s32, ss_flags)do { (s32).ss_flags = (oss).ss_flags; } while (0);
325 error = copyout(&s32, uap->oss, sizeof(s32));
326 }
327 return (error);
328}
329
330/*
331 * Custom version of exec_copyin_args() so that we can translate
332 * the pointers.
333 */
334int
335freebsd32_exec_copyin_args(struct image_args *args, const char *fname,
336 enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
337{
338 char *argp, *envp;
339 u_int32_t *p32, arg;
340 int error;
341
342 bzero(args, sizeof(*args))__builtin_memset((args), 0, (sizeof(*args)));
343 if (argv == NULL((void *)0))
344 return (EFAULT14);
345
346 /*
347 * Allocate demand-paged memory for the file name, argument, and
348 * environment strings.
349 */
350 error = exec_alloc_args(args);
351 if (error != 0)
352 return (error);
353
354 /*
355 * Copy the file name.
356 */
357 error = exec_args_add_fname(args, fname, segflg);
358 if (error != 0)
359 goto err_exit;
360
361 /*
362 * extract arguments first
363 */
364 p32 = argv;
365 for (;;) {
366 error = copyin(p32++, &arg, sizeof(arg));
367 if (error)
368 goto err_exit;
369 if (arg == 0)
370 break;
371 argp = PTRIN(arg)(void *)(uintptr_t) (arg);
372 error = exec_args_add_arg(args, argp, UIO_USERSPACE);
373 if (error != 0)
374 goto err_exit;
375 }
376
377 /*
378 * extract environment strings
379 */
380 if (envv) {
381 p32 = envv;
382 for (;;) {
383 error = copyin(p32++, &arg, sizeof(arg));
384 if (error)
385 goto err_exit;
386 if (arg == 0)
387 break;
388 envp = PTRIN(arg)(void *)(uintptr_t) (arg);
389 error = exec_args_add_env(args, envp, UIO_USERSPACE);
390 if (error != 0)
391 goto err_exit;
392 }
393 }
394
395 return (0);
396
397err_exit:
398 exec_free_args(args);
399 return (error);
400}
401
402int
403freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
404{
405 struct image_args eargs;
406 struct vmspace *oldvmspace;
407 int error;
408
409 error = pre_execve(td, &oldvmspace);
410 if (error != 0)
411 return (error);
412 error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
413 uap->argv, uap->envv);
414 if (error == 0)
415 error = kern_execve(td, &eargs, NULL((void *)0));
416 post_execve(td, error, oldvmspace);
417 return (error);
418}
419
420int
421freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap)
422{
423 struct image_args eargs;
424 struct vmspace *oldvmspace;
425 int error;
426
427 error = pre_execve(td, &oldvmspace);
428 if (error != 0)
429 return (error);
430 error = freebsd32_exec_copyin_args(&eargs, NULL((void *)0), UIO_SYSSPACE,
431 uap->argv, uap->envv);
432 if (error == 0) {
433 eargs.fd = uap->fd;
434 error = kern_execve(td, &eargs, NULL((void *)0));
435 }
436 post_execve(td, error, oldvmspace);
437 return (error);
438}
439
440
441int
442freebsd32_mknodat(struct thread *td, struct freebsd32_mknodat_args *uap)
443{
444
445 return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE,
446 uap->mode, PAIR32TO64(dev_t, uap->dev)((uap->dev1) | ((dev_t)(uap->dev2) << 32))));
447}
448
449int
450freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap)
451{
452 int prot;
453
454 prot = uap->prot;
455#if defined(__amd64__1)
456 if (i386_read_exec && (prot & PROT_READ0x01) != 0)
457 prot |= PROT_EXEC0x04;
458#endif
459 return (kern_mprotect(td, (uintptr_t)PTRIN(uap->addr)(void *)(uintptr_t) (uap->addr), uap->len,
460 prot));
461}
462
463int
464freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
465{
466 int prot;
467
468 prot = uap->prot;
469#if defined(__amd64__1)
470 if (i386_read_exec && (prot & PROT_READ0x01))
471 prot |= PROT_EXEC0x04;
472#endif
473
474 return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot,
475 uap->flags, uap->fd, PAIR32TO64(off_t, uap->pos)((uap->pos1) | ((off_t)(uap->pos2) << 32))));
476}
477
478#ifdef COMPAT_FREEBSD61
479int
480freebsd6_freebsd32_mmap(struct thread *td,
481 struct freebsd6_freebsd32_mmap_args *uap)
482{
483 int prot;
484
485 prot = uap->prot;
486#if defined(__amd64__1)
487 if (i386_read_exec && (prot & PROT_READ0x01))
488 prot |= PROT_EXEC0x04;
489#endif
490
491 return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot,
492 uap->flags, uap->fd, PAIR32TO64(off_t, uap->pos)((uap->pos1) | ((off_t)(uap->pos2) << 32))));
493}
494#endif
495
496int
497freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
498{
499 struct itimerval itv, oitv, *itvp;
500 struct itimerval32 i32;
501 int error;
502
503 if (uap->itv != NULL((void *)0)) {
504 error = copyin(uap->itv, &i32, sizeof(i32));
505 if (error)
506 return (error);
507 TV_CP(i32, itv, it_interval)do { do { ((itv).it_interval).tv_sec = ((i32).it_interval).tv_sec
; } while (0); do { ((itv).it_interval).tv_usec = ((i32).it_interval
).tv_usec; } while (0); } while (0)
;
508 TV_CP(i32, itv, it_value)do { do { ((itv).it_value).tv_sec = ((i32).it_value).tv_sec; }
while (0); do { ((itv).it_value).tv_usec = ((i32).it_value).
tv_usec; } while (0); } while (0)
;
509 itvp = &itv;
510 } else
511 itvp = NULL((void *)0);
512 error = kern_setitimer(td, uap->which, itvp, &oitv);
513 if (error || uap->oitv == NULL((void *)0))
514 return (error);
515 TV_CP(oitv, i32, it_interval)do { do { ((i32).it_interval).tv_sec = ((oitv).it_interval).tv_sec
; } while (0); do { ((i32).it_interval).tv_usec = ((oitv).it_interval
).tv_usec; } while (0); } while (0)
;
516 TV_CP(oitv, i32, it_value)do { do { ((i32).it_value).tv_sec = ((oitv).it_value).tv_sec;
} while (0); do { ((i32).it_value).tv_usec = ((oitv).it_value
).tv_usec; } while (0); } while (0)
;
517 return (copyout(&i32, uap->oitv, sizeof(i32)));
518}
519
520int
521freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
522{
523 struct itimerval itv;
524 struct itimerval32 i32;
525 int error;
526
527 error = kern_getitimer(td, uap->which, &itv);
528 if (error || uap->itv == NULL((void *)0))
529 return (error);
530 TV_CP(itv, i32, it_interval)do { do { ((i32).it_interval).tv_sec = ((itv).it_interval).tv_sec
; } while (0); do { ((i32).it_interval).tv_usec = ((itv).it_interval
).tv_usec; } while (0); } while (0)
;
531 TV_CP(itv, i32, it_value)do { do { ((i32).it_value).tv_sec = ((itv).it_value).tv_sec; }
while (0); do { ((i32).it_value).tv_usec = ((itv).it_value).
tv_usec; } while (0); } while (0)
;
532 return (copyout(&i32, uap->itv, sizeof(i32)));
533}
534
535int
536freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
537{
538 struct timeval32 tv32;
539 struct timeval tv, *tvp;
540 int error;
541
542 if (uap->tv != NULL((void *)0)) {
543 error = copyin(uap->tv, &tv32, sizeof(tv32));
544 if (error)
545 return (error);
546 CP(tv32, tv, tv_sec)do { (tv).tv_sec = (tv32).tv_sec; } while (0);
547 CP(tv32, tv, tv_usec)do { (tv).tv_usec = (tv32).tv_usec; } while (0);
548 tvp = &tv;
549 } else
550 tvp = NULL((void *)0);
551 /*
552 * XXX Do pointers need PTRIN()?
553 */
554 return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
555 sizeof(int32_t) * 8));
556}
557
558int
559freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
560{
561 struct timespec32 ts32;
562 struct timespec ts;
563 struct timeval tv, *tvp;
564 sigset_t set, *uset;
565 int error;
566
567 if (uap->ts != NULL((void *)0)) {
568 error = copyin(uap->ts, &ts32, sizeof(ts32));
569 if (error != 0)
570 return (error);
571 CP(ts32, ts, tv_sec)do { (ts).tv_sec = (ts32).tv_sec; } while (0);
572 CP(ts32, ts, tv_nsec)do { (ts).tv_nsec = (ts32).tv_nsec; } while (0);
573 TIMESPEC_TO_TIMEVAL(&tv, &ts)do { (&tv)->tv_sec = (&ts)->tv_sec; (&tv)->
tv_usec = (&ts)->tv_nsec / 1000; } while (0)
;
574 tvp = &tv;
575 } else
576 tvp = NULL((void *)0);
577 if (uap->sm != NULL((void *)0)) {
578 error = copyin(uap->sm, &set, sizeof(set));
579 if (error != 0)
580 return (error);
581 uset = &set;
582 } else
583 uset = NULL((void *)0);
584 /*
585 * XXX Do pointers need PTRIN()?
586 */
587 error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
588 uset, sizeof(int32_t) * 8);
589 return (error);
590}
591
592/*
593 * Copy 'count' items into the destination list pointed to by uap->eventlist.
594 */
595static int
596freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
597{
598 struct freebsd32_kevent_args *uap;
599 struct kevent32 ks32[KQ_NEVENTS8];
600 uint64_t e;
601 int i, j, error;
602
603 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count))do { if (__builtin_expect((!(count <= 8)), 0)) panic ("count (%d) > KQ_NEVENTS"
, count); } while (0)
;
604 uap = (struct freebsd32_kevent_args *)arg;
605
606 for (i = 0; i < count; i++) {
607 CP(kevp[i], ks32[i], ident)do { (ks32[i]).ident = (kevp[i]).ident; } while (0);
608 CP(kevp[i], ks32[i], filter)do { (ks32[i]).filter = (kevp[i]).filter; } while (0);
609 CP(kevp[i], ks32[i], flags)do { (ks32[i]).flags = (kevp[i]).flags; } while (0);
610 CP(kevp[i], ks32[i], fflags)do { (ks32[i]).fflags = (kevp[i]).fflags; } while (0);
611#if BYTE_ORDER1234 == LITTLE_ENDIAN1234
612 ks32[i].data1 = kevp[i].data;
613 ks32[i].data2 = kevp[i].data >> 32;
614#else
615 ks32[i].data1 = kevp[i].data >> 32;
616 ks32[i].data2 = kevp[i].data;
617#endif
618 PTROUT_CP(kevp[i], ks32[i], udata)do { (ks32[i]).udata = (u_int32_t)(uintptr_t) ((kevp[i]).udata
); } while (0)
;
619 for (j = 0; j < nitems(kevp->ext)(sizeof((kevp->ext)) / sizeof((kevp->ext)[0])); j++) {
620 e = kevp[i].ext[j];
621#if BYTE_ORDER1234 == LITTLE_ENDIAN1234
622 ks32[i].ext64[2 * j] = e;
623 ks32[i].ext64[2 * j + 1] = e >> 32;
624#else
625 ks32[i].ext64[2 * j] = e >> 32;
626 ks32[i].ext64[2 * j + 1] = e;
627#endif
628 }
629 }
630 error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
631 if (error == 0)
632 uap->eventlist += count;
633 return (error);
634}
635
636/*
637 * Copy 'count' items from the list pointed to by uap->changelist.
638 */
639static int
640freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
641{
642 struct freebsd32_kevent_args *uap;
643 struct kevent32 ks32[KQ_NEVENTS8];
644 uint64_t e;
645 int i, j, error;
646
647 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count))do { if (__builtin_expect((!(count <= 8)), 0)) panic ("count (%d) > KQ_NEVENTS"
, count); } while (0)
;
648 uap = (struct freebsd32_kevent_args *)arg;
649
650 error = copyin(uap->changelist, ks32, count * sizeof *ks32);
651 if (error)
652 goto done;
653 uap->changelist += count;
654
655 for (i = 0; i < count; i++) {
656 CP(ks32[i], kevp[i], ident)do { (kevp[i]).ident = (ks32[i]).ident; } while (0);
657 CP(ks32[i], kevp[i], filter)do { (kevp[i]).filter = (ks32[i]).filter; } while (0);
658 CP(ks32[i], kevp[i], flags)do { (kevp[i]).flags = (ks32[i]).flags; } while (0);
659 CP(ks32[i], kevp[i], fflags)do { (kevp[i]).fflags = (ks32[i]).fflags; } while (0);
660 kevp[i].data = PAIR32TO64(uint64_t, ks32[i].data)((ks32[i].data1) | ((uint64_t)(ks32[i].data2) << 32));
661 PTRIN_CP(ks32[i], kevp[i], udata)do { (kevp[i]).udata = (void *)(uintptr_t) ((ks32[i]).udata);
} while (0)
;
662 for (j = 0; j < nitems(kevp->ext)(sizeof((kevp->ext)) / sizeof((kevp->ext)[0])); j++) {
663#if BYTE_ORDER1234 == LITTLE_ENDIAN1234
664 e = ks32[i].ext64[2 * j + 1];
665 e <<= 32;
666 e += ks32[i].ext64[2 * j];
667#else
668 e = ks32[i].ext64[2 * j];
669 e <<= 32;
670 e += ks32[i].ext64[2 * j + 1];
671#endif
672 kevp[i].ext[j] = e;
673 }
674 }
675done:
676 return (error);
677}
678
679int
680freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
681{
682 struct timespec32 ts32;
683 struct timespec ts, *tsp;
684 struct kevent_copyops k_ops = {
685 .arg = uap,
686 .k_copyout = freebsd32_kevent_copyout,
687 .k_copyin = freebsd32_kevent_copyin,
688 };
689#ifdef KTRACE1
690 struct kevent32 *eventlist = uap->eventlist;
691#endif
692 int error;
693
694 if (uap->timeout) {
695 error = copyin(uap->timeout, &ts32, sizeof(ts32));
696 if (error)
697 return (error);
698 CP(ts32, ts, tv_sec)do { (ts).tv_sec = (ts32).tv_sec; } while (0);
699 CP(ts32, ts, tv_nsec)do { (ts).tv_nsec = (ts32).tv_nsec; } while (0);
700 tsp = &ts;
701 } else
702 tsp = NULL((void *)0);
703#ifdef KTRACE1
704 if (KTRPOINT(td, KTR_STRUCT_ARRAY)(__builtin_expect(((((td))->td_proc->p_traceflag & (
1 << (15)))), 0))
)
705 ktrstructarray("kevent32", UIO_USERSPACE, uap->changelist,
706 uap->nchanges, sizeof(struct kevent32));
707#endif
708 error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
709 &k_ops, tsp);
710#ifdef KTRACE1
711 if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY)(__builtin_expect(((((td))->td_proc->p_traceflag & (
1 << (15)))), 0))
)
712 ktrstructarray("kevent32", UIO_USERSPACE, eventlist,
713 td->td_retvaltd_uretoff.tdu_retval[0], sizeof(struct kevent32));
714#endif
715 return (error);
716}
717
718#ifdef COMPAT_FREEBSD111
719static int
720freebsd32_kevent11_copyout(void *arg, struct kevent *kevp, int count)
721{
722 struct freebsd11_freebsd32_kevent_args *uap;
723 struct kevent32_freebsd11 ks32[KQ_NEVENTS8];
724 int i, error;
725
726 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count))do { if (__builtin_expect((!(count <= 8)), 0)) panic ("count (%d) > KQ_NEVENTS"
, count); } while (0)
;
727 uap = (struct freebsd11_freebsd32_kevent_args *)arg;
728
729 for (i = 0; i < count; i++) {
730 CP(kevp[i], ks32[i], ident)do { (ks32[i]).ident = (kevp[i]).ident; } while (0);
731 CP(kevp[i], ks32[i], filter)do { (ks32[i]).filter = (kevp[i]).filter; } while (0);
732 CP(kevp[i], ks32[i], flags)do { (ks32[i]).flags = (kevp[i]).flags; } while (0);
733 CP(kevp[i], ks32[i], fflags)do { (ks32[i]).fflags = (kevp[i]).fflags; } while (0);
734 CP(kevp[i], ks32[i], data)do { (ks32[i]).data = (kevp[i]).data; } while (0);
735 PTROUT_CP(kevp[i], ks32[i], udata)do { (ks32[i]).udata = (u_int32_t)(uintptr_t) ((kevp[i]).udata
); } while (0)
;
736 }
737 error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
738 if (error == 0)
739 uap->eventlist += count;
740 return (error);
741}
742
743/*
744 * Copy 'count' items from the list pointed to by uap->changelist.
745 */
746static int
747freebsd32_kevent11_copyin(void *arg, struct kevent *kevp, int count)
748{
749 struct freebsd11_freebsd32_kevent_args *uap;
750 struct kevent32_freebsd11 ks32[KQ_NEVENTS8];
751 int i, j, error;
752
753 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count))do { if (__builtin_expect((!(count <= 8)), 0)) panic ("count (%d) > KQ_NEVENTS"
, count); } while (0)
;
754 uap = (struct freebsd11_freebsd32_kevent_args *)arg;
755
756 error = copyin(uap->changelist, ks32, count * sizeof *ks32);
757 if (error)
758 goto done;
759 uap->changelist += count;
760
761 for (i = 0; i < count; i++) {
762 CP(ks32[i], kevp[i], ident)do { (kevp[i]).ident = (ks32[i]).ident; } while (0);
763 CP(ks32[i], kevp[i], filter)do { (kevp[i]).filter = (ks32[i]).filter; } while (0);
764 CP(ks32[i], kevp[i], flags)do { (kevp[i]).flags = (ks32[i]).flags; } while (0);
765 CP(ks32[i], kevp[i], fflags)do { (kevp[i]).fflags = (ks32[i]).fflags; } while (0);
766 CP(ks32[i], kevp[i], data)do { (kevp[i]).data = (ks32[i]).data; } while (0);
767 PTRIN_CP(ks32[i], kevp[i], udata)do { (kevp[i]).udata = (void *)(uintptr_t) ((ks32[i]).udata);
} while (0)
;
768 for (j = 0; j < nitems(kevp->ext)(sizeof((kevp->ext)) / sizeof((kevp->ext)[0])); j++)
769 kevp[i].ext[j] = 0;
770 }
771done:
772 return (error);
773}
774
775int
776freebsd11_freebsd32_kevent(struct thread *td,
777 struct freebsd11_freebsd32_kevent_args *uap)
778{
779 struct timespec32 ts32;
780 struct timespec ts, *tsp;
781 struct kevent_copyops k_ops = {
782 .arg = uap,
783 .k_copyout = freebsd32_kevent11_copyout,
784 .k_copyin = freebsd32_kevent11_copyin,
785 };
786#ifdef KTRACE1
787 struct kevent32_freebsd11 *eventlist = uap->eventlist;
788#endif
789 int error;
790
791 if (uap->timeout) {
792 error = copyin(uap->timeout, &ts32, sizeof(ts32));
793 if (error)
794 return (error);
795 CP(ts32, ts, tv_sec)do { (ts).tv_sec = (ts32).tv_sec; } while (0);
796 CP(ts32, ts, tv_nsec)do { (ts).tv_nsec = (ts32).tv_nsec; } while (0);
797 tsp = &ts;
798 } else
799 tsp = NULL((void *)0);
800#ifdef KTRACE1
801 if (KTRPOINT(td, KTR_STRUCT_ARRAY)(__builtin_expect(((((td))->td_proc->p_traceflag & (
1 << (15)))), 0))
)
802 ktrstructarray("kevent32_freebsd11", UIO_USERSPACE,
803 uap->changelist, uap->nchanges,
804 sizeof(struct kevent32_freebsd11));
805#endif
806 error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
807 &k_ops, tsp);
808#ifdef KTRACE1
809 if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY)(__builtin_expect(((((td))->td_proc->p_traceflag & (
1 << (15)))), 0))
)
810 ktrstructarray("kevent32_freebsd11", UIO_USERSPACE,
811 eventlist, td->td_retvaltd_uretoff.tdu_retval[0],
812 sizeof(struct kevent32_freebsd11));
813#endif
814 return (error);
815}
816#endif
817
818int
819freebsd32_gettimeofday(struct thread *td,
820 struct freebsd32_gettimeofday_args *uap)
821{
822 struct timeval atv;
823 struct timeval32 atv32;
824 struct timezone rtz;
825 int error = 0;
826
827 if (uap->tp) {
828 microtime(&atv);
829 CP(atv, atv32, tv_sec)do { (atv32).tv_sec = (atv).tv_sec; } while (0);
830 CP(atv, atv32, tv_usec)do { (atv32).tv_usec = (atv).tv_usec; } while (0);
831 error = copyout(&atv32, uap->tp, sizeof (atv32));
832 }
833 if (error == 0 && uap->tzp != NULL((void *)0)) {
834 rtz.tz_minuteswest = tz_minuteswest;
835 rtz.tz_dsttime = tz_dsttime;
836 error = copyout(&rtz, uap->tzp, sizeof (rtz));
837 }
838 return (error);
839}
840
841int
842freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
843{
844 struct rusage32 s32;
845 struct rusage s;
846 int error;
847
848 error = kern_getrusage(td, uap->who, &s);
849 if (error == 0) {
850 freebsd32_rusage_out(&s, &s32);
851 error = copyout(&s32, uap->rusage, sizeof(s32));
852 }
853 return (error);
854}
855
856static int
857freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
858{
859 struct iovec32 iov32;
860 struct iovec *iov;
861 struct uio *uio;
862 u_int iovlen;
863 int error, i;
864
865 *uiop = NULL((void *)0);
866 if (iovcnt > UIO_MAXIOV1024)
867 return (EINVAL22);
868 iovlen = iovcnt * sizeof(struct iovec);
869 uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK0x0002);
870 iov = (struct iovec *)(uio + 1);
871 for (i = 0; i < iovcnt; i++) {
872 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
873 if (error) {
874 free(uio, M_IOV);
875 return (error);
876 }
877 iov[i].iov_base = PTRIN(iov32.iov_base)(void *)(uintptr_t) (iov32.iov_base);
878 iov[i].iov_len = iov32.iov_len;
879 }
880 uio->uio_iov = iov;
881 uio->uio_iovcnt = iovcnt;
882 uio->uio_segflg = UIO_USERSPACE;
883 uio->uio_offset = -1;
884 uio->uio_resid = 0;
885 for (i = 0; i < iovcnt; i++) {
886 if (iov->iov_len > INT_MAX0x7fffffff - uio->uio_resid) {
887 free(uio, M_IOV);
888 return (EINVAL22);
889 }
890 uio->uio_resid += iov->iov_len;
891 iov++;
892 }
893 *uiop = uio;
894 return (0);
895}
896
897int
898freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
899{
900 struct uio *auio;
901 int error;
902
903 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
904 if (error)
905 return (error);
906 error = kern_readv(td, uap->fd, auio);
907 free(auio, M_IOV);
908 return (error);
909}
910
911int
912freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
913{
914 struct uio *auio;
915 int error;
916
917 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
918 if (error)
919 return (error);
920 error = kern_writev(td, uap->fd, auio);
921 free(auio, M_IOV);
922 return (error);
923}
924
925int
926freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
927{
928 struct uio *auio;
929 int error;
930
931 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
932 if (error)
933 return (error);
934 error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)));
935 free(auio, M_IOV);
936 return (error);
937}
938
939int
940freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
941{
942 struct uio *auio;
943 int error;
944
945 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
946 if (error)
947 return (error);
948 error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)));
949 free(auio, M_IOV);
950 return (error);
951}
952
953int
954freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
955 int error)
956{
957 struct iovec32 iov32;
958 struct iovec *iov;
959 u_int iovlen;
960 int i;
961
962 *iovp = NULL((void *)0);
963 if (iovcnt > UIO_MAXIOV1024)
964 return (error);
965 iovlen = iovcnt * sizeof(struct iovec);
966 iov = malloc(iovlen, M_IOV, M_WAITOK0x0002);
967 for (i = 0; i < iovcnt; i++) {
968 error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
969 if (error) {
970 free(iov, M_IOV);
971 return (error);
972 }
973 iov[i].iov_base = PTRIN(iov32.iov_base)(void *)(uintptr_t) (iov32.iov_base);
974 iov[i].iov_len = iov32.iov_len;
975 }
976 *iovp = iov;
977 return (0);
978}
979
980static int
981freebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
982{
983 struct msghdr32 m32;
984 int error;
985
986 error = copyin(msg32, &m32, sizeof(m32));
987 if (error)
988 return (error);
989 msg->msg_name = PTRIN(m32.msg_name)(void *)(uintptr_t) (m32.msg_name);
990 msg->msg_namelen = m32.msg_namelen;
991 msg->msg_iov = PTRIN(m32.msg_iov)(void *)(uintptr_t) (m32.msg_iov);
992 msg->msg_iovlen = m32.msg_iovlen;
993 msg->msg_control = PTRIN(m32.msg_control)(void *)(uintptr_t) (m32.msg_control);
994 msg->msg_controllen = m32.msg_controllen;
995 msg->msg_flags = m32.msg_flags;
996 return (0);
997}
998
999static int
1000freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
1001{
1002 struct msghdr32 m32;
1003 int error;
1004
1005 m32.msg_name = PTROUT(msg->msg_name)(u_int32_t)(uintptr_t) (msg->msg_name);
1006 m32.msg_namelen = msg->msg_namelen;
1007 m32.msg_iov = PTROUT(msg->msg_iov)(u_int32_t)(uintptr_t) (msg->msg_iov);
1008 m32.msg_iovlen = msg->msg_iovlen;
1009 m32.msg_control = PTROUT(msg->msg_control)(u_int32_t)(uintptr_t) (msg->msg_control);
1010 m32.msg_controllen = msg->msg_controllen;
1011 m32.msg_flags = msg->msg_flags;
1012 error = copyout(&m32, msg32, sizeof(m32));
1013 return (error);
1014}
1015
1016#ifndef __mips__
1017#define FREEBSD32_ALIGNBYTES(sizeof(int) - 1) (sizeof(int) - 1)
1018#else
1019#define FREEBSD32_ALIGNBYTES(sizeof(int) - 1) (sizeof(long) - 1)
1020#endif
1021#define FREEBSD32_ALIGN(p)(((u_long)(p) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) \
1022 (((u_long)(p) + FREEBSD32_ALIGNBYTES(sizeof(int) - 1)) & ~FREEBSD32_ALIGNBYTES(sizeof(int) - 1))
1023#define FREEBSD32_CMSG_SPACE(l)((((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1)) + (((u_long)(l) + (sizeof(int) - 1)) &
~(sizeof(int) - 1)))
\
1024 (FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1))
+ FREEBSD32_ALIGN(l)(((u_long)(l) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)))
1025
1026#define FREEBSD32_CMSG_DATA(cmsg)((unsigned char *)(cmsg) + (((u_long)(sizeof(struct cmsghdr))
+ (sizeof(int) - 1)) & ~(sizeof(int) - 1)))
((unsigned char *)(cmsg) + \
1027 FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1))
)
1028
1029static size_t
1030freebsd32_cmsg_convert(const struct cmsghdr *cm, void *data, socklen_t datalen)
1031{
1032 size_t copylen;
1033 union {
1034 struct timespec32 ts;
1035 struct timeval32 tv;
1036 struct bintime32 bt;
1037 } tmp32;
1038
1039 union {
1040 struct timespec ts;
1041 struct timeval tv;
1042 struct bintime bt;
1043 } *in;
1044
1045 in = data;
1046 copylen = 0;
1047 switch (cm->cmsg_level) {
1048 case SOL_SOCKET0xffff:
1049 switch (cm->cmsg_type) {
1050 case SCM_TIMESTAMP0x02:
1051 TV_CP(*in, tmp32, tv)do { do { ((tmp32).tv).tv_sec = ((*in).tv).tv_sec; } while (0
); do { ((tmp32).tv).tv_usec = ((*in).tv).tv_usec; } while (0
); } while (0)
;
1052 copylen = sizeof(tmp32.tv);
1053 break;
1054
1055 case SCM_BINTIME0x04:
1056 BT_CP(*in, tmp32, bt)do { do { ((tmp32).bt).sec = ((*in).bt).sec; } while (0); *(uint64_t
*)&(tmp32).bt.frac[0] = (*in).bt.frac; } while (0)
;
1057 copylen = sizeof(tmp32.bt);
1058 break;
1059
1060 case SCM_REALTIME0x05:
1061 case SCM_MONOTONIC0x06:
1062 TS_CP(*in, tmp32, ts)do { do { ((tmp32).ts).tv_sec = ((*in).ts).tv_sec; } while (0
); do { ((tmp32).ts).tv_nsec = ((*in).ts).tv_nsec; } while (0
); } while (0)
;
1063 copylen = sizeof(tmp32.ts);
1064 break;
1065
1066 default:
1067 break;
1068 }
1069
1070 default:
1071 break;
1072 }
1073
1074 if (copylen == 0)
1075 return (datalen);
1076
1077 KASSERT((datalen >= copylen), ("corrupted cmsghdr"))do { if (__builtin_expect((!((datalen >= copylen))), 0)) panic
("corrupted cmsghdr"); } while (0)
;
1078
1079 bcopy(&tmp32, data, copylen)__builtin_memmove((data), (&tmp32), (copylen));
1080 return (copylen);
1081}
1082
1083static int
1084freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
1085{
1086 struct cmsghdr *cm;
1087 void *data;
1088 socklen_t clen, datalen, datalen_out, oldclen;
1089 int error;
1090 caddr_t ctlbuf;
1091 int len, maxlen, copylen;
1092 struct mbuf *m;
1093 error = 0;
1094
1095 len = msg->msg_controllen;
1096 maxlen = msg->msg_controllen;
1097 msg->msg_controllen = 0;
1098
1099 ctlbuf = msg->msg_control;
1100 for (m = control; m != NULL((void *)0) && len > 0; m = m->m_next) {
1101 cm = mtod(m, struct cmsghdr *)((struct cmsghdr *)((m)->m_data));
1102 clen = m->m_len;
1103 while (cm != NULL((void *)0)) {
1104 if (sizeof(struct cmsghdr) > clen ||
1105 cm->cmsg_len > clen) {
1106 error = EINVAL22;
1107 break;
1108 }
1109
1110 data = CMSG_DATA(cm)((unsigned char *)(cm) + (((__uintptr_t)(sizeof(struct cmsghdr
)) + (sizeof(__register_t) - 1)) & ~(sizeof(__register_t)
- 1)))
;
1111 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1112 datalen_out = freebsd32_cmsg_convert(cm, data, datalen);
1113
1114 /*
1115 * Copy out the message header. Preserve the native
1116 * message size in case we need to inspect the message
1117 * contents later.
1118 */
1119 copylen = sizeof(struct cmsghdr);
1120 if (len < copylen) {
1121 msg->msg_flags |= MSG_CTRUNC0x00000020;
1122 m_dispose_extcontrolm(m);
1123 goto exit;
1124 }
1125 oldclen = cm->cmsg_len;
1126 cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1))
+
1127 datalen_out;
1128 error = copyout(cm, ctlbuf, copylen);
1129 cm->cmsg_len = oldclen;
1130 if (error != 0)
1131 goto exit;
1132
1133 ctlbuf += FREEBSD32_ALIGN(copylen)(((u_long)(copylen) + (sizeof(int) - 1)) & ~(sizeof(int) -
1))
;
1134 len -= FREEBSD32_ALIGN(copylen)(((u_long)(copylen) + (sizeof(int) - 1)) & ~(sizeof(int) -
1))
;
1135
1136 copylen = datalen_out;
1137 if (len < copylen) {
1138 msg->msg_flags |= MSG_CTRUNC0x00000020;
1139 m_dispose_extcontrolm(m);
1140 break;
1141 }
1142
1143 /* Copy out the message data. */
1144 error = copyout(data, ctlbuf, copylen);
1145 if (error)
1146 goto exit;
1147
1148 ctlbuf += FREEBSD32_ALIGN(copylen)(((u_long)(copylen) + (sizeof(int) - 1)) & ~(sizeof(int) -
1))
;
1149 len -= FREEBSD32_ALIGN(copylen)(((u_long)(copylen) + (sizeof(int) - 1)) & ~(sizeof(int) -
1))
;
1150
1151 if (CMSG_SPACE(datalen)((((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t
) - 1)) & ~(sizeof(__register_t) - 1)) + (((__uintptr_t)(
datalen) + (sizeof(__register_t) - 1)) & ~(sizeof(__register_t
) - 1)))
< clen) {
1152 clen -= CMSG_SPACE(datalen)((((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t
) - 1)) & ~(sizeof(__register_t) - 1)) + (((__uintptr_t)(
datalen) + (sizeof(__register_t) - 1)) & ~(sizeof(__register_t
) - 1)))
;
1153 cm = (struct cmsghdr *)
1154 ((caddr_t)cm + CMSG_SPACE(datalen)((((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t
) - 1)) & ~(sizeof(__register_t) - 1)) + (((__uintptr_t)(
datalen) + (sizeof(__register_t) - 1)) & ~(sizeof(__register_t
) - 1)))
);
1155 } else {
1156 clen = 0;
1157 cm = NULL((void *)0);
1158 }
1159
1160 msg->msg_controllen += FREEBSD32_ALIGN(sizeof(*cm))(((u_long)(sizeof(*cm)) + (sizeof(int) - 1)) & ~(sizeof(int
) - 1))
+
1161 datalen_out;
1162 }
1163 }
1164 if (len == 0 && m != NULL((void *)0)) {
1165 msg->msg_flags |= MSG_CTRUNC0x00000020;
1166 m_dispose_extcontrolm(m);
1167 }
1168
1169exit:
1170 return (error);
1171}
1172
1173int
1174freebsd32_recvmsg(td, uap)
1175 struct thread *td;
1176 struct freebsd32_recvmsg_args /* {
1177 int s;
1178 struct msghdr32 *msg;
1179 int flags;
1180 } */ *uap;
1181{
1182 struct msghdr msg;
1183 struct msghdr32 m32;
1184 struct iovec *uiov, *iov;
1185 struct mbuf *control = NULL((void *)0);
1186 struct mbuf **controlp;
1187
1188 int error;
1189 error = copyin(uap->msg, &m32, sizeof(m32));
1190 if (error)
1191 return (error);
1192 error = freebsd32_copyinmsghdr(uap->msg, &msg);
1193 if (error)
1194 return (error);
1195 error = freebsd32_copyiniov(PTRIN(m32.msg_iov)(void *)(uintptr_t) (m32.msg_iov), m32.msg_iovlen, &iov,
1196 EMSGSIZE40);
1197 if (error)
1198 return (error);
1199 msg.msg_flags = uap->flags;
1200 uiov = msg.msg_iov;
1201 msg.msg_iov = iov;
1202
1203 controlp = (msg.msg_control != NULL((void *)0)) ? &control : NULL((void *)0);
1204 error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
1205 if (error == 0) {
1206 msg.msg_iov = uiov;
1207
1208 if (control != NULL((void *)0))
1209 error = freebsd32_copy_msg_out(&msg, control);
1210 else
1211 msg.msg_controllen = 0;
1212
1213 if (error == 0)
1214 error = freebsd32_copyoutmsghdr(&msg, uap->msg);
1215 }
1216 free(iov, M_IOV);
1217
1218 if (control != NULL((void *)0)) {
1219 if (error != 0)
1220 m_dispose_extcontrolm(control);
1221 m_freem(control);
1222 }
1223
1224 return (error);
1225}
1226
1227/*
1228 * Copy-in the array of control messages constructed using alignment
1229 * and padding suitable for a 32-bit environment and construct an
1230 * mbuf using alignment and padding suitable for a 64-bit kernel.
1231 * The alignment and padding are defined indirectly by CMSG_DATA(),
1232 * CMSG_SPACE() and CMSG_LEN().
1233 */
1234static int
1235freebsd32_copyin_control(struct mbuf **mp, caddr_t buf, u_int buflen)
1236{
1237 struct mbuf *m;
1238 void *md;
1239 u_int idx, len, msglen;
1240 int error;
1241
1242 buflen = FREEBSD32_ALIGN(buflen)(((u_long)(buflen) + (sizeof(int) - 1)) & ~(sizeof(int) -
1))
;
1243
1244 if (buflen > MCLBYTES(1 << 11))
1245 return (EINVAL22);
1246
1247 /*
1248 * Iterate over the buffer and get the length of each message
1249 * in there. This has 32-bit alignment and padding. Use it to
1250 * determine the length of these messages when using 64-bit
1251 * alignment and padding.
1252 */
1253 idx = 0;
1254 len = 0;
1255 while (idx < buflen) {
1256 error = copyin(buf + idx, &msglen, sizeof(msglen));
1257 if (error)
1258 return (error);
1259 if (msglen < sizeof(struct cmsghdr))
1260 return (EINVAL22);
1261 msglen = FREEBSD32_ALIGN(msglen)(((u_long)(msglen) + (sizeof(int) - 1)) & ~(sizeof(int) -
1))
;
1262 if (idx + msglen > buflen)
1263 return (EINVAL22);
1264 idx += msglen;
1265 msglen += CMSG_ALIGN(sizeof(struct cmsghdr))(((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t
) - 1)) & ~(sizeof(__register_t) - 1))
-
1266 FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1))
;
1267 len += CMSG_ALIGN(msglen)(((__uintptr_t)(msglen) + (sizeof(__register_t) - 1)) & ~
(sizeof(__register_t) - 1))
;
1268 }
1269
1270 if (len > MCLBYTES(1 << 11))
1271 return (EINVAL22);
1272
1273 m = m_get(M_WAITOK0x0002, MT_CONTROL14);
1274 if (len > MLEN((int)(256 - __builtin_offsetof(struct mbuf, m_dat))))
1275 MCLGET(m, M_WAITOK)m_clget((m), (0x0002));
1276 m->m_len = len;
1277
1278 md = mtod(m, void *)((void *)((m)->m_data));
1279 while (buflen > 0) {
1280 error = copyin(buf, md, sizeof(struct cmsghdr));
1281 if (error)
1282 break;
1283 msglen = *(u_int *)md;
1284 msglen = FREEBSD32_ALIGN(msglen)(((u_long)(msglen) + (sizeof(int) - 1)) & ~(sizeof(int) -
1))
;
1285
1286 /* Modify the message length to account for alignment. */
1287 *(u_int *)md = msglen + CMSG_ALIGN(sizeof(struct cmsghdr))(((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t
) - 1)) & ~(sizeof(__register_t) - 1))
-
1288 FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1))
;
1289
1290 md = (char *)md + CMSG_ALIGN(sizeof(struct cmsghdr))(((__uintptr_t)(sizeof(struct cmsghdr)) + (sizeof(__register_t
) - 1)) & ~(sizeof(__register_t) - 1))
;
1291 buf += FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1))
;
1292 buflen -= FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1))
;
1293
1294 msglen -= FREEBSD32_ALIGN(sizeof(struct cmsghdr))(((u_long)(sizeof(struct cmsghdr)) + (sizeof(int) - 1)) &
~(sizeof(int) - 1))
;
1295 if (msglen > 0) {
1296 error = copyin(buf, md, msglen);
1297 if (error)
1298 break;
1299 md = (char *)md + CMSG_ALIGN(msglen)(((__uintptr_t)(msglen) + (sizeof(__register_t) - 1)) & ~
(sizeof(__register_t) - 1))
;
1300 buf += msglen;
1301 buflen -= msglen;
1302 }
1303 }
1304
1305 if (error)
1306 m_free(m);
1307 else
1308 *mp = m;
1309 return (error);
1310}
1311
1312int
1313freebsd32_sendmsg(struct thread *td,
1314 struct freebsd32_sendmsg_args *uap)
1315{
1316 struct msghdr msg;
1317 struct msghdr32 m32;
1318 struct iovec *iov;
1319 struct mbuf *control = NULL((void *)0);
1320 struct sockaddr *to = NULL((void *)0);
1321 int error;
1322
1323 error = copyin(uap->msg, &m32, sizeof(m32));
1324 if (error)
1325 return (error);
1326 error = freebsd32_copyinmsghdr(uap->msg, &msg);
1327 if (error)
1328 return (error);
1329 error = freebsd32_copyiniov(PTRIN(m32.msg_iov)(void *)(uintptr_t) (m32.msg_iov), m32.msg_iovlen, &iov,
1330 EMSGSIZE40);
1331 if (error)
1332 return (error);
1333 msg.msg_iov = iov;
1334 if (msg.msg_name != NULL((void *)0)) {
1335 error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
1336 if (error) {
1337 to = NULL((void *)0);
1338 goto out;
1339 }
1340 msg.msg_name = to;
1341 }
1342
1343 if (msg.msg_control) {
1344 if (msg.msg_controllen < sizeof(struct cmsghdr)) {
1345 error = EINVAL22;
1346 goto out;
1347 }
1348
1349 error = freebsd32_copyin_control(&control, msg.msg_control,
1350 msg.msg_controllen);
1351 if (error)
1352 goto out;
1353
1354 msg.msg_control = NULL((void *)0);
1355 msg.msg_controllen = 0;
1356 }
1357
1358 error = kern_sendit(td, uap->s, &msg, uap->flags, control,
1359 UIO_USERSPACE);
1360
1361out:
1362 free(iov, M_IOV);
1363 if (to)
1364 free(to, M_SONAME);
1365 return (error);
1366}
1367
1368int
1369freebsd32_recvfrom(struct thread *td,
1370 struct freebsd32_recvfrom_args *uap)
1371{
1372 struct msghdr msg;
1373 struct iovec aiov;
1374 int error;
1375
1376 if (uap->fromlenaddr) {
1377 error = copyin(PTRIN(uap->fromlenaddr)(void *)(uintptr_t) (uap->fromlenaddr), &msg.msg_namelen,
1378 sizeof(msg.msg_namelen));
1379 if (error)
1380 return (error);
1381 } else {
1382 msg.msg_namelen = 0;
1383 }
1384
1385 msg.msg_name = PTRIN(uap->from)(void *)(uintptr_t) (uap->from);
1386 msg.msg_iov = &aiov;
1387 msg.msg_iovlen = 1;
1388 aiov.iov_base = PTRIN(uap->buf)(void *)(uintptr_t) (uap->buf);
1389 aiov.iov_len = uap->len;
1390 msg.msg_control = NULL((void *)0);
1391 msg.msg_flags = uap->flags;
1392 error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL((void *)0));
1393 if (error == 0 && uap->fromlenaddr)
1394 error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr)(void *)(uintptr_t) (uap->fromlenaddr),
1395 sizeof (msg.msg_namelen));
1396 return (error);
1397}
1398
1399int
1400freebsd32_settimeofday(struct thread *td,
1401 struct freebsd32_settimeofday_args *uap)
1402{
1403 struct timeval32 tv32;
1404 struct timeval tv, *tvp;
1405 struct timezone tz, *tzp;
1406 int error;
1407
1408 if (uap->tv) {
1409 error = copyin(uap->tv, &tv32, sizeof(tv32));
1410 if (error)
1411 return (error);
1412 CP(tv32, tv, tv_sec)do { (tv).tv_sec = (tv32).tv_sec; } while (0);
1413 CP(tv32, tv, tv_usec)do { (tv).tv_usec = (tv32).tv_usec; } while (0);
1414 tvp = &tv;
1415 } else
1416 tvp = NULL((void *)0);
1417 if (uap->tzp) {
1418 error = copyin(uap->tzp, &tz, sizeof(tz));
1419 if (error)
1420 return (error);
1421 tzp = &tz;
1422 } else
1423 tzp = NULL((void *)0);
1424 return (kern_settimeofday(td, tvp, tzp));
1425}
1426
1427int
1428freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
1429{
1430 struct timeval32 s32[2];
1431 struct timeval s[2], *sp;
1432 int error;
1433
1434 if (uap->tptr != NULL((void *)0)) {
1435 error = copyin(uap->tptr, s32, sizeof(s32));
1436 if (error)
1437 return (error);
1438 CP(s32[0], s[0], tv_sec)do { (s[0]).tv_sec = (s32[0]).tv_sec; } while (0);
1439 CP(s32[0], s[0], tv_usec)do { (s[0]).tv_usec = (s32[0]).tv_usec; } while (0);
1440 CP(s32[1], s[1], tv_sec)do { (s[1]).tv_sec = (s32[1]).tv_sec; } while (0);
1441 CP(s32[1], s[1], tv_usec)do { (s[1]).tv_usec = (s32[1]).tv_usec; } while (0);
1442 sp = s;
1443 } else
1444 sp = NULL((void *)0);
1445 return (kern_utimesat(td, AT_FDCWD-100, uap->path, UIO_USERSPACE,
1446 sp, UIO_SYSSPACE));
1447}
1448
1449int
1450freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
1451{
1452 struct timeval32 s32[2];
1453 struct timeval s[2], *sp;
1454 int error;
1455
1456 if (uap->tptr != NULL((void *)0)) {
1457 error = copyin(uap->tptr, s32, sizeof(s32));
1458 if (error)
1459 return (error);
1460 CP(s32[0], s[0], tv_sec)do { (s[0]).tv_sec = (s32[0]).tv_sec; } while (0);
1461 CP(s32[0], s[0], tv_usec)do { (s[0]).tv_usec = (s32[0]).tv_usec; } while (0);
1462 CP(s32[1], s[1], tv_sec)do { (s[1]).tv_sec = (s32[1]).tv_sec; } while (0);
1463 CP(s32[1], s[1], tv_usec)do { (s[1]).tv_usec = (s32[1]).tv_usec; } while (0);
1464 sp = s;
1465 } else
1466 sp = NULL((void *)0);
1467 return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1468}
1469
1470int
1471freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
1472{
1473 struct timeval32 s32[2];
1474 struct timeval s[2], *sp;
1475 int error;
1476
1477 if (uap->tptr != NULL((void *)0)) {
1478 error = copyin(uap->tptr, s32, sizeof(s32));
1479 if (error)
1480 return (error);
1481 CP(s32[0], s[0], tv_sec)do { (s[0]).tv_sec = (s32[0]).tv_sec; } while (0);
1482 CP(s32[0], s[0], tv_usec)do { (s[0]).tv_usec = (s32[0]).tv_usec; } while (0);
1483 CP(s32[1], s[1], tv_sec)do { (s[1]).tv_sec = (s32[1]).tv_sec; } while (0);
1484 CP(s32[1], s[1], tv_usec)do { (s[1]).tv_usec = (s32[1]).tv_usec; } while (0);
1485 sp = s;
1486 } else
1487 sp = NULL((void *)0);
1488 return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
1489}
1490
1491int
1492freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap)
1493{
1494 struct timeval32 s32[2];
1495 struct timeval s[2], *sp;
1496 int error;
1497
1498 if (uap->times != NULL((void *)0)) {
1499 error = copyin(uap->times, s32, sizeof(s32));
1500 if (error)
1501 return (error);
1502 CP(s32[0], s[0], tv_sec)do { (s[0]).tv_sec = (s32[0]).tv_sec; } while (0);
1503 CP(s32[0], s[0], tv_usec)do { (s[0]).tv_usec = (s32[0]).tv_usec; } while (0);
1504 CP(s32[1], s[1], tv_sec)do { (s[1]).tv_sec = (s32[1]).tv_sec; } while (0);
1505 CP(s32[1], s[1], tv_usec)do { (s[1]).tv_usec = (s32[1]).tv_usec; } while (0);
1506 sp = s;
1507 } else
1508 sp = NULL((void *)0);
1509 return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
1510 sp, UIO_SYSSPACE));
1511}
1512
1513int
1514freebsd32_futimens(struct thread *td, struct freebsd32_futimens_args *uap)
1515{
1516 struct timespec32 ts32[2];
1517 struct timespec ts[2], *tsp;
1518 int error;
1519
1520 if (uap->times != NULL((void *)0)) {
1521 error = copyin(uap->times, ts32, sizeof(ts32));
1522 if (error)
1523 return (error);
1524 CP(ts32[0], ts[0], tv_sec)do { (ts[0]).tv_sec = (ts32[0]).tv_sec; } while (0);
1525 CP(ts32[0], ts[0], tv_nsec)do { (ts[0]).tv_nsec = (ts32[0]).tv_nsec; } while (0);
1526 CP(ts32[1], ts[1], tv_sec)do { (ts[1]).tv_sec = (ts32[1]).tv_sec; } while (0);
1527 CP(ts32[1], ts[1], tv_nsec)do { (ts[1]).tv_nsec = (ts32[1]).tv_nsec; } while (0);
1528 tsp = ts;
1529 } else
1530 tsp = NULL((void *)0);
1531 return (kern_futimens(td, uap->fd, tsp, UIO_SYSSPACE));
1532}
1533
1534int
1535freebsd32_utimensat(struct thread *td, struct freebsd32_utimensat_args *uap)
1536{
1537 struct timespec32 ts32[2];
1538 struct timespec ts[2], *tsp;
1539 int error;
1540
1541 if (uap->times != NULL((void *)0)) {
1542 error = copyin(uap->times, ts32, sizeof(ts32));
1543 if (error)
1544 return (error);
1545 CP(ts32[0], ts[0], tv_sec)do { (ts[0]).tv_sec = (ts32[0]).tv_sec; } while (0);
1546 CP(ts32[0], ts[0], tv_nsec)do { (ts[0]).tv_nsec = (ts32[0]).tv_nsec; } while (0);
1547 CP(ts32[1], ts[1], tv_sec)do { (ts[1]).tv_sec = (ts32[1]).tv_sec; } while (0);
1548 CP(ts32[1], ts[1], tv_nsec)do { (ts[1]).tv_nsec = (ts32[1]).tv_nsec; } while (0);
1549 tsp = ts;
1550 } else
1551 tsp = NULL((void *)0);
1552 return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE,
1553 tsp, UIO_SYSSPACE, uap->flag));
1554}
1555
1556int
1557freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
1558{
1559 struct timeval32 tv32;
1560 struct timeval delta, olddelta, *deltap;
1561 int error;
1562
1563 if (uap->delta) {
1564 error = copyin(uap->delta, &tv32, sizeof(tv32));
1565 if (error)
1566 return (error);
1567 CP(tv32, delta, tv_sec)do { (delta).tv_sec = (tv32).tv_sec; } while (0);
1568 CP(tv32, delta, tv_usec)do { (delta).tv_usec = (tv32).tv_usec; } while (0);
1569 deltap = &delta;
1570 } else
1571 deltap = NULL((void *)0);
1572 error = kern_adjtime(td, deltap, &olddelta);
1573 if (uap->olddelta && error == 0) {
1574 CP(olddelta, tv32, tv_sec)do { (tv32).tv_sec = (olddelta).tv_sec; } while (0);
1575 CP(olddelta, tv32, tv_usec)do { (tv32).tv_usec = (olddelta).tv_usec; } while (0);
1576 error = copyout(&tv32, uap->olddelta, sizeof(tv32));
1577 }
1578 return (error);
1579}
1580
1581#ifdef COMPAT_FREEBSD41
1582int
1583freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
1584{
1585 struct statfs32 s32;
1586 struct statfs *sp;
1587 int error;
1588
1589 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK0x0002);
1590 error = kern_statfs(td, uap->path, UIO_USERSPACE, sp);
1591 if (error == 0) {
1592 copy_statfs(sp, &s32);
1593 error = copyout(&s32, uap->buf, sizeof(s32));
1594 }
1595 free(sp, M_STATFS);
1596 return (error);
1597}
1598#endif
1599
1600#ifdef COMPAT_FREEBSD41
1601int
1602freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
1603{
1604 struct statfs32 s32;
1605 struct statfs *sp;
1606 int error;
1607
1608 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK0x0002);
1609 error = kern_fstatfs(td, uap->fd, sp);
1610 if (error == 0) {
1611 copy_statfs(sp, &s32);
1612 error = copyout(&s32, uap->buf, sizeof(s32));
1613 }
1614 free(sp, M_STATFS);
1615 return (error);
1616}
1617#endif
1618
1619#ifdef COMPAT_FREEBSD41
1620int
1621freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
1622{
1623 struct statfs32 s32;
1624 struct statfs *sp;
1625 fhandle_t fh;
1626 int error;
1627
1628 if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
1629 return (error);
1630 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK0x0002);
1631 error = kern_fhstatfs(td, fh, sp);
1632 if (error == 0) {
1633 copy_statfs(sp, &s32);
1634 error = copyout(&s32, uap->buf, sizeof(s32));
1635 }
1636 free(sp, M_STATFS);
1637 return (error);
1638}
1639#endif
1640
1641int
1642freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
1643{
1644
1645 return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
1646 PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32))));
1647}
1648
1649int
1650freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
1651{
1652
1653 return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
1654 PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32))));
1655}
1656
1657#ifdef COMPAT_43
1658int
1659ofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap)
1660{
1661
1662 return (kern_lseek(td, uap->fd, uap->offset, uap->whence));
1663}
1664#endif
1665
1666int
1667freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1668{
1669 int error;
1670 off_t pos;
1671
1672 error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)),
1673 uap->whence);
1674 /* Expand the quad return into two parts for eax and edx */
1675 pos = td->td_uretoff.tdu_off;
1676 td->td_retvaltd_uretoff.tdu_retval[RETVAL_LO0] = pos & 0xffffffff; /* %eax */
1677 td->td_retvaltd_uretoff.tdu_retval[RETVAL_HI1] = pos >> 32; /* %edx */
1678 return error;
1679}
1680
1681int
1682freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1683{
1684
1685 return (kern_truncate(td, uap->path, UIO_USERSPACE,
1686 PAIR32TO64(off_t, uap->length)((uap->length1) | ((off_t)(uap->length2) << 32))));
1687}
1688
1689int
1690freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1691{
1692
1693 return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)((uap->length1) | ((off_t)(uap->length2) << 32))));
1694}
1695
1696#ifdef COMPAT_43
1697int
1698ofreebsd32_getdirentries(struct thread *td,
1699 struct ofreebsd32_getdirentries_args *uap)
1700{
1701 struct ogetdirentries_args ap;
1702 int error;
1703 long loff;
1704 int32_t loff_cut;
1705
1706 ap.fd = uap->fd;
1707 ap.buf = uap->buf;
1708 ap.count = uap->count;
1709 ap.basep = NULL((void *)0);
1710 error = kern_ogetdirentries(td, &ap, &loff);
1711 if (error == 0) {
1712 loff_cut = loff;
1713 error = copyout(&loff_cut, uap->basep, sizeof(int32_t));
1714 }
1715 return (error);
1716}
1717#endif
1718
1719#if defined(COMPAT_FREEBSD111)
1720int
1721freebsd11_freebsd32_getdirentries(struct thread *td,
1722 struct freebsd11_freebsd32_getdirentries_args *uap)
1723{
1724 long base;
1725 int32_t base32;
1726 int error;
1727
1728 error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
1729 &base, NULL((void *)0));
1730 if (error)
1731 return (error);
1732 if (uap->basep != NULL((void *)0)) {
1733 base32 = base;
1734 error = copyout(&base32, uap->basep, sizeof(int32_t));
1735 }
1736 return (error);
1737}
1738
1739int
1740freebsd11_freebsd32_getdents(struct thread *td,
1741 struct freebsd11_freebsd32_getdents_args *uap)
1742{
1743 struct freebsd11_freebsd32_getdirentries_args ap;
1744
1745 ap.fd = uap->fd;
1746 ap.buf = uap->buf;
1747 ap.count = uap->count;
1748 ap.basep = NULL((void *)0);
1749 return (freebsd11_freebsd32_getdirentries(td, &ap));
1750}
1751#endif /* COMPAT_FREEBSD11 */
1752
1753#ifdef COMPAT_FREEBSD61
1754/* versions with the 'int pad' argument */
1755int
1756freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
1757{
1758
1759 return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
1760 PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32))));
1761}
1762
1763int
1764freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
1765{
1766
1767 return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
1768 PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32))));
1769}
1770
1771int
1772freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
1773{
1774 int error;
1775 off_t pos;
1776
1777 error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)),
1778 uap->whence);
1779 /* Expand the quad return into two parts for eax and edx */
1780 pos = *(off_t *)(td->td_retvaltd_uretoff.tdu_retval);
1781 td->td_retvaltd_uretoff.tdu_retval[RETVAL_LO0] = pos & 0xffffffff; /* %eax */
1782 td->td_retvaltd_uretoff.tdu_retval[RETVAL_HI1] = pos >> 32; /* %edx */
1783 return error;
1784}
1785
1786int
1787freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
1788{
1789
1790 return (kern_truncate(td, uap->path, UIO_USERSPACE,
1791 PAIR32TO64(off_t, uap->length)((uap->length1) | ((off_t)(uap->length2) << 32))));
1792}
1793
1794int
1795freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
1796{
1797
1798 return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)((uap->length1) | ((off_t)(uap->length2) << 32))));
1799}
1800#endif /* COMPAT_FREEBSD6 */
1801
1802struct sf_hdtr32 {
1803 uint32_t headers;
1804 int hdr_cnt;
1805 uint32_t trailers;
1806 int trl_cnt;
1807};
1808
1809static int
1810freebsd32_do_sendfile(struct thread *td,
1811 struct freebsd32_sendfile_args *uap, int compat)
1812{
1813 struct sf_hdtr32 hdtr32;
1814 struct sf_hdtr hdtr;
1815 struct uio *hdr_uio, *trl_uio;
1816 struct file *fp;
1817 cap_rights_t rights;
1818 struct iovec32 *iov32;
1819 off_t offset, sbytes;
1820 int error;
1821
1822 offset = PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32));
1823 if (offset < 0)
1824 return (EINVAL22);
1825
1826 hdr_uio = trl_uio = NULL((void *)0);
1827
1828 if (uap->hdtr != NULL((void *)0)) {
1829 error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
1830 if (error)
1831 goto out;
1832 PTRIN_CP(hdtr32, hdtr, headers)do { (hdtr).headers = (void *)(uintptr_t) ((hdtr32).headers);
} while (0)
;
1833 CP(hdtr32, hdtr, hdr_cnt)do { (hdtr).hdr_cnt = (hdtr32).hdr_cnt; } while (0);
1834 PTRIN_CP(hdtr32, hdtr, trailers)do { (hdtr).trailers = (void *)(uintptr_t) ((hdtr32).trailers
); } while (0)
;
1835 CP(hdtr32, hdtr, trl_cnt)do { (hdtr).trl_cnt = (hdtr32).trl_cnt; } while (0);
1836
1837 if (hdtr.headers != NULL((void *)0)) {
1838 iov32 = PTRIN(hdtr32.headers)(void *)(uintptr_t) (hdtr32.headers);
1839 error = freebsd32_copyinuio(iov32,
1840 hdtr32.hdr_cnt, &hdr_uio);
1841 if (error)
1842 goto out;
1843#ifdef COMPAT_FREEBSD41
1844 /*
1845 * In FreeBSD < 5.0 the nbytes to send also included
1846 * the header. If compat is specified subtract the
1847 * header size from nbytes.
1848 */
1849 if (compat) {
1850 if (uap->nbytes > hdr_uio->uio_resid)
1851 uap->nbytes -= hdr_uio->uio_resid;
1852 else
1853 uap->nbytes = 0;
1854 }
1855#endif
1856 }
1857 if (hdtr.trailers != NULL((void *)0)) {
1858 iov32 = PTRIN(hdtr32.trailers)(void *)(uintptr_t) (hdtr32.trailers);
1859 error = freebsd32_copyinuio(iov32,
1860 hdtr32.trl_cnt, &trl_uio);
1861 if (error)
1862 goto out;
1863 }
1864 }
1865
1866 AUDIT_ARG_FD(uap->fd)do { if ((__builtin_expect((((__curthread()))->td_pflags &
0x01000000), 0))) audit_arg_fd((uap->fd)); } while (0)
;
1867
1868 if ((error = fget_read(td, uap->fd,
1869 cap_rights_init(&rights, CAP_PREAD)__cap_rights_init(0, &rights, ((((1ULL << (57 + (0)
)) | (0x0000000000000004ULL)) | 0x0000000000000008ULL) | ((1ULL
<< (57 + (0))) | (0x0000000000000001ULL))), 0ULL)
, &fp)) != 0)
1870 goto out;
1871
1872 error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset,
1873 uap->nbytes, &sbytes, uap->flags, td);
1874 fdrop(fp, td)(refcount_release(&(fp)->f_count) ? _fdrop((fp), (td))
: _fnoop())
;
1875
1876 if (uap->sbytes != NULL((void *)0))
1877 copyout(&sbytes, uap->sbytes, sizeof(off_t));
1878
1879out:
1880 if (hdr_uio)
1881 free(hdr_uio, M_IOV);
1882 if (trl_uio)
1883 free(trl_uio, M_IOV);
1884 return (error);
1885}
1886
1887#ifdef COMPAT_FREEBSD41
1888int
1889freebsd4_freebsd32_sendfile(struct thread *td,
1890 struct freebsd4_freebsd32_sendfile_args *uap)
1891{
1892 return (freebsd32_do_sendfile(td,
1893 (struct freebsd32_sendfile_args *)uap, 1));
1894}
1895#endif
1896
1897int
1898freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1899{
1900
1901 return (freebsd32_do_sendfile(td, uap, 0));
1902}
1903
1904static void
1905copy_stat(struct stat *in, struct stat32 *out)
1906{
1907
1908 CP(*in, *out, st_dev)do { (*out).st_dev = (*in).st_dev; } while (0);
1909 CP(*in, *out, st_ino)do { (*out).st_ino = (*in).st_ino; } while (0);
1910 CP(*in, *out, st_mode)do { (*out).st_mode = (*in).st_mode; } while (0);
1911 CP(*in, *out, st_nlink)do { (*out).st_nlink = (*in).st_nlink; } while (0);
1912 CP(*in, *out, st_uid)do { (*out).st_uid = (*in).st_uid; } while (0);
1913 CP(*in, *out, st_gid)do { (*out).st_gid = (*in).st_gid; } while (0);
1914 CP(*in, *out, st_rdev)do { (*out).st_rdev = (*in).st_rdev; } while (0);
1915 TS_CP(*in, *out, st_atim)do { do { ((*out).st_atim).tv_sec = ((*in).st_atim).tv_sec; }
while (0); do { ((*out).st_atim).tv_nsec = ((*in).st_atim).tv_nsec
; } while (0); } while (0)
;
1916 TS_CP(*in, *out, st_mtim)do { do { ((*out).st_mtim).tv_sec = ((*in).st_mtim).tv_sec; }
while (0); do { ((*out).st_mtim).tv_nsec = ((*in).st_mtim).tv_nsec
; } while (0); } while (0)
;
1917 TS_CP(*in, *out, st_ctim)do { do { ((*out).st_ctim).tv_sec = ((*in).st_ctim).tv_sec; }
while (0); do { ((*out).st_ctim).tv_nsec = ((*in).st_ctim).tv_nsec
; } while (0); } while (0)
;
1918 CP(*in, *out, st_size)do { (*out).st_size = (*in).st_size; } while (0);
1919 CP(*in, *out, st_blocks)do { (*out).st_blocks = (*in).st_blocks; } while (0);
1920 CP(*in, *out, st_blksize)do { (*out).st_blksize = (*in).st_blksize; } while (0);
1921 CP(*in, *out, st_flags)do { (*out).st_flags = (*in).st_flags; } while (0);
1922 CP(*in, *out, st_gen)do { (*out).st_gen = (*in).st_gen; } while (0);
1923 TS_CP(*in, *out, st_birthtim)do { do { ((*out).st_birthtim).tv_sec = ((*in).st_birthtim).tv_sec
; } while (0); do { ((*out).st_birthtim).tv_nsec = ((*in).st_birthtim
).tv_nsec; } while (0); } while (0)
;
1924 out->st_padding0 = 0;
1925 out->st_padding1 = 0;
1926#ifdef __STAT32_TIME_T_EXT1
1927 out->st_atim_ext = 0;
1928 out->st_mtim_ext = 0;
1929 out->st_ctim_ext = 0;
1930 out->st_btim_ext = 0;
1931#endif
1932 bzero(out->st_spare, sizeof(out->st_spare))__builtin_memset((out->st_spare), 0, (sizeof(out->st_spare
)))
;
1933}
1934
1935#ifdef COMPAT_43
1936static void
1937copy_ostat(struct stat *in, struct ostat32 *out)
1938{
1939
1940 bzero(out, sizeof(*out))__builtin_memset((out), 0, (sizeof(*out)));
1941 CP(*in, *out, st_dev)do { (*out).st_dev = (*in).st_dev; } while (0);
1942 CP(*in, *out, st_ino)do { (*out).st_ino = (*in).st_ino; } while (0);
1943 CP(*in, *out, st_mode)do { (*out).st_mode = (*in).st_mode; } while (0);
1944 CP(*in, *out, st_nlink)do { (*out).st_nlink = (*in).st_nlink; } while (0);
1945 CP(*in, *out, st_uid)do { (*out).st_uid = (*in).st_uid; } while (0);
1946 CP(*in, *out, st_gid)do { (*out).st_gid = (*in).st_gid; } while (0);
1947 CP(*in, *out, st_rdev)do { (*out).st_rdev = (*in).st_rdev; } while (0);
1948 out->st_size = MIN(in->st_size, INT32_MAX)(((in->st_size)<(0x7fffffff))?(in->st_size):(0x7fffffff
))
;
1949 TS_CP(*in, *out, st_atim)do { do { ((*out).st_atim).tv_sec = ((*in).st_atim).tv_sec; }
while (0); do { ((*out).st_atim).tv_nsec = ((*in).st_atim).tv_nsec
; } while (0); } while (0)
;
1950 TS_CP(*in, *out, st_mtim)do { do { ((*out).st_mtim).tv_sec = ((*in).st_mtim).tv_sec; }
while (0); do { ((*out).st_mtim).tv_nsec = ((*in).st_mtim).tv_nsec
; } while (0); } while (0)
;
1951 TS_CP(*in, *out, st_ctim)do { do { ((*out).st_ctim).tv_sec = ((*in).st_ctim).tv_sec; }
while (0); do { ((*out).st_ctim).tv_nsec = ((*in).st_ctim).tv_nsec
; } while (0); } while (0)
;
1952 CP(*in, *out, st_blksize)do { (*out).st_blksize = (*in).st_blksize; } while (0);
1953 CP(*in, *out, st_blocks)do { (*out).st_blocks = (*in).st_blocks; } while (0);
1954 CP(*in, *out, st_flags)do { (*out).st_flags = (*in).st_flags; } while (0);
1955 CP(*in, *out, st_gen)do { (*out).st_gen = (*in).st_gen; } while (0);
1956}
1957#endif
1958
1959#ifdef COMPAT_43
1960int
1961ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
1962{
1963 struct stat sb;
1964 struct ostat32 sb32;
1965 int error;
1966
1967 error = kern_statat(td, 0, AT_FDCWD-100, uap->path, UIO_USERSPACE,
1968 &sb, NULL((void *)0));
1969 if (error)
1970 return (error);
1971 copy_ostat(&sb, &sb32);
1972 error = copyout(&sb32, uap->ub, sizeof (sb32));
1973 return (error);
1974}
1975#endif
1976
1977int
1978freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1979{
1980 struct stat ub;
1981 struct stat32 ub32;
1982 int error;
1983
1984 error = kern_fstat(td, uap->fd, &ub);
1985 if (error)
1986 return (error);
1987 copy_stat(&ub, &ub32);
1988 error = copyout(&ub32, uap->ub, sizeof(ub32));
1989 return (error);
1990}
1991
1992#ifdef COMPAT_43
1993int
1994ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap)
1995{
1996 struct stat ub;
1997 struct ostat32 ub32;
1998 int error;
1999
2000 error = kern_fstat(td, uap->fd, &ub);
2001 if (error)
2002 return (error);
2003 copy_ostat(&ub, &ub32);
2004 error = copyout(&ub32, uap->ub, sizeof(ub32));
2005 return (error);
2006}
2007#endif
2008
2009int
2010freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
2011{
2012 struct stat ub;
2013 struct stat32 ub32;
2014 int error;
2015
2016 error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
2017 &ub, NULL((void *)0));
2018 if (error)
2019 return (error);
2020 copy_stat(&ub, &ub32);
2021 error = copyout(&ub32, uap->buf, sizeof(ub32));
2022 return (error);
2023}
2024
2025#ifdef COMPAT_43
2026int
2027ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
2028{
2029 struct stat sb;
2030 struct ostat32 sb32;
2031 int error;
2032
2033 error = kern_statat(td, AT_SYMLINK_NOFOLLOW0x0200, AT_FDCWD-100, uap->path,
2034 UIO_USERSPACE, &sb, NULL((void *)0));
2035 if (error)
2036 return (error);
2037 copy_ostat(&sb, &sb32);
2038 error = copyout(&sb32, uap->ub, sizeof (sb32));
2039 return (error);
2040}
2041#endif
2042
2043int
2044freebsd32_fhstat(struct thread *td, struct freebsd32_fhstat_args *uap)
2045{
2046 struct stat sb;
2047 struct stat32 sb32;
2048 struct fhandle fh;
2049 int error;
2050
2051 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
2052 if (error != 0)
2053 return (error);
2054 error = kern_fhstat(td, fh, &sb);
2055 if (error != 0)
2056 return (error);
2057 copy_stat(&sb, &sb32);
2058 error = copyout(&sb32, uap->sb, sizeof (sb32));
2059 return (error);
2060}
2061
2062#if defined(COMPAT_FREEBSD111)
2063extern int ino64_trunc_error;
2064
2065static int
2066freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out)
2067{
2068
2069 CP(*in, *out, st_ino)do { (*out).st_ino = (*in).st_ino; } while (0);
2070 if (in->st_ino != out->st_ino) {
2071 switch (ino64_trunc_error) {
2072 default:
2073 case 0:
2074 break;
2075 case 1:
2076 return (EOVERFLOW84);
2077 case 2:
2078 out->st_ino = UINT32_MAX0xffffffffU;
2079 break;
2080 }
2081 }
2082 CP(*in, *out, st_nlink)do { (*out).st_nlink = (*in).st_nlink; } while (0);
2083 if (in->st_nlink != out->st_nlink) {
2084 switch (ino64_trunc_error) {
2085 default:
2086 case 0:
2087 break;
2088 case 1:
2089 return (EOVERFLOW84);
2090 case 2:
2091 out->st_nlink = UINT16_MAX0xffff;
2092 break;
2093 }
2094 }
2095 out->st_dev = in->st_dev;
2096 if (out->st_dev != in->st_dev) {
2097 switch (ino64_trunc_error) {
2098 default:
2099 break;
2100 case 1:
2101 return (EOVERFLOW84);
2102 }
2103 }
2104 CP(*in, *out, st_mode)do { (*out).st_mode = (*in).st_mode; } while (0);
2105 CP(*in, *out, st_uid)do { (*out).st_uid = (*in).st_uid; } while (0);
2106 CP(*in, *out, st_gid)do { (*out).st_gid = (*in).st_gid; } while (0);
2107 out->st_rdev = in->st_rdev;
2108 if (out->st_rdev != in->st_rdev) {
2109 switch (ino64_trunc_error) {
2110 default:
2111 break;
2112 case 1:
2113 return (EOVERFLOW84);
2114 }
2115 }
2116 TS_CP(*in, *out, st_atim)do { do { ((*out).st_atim).tv_sec = ((*in).st_atim).tv_sec; }
while (0); do { ((*out).st_atim).tv_nsec = ((*in).st_atim).tv_nsec
; } while (0); } while (0)
;
2117 TS_CP(*in, *out, st_mtim)do { do { ((*out).st_mtim).tv_sec = ((*in).st_mtim).tv_sec; }
while (0); do { ((*out).st_mtim).tv_nsec = ((*in).st_mtim).tv_nsec
; } while (0); } while (0)
;
2118 TS_CP(*in, *out, st_ctim)do { do { ((*out).st_ctim).tv_sec = ((*in).st_ctim).tv_sec; }
while (0); do { ((*out).st_ctim).tv_nsec = ((*in).st_ctim).tv_nsec
; } while (0); } while (0)
;
2119 CP(*in, *out, st_size)do { (*out).st_size = (*in).st_size; } while (0);
2120 CP(*in, *out, st_blocks)do { (*out).st_blocks = (*in).st_blocks; } while (0);
2121 CP(*in, *out, st_blksize)do { (*out).st_blksize = (*in).st_blksize; } while (0);
2122 CP(*in, *out, st_flags)do { (*out).st_flags = (*in).st_flags; } while (0);
2123 CP(*in, *out, st_gen)do { (*out).st_gen = (*in).st_gen; } while (0);
2124 TS_CP(*in, *out, st_birthtim)do { do { ((*out).st_birthtim).tv_sec = ((*in).st_birthtim).tv_sec
; } while (0); do { ((*out).st_birthtim).tv_nsec = ((*in).st_birthtim
).tv_nsec; } while (0); } while (0)
;
2125 out->st_lspare = 0;
2126 bzero((char *)&out->st_birthtim + sizeof(out->st_birthtim),__builtin_memset(((char *)&out->st_birthtim + sizeof(out
->st_birthtim)), 0, (sizeof(*out) - __builtin_offsetof(struct
freebsd11_stat32, st_birthtim) - sizeof(out->st_birthtim)
))
2127 sizeof(*out) - offsetof(struct freebsd11_stat32,__builtin_memset(((char *)&out->st_birthtim + sizeof(out
->st_birthtim)), 0, (sizeof(*out) - __builtin_offsetof(struct
freebsd11_stat32, st_birthtim) - sizeof(out->st_birthtim)
))
2128 st_birthtim) - sizeof(out->st_birthtim))__builtin_memset(((char *)&out->st_birthtim + sizeof(out
->st_birthtim)), 0, (sizeof(*out) - __builtin_offsetof(struct
freebsd11_stat32, st_birthtim) - sizeof(out->st_birthtim)
))
;
2129 return (0);
2130}
2131
2132int
2133freebsd11_freebsd32_stat(struct thread *td,
2134 struct freebsd11_freebsd32_stat_args *uap)
2135{
2136 struct stat sb;
2137 struct freebsd11_stat32 sb32;
2138 int error;
2139
2140 error = kern_statat(td, 0, AT_FDCWD-100, uap->path, UIO_USERSPACE,
2141 &sb, NULL((void *)0));
2142 if (error != 0)
2143 return (error);
2144 error = freebsd11_cvtstat32(&sb, &sb32);
2145 if (error == 0)
2146 error = copyout(&sb32, uap->ub, sizeof (sb32));
2147 return (error);
2148}
2149
2150int
2151freebsd11_freebsd32_fstat(struct thread *td,
2152 struct freebsd11_freebsd32_fstat_args *uap)
2153{
2154 struct stat sb;
2155 struct freebsd11_stat32 sb32;
2156 int error;
2157
2158 error = kern_fstat(td, uap->fd, &sb);
2159 if (error != 0)
2160 return (error);
2161 error = freebsd11_cvtstat32(&sb, &sb32);
2162 if (error == 0)
2163 error = copyout(&sb32, uap->ub, sizeof (sb32));
2164 return (error);
2165}
2166
2167int
2168freebsd11_freebsd32_fstatat(struct thread *td,
2169 struct freebsd11_freebsd32_fstatat_args *uap)
2170{
2171 struct stat sb;
2172 struct freebsd11_stat32 sb32;
2173 int error;
2174
2175 error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
2176 &sb, NULL((void *)0));
2177 if (error != 0)
2178 return (error);
2179 error = freebsd11_cvtstat32(&sb, &sb32);
2180 if (error == 0)
2181 error = copyout(&sb32, uap->buf, sizeof (sb32));
2182 return (error);
2183}
2184
2185int
2186freebsd11_freebsd32_lstat(struct thread *td,
2187 struct freebsd11_freebsd32_lstat_args *uap)
2188{
2189 struct stat sb;
2190 struct freebsd11_stat32 sb32;
2191 int error;
2192
2193 error = kern_statat(td, AT_SYMLINK_NOFOLLOW0x0200, AT_FDCWD-100, uap->path,
2194 UIO_USERSPACE, &sb, NULL((void *)0));
2195 if (error != 0)
1
Assuming 'error' is equal to 0
2
Taking false branch
2196 return (error);
2197 error = freebsd11_cvtstat32(&sb, &sb32);
2198 if (error == 0)
3
Taking true branch
2199 error = copyout(&sb32, uap->ub, sizeof (sb32));
4
Copies out a struct with untouched element(s): ,
2200 return (error);
2201}
2202
2203int
2204freebsd11_freebsd32_fhstat(struct thread *td,
2205 struct freebsd11_freebsd32_fhstat_args *uap)
2206{
2207 struct stat sb;
2208 struct freebsd11_stat32 sb32;
2209 struct fhandle fh;
2210 int error;
2211
2212 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
2213 if (error != 0)
2214 return (error);
2215 error = kern_fhstat(td, fh, &sb);
2216 if (error != 0)
2217 return (error);
2218 error = freebsd11_cvtstat32(&sb, &sb32);
2219 if (error == 0)
2220 error = copyout(&sb32, uap->sb, sizeof (sb32));
2221 return (error);
2222}
2223#endif
2224
2225int
2226freebsd32___sysctl(struct thread *td, struct freebsd32___sysctl_args *uap)
2227{
2228 int error, name[CTL_MAXNAME24];
2229 size_t j, oldlen;
2230 uint32_t tmp;
2231
2232 if (uap->namelen > CTL_MAXNAME24 || uap->namelen < 2)
2233 return (EINVAL22);
2234 error = copyin(uap->name, name, uap->namelen * sizeof(int));
2235 if (error)
2236 return (error);
2237 if (uap->oldlenp) {
2238 error = fueword32(uap->oldlenp, &tmp);
2239 oldlen = tmp;
2240 } else {
2241 oldlen = 0;
2242 }
2243 if (error != 0)
2244 return (EFAULT14);
2245 error = userland_sysctl(td, name, uap->namelen,
2246 uap->old, &oldlen, 1,
2247 uap->new, uap->newlen, &j, SCTL_MASK321);
2248 if (error)
2249 return (error);
2250 if (uap->oldlenp)
2251 suword32(uap->oldlenp, j);
2252 return (0);
2253}
2254
2255int
2256freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
2257{
2258 uint32_t version;
2259 int error;
2260 struct jail j;
2261
2262 error = copyin(uap->jail, &version, sizeof(uint32_t));
2263 if (error)
2264 return (error);
2265
2266 switch (version) {
2267 case 0:
2268 {
2269 /* FreeBSD single IPv4 jails. */
2270 struct jail32_v0 j32_v0;
2271
2272 bzero(&j, sizeof(struct jail))__builtin_memset((&j), 0, (sizeof(struct jail)));
2273 error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0));
2274 if (error)
2275 return (error);
2276 CP(j32_v0, j, version)do { (j).version = (j32_v0).version; } while (0);
2277 PTRIN_CP(j32_v0, j, path)do { (j).path = (void *)(uintptr_t) ((j32_v0).path); } while (
0)
;
2278 PTRIN_CP(j32_v0, j, hostname)do { (j).hostname = (void *)(uintptr_t) ((j32_v0).hostname); }
while (0)
;
2279 j.ip4s = htonl(j32_v0.ip_number)(__builtin_constant_p(j32_v0.ip_number) ? (((__uint32_t)((__uint16_t
)(__builtin_constant_p(((__uint32_t)(j32_v0.ip_number)) &
0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(j32_v0.ip_number
)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(j32_v0
.ip_number)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t
)(j32_v0.ip_number)) & 0xffff))) << 16) | ((__uint16_t
)(__builtin_constant_p(((__uint32_t)(j32_v0.ip_number)) >>
16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(j32_v0.ip_number
)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(j32_v0
.ip_number)) >> 16)) >> 8) : __bswap16_var(((__uint32_t
)(j32_v0.ip_number)) >> 16)))) : __bswap32_var(j32_v0.ip_number
))
; /* jail_v0 is host order */
2280 break;
2281 }
2282
2283 case 1:
2284 /*
2285 * Version 1 was used by multi-IPv4 jail implementations
2286 * that never made it into the official kernel.
2287 */
2288 return (EINVAL22);
2289
2290 case 2: /* JAIL_API_VERSION */
2291 {
2292 /* FreeBSD multi-IPv4/IPv6,noIP jails. */
2293 struct jail32 j32;
2294
2295 error = copyin(uap->jail, &j32, sizeof(struct jail32));
2296 if (error)
2297 return (error);
2298 CP(j32, j, version)do { (j).version = (j32).version; } while (0);
2299 PTRIN_CP(j32, j, path)do { (j).path = (void *)(uintptr_t) ((j32).path); } while (0);
2300 PTRIN_CP(j32, j, hostname)do { (j).hostname = (void *)(uintptr_t) ((j32).hostname); } while
(0)
;
2301 PTRIN_CP(j32, j, jailname)do { (j).jailname = (void *)(uintptr_t) ((j32).jailname); } while
(0)
;
2302 CP(j32, j, ip4s)do { (j).ip4s = (j32).ip4s; } while (0);
2303 CP(j32, j, ip6s)do { (j).ip6s = (j32).ip6s; } while (0);
2304 PTRIN_CP(j32, j, ip4)do { (j).ip4 = (void *)(uintptr_t) ((j32).ip4); } while (0);
2305 PTRIN_CP(j32, j, ip6)do { (j).ip6 = (void *)(uintptr_t) ((j32).ip6); } while (0);
2306 break;
2307 }
2308
2309 default:
2310 /* Sci-Fi jails are not supported, sorry. */
2311 return (EINVAL22);
2312 }
2313 return (kern_jail(td, &j));
2314}
2315
2316int
2317freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
2318{
2319 struct uio *auio;
2320 int error;
2321
2322 /* Check that we have an even number of iovecs. */
2323 if (uap->iovcnt & 1)
2324 return (EINVAL22);
2325
2326 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2327 if (error)
2328 return (error);
2329 error = kern_jail_set(td, auio, uap->flags);
2330 free(auio, M_IOV);
2331 return (error);
2332}
2333
2334int
2335freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
2336{
2337 struct iovec32 iov32;
2338 struct uio *auio;
2339 int error, i;
2340
2341 /* Check that we have an even number of iovecs. */
2342 if (uap->iovcnt & 1)
2343 return (EINVAL22);
2344
2345 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2346 if (error)
2347 return (error);
2348 error = kern_jail_get(td, auio, uap->flags);
2349 if (error == 0)
2350 for (i = 0; i < uap->iovcnt; i++) {
2351 PTROUT_CP(auio->uio_iov[i], iov32, iov_base)do { (iov32).iov_base = (u_int32_t)(uintptr_t) ((auio->uio_iov
[i]).iov_base); } while (0)
;
2352 CP(auio->uio_iov[i], iov32, iov_len)do { (iov32).iov_len = (auio->uio_iov[i]).iov_len; } while
(0)
;
2353 error = copyout(&iov32, uap->iovp + i, sizeof(iov32));
2354 if (error != 0)
2355 break;
2356 }
2357 free(auio, M_IOV);
2358 return (error);
2359}
2360
2361int
2362freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
2363{
2364 struct sigaction32 s32;
2365 struct sigaction sa, osa, *sap;
2366 int error;
2367
2368 if (uap->act) {
2369 error = copyin(uap->act, &s32, sizeof(s32));
2370 if (error)
2371 return (error);
2372 sa.sa_handler__sigaction_u.__sa_handler = PTRIN(s32.sa_u)(void *)(uintptr_t) (s32.sa_u);
2373 CP(s32, sa, sa_flags)do { (sa).sa_flags = (s32).sa_flags; } while (0);
2374 CP(s32, sa, sa_mask)do { (sa).sa_mask = (s32).sa_mask; } while (0);
2375 sap = &sa;
2376 } else
2377 sap = NULL((void *)0);
2378 error = kern_sigaction(td, uap->sig, sap, &osa, 0);
2379 if (error == 0 && uap->oact != NULL((void *)0)) {
2380 s32.sa_u = PTROUT(osa.sa_handler)(u_int32_t)(uintptr_t) (osa.__sigaction_u.__sa_handler);
2381 CP(osa, s32, sa_flags)do { (s32).sa_flags = (osa).sa_flags; } while (0);
2382 CP(osa, s32, sa_mask)do { (s32).sa_mask = (osa).sa_mask; } while (0);
2383 error = copyout(&s32, uap->oact, sizeof(s32));
2384 }
2385 return (error);
2386}
2387
2388#ifdef COMPAT_FREEBSD41
2389int
2390freebsd4_freebsd32_sigaction(struct thread *td,
2391 struct freebsd4_freebsd32_sigaction_args *uap)
2392{
2393 struct sigaction32 s32;
2394 struct sigaction sa, osa, *sap;
2395 int error;
2396
2397 if (uap->act) {
2398 error = copyin(uap->act, &s32, sizeof(s32));
2399 if (error)
2400 return (error);
2401 sa.sa_handler__sigaction_u.__sa_handler = PTRIN(s32.sa_u)(void *)(uintptr_t) (s32.sa_u);
2402 CP(s32, sa, sa_flags)do { (sa).sa_flags = (s32).sa_flags; } while (0);
2403 CP(s32, sa, sa_mask)do { (sa).sa_mask = (s32).sa_mask; } while (0);
2404 sap = &sa;
2405 } else
2406 sap = NULL((void *)0);
2407 error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD40x0002);
2408 if (error == 0 && uap->oact != NULL((void *)0)) {
2409 s32.sa_u = PTROUT(osa.sa_handler)(u_int32_t)(uintptr_t) (osa.__sigaction_u.__sa_handler);
2410 CP(osa, s32, sa_flags)do { (s32).sa_flags = (osa).sa_flags; } while (0);
2411 CP(osa, s32, sa_mask)do { (s32).sa_mask = (osa).sa_mask; } while (0);
2412 error = copyout(&s32, uap->oact, sizeof(s32));
2413 }
2414 return (error);
2415}
2416#endif
2417
2418#ifdef COMPAT_43
2419struct osigaction32 {
2420 u_int32_t sa_u;
2421 osigset_t sa_mask;
2422 int sa_flags;
2423};
2424
2425#define ONSIG 32
2426
2427int
2428ofreebsd32_sigaction(struct thread *td,
2429 struct ofreebsd32_sigaction_args *uap)
2430{
2431 struct osigaction32 s32;
2432 struct sigaction sa, osa, *sap;
2433 int error;
2434
2435 if (uap->signum <= 0 || uap->signum >= ONSIG)
2436 return (EINVAL22);
2437
2438 if (uap->nsa) {
2439 error = copyin(uap->nsa, &s32, sizeof(s32));
2440 if (error)
2441 return (error);
2442 sa.sa_handler__sigaction_u.__sa_handler = PTRIN(s32.sa_u)(void *)(uintptr_t) (s32.sa_u);
2443 CP(s32, sa, sa_flags)do { (sa).sa_flags = (s32).sa_flags; } while (0);
2444 OSIG2SIG(s32.sa_mask, sa.sa_mask)do { int __i; for (__i = 0; __i < 4; __i++) (sa.sa_mask).__bits
[__i] = 0; } while (0); (sa.sa_mask).__bits[0] = s32.sa_mask
;
2445 sap = &sa;
2446 } else
2447 sap = NULL((void *)0);
2448 error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET0x0001);
2449 if (error == 0 && uap->osa != NULL((void *)0)) {
2450 s32.sa_u = PTROUT(osa.sa_handler)(u_int32_t)(uintptr_t) (osa.__sigaction_u.__sa_handler);
2451 CP(osa, s32, sa_flags)do { (s32).sa_flags = (osa).sa_flags; } while (0);
2452 SIG2OSIG(osa.sa_mask, s32.sa_mask)(s32.sa_mask = (osa.sa_mask).__bits[0]);
2453 error = copyout(&s32, uap->osa, sizeof(s32));
2454 }
2455 return (error);
2456}
2457
2458int
2459ofreebsd32_sigprocmask(struct thread *td,
2460 struct ofreebsd32_sigprocmask_args *uap)
2461{
2462 sigset_t set, oset;
2463 int error;
2464
2465 OSIG2SIG(uap->mask, set)do { int __i; for (__i = 0; __i < 4; __i++) (set).__bits[__i
] = 0; } while (0); (set).__bits[0] = uap->mask
;
2466 error = kern_sigprocmask(td, uap->how, &set, &oset, SIGPROCMASK_OLD0x0001);
2467 SIG2OSIG(oset, td->td_retval[0])(td->td_uretoff.tdu_retval[0] = (oset).__bits[0]);
2468 return (error);
2469}
2470
2471int
2472ofreebsd32_sigpending(struct thread *td,
2473 struct ofreebsd32_sigpending_args *uap)
2474{
2475 struct proc *p = td->td_proc;
2476 sigset_t siglist;
2477
2478 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/compat/freebsd32/freebsd32_misc.c"
), (2478))
;
2479 siglist = p->p_siglistp_sigqueue.sq_signals;
2480 SIGSETOR(siglist, td->td_siglist)do { int __i; for (__i = 0; __i < 4; __i++) (siglist).__bits
[__i] |= (td->td_sigqueue.sq_signals).__bits[__i]; } while
(0)
;
2481 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/compat/freebsd32/freebsd32_misc.c"
), (2481))
;
2482 SIG2OSIG(siglist, td->td_retval[0])(td->td_uretoff.tdu_retval[0] = (siglist).__bits[0]);
2483 return (0);
2484}
2485
2486struct sigvec32 {
2487 u_int32_t sv_handler;
2488 int sv_mask;
2489 int sv_flags;
2490};
2491
2492int
2493ofreebsd32_sigvec(struct thread *td,
2494 struct ofreebsd32_sigvec_args *uap)
2495{
2496 struct sigvec32 vec;
2497 struct sigaction sa, osa, *sap;
2498 int error;
2499
2500 if (uap->signum <= 0 || uap->signum >= ONSIG)
2501 return (EINVAL22);
2502
2503 if (uap->nsv) {
2504 error = copyin(uap->nsv, &vec, sizeof(vec));
2505 if (error)
2506 return (error);
2507 sa.sa_handler__sigaction_u.__sa_handler = PTRIN(vec.sv_handler)(void *)(uintptr_t) (vec.sv_handler);
2508 OSIG2SIG(vec.sv_mask, sa.sa_mask)do { int __i; for (__i = 0; __i < 4; __i++) (sa.sa_mask).__bits
[__i] = 0; } while (0); (sa.sa_mask).__bits[0] = vec.sv_mask
;
2509 sa.sa_flags = vec.sv_flags;
2510 sa.sa_flags ^= SA_RESTART0x0002;
2511 sap = &sa;
2512 } else
2513 sap = NULL((void *)0);
2514 error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET0x0001);
2515 if (error == 0 && uap->osv != NULL((void *)0)) {
2516 vec.sv_handler = PTROUT(osa.sa_handler)(u_int32_t)(uintptr_t) (osa.__sigaction_u.__sa_handler);
2517 SIG2OSIG(osa.sa_mask, vec.sv_mask)(vec.sv_mask = (osa.sa_mask).__bits[0]);
2518 vec.sv_flags = osa.sa_flags;
2519 vec.sv_flags &= ~SA_NOCLDWAIT0x0020;
2520 vec.sv_flags ^= SA_RESTART0x0002;
2521 error = copyout(&vec, uap->osv, sizeof(vec));
2522 }
2523 return (error);
2524}
2525
2526int
2527ofreebsd32_sigblock(struct thread *td,
2528 struct ofreebsd32_sigblock_args *uap)
2529{
2530 sigset_t set, oset;
2531
2532 OSIG2SIG(uap->mask, set)do { int __i; for (__i = 0; __i < 4; __i++) (set).__bits[__i
] = 0; } while (0); (set).__bits[0] = uap->mask
;
2533 kern_sigprocmask(td, SIG_BLOCK1, &set, &oset, 0);
2534 SIG2OSIG(oset, td->td_retval[0])(td->td_uretoff.tdu_retval[0] = (oset).__bits[0]);
2535 return (0);
2536}
2537
2538int
2539ofreebsd32_sigsetmask(struct thread *td,
2540 struct ofreebsd32_sigsetmask_args *uap)
2541{
2542 sigset_t set, oset;
2543
2544 OSIG2SIG(uap->mask, set)do { int __i; for (__i = 0; __i < 4; __i++) (set).__bits[__i
] = 0; } while (0); (set).__bits[0] = uap->mask
;
2545 kern_sigprocmask(td, SIG_SETMASK3, &set, &oset, 0);
2546 SIG2OSIG(oset, td->td_retval[0])(td->td_uretoff.tdu_retval[0] = (oset).__bits[0]);
2547 return (0);
2548}
2549
2550int
2551ofreebsd32_sigsuspend(struct thread *td,
2552 struct ofreebsd32_sigsuspend_args *uap)
2553{
2554 sigset_t mask;
2555
2556 OSIG2SIG(uap->mask, mask)do { int __i; for (__i = 0; __i < 4; __i++) (mask).__bits[
__i] = 0; } while (0); (mask).__bits[0] = uap->mask
;
2557 return (kern_sigsuspend(td, mask));
2558}
2559
2560struct sigstack32 {
2561 u_int32_t ss_sp;
2562 int ss_onstack;
2563};
2564
2565int
2566ofreebsd32_sigstack(struct thread *td,
2567 struct ofreebsd32_sigstack_args *uap)
2568{
2569 struct sigstack32 s32;
2570 struct sigstack nss, oss;
2571 int error = 0, unss;
2572
2573 if (uap->nss != NULL((void *)0)) {
2574 error = copyin(uap->nss, &s32, sizeof(s32));
2575 if (error)
2576 return (error);
2577 nss.ss_sp = PTRIN(s32.ss_sp)(void *)(uintptr_t) (s32.ss_sp);
2578 CP(s32, nss, ss_onstack)do { (nss).ss_onstack = (s32).ss_onstack; } while (0);
2579 unss = 1;
2580 } else {
2581 unss = 0;
2582 }
2583 oss.ss_sp = td->td_sigstk.ss_sp;
2584 oss.ss_onstack = sigonstack(cpu_getstack(td)((td)->td_frame->tf_rsp));
2585 if (unss) {
2586 td->td_sigstk.ss_sp = nss.ss_sp;
2587 td->td_sigstk.ss_size = 0;
2588 td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK0x0001);
2589 td->td_pflags |= TDP_ALTSTACK0x00000020;
2590 }
2591 if (uap->oss != NULL((void *)0)) {
2592 s32.ss_sp = PTROUT(oss.ss_sp)(u_int32_t)(uintptr_t) (oss.ss_sp);
2593 CP(oss, s32, ss_onstack)do { (s32).ss_onstack = (oss).ss_onstack; } while (0);
2594 error = copyout(&s32, uap->oss, sizeof(s32));
2595 }
2596 return (error);
2597}
2598#endif
2599
2600int
2601freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
2602{
2603
2604 return (freebsd32_user_clock_nanosleep(td, CLOCK_REALTIME0,
2605 TIMER_RELTIME0x0, uap->rqtp, uap->rmtp));
2606}
2607
2608int
2609freebsd32_clock_nanosleep(struct thread *td,
2610 struct freebsd32_clock_nanosleep_args *uap)
2611{
2612 int error;
2613
2614 error = freebsd32_user_clock_nanosleep(td, uap->clock_id, uap->flags,
2615 uap->rqtp, uap->rmtp);
2616 return (kern_posix_error(td, error));
2617}
2618
2619static int
2620freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
2621 int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp)
2622{
2623 struct timespec32 rmt32, rqt32;
2624 struct timespec rmt, rqt;
2625 int error;
2626
2627 error = copyin(ua_rqtp, &rqt32, sizeof(rqt32));
2628 if (error)
2629 return (error);
2630
2631 CP(rqt32, rqt, tv_sec)do { (rqt).tv_sec = (rqt32).tv_sec; } while (0);
2632 CP(rqt32, rqt, tv_nsec)do { (rqt).tv_nsec = (rqt32).tv_nsec; } while (0);
2633
2634 if (ua_rmtp != NULL((void *)0) && (flags & TIMER_ABSTIME0x1) == 0 &&
2635 !useracc(ua_rmtp, sizeof(rmt32), VM_PROT_WRITE((vm_prot_t) 0x02)))
2636 return (EFAULT14);
2637 error = kern_clock_nanosleep(td, clock_id, flags, &rqt, &rmt);
2638 if (error == EINTR4 && ua_rmtp != NULL((void *)0) && (flags & TIMER_ABSTIME0x1) == 0) {
2639 int error2;
2640
2641 CP(rmt, rmt32, tv_sec)do { (rmt32).tv_sec = (rmt).tv_sec; } while (0);
2642 CP(rmt, rmt32, tv_nsec)do { (rmt32).tv_nsec = (rmt).tv_nsec; } while (0);
2643
2644 error2 = copyout(&rmt32, ua_rmtp, sizeof(rmt32));
2645 if (error2)
2646 error = error2;
2647 }
2648 return (error);
2649}
2650
2651int
2652freebsd32_clock_gettime(struct thread *td,
2653 struct freebsd32_clock_gettime_args *uap)
2654{
2655 struct timespec ats;
2656 struct timespec32 ats32;
2657 int error;
2658
2659 error = kern_clock_gettime(td, uap->clock_id, &ats);
2660 if (error == 0) {
2661 CP(ats, ats32, tv_sec)do { (ats32).tv_sec = (ats).tv_sec; } while (0);
2662 CP(ats, ats32, tv_nsec)do { (ats32).tv_nsec = (ats).tv_nsec; } while (0);
2663 error = copyout(&ats32, uap->tp, sizeof(ats32));
2664 }
2665 return (error);
2666}
2667
2668int
2669freebsd32_clock_settime(struct thread *td,
2670 struct freebsd32_clock_settime_args *uap)
2671{
2672 struct timespec ats;
2673 struct timespec32 ats32;
2674 int error;
2675
2676 error = copyin(uap->tp, &ats32, sizeof(ats32));
2677 if (error)
2678 return (error);
2679 CP(ats32, ats, tv_sec)do { (ats).tv_sec = (ats32).tv_sec; } while (0);
2680 CP(ats32, ats, tv_nsec)do { (ats).tv_nsec = (ats32).tv_nsec; } while (0);
2681
2682 return (kern_clock_settime(td, uap->clock_id, &ats));
2683}
2684
2685int
2686freebsd32_clock_getres(struct thread *td,
2687 struct freebsd32_clock_getres_args *uap)
2688{
2689 struct timespec ts;
2690 struct timespec32 ts32;
2691 int error;
2692
2693 if (uap->tp == NULL((void *)0))
2694 return (0);
2695 error = kern_clock_getres(td, uap->clock_id, &ts);
2696 if (error == 0) {
2697 CP(ts, ts32, tv_sec)do { (ts32).tv_sec = (ts).tv_sec; } while (0);
2698 CP(ts, ts32, tv_nsec)do { (ts32).tv_nsec = (ts).tv_nsec; } while (0);
2699 error = copyout(&ts32, uap->tp, sizeof(ts32));
2700 }
2701 return (error);
2702}
2703
2704int freebsd32_ktimer_create(struct thread *td,
2705 struct freebsd32_ktimer_create_args *uap)
2706{
2707 struct sigevent32 ev32;
2708 struct sigevent ev, *evp;
2709 int error, id;
2710
2711 if (uap->evp == NULL((void *)0)) {
2712 evp = NULL((void *)0);
2713 } else {
2714 evp = &ev;
2715 error = copyin(uap->evp, &ev32, sizeof(ev32));
2716 if (error != 0)
2717 return (error);
2718 error = convert_sigevent32(&ev32, &ev);
2719 if (error != 0)
2720 return (error);
2721 }
2722 error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
2723 if (error == 0) {
2724 error = copyout(&id, uap->timerid, sizeof(int));
2725 if (error != 0)
2726 kern_ktimer_delete(td, id);
2727 }
2728 return (error);
2729}
2730
2731int
2732freebsd32_ktimer_settime(struct thread *td,
2733 struct freebsd32_ktimer_settime_args *uap)
2734{
2735 struct itimerspec32 val32, oval32;
2736 struct itimerspec val, oval, *ovalp;
2737 int error;
2738
2739 error = copyin(uap->value, &val32, sizeof(val32));
2740 if (error != 0)
2741 return (error);
2742 ITS_CP(val32, val)do { do { do { (((val)).it_interval).tv_sec = (((val32)).it_interval
).tv_sec; } while (0); do { (((val)).it_interval).tv_nsec = (
((val32)).it_interval).tv_nsec; } while (0); } while (0); do {
do { (((val)).it_value).tv_sec = (((val32)).it_value).tv_sec
; } while (0); do { (((val)).it_value).tv_nsec = (((val32)).it_value
).tv_nsec; } while (0); } while (0); } while (0)
;
2743 ovalp = uap->ovalue != NULL((void *)0) ? &oval : NULL((void *)0);
2744 error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
2745 if (error == 0 && uap->ovalue != NULL((void *)0)) {
2746 ITS_CP(oval, oval32)do { do { do { (((oval32)).it_interval).tv_sec = (((oval)).it_interval
).tv_sec; } while (0); do { (((oval32)).it_interval).tv_nsec =
(((oval)).it_interval).tv_nsec; } while (0); } while (0); do
{ do { (((oval32)).it_value).tv_sec = (((oval)).it_value).tv_sec
; } while (0); do { (((oval32)).it_value).tv_nsec = (((oval))
.it_value).tv_nsec; } while (0); } while (0); } while (0)
;
2747 error = copyout(&oval32, uap->ovalue, sizeof(oval32));
2748 }
2749 return (error);
2750}
2751
2752int
2753freebsd32_ktimer_gettime(struct thread *td,
2754 struct freebsd32_ktimer_gettime_args *uap)
2755{
2756 struct itimerspec32 val32;
2757 struct itimerspec val;
2758 int error;
2759
2760 error = kern_ktimer_gettime(td, uap->timerid, &val);
2761 if (error == 0) {
2762 ITS_CP(val, val32)do { do { do { (((val32)).it_interval).tv_sec = (((val)).it_interval
).tv_sec; } while (0); do { (((val32)).it_interval).tv_nsec =
(((val)).it_interval).tv_nsec; } while (0); } while (0); do {
do { (((val32)).it_value).tv_sec = (((val)).it_value).tv_sec
; } while (0); do { (((val32)).it_value).tv_nsec = (((val)).it_value
).tv_nsec; } while (0); } while (0); } while (0)
;
2763 error = copyout(&val32, uap->value, sizeof(val32));
2764 }
2765 return (error);
2766}
2767
2768int
2769freebsd32_clock_getcpuclockid2(struct thread *td,
2770 struct freebsd32_clock_getcpuclockid2_args *uap)
2771{
2772 clockid_t clk_id;
2773 int error;
2774
2775 error = kern_clock_getcpuclockid2(td, PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)),
2776 uap->which, &clk_id);
2777 if (error == 0)
2778 error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t));
2779 return (error);
2780}
2781
2782int
2783freebsd32_thr_new(struct thread *td,
2784 struct freebsd32_thr_new_args *uap)
2785{
2786 struct thr_param32 param32;
2787 struct thr_param param;
2788 int error;
2789
2790 if (uap->param_size < 0 ||
2791 uap->param_size > sizeof(struct thr_param32))
2792 return (EINVAL22);
2793 bzero(&param, sizeof(struct thr_param))__builtin_memset((&param), 0, (sizeof(struct thr_param)));
2794 bzero(&param32, sizeof(struct thr_param32))__builtin_memset((&param32), 0, (sizeof(struct thr_param32
)))
;
2795 error = copyin(uap->param, &param32, uap->param_size);
2796 if (error != 0)
2797 return (error);
2798 param.start_func = PTRIN(param32.start_func)(void *)(uintptr_t) (param32.start_func);
2799 param.arg = PTRIN(param32.arg)(void *)(uintptr_t) (param32.arg);
2800 param.stack_base = PTRIN(param32.stack_base)(void *)(uintptr_t) (param32.stack_base);
2801 param.stack_size = param32.stack_size;
2802 param.tls_base = PTRIN(param32.tls_base)(void *)(uintptr_t) (param32.tls_base);
2803 param.tls_size = param32.tls_size;
2804 param.child_tid = PTRIN(param32.child_tid)(void *)(uintptr_t) (param32.child_tid);
2805 param.parent_tid = PTRIN(param32.parent_tid)(void *)(uintptr_t) (param32.parent_tid);
2806 param.flags = param32.flags;
2807 param.rtp = PTRIN(param32.rtp)(void *)(uintptr_t) (param32.rtp);
2808 param.spare[0] = PTRIN(param32.spare[0])(void *)(uintptr_t) (param32.spare[0]);
2809 param.spare[1] = PTRIN(param32.spare[1])(void *)(uintptr_t) (param32.spare[1]);
2810 param.spare[2] = PTRIN(param32.spare[2])(void *)(uintptr_t) (param32.spare[2]);
2811
2812 return (kern_thr_new(td, &param));
2813}
2814
2815int
2816freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
2817{
2818 struct timespec32 ts32;
2819 struct timespec ts, *tsp;
2820 int error;
2821
2822 error = 0;
2823 tsp = NULL((void *)0);
2824 if (uap->timeout != NULL((void *)0)) {
2825 error = copyin((const void *)uap->timeout, (void *)&ts32,
2826 sizeof(struct timespec32));
2827 if (error != 0)
2828 return (error);
2829 ts.tv_sec = ts32.tv_sec;
2830 ts.tv_nsec = ts32.tv_nsec;
2831 tsp = &ts;
2832 }
2833 return (kern_thr_suspend(td, tsp));
2834}
2835
2836void
2837siginfo_to_siginfo32(const siginfo_t *src, struct siginfo32 *dst)
2838{
2839 bzero(dst, sizeof(*dst))__builtin_memset((dst), 0, (sizeof(*dst)));
2840 dst->si_signo = src->si_signo;
2841 dst->si_errno = src->si_errno;
2842 dst->si_code = src->si_code;
2843 dst->si_pid = src->si_pid;
2844 dst->si_uid = src->si_uid;
2845 dst->si_status = src->si_status;
2846 dst->si_addr = (uintptr_t)src->si_addr;
2847 dst->si_value.sival_int = src->si_value.sival_int;
2848 dst->si_timerid_reason._timer._timerid = src->si_timerid_reason._timer._timerid;
2849 dst->si_overrun_reason._timer._overrun = src->si_overrun_reason._timer._overrun;
2850}
2851
2852#ifndef _FREEBSD32_SYSPROTO_H_
2853struct freebsd32_sigqueue_args {
2854 pid_t pid;
2855 int signum;
2856 /* union sigval32 */ int value;
2857};
2858#endif
2859int
2860freebsd32_sigqueue(struct thread *td, struct freebsd32_sigqueue_args *uap)
2861{
2862 union sigval sv;
2863
2864 /*
2865 * On 32-bit ABIs, sival_int and sival_ptr are the same.
2866 * On 64-bit little-endian ABIs, the low bits are the same.
2867 * In 64-bit big-endian ABIs, sival_int overlaps with
2868 * sival_ptr's HIGH bits. We choose to support sival_int
2869 * rather than sival_ptr in this case as it seems to be
2870 * more common.
2871 */
2872 bzero(&sv, sizeof(sv))__builtin_memset((&sv), 0, (sizeof(sv)));
2873 sv.sival_int = uap->value;
2874
2875 return (kern_sigqueue(td, uap->pid, uap->signum, &sv));
2876}
2877
2878int
2879freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
2880{
2881 struct timespec32 ts32;
2882 struct timespec ts;
2883 struct timespec *timeout;
2884 sigset_t set;
2885 ksiginfo_t ksi;
2886 struct siginfo32 si32;
2887 int error;
2888
2889 if (uap->timeout) {
2890 error = copyin(uap->timeout, &ts32, sizeof(ts32));
2891 if (error)
2892 return (error);
2893 ts.tv_sec = ts32.tv_sec;
2894 ts.tv_nsec = ts32.tv_nsec;
2895 timeout = &ts;
2896 } else
2897 timeout = NULL((void *)0);
2898
2899 error = copyin(uap->set, &set, sizeof(set));
2900 if (error)
2901 return (error);
2902
2903 error = kern_sigtimedwait(td, set, &ksi, timeout);
2904 if (error)
2905 return (error);
2906
2907 if (uap->info) {
2908 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2909 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2910 }
2911
2912 if (error == 0)
2913 td->td_retvaltd_uretoff.tdu_retval[0] = ksi.ksi_signoksi_info.si_signo;
2914 return (error);
2915}
2916
2917/*
2918 * MPSAFE
2919 */
2920int
2921freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
2922{
2923 ksiginfo_t ksi;
2924 struct siginfo32 si32;
2925 sigset_t set;
2926 int error;
2927
2928 error = copyin(uap->set, &set, sizeof(set));
2929 if (error)
2930 return (error);
2931
2932 error = kern_sigtimedwait(td, set, &ksi, NULL((void *)0));
2933 if (error)
2934 return (error);
2935
2936 if (uap->info) {
2937 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2938 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2939 }
2940 if (error == 0)
2941 td->td_retvaltd_uretoff.tdu_retval[0] = ksi.ksi_signoksi_info.si_signo;
2942 return (error);
2943}
2944
2945int
2946freebsd32_cpuset_setid(struct thread *td,
2947 struct freebsd32_cpuset_setid_args *uap)
2948{
2949
2950 return (kern_cpuset_setid(td, uap->which,
2951 PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->setid));
2952}
2953
2954int
2955freebsd32_cpuset_getid(struct thread *td,
2956 struct freebsd32_cpuset_getid_args *uap)
2957{
2958
2959 return (kern_cpuset_getid(td, uap->level, uap->which,
2960 PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->setid));
2961}
2962
2963int
2964freebsd32_cpuset_getaffinity(struct thread *td,
2965 struct freebsd32_cpuset_getaffinity_args *uap)
2966{
2967
2968 return (kern_cpuset_getaffinity(td, uap->level, uap->which,
2969 PAIR32TO64(id_t,uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->cpusetsize, uap->mask));
2970}
2971
2972int
2973freebsd32_cpuset_setaffinity(struct thread *td,
2974 struct freebsd32_cpuset_setaffinity_args *uap)
2975{
2976
2977 return (kern_cpuset_setaffinity(td, uap->level, uap->which,
2978 PAIR32TO64(id_t,uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->cpusetsize, uap->mask));
2979}
2980
2981int
2982freebsd32_cpuset_getdomain(struct thread *td,
2983 struct freebsd32_cpuset_getdomain_args *uap)
2984{
2985
2986 return (kern_cpuset_getdomain(td, uap->level, uap->which,
2987 PAIR32TO64(id_t,uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->domainsetsize, uap->mask, uap->policy));
2988}
2989
2990int
2991freebsd32_cpuset_setdomain(struct thread *td,
2992 struct freebsd32_cpuset_setdomain_args *uap)
2993{
2994
2995 return (kern_cpuset_setdomain(td, uap->level, uap->which,
2996 PAIR32TO64(id_t,uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)), uap->domainsetsize, uap->mask, uap->policy));
2997}
2998
2999int
3000freebsd32_nmount(struct thread *td,
3001 struct freebsd32_nmount_args /* {
3002 struct iovec *iovp;
3003 unsigned int iovcnt;
3004 int flags;
3005 } */ *uap)
3006{
3007 struct uio *auio;
3008 uint64_t flags;
3009 int error;
3010
3011 /*
3012 * Mount flags are now 64-bits. On 32-bit archtectures only
3013 * 32-bits are passed in, but from here on everything handles
3014 * 64-bit flags correctly.
3015 */
3016 flags = uap->flags;
3017
3018 AUDIT_ARG_FFLAGS(flags)do { if ((__builtin_expect((((__curthread()))->td_pflags &
0x01000000), 0))) audit_arg_fflags((flags)); } while (0)
;
3019
3020 /*
3021 * Filter out MNT_ROOTFS. We do not want clients of nmount() in
3022 * userspace to set this flag, but we must filter it out if we want
3023 * MNT_UPDATE on the root file system to work.
3024 * MNT_ROOTFS should only be set by the kernel when mounting its
3025 * root file system.
3026 */
3027 flags &= ~MNT_ROOTFS0x0000000000004000ULL;
3028
3029 /*
3030 * check that we have an even number of iovec's
3031 * and that we have at least two options.
3032 */
3033 if ((uap->iovcnt & 1) || (uap->iovcnt < 4))
3034 return (EINVAL22);
3035
3036 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
3037 if (error)
3038 return (error);
3039 error = vfs_donmount(td, flags, auio);
3040
3041 free(auio, M_IOV);
3042 return error;
3043}
3044
3045#if 0
3046int
3047freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
3048{
3049 struct yyy32 *p32, s32;
3050 struct yyy *p = NULL((void *)0), s;
3051 struct xxx_arg ap;
3052 int error;
3053
3054 if (uap->zzz) {
3055 error = copyin(uap->zzz, &s32, sizeof(s32));
3056 if (error)
3057 return (error);
3058 /* translate in */
3059 p = &s;
3060 }
3061 error = kern_xxx(td, p);
3062 if (error)
3063 return (error);
3064 if (uap->zzz) {
3065 /* translate out */
3066 error = copyout(&s32, p32, sizeof(s32));
3067 }
3068 return (error);
3069}
3070#endif
3071
3072int
3073syscall32_module_handler(struct module *mod, int what, void *arg)
3074{
3075
3076 return (kern_syscall_module_handler(freebsd32_sysent, mod, what, arg));
3077}
3078
3079int
3080syscall32_helper_register(struct syscall_helper_data *sd, int flags)
3081{
3082
3083 return (kern_syscall_helper_register(freebsd32_sysent, sd, flags));
3084}
3085
3086int
3087syscall32_helper_unregister(struct syscall_helper_data *sd)
3088{
3089
3090 return (kern_syscall_helper_unregister(freebsd32_sysent, sd));
3091}
3092
3093register_t *
3094freebsd32_copyout_strings(struct image_params *imgp)
3095{
3096 int argc, envc, i;
3097 u_int32_t *vectp;
3098 char *stringp;
3099 uintptr_t destp;
3100 u_int32_t *stack_base;
3101 struct freebsd32_ps_strings *arginfo;
3102 char canary[sizeof(long) * 8];
3103 int32_t pagesizes32[MAXPAGESIZES3];
3104 size_t execpath_len;
3105 int szsigcode;
3106
3107 /*
3108 * Calculate string base and vector table pointers.
3109 * Also deal with signal trampoline code for this exec type.
3110 */
3111 if (imgp->execpath != NULL((void *)0) && imgp->auxargs != NULL((void *)0))
3112 execpath_len = strlen(imgp->execpath) + 1;
3113 else
3114 execpath_len = 0;
3115 arginfo = (struct freebsd32_ps_strings *)curproc((__curthread())->td_proc)->p_sysent->
3116 sv_psstrings;
3117 if (imgp->proc->p_sysent->sv_sigcode_base == 0)
3118 szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
3119 else
3120 szsigcode = 0;
3121 destp = (uintptr_t)arginfo;
3122
3123 /*
3124 * install sigcode
3125 */
3126 if (szsigcode != 0) {
3127 destp -= szsigcode;
3128 destp = rounddown2(destp, sizeof(uint32_t))((destp)&(~((sizeof(uint32_t))-1)));
3129 copyout(imgp->proc->p_sysent->sv_sigcode, (void *)destp,
3130 szsigcode);
3131 }
3132
3133 /*
3134 * Copy the image path for the rtld.
3135 */
3136 if (execpath_len != 0) {
3137 destp -= execpath_len;
3138 imgp->execpathp = destp;
3139 copyout(imgp->execpath, (void *)destp, execpath_len);
3140 }
3141
3142 /*
3143 * Prepare the canary for SSP.
3144 */
3145 arc4rand(canary, sizeof(canary), 0);
3146 destp -= sizeof(canary);
3147 imgp->canary = destp;
3148 copyout(canary, (void *)destp, sizeof(canary));
3149 imgp->canarylen = sizeof(canary);
3150
3151 /*
3152 * Prepare the pagesizes array.
3153 */
3154 for (i = 0; i < MAXPAGESIZES3; i++)
3155 pagesizes32[i] = (uint32_t)pagesizes[i];
3156 destp -= sizeof(pagesizes32);
3157 destp = rounddown2(destp, sizeof(uint32_t))((destp)&(~((sizeof(uint32_t))-1)));
3158 imgp->pagesizes = destp;
3159 copyout(pagesizes32, (void *)destp, sizeof(pagesizes32));
3160 imgp->pagesizeslen = sizeof(pagesizes32);
3161
3162 destp -= ARG_MAX262144 - imgp->args->stringspace;
3163 destp = rounddown2(destp, sizeof(uint32_t))((destp)&(~((sizeof(uint32_t))-1)));
3164
3165 vectp = (uint32_t *)destp;
3166 if (imgp->auxargs) {
3167 /*
3168 * Allocate room on the stack for the ELF auxargs
3169 * array. It has up to AT_COUNT entries.
3170 */
3171 vectp -= howmany(AT_COUNT * sizeof(Elf32_Auxinfo),(((27 * sizeof(Elf32_Auxinfo))+((sizeof(*vectp))-1))/(sizeof(
*vectp)))
3172 sizeof(*vectp))(((27 * sizeof(Elf32_Auxinfo))+((sizeof(*vectp))-1))/(sizeof(
*vectp)))
;
3173 }
3174
3175 /*
3176 * Allocate room for the argv[] and env vectors including the
3177 * terminating NULL pointers.
3178 */
3179 vectp -= imgp->args->argc + 1 + imgp->args->envc + 1;
3180
3181 /*
3182 * vectp also becomes our initial stack base
3183 */
3184 stack_base = vectp;
3185
3186 stringp = imgp->args->begin_argv;
3187 argc = imgp->args->argc;
3188 envc = imgp->args->envc;
3189 /*
3190 * Copy out strings - arguments and environment.
3191 */
3192 copyout(stringp, (void *)destp, ARG_MAX262144 - imgp->args->stringspace);
3193
3194 /*
3195 * Fill in "ps_strings" struct for ps, w, etc.
3196 */
3197 suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
3198 suword32(&arginfo->ps_nargvstr, argc);
3199
3200 /*
3201 * Fill in argument portion of vector table.
3202 */
3203 for (; argc > 0; --argc) {
3204 suword32(vectp++, (u_int32_t)(intptr_t)destp);
3205 while (*stringp++ != 0)
3206 destp++;
3207 destp++;
3208 }
3209
3210 /* a null vector table pointer separates the argp's from the envp's */
3211 suword32(vectp++, 0);
3212
3213 suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
3214 suword32(&arginfo->ps_nenvstr, envc);
3215
3216 /*
3217 * Fill in environment portion of vector table.
3218 */
3219 for (; envc > 0; --envc) {
3220 suword32(vectp++, (u_int32_t)(intptr_t)destp);
3221 while (*stringp++ != 0)
3222 destp++;
3223 destp++;
3224 }
3225
3226 /* end of vector table is a null pointer */
3227 suword32(vectp, 0);
3228
3229 return ((register_t *)stack_base);
3230}
3231
3232int
3233freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap)
3234{
3235 struct kld_file_stat *stat;
3236 struct kld32_file_stat *stat32;
3237 int error, version;
3238
3239 if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
3240 != 0)
3241 return (error);
3242 if (version != sizeof(struct kld32_file_stat_1) &&
3243 version != sizeof(struct kld32_file_stat))
3244 return (EINVAL22);
3245
3246 stat = malloc(sizeof(*stat), M_TEMP, M_WAITOK0x0002 | M_ZERO0x0100);
3247 stat32 = malloc(sizeof(*stat32), M_TEMP, M_WAITOK0x0002 | M_ZERO0x0100);
3248 error = kern_kldstat(td, uap->fileid, stat);
3249 if (error == 0) {
3250 bcopy(&stat->name[0], &stat32->name[0], sizeof(stat->name))__builtin_memmove((&stat32->name[0]), (&stat->name
[0]), (sizeof(stat->name)))
;
3251 CP(*stat, *stat32, refs)do { (*stat32).refs = (*stat).refs; } while (0);
3252 CP(*stat, *stat32, id)do { (*stat32).id = (*stat).id; } while (0);
3253 PTROUT_CP(*stat, *stat32, address)do { (*stat32).address = (u_int32_t)(uintptr_t) ((*stat).address
); } while (0)
;
3254 CP(*stat, *stat32, size)do { (*stat32).size = (*stat).size; } while (0);
3255 bcopy(&stat->pathname[0], &stat32->pathname[0],__builtin_memmove((&stat32->pathname[0]), (&stat->
pathname[0]), (sizeof(stat->pathname)))
3256 sizeof(stat->pathname))__builtin_memmove((&stat32->pathname[0]), (&stat->
pathname[0]), (sizeof(stat->pathname)))
;
3257 stat32->version = version;
3258 error = copyout(stat32, uap->stat, version);
3259 }
3260 free(stat, M_TEMP);
3261 free(stat32, M_TEMP);
3262 return (error);
3263}
3264
3265int
3266freebsd32_posix_fallocate(struct thread *td,
3267 struct freebsd32_posix_fallocate_args *uap)
3268{
3269 int error;
3270
3271 error = kern_posix_fallocate(td, uap->fd,
3272 PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)), PAIR32TO64(off_t, uap->len)((uap->len1) | ((off_t)(uap->len2) << 32)));
3273 return (kern_posix_error(td, error));
3274}
3275
3276int
3277freebsd32_posix_fadvise(struct thread *td,
3278 struct freebsd32_posix_fadvise_args *uap)
3279{
3280 int error;
3281
3282 error = kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset)((uap->offset1) | ((off_t)(uap->offset2) << 32)),
3283 PAIR32TO64(off_t, uap->len)((uap->len1) | ((off_t)(uap->len2) << 32)), uap->advice);
3284 return (kern_posix_error(td, error));
3285}
3286
3287int
3288convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig)
3289{
3290
3291 CP(*sig32, *sig, sigev_notify)do { (*sig).sigev_notify = (*sig32).sigev_notify; } while (0);
3292 switch (sig->sigev_notify) {
3293 case SIGEV_NONE0:
3294 break;
3295 case SIGEV_THREAD_ID4:
3296 CP(*sig32, *sig, sigev_notify_thread_id)do { (*sig)._sigev_un._threadid = (*sig32)._sigev_un._threadid
; } while (0)
;
3297 /* FALLTHROUGH */
3298 case SIGEV_SIGNAL1:
3299 CP(*sig32, *sig, sigev_signo)do { (*sig).sigev_signo = (*sig32).sigev_signo; } while (0);
3300 PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr)do { (*sig).sigev_value.sival_ptr = (void *)(uintptr_t) ((*sig32
).sigev_value.sival_ptr); } while (0)
;
3301 break;
3302 case SIGEV_KEVENT3:
3303 CP(*sig32, *sig, sigev_notify_kqueue)do { (*sig).sigev_signo = (*sig32).sigev_signo; } while (0);
3304 CP(*sig32, *sig, sigev_notify_kevent_flags)do { (*sig)._sigev_un._kevent_flags = (*sig32)._sigev_un._kevent_flags
; } while (0)
;
3305 PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr)do { (*sig).sigev_value.sival_ptr = (void *)(uintptr_t) ((*sig32
).sigev_value.sival_ptr); } while (0)
;
3306 break;
3307 default:
3308 return (EINVAL22);
3309 }
3310 return (0);
3311}
3312
3313int
3314freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap)
3315{
3316 void *data;
3317 union {
3318 struct procctl_reaper_status rs;
3319 struct procctl_reaper_pids rp;
3320 struct procctl_reaper_kill rk;
3321 } x;
3322 union {
3323 struct procctl_reaper_pids32 rp;
3324 } x32;
3325 int error, error1, flags, signum;
3326
3327 switch (uap->com) {
3328 case PROC_SPROTECT1:
3329 case PROC_TRACE_CTL7:
3330 case PROC_TRAPCAP_CTL9:
3331 error = copyin(PTRIN(uap->data)(void *)(uintptr_t) (uap->data), &flags, sizeof(flags));
3332 if (error != 0)
3333 return (error);
3334 data = &flags;
3335 break;
3336 case PROC_REAP_ACQUIRE2:
3337 case PROC_REAP_RELEASE3:
3338 if (uap->data != NULL((void *)0))
3339 return (EINVAL22);
3340 data = NULL((void *)0);
3341 break;
3342 case PROC_REAP_STATUS4:
3343 data = &x.rs;
3344 break;
3345 case PROC_REAP_GETPIDS5:
3346 error = copyin(uap->data, &x32.rp, sizeof(x32.rp));
3347 if (error != 0)
3348 return (error);
3349 CP(x32.rp, x.rp, rp_count)do { (x.rp).rp_count = (x32.rp).rp_count; } while (0);
3350 PTRIN_CP(x32.rp, x.rp, rp_pids)do { (x.rp).rp_pids = (void *)(uintptr_t) ((x32.rp).rp_pids);
} while (0)
;
3351 data = &x.rp;
3352 break;
3353 case PROC_REAP_KILL6:
3354 error = copyin(uap->data, &x.rk, sizeof(x.rk));
3355 if (error != 0)
3356 return (error);
3357 data = &x.rk;
3358 break;
3359 case PROC_TRACE_STATUS8:
3360 case PROC_TRAPCAP_STATUS10:
3361 data = &flags;
3362 break;
3363 case PROC_PDEATHSIG_CTL11:
3364 error = copyin(uap->data, &signum, sizeof(signum));
3365 if (error != 0)
3366 return (error);
3367 data = &signum;
3368 break;
3369 case PROC_PDEATHSIG_STATUS12:
3370 data = &signum;
3371 break;
3372 default:
3373 return (EINVAL22);
3374 }
3375 error = kern_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id)((uap->id1) | ((id_t)(uap->id2) << 32)),
3376 uap->com, data);
3377 switch (uap->com) {
3378 case PROC_REAP_STATUS4:
3379 if (error == 0)
3380 error = copyout(&x.rs, uap->data, sizeof(x.rs));
3381 break;
3382 case PROC_REAP_KILL6:
3383 error1 = copyout(&x.rk, uap->data, sizeof(x.rk));
3384 if (error == 0)
3385 error = error1;
3386 break;
3387 case PROC_TRACE_STATUS8:
3388 case PROC_TRAPCAP_STATUS10:
3389 if (error == 0)
3390 error = copyout(&flags, uap->data, sizeof(flags));
3391 break;
3392 case PROC_PDEATHSIG_STATUS12:
3393 if (error == 0)
3394 error = copyout(&signum, uap->data, sizeof(signum));
3395 break;
3396 }
3397 return (error);
3398}
3399
3400int
3401freebsd32_fcntl(struct thread *td, struct freebsd32_fcntl_args *uap)
3402{
3403 long tmp;
3404
3405 switch (uap->cmd) {
3406 /*
3407 * Do unsigned conversion for arg when operation
3408 * interprets it as flags or pointer.
3409 */
3410 case F_SETLK_REMOTE14:
3411 case F_SETLKW13:
3412 case F_SETLK12:
3413 case F_GETLK11:
3414 case F_SETFD2:
3415 case F_SETFL4:
3416 case F_OGETLK7:
3417 case F_OSETLK8:
3418 case F_OSETLKW9:
3419 tmp = (unsigned int)(uap->arg);
3420 break;
3421 default:
3422 tmp = uap->arg;
3423 break;
3424 }
3425 return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp));
3426}
3427
3428int
3429freebsd32_ppoll(struct thread *td, struct freebsd32_ppoll_args *uap)
3430{
3431 struct timespec32 ts32;
3432 struct timespec ts, *tsp;
3433 sigset_t set, *ssp;
3434 int error;
3435
3436 if (uap->ts != NULL((void *)0)) {
3437 error = copyin(uap->ts, &ts32, sizeof(ts32));
3438 if (error != 0)
3439 return (error);
3440 CP(ts32, ts, tv_sec)do { (ts).tv_sec = (ts32).tv_sec; } while (0);
3441 CP(ts32, ts, tv_nsec)do { (ts).tv_nsec = (ts32).tv_nsec; } while (0);
3442 tsp = &ts;
3443 } else
3444 tsp = NULL((void *)0);
3445 if (uap->set != NULL((void *)0)) {
3446 error = copyin(uap->set, &set, sizeof(set));
3447 if (error != 0)
3448 return (error);
3449 ssp = &set;
3450 } else
3451 ssp = NULL((void *)0);
3452
3453 return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
3454}
3455
3456int
3457freebsd32_sched_rr_get_interval(struct thread *td,
3458 struct freebsd32_sched_rr_get_interval_args *uap)
3459{
3460 struct timespec ts;
3461 struct timespec32 ts32;
3462 int error;
3463
3464 error = kern_sched_rr_get_interval(td, uap->pid, &ts);
3465 if (error == 0) {
3466 CP(ts, ts32, tv_sec)do { (ts32).tv_sec = (ts).tv_sec; } while (0);
3467 CP(ts, ts32, tv_nsec)do { (ts32).tv_nsec = (ts).tv_nsec; } while (0);
3468 error = copyout(&ts32, uap->interval, sizeof(ts32));
3469 }
3470 return (error);
3471}