Bug Summary

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

Annotated Source Code

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