1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2002 Doug Rabson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 #include "opt_ffclock.h"
31 #include "opt_inet.h"
32 #include "opt_inet6.h"
33 #include "opt_ktrace.h"
34
35 #define __ELF_WORD_SIZE 32
36
37 #ifdef COMPAT_FREEBSD11
38 #define _WANT_FREEBSD11_KEVENT
39 #endif
40
41 #include <sys/param.h>
42 #include <sys/bus.h>
43 #include <sys/capsicum.h>
44 #include <sys/clock.h>
45 #include <sys/exec.h>
46 #include <sys/fcntl.h>
47 #include <sys/filedesc.h>
48 #include <sys/imgact.h>
49 #include <sys/jail.h>
50 #include <sys/kernel.h>
51 #include <sys/limits.h>
52 #include <sys/linker.h>
53 #include <sys/lock.h>
54 #include <sys/malloc.h>
55 #include <sys/file.h> /* Must come after sys/malloc.h */
56 #include <sys/imgact.h>
57 #include <sys/mbuf.h>
58 #include <sys/mman.h>
59 #include <sys/module.h>
60 #include <sys/mount.h>
61 #include <sys/mutex.h>
62 #include <sys/namei.h>
63 #include <sys/priv.h>
64 #include <sys/proc.h>
65 #include <sys/procctl.h>
66 #include <sys/ptrace.h>
67 #include <sys/reboot.h>
68 #include <sys/resource.h>
69 #include <sys/resourcevar.h>
70 #include <sys/selinfo.h>
71 #include <sys/eventvar.h> /* Must come after sys/selinfo.h */
72 #include <sys/pipe.h> /* Must come after sys/selinfo.h */
73 #include <sys/signal.h>
74 #include <sys/signalvar.h>
75 #include <sys/socket.h>
76 #include <sys/socketvar.h>
77 #include <sys/stat.h>
78 #include <sys/syscall.h>
79 #include <sys/syscallsubr.h>
80 #include <sys/sysctl.h>
81 #include <sys/sysent.h>
82 #include <sys/sysproto.h>
83 #include <sys/systm.h>
84 #include <sys/thr.h>
85 #include <sys/timerfd.h>
86 #include <sys/timex.h>
87 #include <sys/unistd.h>
88 #include <sys/ucontext.h>
89 #include <sys/ucred.h>
90 #include <sys/vnode.h>
91 #include <sys/wait.h>
92 #include <sys/ipc.h>
93 #include <sys/msg.h>
94 #include <sys/sem.h>
95 #include <sys/shm.h>
96 #include <sys/timeffc.h>
97 #ifdef KTRACE
98 #include <sys/ktrace.h>
99 #endif
100
101 #ifdef INET
102 #include <netinet/in.h>
103 #endif
104
105 #include <vm/vm.h>
106 #include <vm/vm_param.h>
107 #include <vm/pmap.h>
108 #include <vm/vm_map.h>
109 #include <vm/vm_object.h>
110 #include <vm/vm_extern.h>
111
112 #include <machine/cpu.h>
113 #include <machine/elf.h>
114 #ifdef __amd64__
115 #include <machine/md_var.h>
116 #endif
117
118 #include <security/audit/audit.h>
119 #include <security/mac/mac_syscalls.h>
120
121 #include <compat/freebsd32/freebsd32_util.h>
122 #include <compat/freebsd32/freebsd32.h>
123 #include <compat/freebsd32/freebsd32_ipc.h>
124 #include <compat/freebsd32/freebsd32_misc.h>
125 #include <compat/freebsd32/freebsd32_signal.h>
126 #include <compat/freebsd32/freebsd32_proto.h>
127
128 int compat_freebsd_32bit = 1;
129
130 static void
register_compat32_feature(void * arg)131 register_compat32_feature(void *arg)
132 {
133 if (!compat_freebsd_32bit)
134 return;
135
136 FEATURE_ADD("compat_freebsd32", "Compatible with 32-bit FreeBSD");
137 FEATURE_ADD("compat_freebsd_32bit",
138 "Compatible with 32-bit FreeBSD (legacy feature name)");
139 }
140 SYSINIT(freebsd32, SI_SUB_EXEC, SI_ORDER_ANY, register_compat32_feature,
141 NULL);
142
143 struct ptrace_io_desc32 {
144 int piod_op;
145 uint32_t piod_offs;
146 uint32_t piod_addr;
147 uint32_t piod_len;
148 };
149
150 struct ptrace_vm_entry32 {
151 int pve_entry;
152 int pve_timestamp;
153 uint32_t pve_start;
154 uint32_t pve_end;
155 uint32_t pve_offset;
156 u_int pve_prot;
157 u_int pve_pathlen;
158 int32_t pve_fileid;
159 u_int pve_fsid;
160 uint32_t pve_path;
161 };
162
163 #ifdef __amd64__
164 CTASSERT(sizeof(struct timeval32) == 8);
165 CTASSERT(sizeof(struct timespec32) == 8);
166 CTASSERT(sizeof(struct itimerval32) == 16);
167 CTASSERT(sizeof(struct bintime32) == 12);
168 #else
169 CTASSERT(sizeof(struct timeval32) == 16);
170 CTASSERT(sizeof(struct timespec32) == 16);
171 CTASSERT(sizeof(struct itimerval32) == 32);
172 CTASSERT(sizeof(struct bintime32) == 16);
173 #endif
174 CTASSERT(sizeof(struct ostatfs32) == 256);
175 #ifdef __amd64__
176 CTASSERT(sizeof(struct rusage32) == 72);
177 #else
178 CTASSERT(sizeof(struct rusage32) == 88);
179 #endif
180 CTASSERT(sizeof(struct sigaltstack32) == 12);
181 #ifdef __amd64__
182 CTASSERT(sizeof(struct kevent32) == 56);
183 #else
184 CTASSERT(sizeof(struct kevent32) == 64);
185 #endif
186 CTASSERT(sizeof(struct iovec32) == 8);
187 CTASSERT(sizeof(struct msghdr32) == 28);
188 #ifdef __amd64__
189 CTASSERT(sizeof(struct stat32) == 208);
190 CTASSERT(sizeof(struct freebsd11_stat32) == 96);
191 #else
192 CTASSERT(sizeof(struct stat32) == 224);
193 CTASSERT(sizeof(struct freebsd11_stat32) == 120);
194 #endif
195 CTASSERT(sizeof(struct sigaction32) == 24);
196
197 static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
198 static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
199 static int freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
200 int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp);
201
202 void
freebsd32_rusage_out(const struct rusage * s,struct rusage32 * s32)203 freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32)
204 {
205
206 TV_CP(*s, *s32, ru_utime);
207 TV_CP(*s, *s32, ru_stime);
208 CP(*s, *s32, ru_maxrss);
209 CP(*s, *s32, ru_ixrss);
210 CP(*s, *s32, ru_idrss);
211 CP(*s, *s32, ru_isrss);
212 CP(*s, *s32, ru_minflt);
213 CP(*s, *s32, ru_majflt);
214 CP(*s, *s32, ru_nswap);
215 CP(*s, *s32, ru_inblock);
216 CP(*s, *s32, ru_oublock);
217 CP(*s, *s32, ru_msgsnd);
218 CP(*s, *s32, ru_msgrcv);
219 CP(*s, *s32, ru_nsignals);
220 CP(*s, *s32, ru_nvcsw);
221 CP(*s, *s32, ru_nivcsw);
222 }
223
224 int
freebsd32_wait4(struct thread * td,struct freebsd32_wait4_args * uap)225 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
226 {
227 int error, status;
228 struct rusage32 ru32;
229 struct rusage ru, *rup;
230
231 if (uap->rusage != NULL)
232 rup = &ru;
233 else
234 rup = NULL;
235 error = kern_wait(td, uap->pid, &status, uap->options, rup);
236 if (error)
237 return (error);
238 if (uap->status != NULL)
239 error = copyout(&status, uap->status, sizeof(status));
240 if (uap->rusage != NULL && error == 0) {
241 freebsd32_rusage_out(&ru, &ru32);
242 error = copyout(&ru32, uap->rusage, sizeof(ru32));
243 }
244 return (error);
245 }
246
247 int
freebsd32_wait6(struct thread * td,struct freebsd32_wait6_args * uap)248 freebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap)
249 {
250 struct __wrusage32 wru32;
251 struct __wrusage wru, *wrup;
252 struct __siginfo32 si32;
253 struct __siginfo si, *sip;
254 int error, status;
255
256 if (uap->wrusage != NULL)
257 wrup = &wru;
258 else
259 wrup = NULL;
260 if (uap->info != NULL) {
261 sip = &si;
262 bzero(sip, sizeof(*sip));
263 } else
264 sip = NULL;
265 error = kern_wait6(td, uap->idtype, PAIR32TO64(id_t, uap->id),
266 &status, uap->options, wrup, sip);
267 if (error != 0)
268 return (error);
269 if (uap->status != NULL)
270 error = copyout(&status, uap->status, sizeof(status));
271 if (uap->wrusage != NULL && error == 0) {
272 freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self);
273 freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children);
274 error = copyout(&wru32, uap->wrusage, sizeof(wru32));
275 }
276 if (uap->info != NULL && error == 0) {
277 siginfo_to_siginfo32 (&si, &si32);
278 error = copyout(&si32, uap->info, sizeof(si32));
279 }
280 return (error);
281 }
282
283 #ifdef COMPAT_FREEBSD4
284 static void
copy_statfs(struct statfs * in,struct ostatfs32 * out)285 copy_statfs(struct statfs *in, struct ostatfs32 *out)
286 {
287
288 statfs_scale_blocks(in, INT32_MAX);
289 bzero(out, sizeof(*out));
290 CP(*in, *out, f_bsize);
291 out->f_iosize = MIN(in->f_iosize, INT32_MAX);
292 CP(*in, *out, f_blocks);
293 CP(*in, *out, f_bfree);
294 CP(*in, *out, f_bavail);
295 out->f_files = MIN(in->f_files, INT32_MAX);
296 out->f_ffree = MIN(in->f_ffree, INT32_MAX);
297 CP(*in, *out, f_fsid);
298 CP(*in, *out, f_owner);
299 CP(*in, *out, f_type);
300 CP(*in, *out, f_flags);
301 out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX);
302 out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX);
303 strlcpy(out->f_fstypename,
304 in->f_fstypename, MFSNAMELEN);
305 strlcpy(out->f_mntonname,
306 in->f_mntonname, min(MNAMELEN, FREEBSD4_OMNAMELEN));
307 out->f_syncreads = MIN(in->f_syncreads, INT32_MAX);
308 out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX);
309 strlcpy(out->f_mntfromname,
310 in->f_mntfromname, min(MNAMELEN, FREEBSD4_OMNAMELEN));
311 }
312 #endif
313
314 int
freebsd32_getfsstat(struct thread * td,struct freebsd32_getfsstat_args * uap)315 freebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap)
316 {
317 size_t count;
318 int error;
319
320 if (uap->bufsize < 0 || uap->bufsize > SIZE_MAX)
321 return (EINVAL);
322 error = kern_getfsstat(td, &uap->buf, uap->bufsize, &count,
323 UIO_USERSPACE, uap->mode);
324 if (error == 0)
325 td->td_retval[0] = count;
326 return (error);
327 }
328
329 #ifdef COMPAT_FREEBSD4
330 int
freebsd4_freebsd32_getfsstat(struct thread * td,struct freebsd4_freebsd32_getfsstat_args * uap)331 freebsd4_freebsd32_getfsstat(struct thread *td,
332 struct freebsd4_freebsd32_getfsstat_args *uap)
333 {
334 struct statfs *buf, *sp;
335 struct ostatfs32 stat32;
336 size_t count, size, copycount;
337 int error;
338
339 count = uap->bufsize / sizeof(struct ostatfs32);
340 size = count * sizeof(struct statfs);
341 error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->mode);
342 if (size > 0) {
343 sp = buf;
344 copycount = count;
345 while (copycount > 0 && error == 0) {
346 copy_statfs(sp, &stat32);
347 error = copyout(&stat32, uap->buf, sizeof(stat32));
348 sp++;
349 uap->buf++;
350 copycount--;
351 }
352 free(buf, M_STATFS);
353 }
354 if (error == 0)
355 td->td_retval[0] = count;
356 return (error);
357 }
358 #endif
359
360 #ifdef COMPAT_FREEBSD11
361 int
freebsd11_freebsd32_getfsstat(struct thread * td,struct freebsd11_freebsd32_getfsstat_args * uap)362 freebsd11_freebsd32_getfsstat(struct thread *td,
363 struct freebsd11_freebsd32_getfsstat_args *uap)
364 {
365 return(kern_freebsd11_getfsstat(td, uap->buf, uap->bufsize,
366 uap->mode));
367 }
368 #endif
369
370 int
freebsd32_sigaltstack(struct thread * td,struct freebsd32_sigaltstack_args * uap)371 freebsd32_sigaltstack(struct thread *td,
372 struct freebsd32_sigaltstack_args *uap)
373 {
374 struct sigaltstack32 s32;
375 struct sigaltstack ss, oss, *ssp;
376 int error;
377
378 if (uap->ss != NULL) {
379 error = copyin(uap->ss, &s32, sizeof(s32));
380 if (error)
381 return (error);
382 PTRIN_CP(s32, ss, ss_sp);
383 CP(s32, ss, ss_size);
384 CP(s32, ss, ss_flags);
385 ssp = &ss;
386 } else
387 ssp = NULL;
388 error = kern_sigaltstack(td, ssp, &oss);
389 if (error == 0 && uap->oss != NULL) {
390 PTROUT_CP(oss, s32, ss_sp);
391 CP(oss, s32, ss_size);
392 CP(oss, s32, ss_flags);
393 error = copyout(&s32, uap->oss, sizeof(s32));
394 }
395 return (error);
396 }
397
398 /*
399 * Custom version of exec_copyin_args() so that we can translate
400 * the pointers.
401 */
402 int
freebsd32_exec_copyin_args(struct image_args * args,const char * fname,uint32_t * argv,uint32_t * envv)403 freebsd32_exec_copyin_args(struct image_args *args, const char *fname,
404 uint32_t *argv, uint32_t *envv)
405 {
406 char *argp, *envp;
407 uint32_t *p32, arg;
408 int error;
409
410 bzero(args, sizeof(*args));
411 if (argv == NULL)
412 return (EFAULT);
413
414 /*
415 * Allocate demand-paged memory for the file name, argument, and
416 * environment strings.
417 */
418 error = exec_alloc_args(args);
419 if (error != 0)
420 return (error);
421
422 /*
423 * Copy the file name.
424 */
425 error = exec_args_add_fname(args, fname, UIO_USERSPACE);
426 if (error != 0)
427 goto err_exit;
428
429 /*
430 * extract arguments first
431 */
432 p32 = argv;
433 for (;;) {
434 error = copyin(p32++, &arg, sizeof(arg));
435 if (error)
436 goto err_exit;
437 if (arg == 0)
438 break;
439 argp = PTRIN(arg);
440 error = exec_args_add_arg(args, argp, UIO_USERSPACE);
441 if (error != 0)
442 goto err_exit;
443 }
444
445 /*
446 * extract environment strings
447 */
448 if (envv) {
449 p32 = envv;
450 for (;;) {
451 error = copyin(p32++, &arg, sizeof(arg));
452 if (error)
453 goto err_exit;
454 if (arg == 0)
455 break;
456 envp = PTRIN(arg);
457 error = exec_args_add_env(args, envp, UIO_USERSPACE);
458 if (error != 0)
459 goto err_exit;
460 }
461 }
462
463 return (0);
464
465 err_exit:
466 exec_free_args(args);
467 return (error);
468 }
469
470 int
freebsd32_execve(struct thread * td,struct freebsd32_execve_args * uap)471 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
472 {
473 struct image_args eargs;
474 struct vmspace *oldvmspace;
475 int error;
476
477 error = pre_execve(td, &oldvmspace);
478 if (error != 0)
479 return (error);
480 error = freebsd32_exec_copyin_args(&eargs, uap->fname, uap->argv,
481 uap->envv);
482 if (error == 0)
483 error = kern_execve(td, &eargs, NULL, oldvmspace);
484 post_execve(td, error, oldvmspace);
485 AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
486 return (error);
487 }
488
489 int
freebsd32_fexecve(struct thread * td,struct freebsd32_fexecve_args * uap)490 freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap)
491 {
492 struct image_args eargs;
493 struct vmspace *oldvmspace;
494 int error;
495
496 error = pre_execve(td, &oldvmspace);
497 if (error != 0)
498 return (error);
499 error = freebsd32_exec_copyin_args(&eargs, NULL, uap->argv, uap->envv);
500 if (error == 0) {
501 eargs.fd = uap->fd;
502 error = kern_execve(td, &eargs, NULL, oldvmspace);
503 }
504 post_execve(td, error, oldvmspace);
505 AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
506 return (error);
507 }
508
509 int
freebsd32_mknodat(struct thread * td,struct freebsd32_mknodat_args * uap)510 freebsd32_mknodat(struct thread *td, struct freebsd32_mknodat_args *uap)
511 {
512
513 return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE,
514 uap->mode, PAIR32TO64(dev_t, uap->dev)));
515 }
516
517 int
freebsd32_mprotect(struct thread * td,struct freebsd32_mprotect_args * uap)518 freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap)
519 {
520 int prot;
521
522 prot = uap->prot;
523 #if defined(__amd64__)
524 if (i386_read_exec && (prot & PROT_READ) != 0)
525 prot |= PROT_EXEC;
526 #endif
527 return (kern_mprotect(td, (uintptr_t)PTRIN(uap->addr), uap->len,
528 prot, 0));
529 }
530
531 int
freebsd32_mmap(struct thread * td,struct freebsd32_mmap_args * uap)532 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
533 {
534 int prot;
535
536 prot = uap->prot;
537 #if defined(__amd64__)
538 if (i386_read_exec && (prot & PROT_READ))
539 prot |= PROT_EXEC;
540 #endif
541
542 return (kern_mmap(td, &(struct mmap_req){
543 .mr_hint = (uintptr_t)uap->addr,
544 .mr_len = uap->len,
545 .mr_prot = prot,
546 .mr_flags = uap->flags,
547 .mr_fd = uap->fd,
548 .mr_pos = PAIR32TO64(off_t, uap->pos),
549 }));
550 }
551
552 #ifdef COMPAT_FREEBSD6
553 int
freebsd6_freebsd32_mmap(struct thread * td,struct freebsd6_freebsd32_mmap_args * uap)554 freebsd6_freebsd32_mmap(struct thread *td,
555 struct freebsd6_freebsd32_mmap_args *uap)
556 {
557 int prot;
558
559 prot = uap->prot;
560 #if defined(__amd64__)
561 if (i386_read_exec && (prot & PROT_READ))
562 prot |= PROT_EXEC;
563 #endif
564
565 return (kern_mmap(td, &(struct mmap_req){
566 .mr_hint = (uintptr_t)uap->addr,
567 .mr_len = uap->len,
568 .mr_prot = prot,
569 .mr_flags = uap->flags,
570 .mr_fd = uap->fd,
571 .mr_pos = PAIR32TO64(off_t, uap->pos),
572 }));
573 }
574 #endif
575
576 #ifdef COMPAT_43
577 int
ofreebsd32_mmap(struct thread * td,struct ofreebsd32_mmap_args * uap)578 ofreebsd32_mmap(struct thread *td, struct ofreebsd32_mmap_args *uap)
579 {
580 return (kern_ommap(td, (uintptr_t)uap->addr, uap->len, uap->prot,
581 uap->flags, uap->fd, uap->pos));
582 }
583 #endif
584
585 int
freebsd32_setitimer(struct thread * td,struct freebsd32_setitimer_args * uap)586 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
587 {
588 struct itimerval itv, oitv, *itvp;
589 struct itimerval32 i32;
590 int error;
591
592 if (uap->itv != NULL) {
593 error = copyin(uap->itv, &i32, sizeof(i32));
594 if (error)
595 return (error);
596 TV_CP(i32, itv, it_interval);
597 TV_CP(i32, itv, it_value);
598 itvp = &itv;
599 } else
600 itvp = NULL;
601 error = kern_setitimer(td, uap->which, itvp, &oitv);
602 if (error || uap->oitv == NULL)
603 return (error);
604 TV_CP(oitv, i32, it_interval);
605 TV_CP(oitv, i32, it_value);
606 return (copyout(&i32, uap->oitv, sizeof(i32)));
607 }
608
609 int
freebsd32_getitimer(struct thread * td,struct freebsd32_getitimer_args * uap)610 freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
611 {
612 struct itimerval itv;
613 struct itimerval32 i32;
614 int error;
615
616 error = kern_getitimer(td, uap->which, &itv);
617 if (error || uap->itv == NULL)
618 return (error);
619 TV_CP(itv, i32, it_interval);
620 TV_CP(itv, i32, it_value);
621 return (copyout(&i32, uap->itv, sizeof(i32)));
622 }
623
624 int
freebsd32_select(struct thread * td,struct freebsd32_select_args * uap)625 freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
626 {
627 struct timeval32 tv32;
628 struct timeval tv, *tvp;
629 int error;
630
631 if (uap->tv != NULL) {
632 error = copyin(uap->tv, &tv32, sizeof(tv32));
633 if (error)
634 return (error);
635 CP(tv32, tv, tv_sec);
636 CP(tv32, tv, tv_usec);
637 tvp = &tv;
638 } else
639 tvp = NULL;
640 /*
641 * XXX Do pointers need PTRIN()?
642 */
643 return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
644 sizeof(int32_t) * 8));
645 }
646
647 int
freebsd32_pselect(struct thread * td,struct freebsd32_pselect_args * uap)648 freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
649 {
650 struct timespec32 ts32;
651 struct timespec ts;
652 struct timeval tv, *tvp;
653 sigset_t set, *uset;
654 int error;
655
656 if (uap->ts != NULL) {
657 error = copyin(uap->ts, &ts32, sizeof(ts32));
658 if (error != 0)
659 return (error);
660 CP(ts32, ts, tv_sec);
661 CP(ts32, ts, tv_nsec);
662 TIMESPEC_TO_TIMEVAL(&tv, &ts);
663 tvp = &tv;
664 } else
665 tvp = NULL;
666 if (uap->sm != NULL) {
667 error = copyin(uap->sm, &set, sizeof(set));
668 if (error != 0)
669 return (error);
670 uset = &set;
671 } else
672 uset = NULL;
673 /*
674 * XXX Do pointers need PTRIN()?
675 */
676 error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
677 uset, sizeof(int32_t) * 8);
678 return (error);
679 }
680
681 static void
freebsd32_kevent_to_kevent32(const struct kevent * kevp,struct kevent32 * ks32)682 freebsd32_kevent_to_kevent32(const struct kevent *kevp, struct kevent32 *ks32)
683 {
684 uint64_t e;
685 int j;
686
687 CP(*kevp, *ks32, ident);
688 CP(*kevp, *ks32, filter);
689 CP(*kevp, *ks32, flags);
690 CP(*kevp, *ks32, fflags);
691 #if BYTE_ORDER == LITTLE_ENDIAN
692 ks32->data1 = kevp->data;
693 ks32->data2 = kevp->data >> 32;
694 #else
695 ks32->data1 = kevp->data >> 32;
696 ks32->data2 = kevp->data;
697 #endif
698 PTROUT_CP(*kevp, *ks32, udata);
699 for (j = 0; j < nitems(kevp->ext); j++) {
700 e = kevp->ext[j];
701 #if BYTE_ORDER == LITTLE_ENDIAN
702 ks32->ext64[2 * j] = e;
703 ks32->ext64[2 * j + 1] = e >> 32;
704 #else
705 ks32->ext64[2 * j] = e >> 32;
706 ks32->ext64[2 * j + 1] = e;
707 #endif
708 }
709 }
710
711 void
freebsd32_kinfo_knote_to_32(const struct kinfo_knote * kin,struct kinfo_knote32 * kin32)712 freebsd32_kinfo_knote_to_32(const struct kinfo_knote *kin,
713 struct kinfo_knote32 *kin32)
714 {
715 memset(kin32, 0, sizeof(*kin32));
716 CP(*kin, *kin32, knt_kq_fd);
717 freebsd32_kevent_to_kevent32(&kin->knt_event, &kin32->knt_event);
718 CP(*kin, *kin32, knt_status);
719 CP(*kin, *kin32, knt_extdata);
720 switch (kin->knt_extdata) {
721 case KNOTE_EXTDATA_NONE:
722 break;
723 case KNOTE_EXTDATA_VNODE:
724 CP(*kin, *kin32, knt_vnode.knt_vnode_type);
725 #if BYTE_ORDER == LITTLE_ENDIAN
726 kin32->knt_vnode.knt_vnode_fsid[0] = kin->knt_vnode.
727 knt_vnode_fsid;
728 kin32->knt_vnode.knt_vnode_fsid[1] = kin->knt_vnode.
729 knt_vnode_fsid >> 32;
730 kin32->knt_vnode.knt_vnode_fileid[0] = kin->knt_vnode.
731 knt_vnode_fileid;
732 kin32->knt_vnode.knt_vnode_fileid[1] = kin->knt_vnode.
733 knt_vnode_fileid >> 32;
734 #else
735 kin32->knt_vnode.knt_vnode_fsid[1] = kin->knt_vnode.
736 knt_vnode_fsid;
737 kin32->knt_vnode.knt_vnode_fsid[0] = kin->knt_vnode.
738 knt_vnode_fsid >> 32;
739 kin32->knt_vnode.knt_vnode_fileid[1] = kin->knt_vnode.
740 knt_vnode_fileid;
741 kin32->knt_vnode.knt_vnode_fileid[0] = kin->knt_vnode.
742 knt_vnode_fileid >> 32;
743 #endif
744 memcpy(kin32->knt_vnode.knt_vnode_fullpath,
745 kin->knt_vnode.knt_vnode_fullpath, PATH_MAX);
746 break;
747 case KNOTE_EXTDATA_PIPE:
748 #if BYTE_ORDER == LITTLE_ENDIAN
749 kin32->knt_pipe.knt_pipe_ino[0] = kin->knt_pipe.knt_pipe_ino;
750 kin32->knt_pipe.knt_pipe_ino[1] = kin->knt_pipe.
751 knt_pipe_ino >> 32;
752 #else
753 kin32->knt_pipe.knt_pipe_ino[1] = kin->knt_pipe.knt_pipe_ino;
754 kin32->knt_pipe.knt_pipe_ino[0] = kin->knt_pipe.
755 knt_pipe_ino >> 32;
756 #endif
757 break;
758 }
759 }
760
761 /*
762 * Copy 'count' items into the destination list pointed to by uap->eventlist.
763 */
764 static int
freebsd32_kevent_copyout(void * arg,struct kevent * kevp,int count)765 freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
766 {
767 struct freebsd32_kevent_args *uap;
768 struct kevent32 ks32[KQ_NEVENTS];
769 int i, error;
770
771 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
772 uap = (struct freebsd32_kevent_args *)arg;
773
774 for (i = 0; i < count; i++)
775 freebsd32_kevent_to_kevent32(&kevp[i], &ks32[i]);
776 error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
777 if (error == 0)
778 uap->eventlist += count;
779 return (error);
780 }
781
782 /*
783 * Copy 'count' items from the list pointed to by uap->changelist.
784 */
785 static int
freebsd32_kevent_copyin(void * arg,struct kevent * kevp,int count)786 freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
787 {
788 struct freebsd32_kevent_args *uap;
789 struct kevent32 ks32[KQ_NEVENTS];
790 uint64_t e;
791 int i, j, error;
792
793 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
794 uap = (struct freebsd32_kevent_args *)arg;
795
796 error = copyin(uap->changelist, ks32, count * sizeof *ks32);
797 if (error)
798 goto done;
799 uap->changelist += count;
800
801 for (i = 0; i < count; i++) {
802 CP(ks32[i], kevp[i], ident);
803 CP(ks32[i], kevp[i], filter);
804 CP(ks32[i], kevp[i], flags);
805 CP(ks32[i], kevp[i], fflags);
806 kevp[i].data = PAIR32TO64(uint64_t, ks32[i].data);
807 PTRIN_CP(ks32[i], kevp[i], udata);
808 for (j = 0; j < nitems(kevp->ext); j++) {
809 #if BYTE_ORDER == LITTLE_ENDIAN
810 e = ks32[i].ext64[2 * j + 1];
811 e <<= 32;
812 e += ks32[i].ext64[2 * j];
813 #else
814 e = ks32[i].ext64[2 * j];
815 e <<= 32;
816 e += ks32[i].ext64[2 * j + 1];
817 #endif
818 kevp[i].ext[j] = e;
819 }
820 }
821 done:
822 return (error);
823 }
824
825 int
freebsd32_kevent(struct thread * td,struct freebsd32_kevent_args * uap)826 freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
827 {
828 struct timespec32 ts32;
829 struct timespec ts, *tsp;
830 struct kevent_copyops k_ops = {
831 .arg = uap,
832 .k_copyout = freebsd32_kevent_copyout,
833 .k_copyin = freebsd32_kevent_copyin,
834 };
835 #ifdef KTRACE
836 struct kevent32 *eventlist = uap->eventlist;
837 #endif
838 int error;
839
840 if (uap->timeout) {
841 error = copyin(uap->timeout, &ts32, sizeof(ts32));
842 if (error)
843 return (error);
844 CP(ts32, ts, tv_sec);
845 CP(ts32, ts, tv_nsec);
846 tsp = &ts;
847 } else
848 tsp = NULL;
849 #ifdef KTRACE
850 if (KTRPOINT(td, KTR_STRUCT_ARRAY))
851 ktrstructarray("kevent32", UIO_USERSPACE, uap->changelist,
852 uap->nchanges, sizeof(struct kevent32));
853 #endif
854 error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
855 &k_ops, tsp);
856 #ifdef KTRACE
857 if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY))
858 ktrstructarray("kevent32", UIO_USERSPACE, eventlist,
859 td->td_retval[0], sizeof(struct kevent32));
860 #endif
861 return (error);
862 }
863
864 #ifdef COMPAT_FREEBSD11
865 static int
freebsd32_kevent11_copyout(void * arg,struct kevent * kevp,int count)866 freebsd32_kevent11_copyout(void *arg, struct kevent *kevp, int count)
867 {
868 struct freebsd11_freebsd32_kevent_args *uap;
869 struct freebsd11_kevent32 ks32[KQ_NEVENTS];
870 int i, error;
871
872 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
873 uap = (struct freebsd11_freebsd32_kevent_args *)arg;
874
875 for (i = 0; i < count; i++) {
876 CP(kevp[i], ks32[i], ident);
877 CP(kevp[i], ks32[i], filter);
878 CP(kevp[i], ks32[i], flags);
879 CP(kevp[i], ks32[i], fflags);
880 CP(kevp[i], ks32[i], data);
881 PTROUT_CP(kevp[i], ks32[i], udata);
882 }
883 error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
884 if (error == 0)
885 uap->eventlist += count;
886 return (error);
887 }
888
889 /*
890 * Copy 'count' items from the list pointed to by uap->changelist.
891 */
892 static int
freebsd32_kevent11_copyin(void * arg,struct kevent * kevp,int count)893 freebsd32_kevent11_copyin(void *arg, struct kevent *kevp, int count)
894 {
895 struct freebsd11_freebsd32_kevent_args *uap;
896 struct freebsd11_kevent32 ks32[KQ_NEVENTS];
897 int i, j, error;
898
899 KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
900 uap = (struct freebsd11_freebsd32_kevent_args *)arg;
901
902 error = copyin(uap->changelist, ks32, count * sizeof *ks32);
903 if (error)
904 goto done;
905 uap->changelist += count;
906
907 for (i = 0; i < count; i++) {
908 CP(ks32[i], kevp[i], ident);
909 CP(ks32[i], kevp[i], filter);
910 CP(ks32[i], kevp[i], flags);
911 CP(ks32[i], kevp[i], fflags);
912 CP(ks32[i], kevp[i], data);
913 PTRIN_CP(ks32[i], kevp[i], udata);
914 for (j = 0; j < nitems(kevp->ext); j++)
915 kevp[i].ext[j] = 0;
916 }
917 done:
918 return (error);
919 }
920
921 int
freebsd11_freebsd32_kevent(struct thread * td,struct freebsd11_freebsd32_kevent_args * uap)922 freebsd11_freebsd32_kevent(struct thread *td,
923 struct freebsd11_freebsd32_kevent_args *uap)
924 {
925 struct timespec32 ts32;
926 struct timespec ts, *tsp;
927 struct kevent_copyops k_ops = {
928 .arg = uap,
929 .k_copyout = freebsd32_kevent11_copyout,
930 .k_copyin = freebsd32_kevent11_copyin,
931 };
932 #ifdef KTRACE
933 struct freebsd11_kevent32 *eventlist = uap->eventlist;
934 #endif
935 int error;
936
937 if (uap->timeout) {
938 error = copyin(uap->timeout, &ts32, sizeof(ts32));
939 if (error)
940 return (error);
941 CP(ts32, ts, tv_sec);
942 CP(ts32, ts, tv_nsec);
943 tsp = &ts;
944 } else
945 tsp = NULL;
946 #ifdef KTRACE
947 if (KTRPOINT(td, KTR_STRUCT_ARRAY))
948 ktrstructarray("freebsd11_kevent32", UIO_USERSPACE,
949 uap->changelist, uap->nchanges,
950 sizeof(struct freebsd11_kevent32));
951 #endif
952 error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
953 &k_ops, tsp);
954 #ifdef KTRACE
955 if (error == 0 && KTRPOINT(td, KTR_STRUCT_ARRAY))
956 ktrstructarray("freebsd11_kevent32", UIO_USERSPACE,
957 eventlist, td->td_retval[0],
958 sizeof(struct freebsd11_kevent32));
959 #endif
960 return (error);
961 }
962 #endif
963
964 int
freebsd32_gettimeofday(struct thread * td,struct freebsd32_gettimeofday_args * uap)965 freebsd32_gettimeofday(struct thread *td,
966 struct freebsd32_gettimeofday_args *uap)
967 {
968 struct timeval atv;
969 struct timeval32 atv32;
970 struct timezone rtz;
971 int error = 0;
972
973 if (uap->tp) {
974 microtime(&atv);
975 CP(atv, atv32, tv_sec);
976 CP(atv, atv32, tv_usec);
977 error = copyout(&atv32, uap->tp, sizeof (atv32));
978 }
979 if (error == 0 && uap->tzp != NULL) {
980 rtz.tz_minuteswest = 0;
981 rtz.tz_dsttime = 0;
982 error = copyout(&rtz, uap->tzp, sizeof (rtz));
983 }
984 return (error);
985 }
986
987 int
freebsd32_getrusage(struct thread * td,struct freebsd32_getrusage_args * uap)988 freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
989 {
990 struct rusage32 s32;
991 struct rusage s;
992 int error;
993
994 error = kern_getrusage(td, uap->who, &s);
995 if (error == 0) {
996 freebsd32_rusage_out(&s, &s32);
997 error = copyout(&s32, uap->rusage, sizeof(s32));
998 }
999 return (error);
1000 }
1001
1002 static void
ptrace_lwpinfo_to32(const struct ptrace_lwpinfo * pl,struct ptrace_lwpinfo32 * pl32)1003 ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl,
1004 struct ptrace_lwpinfo32 *pl32)
1005 {
1006
1007 bzero(pl32, sizeof(*pl32));
1008 pl32->pl_lwpid = pl->pl_lwpid;
1009 pl32->pl_event = pl->pl_event;
1010 pl32->pl_flags = pl->pl_flags;
1011 pl32->pl_sigmask = pl->pl_sigmask;
1012 pl32->pl_siglist = pl->pl_siglist;
1013 siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
1014 strcpy(pl32->pl_tdname, pl->pl_tdname);
1015 pl32->pl_child_pid = pl->pl_child_pid;
1016 pl32->pl_syscall_code = pl->pl_syscall_code;
1017 pl32->pl_syscall_narg = pl->pl_syscall_narg;
1018 }
1019
1020 static void
ptrace_sc_ret_to32(const struct ptrace_sc_ret * psr,struct ptrace_sc_ret32 * psr32)1021 ptrace_sc_ret_to32(const struct ptrace_sc_ret *psr,
1022 struct ptrace_sc_ret32 *psr32)
1023 {
1024
1025 bzero(psr32, sizeof(*psr32));
1026 psr32->sr_retval[0] = psr->sr_retval[0];
1027 psr32->sr_retval[1] = psr->sr_retval[1];
1028 psr32->sr_error = psr->sr_error;
1029 }
1030
1031 int
freebsd32_ptrace(struct thread * td,struct freebsd32_ptrace_args * uap)1032 freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap)
1033 {
1034 union {
1035 struct ptrace_io_desc piod;
1036 struct ptrace_lwpinfo pl;
1037 struct ptrace_vm_entry pve;
1038 struct ptrace_coredump pc;
1039 struct ptrace_sc_remote sr;
1040 struct dbreg32 dbreg;
1041 struct fpreg32 fpreg;
1042 struct reg32 reg;
1043 struct iovec vec;
1044 register_t args[nitems(td->td_sa.args)];
1045 struct ptrace_sc_ret psr;
1046 int ptevents;
1047 } r;
1048 union {
1049 struct ptrace_io_desc32 piod;
1050 struct ptrace_lwpinfo32 pl;
1051 struct ptrace_vm_entry32 pve;
1052 struct ptrace_coredump32 pc;
1053 struct ptrace_sc_remote32 sr;
1054 uint32_t args[nitems(td->td_sa.args)];
1055 struct ptrace_sc_ret32 psr;
1056 struct iovec32 vec;
1057 } r32;
1058 syscallarg_t pscr_args[nitems(td->td_sa.args)];
1059 u_int pscr_args32[nitems(td->td_sa.args)];
1060 void *addr;
1061 int data, error, i;
1062
1063 if (!allow_ptrace)
1064 return (ENOSYS);
1065 error = 0;
1066
1067 AUDIT_ARG_PID(uap->pid);
1068 AUDIT_ARG_CMD(uap->req);
1069 AUDIT_ARG_VALUE(uap->data);
1070 addr = &r;
1071 data = uap->data;
1072 switch (uap->req) {
1073 case PT_GET_EVENT_MASK:
1074 case PT_GET_SC_ARGS:
1075 case PT_GET_SC_RET:
1076 break;
1077 case PT_LWPINFO:
1078 if (uap->data > sizeof(r32.pl))
1079 return (EINVAL);
1080
1081 /*
1082 * Pass size of native structure in 'data'. Truncate
1083 * if necessary to avoid siginfo.
1084 */
1085 data = sizeof(r.pl);
1086 if (uap->data < offsetof(struct ptrace_lwpinfo32, pl_siginfo) +
1087 sizeof(struct __siginfo32))
1088 data = offsetof(struct ptrace_lwpinfo, pl_siginfo);
1089 break;
1090 case PT_GETREGS:
1091 bzero(&r.reg, sizeof(r.reg));
1092 break;
1093 case PT_GETFPREGS:
1094 bzero(&r.fpreg, sizeof(r.fpreg));
1095 break;
1096 case PT_GETDBREGS:
1097 bzero(&r.dbreg, sizeof(r.dbreg));
1098 break;
1099 case PT_SETREGS:
1100 error = copyin(uap->addr, &r.reg, sizeof(r.reg));
1101 break;
1102 case PT_SETFPREGS:
1103 error = copyin(uap->addr, &r.fpreg, sizeof(r.fpreg));
1104 break;
1105 case PT_SETDBREGS:
1106 error = copyin(uap->addr, &r.dbreg, sizeof(r.dbreg));
1107 break;
1108 case PT_GETREGSET:
1109 case PT_SETREGSET:
1110 error = copyin(uap->addr, &r32.vec, sizeof(r32.vec));
1111 if (error != 0)
1112 break;
1113
1114 r.vec.iov_len = r32.vec.iov_len;
1115 r.vec.iov_base = PTRIN(r32.vec.iov_base);
1116 break;
1117 case PT_SET_EVENT_MASK:
1118 if (uap->data != sizeof(r.ptevents))
1119 error = EINVAL;
1120 else
1121 error = copyin(uap->addr, &r.ptevents, uap->data);
1122 break;
1123 case PT_IO:
1124 error = copyin(uap->addr, &r32.piod, sizeof(r32.piod));
1125 if (error)
1126 break;
1127 CP(r32.piod, r.piod, piod_op);
1128 PTRIN_CP(r32.piod, r.piod, piod_offs);
1129 PTRIN_CP(r32.piod, r.piod, piod_addr);
1130 CP(r32.piod, r.piod, piod_len);
1131 break;
1132 case PT_VM_ENTRY:
1133 error = copyin(uap->addr, &r32.pve, sizeof(r32.pve));
1134 if (error)
1135 break;
1136
1137 CP(r32.pve, r.pve, pve_entry);
1138 CP(r32.pve, r.pve, pve_timestamp);
1139 CP(r32.pve, r.pve, pve_start);
1140 CP(r32.pve, r.pve, pve_end);
1141 CP(r32.pve, r.pve, pve_offset);
1142 CP(r32.pve, r.pve, pve_prot);
1143 CP(r32.pve, r.pve, pve_pathlen);
1144 CP(r32.pve, r.pve, pve_fileid);
1145 CP(r32.pve, r.pve, pve_fsid);
1146 PTRIN_CP(r32.pve, r.pve, pve_path);
1147 break;
1148 case PT_COREDUMP:
1149 if (uap->data != sizeof(r32.pc))
1150 error = EINVAL;
1151 else
1152 error = copyin(uap->addr, &r32.pc, uap->data);
1153 CP(r32.pc, r.pc, pc_fd);
1154 CP(r32.pc, r.pc, pc_flags);
1155 r.pc.pc_limit = PAIR32TO64(off_t, r32.pc.pc_limit);
1156 data = sizeof(r.pc);
1157 break;
1158 case PT_SC_REMOTE:
1159 if (uap->data != sizeof(r32.sr)) {
1160 error = EINVAL;
1161 break;
1162 }
1163 error = copyin(uap->addr, &r32.sr, uap->data);
1164 if (error != 0)
1165 break;
1166 CP(r32.sr, r.sr, pscr_syscall);
1167 CP(r32.sr, r.sr, pscr_nargs);
1168 if (r.sr.pscr_nargs > nitems(td->td_sa.args)) {
1169 error = EINVAL;
1170 break;
1171 }
1172 error = copyin(PTRIN(r32.sr.pscr_args), pscr_args32,
1173 sizeof(u_int) * r32.sr.pscr_nargs);
1174 if (error != 0)
1175 break;
1176 for (i = 0; i < r32.sr.pscr_nargs; i++)
1177 pscr_args[i] = pscr_args32[i];
1178 r.sr.pscr_args = pscr_args;
1179 break;
1180 default:
1181 addr = uap->addr;
1182 break;
1183 }
1184 if (error)
1185 return (error);
1186
1187 error = kern_ptrace(td, uap->req, uap->pid, addr, data);
1188 if (error)
1189 return (error);
1190
1191 switch (uap->req) {
1192 case PT_VM_ENTRY:
1193 CP(r.pve, r32.pve, pve_entry);
1194 CP(r.pve, r32.pve, pve_timestamp);
1195 CP(r.pve, r32.pve, pve_start);
1196 CP(r.pve, r32.pve, pve_end);
1197 CP(r.pve, r32.pve, pve_offset);
1198 CP(r.pve, r32.pve, pve_prot);
1199 CP(r.pve, r32.pve, pve_pathlen);
1200 CP(r.pve, r32.pve, pve_fileid);
1201 CP(r.pve, r32.pve, pve_fsid);
1202 error = copyout(&r32.pve, uap->addr, sizeof(r32.pve));
1203 break;
1204 case PT_IO:
1205 CP(r.piod, r32.piod, piod_len);
1206 error = copyout(&r32.piod, uap->addr, sizeof(r32.piod));
1207 break;
1208 case PT_GETREGS:
1209 error = copyout(&r.reg, uap->addr, sizeof(r.reg));
1210 break;
1211 case PT_GETFPREGS:
1212 error = copyout(&r.fpreg, uap->addr, sizeof(r.fpreg));
1213 break;
1214 case PT_GETDBREGS:
1215 error = copyout(&r.dbreg, uap->addr, sizeof(r.dbreg));
1216 break;
1217 case PT_GETREGSET:
1218 r32.vec.iov_len = r.vec.iov_len;
1219 error = copyout(&r32.vec, uap->addr, sizeof(r32.vec));
1220 break;
1221 case PT_GET_EVENT_MASK:
1222 /* NB: The size in uap->data is validated in kern_ptrace(). */
1223 error = copyout(&r.ptevents, uap->addr, uap->data);
1224 break;
1225 case PT_LWPINFO:
1226 ptrace_lwpinfo_to32(&r.pl, &r32.pl);
1227 error = copyout(&r32.pl, uap->addr, uap->data);
1228 break;
1229 case PT_GET_SC_ARGS:
1230 for (i = 0; i < nitems(r.args); i++)
1231 r32.args[i] = (uint32_t)r.args[i];
1232 error = copyout(r32.args, uap->addr, MIN(uap->data,
1233 sizeof(r32.args)));
1234 break;
1235 case PT_GET_SC_RET:
1236 ptrace_sc_ret_to32(&r.psr, &r32.psr);
1237 error = copyout(&r32.psr, uap->addr, MIN(uap->data,
1238 sizeof(r32.psr)));
1239 break;
1240 case PT_SC_REMOTE:
1241 ptrace_sc_ret_to32(&r.sr.pscr_ret, &r32.sr.pscr_ret);
1242 error = copyout(&r32.sr.pscr_ret, uap->addr +
1243 offsetof(struct ptrace_sc_remote32, pscr_ret),
1244 sizeof(r32.psr));
1245 break;
1246 }
1247
1248 return (error);
1249 }
1250
1251 int
freebsd32_copyinuio(const struct iovec32 * iovp,u_int iovcnt,struct uio ** uiop)1252 freebsd32_copyinuio(const struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
1253 {
1254 struct iovec32 iov32;
1255 struct iovec *iov;
1256 struct uio *uio;
1257 int error, i;
1258
1259 *uiop = NULL;
1260 if (iovcnt > UIO_MAXIOV)
1261 return (EINVAL);
1262 uio = allocuio(iovcnt);
1263 iov = uio->uio_iov;
1264 for (i = 0; i < iovcnt; i++) {
1265 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
1266 if (error) {
1267 freeuio(uio);
1268 return (error);
1269 }
1270 iov[i].iov_base = PTRIN(iov32.iov_base);
1271 iov[i].iov_len = iov32.iov_len;
1272 }
1273 uio->uio_iovcnt = iovcnt;
1274 uio->uio_segflg = UIO_USERSPACE;
1275 uio->uio_offset = -1;
1276 uio->uio_resid = 0;
1277 for (i = 0; i < iovcnt; i++) {
1278 if (iov->iov_len > INT_MAX - uio->uio_resid) {
1279 freeuio(uio);
1280 return (EINVAL);
1281 }
1282 uio->uio_resid += iov->iov_len;
1283 iov++;
1284 }
1285 *uiop = uio;
1286 return (0);
1287 }
1288
1289 int
freebsd32_readv(struct thread * td,struct freebsd32_readv_args * uap)1290 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
1291 {
1292 struct uio *auio;
1293 int error;
1294
1295 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1296 if (error)
1297 return (error);
1298 error = kern_readv(td, uap->fd, auio);
1299 freeuio(auio);
1300 return (error);
1301 }
1302
1303 int
freebsd32_writev(struct thread * td,struct freebsd32_writev_args * uap)1304 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
1305 {
1306 struct uio *auio;
1307 int error;
1308
1309 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1310 if (error)
1311 return (error);
1312 error = kern_writev(td, uap->fd, auio);
1313 freeuio(auio);
1314 return (error);
1315 }
1316
1317 int
freebsd32_preadv(struct thread * td,struct freebsd32_preadv_args * uap)1318 freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
1319 {
1320 struct uio *auio;
1321 int error;
1322
1323 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1324 if (error)
1325 return (error);
1326 error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
1327 freeuio(auio);
1328 return (error);
1329 }
1330
1331 int
freebsd32_pwritev(struct thread * td,struct freebsd32_pwritev_args * uap)1332 freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
1333 {
1334 struct uio *auio;
1335 int error;
1336
1337 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1338 if (error)
1339 return (error);
1340 error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
1341 freeuio(auio);
1342 return (error);
1343 }
1344
1345 int
freebsd32_copyiniov(struct iovec32 * iovp32,u_int iovcnt,struct iovec ** iovp,int error)1346 freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
1347 int error)
1348 {
1349 struct iovec32 iov32;
1350 struct iovec *iov;
1351 u_int iovlen;
1352 int i;
1353
1354 *iovp = NULL;
1355 if (iovcnt > UIO_MAXIOV)
1356 return (error);
1357 iovlen = iovcnt * sizeof(struct iovec);
1358 iov = malloc(iovlen, M_IOV, M_WAITOK);
1359 for (i = 0; i < iovcnt; i++) {
1360 error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
1361 if (error) {
1362 free(iov, M_IOV);
1363 return (error);
1364 }
1365 iov[i].iov_base = PTRIN(iov32.iov_base);
1366 iov[i].iov_len = iov32.iov_len;
1367 }
1368 *iovp = iov;
1369 return (0);
1370 }
1371
1372 static int
freebsd32_copyinmsghdr(const struct msghdr32 * msg32,struct msghdr * msg)1373 freebsd32_copyinmsghdr(const struct msghdr32 *msg32, struct msghdr *msg)
1374 {
1375 struct msghdr32 m32;
1376 int error;
1377
1378 error = copyin(msg32, &m32, sizeof(m32));
1379 if (error)
1380 return (error);
1381 msg->msg_name = PTRIN(m32.msg_name);
1382 msg->msg_namelen = m32.msg_namelen;
1383 msg->msg_iov = PTRIN(m32.msg_iov);
1384 msg->msg_iovlen = m32.msg_iovlen;
1385 msg->msg_control = PTRIN(m32.msg_control);
1386 msg->msg_controllen = m32.msg_controllen;
1387 msg->msg_flags = m32.msg_flags;
1388 return (0);
1389 }
1390
1391 static int
freebsd32_copyoutmsghdr(struct msghdr * msg,struct msghdr32 * msg32)1392 freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
1393 {
1394 struct msghdr32 m32;
1395 int error;
1396
1397 m32.msg_name = PTROUT(msg->msg_name);
1398 m32.msg_namelen = msg->msg_namelen;
1399 m32.msg_iov = PTROUT(msg->msg_iov);
1400 m32.msg_iovlen = msg->msg_iovlen;
1401 m32.msg_control = PTROUT(msg->msg_control);
1402 m32.msg_controllen = msg->msg_controllen;
1403 m32.msg_flags = msg->msg_flags;
1404 error = copyout(&m32, msg32, sizeof(m32));
1405 return (error);
1406 }
1407
1408 #define FREEBSD32_ALIGNBYTES (sizeof(int) - 1)
1409 #define FREEBSD32_ALIGN(p) \
1410 (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
1411 #define FREEBSD32_CMSG_SPACE(l) \
1412 (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
1413
1414 #define FREEBSD32_CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \
1415 FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
1416
1417 static size_t
freebsd32_cmsg_convert(const struct cmsghdr * cm,void * data,socklen_t datalen)1418 freebsd32_cmsg_convert(const struct cmsghdr *cm, void *data, socklen_t datalen)
1419 {
1420 size_t copylen;
1421 union {
1422 struct timespec32 ts;
1423 struct timeval32 tv;
1424 struct bintime32 bt;
1425 } tmp32;
1426
1427 union {
1428 struct timespec ts;
1429 struct timeval tv;
1430 struct bintime bt;
1431 } *in;
1432
1433 in = data;
1434 copylen = 0;
1435 switch (cm->cmsg_level) {
1436 case SOL_SOCKET:
1437 switch (cm->cmsg_type) {
1438 case SCM_TIMESTAMP:
1439 TV_CP(*in, tmp32, tv);
1440 copylen = sizeof(tmp32.tv);
1441 break;
1442
1443 case SCM_BINTIME:
1444 BT_CP(*in, tmp32, bt);
1445 copylen = sizeof(tmp32.bt);
1446 break;
1447
1448 case SCM_REALTIME:
1449 case SCM_MONOTONIC:
1450 TS_CP(*in, tmp32, ts);
1451 copylen = sizeof(tmp32.ts);
1452 break;
1453
1454 default:
1455 break;
1456 }
1457
1458 default:
1459 break;
1460 }
1461
1462 if (copylen == 0)
1463 return (datalen);
1464
1465 KASSERT((datalen >= copylen), ("corrupted cmsghdr"));
1466
1467 bcopy(&tmp32, data, copylen);
1468 return (copylen);
1469 }
1470
1471 static int
freebsd32_copy_msg_out(struct msghdr * msg,struct mbuf * control)1472 freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
1473 {
1474 struct cmsghdr *cm;
1475 void *data;
1476 socklen_t clen, datalen, datalen_out, oldclen;
1477 int error;
1478 caddr_t ctlbuf;
1479 int len, copylen;
1480 struct mbuf *m;
1481 error = 0;
1482
1483 len = msg->msg_controllen;
1484 msg->msg_controllen = 0;
1485
1486 ctlbuf = msg->msg_control;
1487 for (m = control; m != NULL && len > 0; m = m->m_next) {
1488 cm = mtod(m, struct cmsghdr *);
1489 clen = m->m_len;
1490 while (cm != NULL) {
1491 if (sizeof(struct cmsghdr) > clen ||
1492 cm->cmsg_len > clen) {
1493 error = EINVAL;
1494 break;
1495 }
1496
1497 data = CMSG_DATA(cm);
1498 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1499 datalen_out = freebsd32_cmsg_convert(cm, data, datalen);
1500
1501 /*
1502 * Copy out the message header. Preserve the native
1503 * message size in case we need to inspect the message
1504 * contents later.
1505 */
1506 copylen = sizeof(struct cmsghdr);
1507 if (len < copylen) {
1508 msg->msg_flags |= MSG_CTRUNC;
1509 m_dispose_extcontrolm(m);
1510 goto exit;
1511 }
1512 oldclen = cm->cmsg_len;
1513 cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
1514 datalen_out;
1515 error = copyout(cm, ctlbuf, copylen);
1516 cm->cmsg_len = oldclen;
1517 if (error != 0)
1518 goto exit;
1519
1520 ctlbuf += FREEBSD32_ALIGN(copylen);
1521 len -= FREEBSD32_ALIGN(copylen);
1522
1523 copylen = datalen_out;
1524 if (len < copylen) {
1525 msg->msg_flags |= MSG_CTRUNC;
1526 m_dispose_extcontrolm(m);
1527 break;
1528 }
1529
1530 /* Copy out the message data. */
1531 error = copyout(data, ctlbuf, copylen);
1532 if (error)
1533 goto exit;
1534
1535 ctlbuf += FREEBSD32_ALIGN(copylen);
1536 len -= FREEBSD32_ALIGN(copylen);
1537
1538 if (CMSG_SPACE(datalen) < clen) {
1539 clen -= CMSG_SPACE(datalen);
1540 cm = (struct cmsghdr *)
1541 ((caddr_t)cm + CMSG_SPACE(datalen));
1542 } else {
1543 clen = 0;
1544 cm = NULL;
1545 }
1546
1547 msg->msg_controllen +=
1548 FREEBSD32_CMSG_SPACE(datalen_out);
1549 }
1550 }
1551 if (len == 0 && m != NULL) {
1552 msg->msg_flags |= MSG_CTRUNC;
1553 m_dispose_extcontrolm(m);
1554 }
1555
1556 exit:
1557 return (error);
1558 }
1559
1560 int
freebsd32_recvmsg(struct thread * td,struct freebsd32_recvmsg_args * uap)1561 freebsd32_recvmsg(struct thread *td, struct freebsd32_recvmsg_args *uap)
1562 {
1563 struct msghdr msg;
1564 struct iovec *uiov, *iov;
1565 struct mbuf *control = NULL;
1566 struct mbuf **controlp;
1567 int error;
1568
1569 error = freebsd32_copyinmsghdr(uap->msg, &msg);
1570 if (error)
1571 return (error);
1572 error = freebsd32_copyiniov((void *)msg.msg_iov, msg.msg_iovlen, &iov,
1573 EMSGSIZE);
1574 if (error)
1575 return (error);
1576 msg.msg_flags = uap->flags;
1577 uiov = msg.msg_iov;
1578 msg.msg_iov = iov;
1579
1580 controlp = (msg.msg_control != NULL) ? &control : NULL;
1581 error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
1582 if (error == 0) {
1583 msg.msg_iov = uiov;
1584
1585 if (control != NULL)
1586 error = freebsd32_copy_msg_out(&msg, control);
1587 else
1588 msg.msg_controllen = 0;
1589
1590 if (error == 0)
1591 error = freebsd32_copyoutmsghdr(&msg, uap->msg);
1592 }
1593 free(iov, M_IOV);
1594
1595 if (control != NULL) {
1596 if (error != 0)
1597 m_dispose_extcontrolm(control);
1598 m_freem(control);
1599 }
1600
1601 return (error);
1602 }
1603
1604 #ifdef COMPAT_43
1605 int
ofreebsd32_recvmsg(struct thread * td,struct ofreebsd32_recvmsg_args * uap)1606 ofreebsd32_recvmsg(struct thread *td, struct ofreebsd32_recvmsg_args *uap)
1607 {
1608 return (ENOSYS);
1609 }
1610 #endif
1611
1612 /*
1613 * Copy-in the array of control messages constructed using alignment
1614 * and padding suitable for a 32-bit environment and construct an
1615 * mbuf using alignment and padding suitable for a 64-bit kernel.
1616 * The alignment and padding are defined indirectly by CMSG_DATA(),
1617 * CMSG_SPACE() and CMSG_LEN().
1618 */
1619 static int
freebsd32_copyin_control(struct mbuf ** mp,caddr_t buf,u_int buflen)1620 freebsd32_copyin_control(struct mbuf **mp, caddr_t buf, u_int buflen)
1621 {
1622 struct cmsghdr *cm;
1623 struct mbuf *m;
1624 void *in, *in1, *md;
1625 u_int msglen, outlen;
1626 int error;
1627
1628 /* Enforce the size limit of the native implementation. */
1629 if (buflen > MCLBYTES)
1630 return (EINVAL);
1631
1632 in = malloc(buflen, M_TEMP, M_WAITOK);
1633 error = copyin(buf, in, buflen);
1634 if (error != 0)
1635 goto out;
1636
1637 /*
1638 * Make a pass over the input buffer to determine the amount of space
1639 * required for 64 bit-aligned copies of the control messages.
1640 */
1641 in1 = in;
1642 outlen = 0;
1643 while (buflen > 0) {
1644 if (buflen < sizeof(*cm)) {
1645 error = EINVAL;
1646 break;
1647 }
1648 cm = (struct cmsghdr *)in1;
1649 if (cm->cmsg_len < FREEBSD32_ALIGN(sizeof(*cm)) ||
1650 cm->cmsg_len > buflen) {
1651 error = EINVAL;
1652 break;
1653 }
1654 msglen = FREEBSD32_ALIGN(cm->cmsg_len);
1655 if (msglen < cm->cmsg_len) {
1656 error = EINVAL;
1657 break;
1658 }
1659 /* The native ABI permits the final padding to be omitted. */
1660 if (msglen > buflen)
1661 msglen = buflen;
1662 buflen -= msglen;
1663
1664 in1 = (char *)in1 + msglen;
1665 outlen += CMSG_ALIGN(sizeof(*cm)) +
1666 CMSG_ALIGN(msglen - FREEBSD32_ALIGN(sizeof(*cm)));
1667 }
1668 if (error != 0)
1669 goto out;
1670
1671 /*
1672 * Allocate up to MJUMPAGESIZE space for the re-aligned and
1673 * re-padded control messages. This allows a full MCLBYTES of
1674 * 32-bit sized and aligned messages to fit and avoids an ABI
1675 * mismatch with the native implementation.
1676 */
1677 m = m_get2(outlen, M_WAITOK, MT_CONTROL, 0);
1678 if (m == NULL) {
1679 error = EINVAL;
1680 goto out;
1681 }
1682 m->m_len = outlen;
1683 md = mtod(m, void *);
1684
1685 /*
1686 * Make a second pass over input messages, copying them into the output
1687 * buffer.
1688 */
1689 in1 = in;
1690 while (outlen > 0) {
1691 /* Copy the message header and align the length field. */
1692 cm = md;
1693 memcpy(cm, in1, sizeof(*cm));
1694 msglen = cm->cmsg_len - FREEBSD32_ALIGN(sizeof(*cm));
1695 cm->cmsg_len = CMSG_ALIGN(sizeof(*cm)) + msglen;
1696
1697 /* Copy the message body. */
1698 in1 = (char *)in1 + FREEBSD32_ALIGN(sizeof(*cm));
1699 md = (char *)md + CMSG_ALIGN(sizeof(*cm));
1700 memcpy(md, in1, msglen);
1701 in1 = (char *)in1 + FREEBSD32_ALIGN(msglen);
1702 md = (char *)md + CMSG_ALIGN(msglen);
1703 KASSERT(outlen >= CMSG_ALIGN(sizeof(*cm)) + CMSG_ALIGN(msglen),
1704 ("outlen %u underflow, msglen %u", outlen, msglen));
1705 outlen -= CMSG_ALIGN(sizeof(*cm)) + CMSG_ALIGN(msglen);
1706 }
1707
1708 *mp = m;
1709 out:
1710 free(in, M_TEMP);
1711 return (error);
1712 }
1713
1714 int
freebsd32_sendmsg(struct thread * td,struct freebsd32_sendmsg_args * uap)1715 freebsd32_sendmsg(struct thread *td, struct freebsd32_sendmsg_args *uap)
1716 {
1717 struct msghdr msg;
1718 struct iovec *iov;
1719 struct mbuf *control = NULL;
1720 struct sockaddr *to = NULL;
1721 int error;
1722
1723 error = freebsd32_copyinmsghdr(uap->msg, &msg);
1724 if (error)
1725 return (error);
1726 error = freebsd32_copyiniov((void *)msg.msg_iov, msg.msg_iovlen, &iov,
1727 EMSGSIZE);
1728 if (error)
1729 return (error);
1730 msg.msg_iov = iov;
1731 if (msg.msg_name != NULL) {
1732 error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
1733 if (error) {
1734 to = NULL;
1735 goto out;
1736 }
1737 msg.msg_name = to;
1738 }
1739
1740 if (msg.msg_control) {
1741 if (msg.msg_controllen < sizeof(struct cmsghdr)) {
1742 error = EINVAL;
1743 goto out;
1744 }
1745
1746 error = freebsd32_copyin_control(&control, msg.msg_control,
1747 msg.msg_controllen);
1748 if (error)
1749 goto out;
1750
1751 msg.msg_control = NULL;
1752 msg.msg_controllen = 0;
1753 }
1754
1755 error = kern_sendit(td, uap->s, &msg, uap->flags, control,
1756 UIO_USERSPACE);
1757
1758 out:
1759 free(iov, M_IOV);
1760 if (to)
1761 free(to, M_SONAME);
1762 return (error);
1763 }
1764
1765 #ifdef COMPAT_43
1766 int
ofreebsd32_sendmsg(struct thread * td,struct ofreebsd32_sendmsg_args * uap)1767 ofreebsd32_sendmsg(struct thread *td, struct ofreebsd32_sendmsg_args *uap)
1768 {
1769 return (ENOSYS);
1770 }
1771 #endif
1772
1773
1774 int
freebsd32_settimeofday(struct thread * td,struct freebsd32_settimeofday_args * uap)1775 freebsd32_settimeofday(struct thread *td,
1776 struct freebsd32_settimeofday_args *uap)
1777 {
1778 struct timeval32 tv32;
1779 struct timeval tv, *tvp;
1780 struct timezone tz, *tzp;
1781 int error;
1782
1783 if (uap->tv) {
1784 error = copyin(uap->tv, &tv32, sizeof(tv32));
1785 if (error)
1786 return (error);
1787 CP(tv32, tv, tv_sec);
1788 CP(tv32, tv, tv_usec);
1789 tvp = &tv;
1790 } else
1791 tvp = NULL;
1792 if (uap->tzp) {
1793 error = copyin(uap->tzp, &tz, sizeof(tz));
1794 if (error)
1795 return (error);
1796 tzp = &tz;
1797 } else
1798 tzp = NULL;
1799 return (kern_settimeofday(td, tvp, tzp));
1800 }
1801
1802 int
freebsd32_utimes(struct thread * td,struct freebsd32_utimes_args * uap)1803 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
1804 {
1805 struct timeval32 s32[2];
1806 struct timeval s[2], *sp;
1807 int error;
1808
1809 if (uap->tptr != NULL) {
1810 error = copyin(uap->tptr, s32, sizeof(s32));
1811 if (error)
1812 return (error);
1813 CP(s32[0], s[0], tv_sec);
1814 CP(s32[0], s[0], tv_usec);
1815 CP(s32[1], s[1], tv_sec);
1816 CP(s32[1], s[1], tv_usec);
1817 sp = s;
1818 } else
1819 sp = NULL;
1820 return (kern_utimesat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
1821 sp, UIO_SYSSPACE));
1822 }
1823
1824 int
freebsd32_lutimes(struct thread * td,struct freebsd32_lutimes_args * uap)1825 freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
1826 {
1827 struct timeval32 s32[2];
1828 struct timeval s[2], *sp;
1829 int error;
1830
1831 if (uap->tptr != NULL) {
1832 error = copyin(uap->tptr, s32, sizeof(s32));
1833 if (error)
1834 return (error);
1835 CP(s32[0], s[0], tv_sec);
1836 CP(s32[0], s[0], tv_usec);
1837 CP(s32[1], s[1], tv_sec);
1838 CP(s32[1], s[1], tv_usec);
1839 sp = s;
1840 } else
1841 sp = NULL;
1842 return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1843 }
1844
1845 int
freebsd32_futimes(struct thread * td,struct freebsd32_futimes_args * uap)1846 freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
1847 {
1848 struct timeval32 s32[2];
1849 struct timeval s[2], *sp;
1850 int error;
1851
1852 if (uap->tptr != NULL) {
1853 error = copyin(uap->tptr, s32, sizeof(s32));
1854 if (error)
1855 return (error);
1856 CP(s32[0], s[0], tv_sec);
1857 CP(s32[0], s[0], tv_usec);
1858 CP(s32[1], s[1], tv_sec);
1859 CP(s32[1], s[1], tv_usec);
1860 sp = s;
1861 } else
1862 sp = NULL;
1863 return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
1864 }
1865
1866 int
freebsd32_futimesat(struct thread * td,struct freebsd32_futimesat_args * uap)1867 freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap)
1868 {
1869 struct timeval32 s32[2];
1870 struct timeval s[2], *sp;
1871 int error;
1872
1873 if (uap->times != NULL) {
1874 error = copyin(uap->times, s32, sizeof(s32));
1875 if (error)
1876 return (error);
1877 CP(s32[0], s[0], tv_sec);
1878 CP(s32[0], s[0], tv_usec);
1879 CP(s32[1], s[1], tv_sec);
1880 CP(s32[1], s[1], tv_usec);
1881 sp = s;
1882 } else
1883 sp = NULL;
1884 return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
1885 sp, UIO_SYSSPACE));
1886 }
1887
1888 int
freebsd32_futimens(struct thread * td,struct freebsd32_futimens_args * uap)1889 freebsd32_futimens(struct thread *td, struct freebsd32_futimens_args *uap)
1890 {
1891 struct timespec32 ts32[2];
1892 struct timespec ts[2], *tsp;
1893 int error;
1894
1895 if (uap->times != NULL) {
1896 error = copyin(uap->times, ts32, sizeof(ts32));
1897 if (error)
1898 return (error);
1899 CP(ts32[0], ts[0], tv_sec);
1900 CP(ts32[0], ts[0], tv_nsec);
1901 CP(ts32[1], ts[1], tv_sec);
1902 CP(ts32[1], ts[1], tv_nsec);
1903 tsp = ts;
1904 } else
1905 tsp = NULL;
1906 return (kern_futimens(td, uap->fd, tsp, UIO_SYSSPACE));
1907 }
1908
1909 int
freebsd32_utimensat(struct thread * td,struct freebsd32_utimensat_args * uap)1910 freebsd32_utimensat(struct thread *td, struct freebsd32_utimensat_args *uap)
1911 {
1912 struct timespec32 ts32[2];
1913 struct timespec ts[2], *tsp;
1914 int error;
1915
1916 if (uap->times != NULL) {
1917 error = copyin(uap->times, ts32, sizeof(ts32));
1918 if (error)
1919 return (error);
1920 CP(ts32[0], ts[0], tv_sec);
1921 CP(ts32[0], ts[0], tv_nsec);
1922 CP(ts32[1], ts[1], tv_sec);
1923 CP(ts32[1], ts[1], tv_nsec);
1924 tsp = ts;
1925 } else
1926 tsp = NULL;
1927 return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE,
1928 tsp, UIO_SYSSPACE, uap->flag));
1929 }
1930
1931 int
freebsd32_adjtime(struct thread * td,struct freebsd32_adjtime_args * uap)1932 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
1933 {
1934 struct timeval32 tv32;
1935 struct timeval delta, olddelta, *deltap;
1936 int error;
1937
1938 if (uap->delta) {
1939 error = copyin(uap->delta, &tv32, sizeof(tv32));
1940 if (error)
1941 return (error);
1942 CP(tv32, delta, tv_sec);
1943 CP(tv32, delta, tv_usec);
1944 deltap = δ
1945 } else
1946 deltap = NULL;
1947 error = kern_adjtime(td, deltap, &olddelta);
1948 if (uap->olddelta && error == 0) {
1949 CP(olddelta, tv32, tv_sec);
1950 CP(olddelta, tv32, tv_usec);
1951 error = copyout(&tv32, uap->olddelta, sizeof(tv32));
1952 }
1953 return (error);
1954 }
1955
1956 #ifdef COMPAT_FREEBSD4
1957 int
freebsd4_freebsd32_statfs(struct thread * td,struct freebsd4_freebsd32_statfs_args * uap)1958 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
1959 {
1960 struct ostatfs32 s32;
1961 struct statfs *sp;
1962 int error;
1963
1964 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
1965 error = kern_statfs(td, uap->path, UIO_USERSPACE, sp);
1966 if (error == 0) {
1967 copy_statfs(sp, &s32);
1968 error = copyout(&s32, uap->buf, sizeof(s32));
1969 }
1970 free(sp, M_STATFS);
1971 return (error);
1972 }
1973 #endif
1974
1975 #ifdef COMPAT_FREEBSD4
1976 int
freebsd4_freebsd32_fstatfs(struct thread * td,struct freebsd4_freebsd32_fstatfs_args * uap)1977 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
1978 {
1979 struct ostatfs32 s32;
1980 struct statfs *sp;
1981 int error;
1982
1983 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
1984 error = kern_fstatfs(td, uap->fd, sp);
1985 if (error == 0) {
1986 copy_statfs(sp, &s32);
1987 error = copyout(&s32, uap->buf, sizeof(s32));
1988 }
1989 free(sp, M_STATFS);
1990 return (error);
1991 }
1992 #endif
1993
1994 #ifdef COMPAT_FREEBSD4
1995 int
freebsd4_freebsd32_fhstatfs(struct thread * td,struct freebsd4_freebsd32_fhstatfs_args * uap)1996 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
1997 {
1998 struct ostatfs32 s32;
1999 struct statfs *sp;
2000 fhandle_t fh;
2001 int error;
2002
2003 if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
2004 return (error);
2005 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
2006 error = kern_fhstatfs(td, fh, sp);
2007 if (error == 0) {
2008 copy_statfs(sp, &s32);
2009 error = copyout(&s32, uap->buf, sizeof(s32));
2010 }
2011 free(sp, M_STATFS);
2012 return (error);
2013 }
2014 #endif
2015
2016 int
freebsd32_pread(struct thread * td,struct freebsd32_pread_args * uap)2017 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
2018 {
2019
2020 return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
2021 PAIR32TO64(off_t, uap->offset)));
2022 }
2023
2024 int
freebsd32_pwrite(struct thread * td,struct freebsd32_pwrite_args * uap)2025 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
2026 {
2027
2028 return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
2029 PAIR32TO64(off_t, uap->offset)));
2030 }
2031
2032 #ifdef COMPAT_43
2033 int
ofreebsd32_lseek(struct thread * td,struct ofreebsd32_lseek_args * uap)2034 ofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap)
2035 {
2036
2037 return (kern_lseek(td, uap->fd, uap->offset, uap->whence));
2038 }
2039 #endif
2040
2041 int
freebsd32_lseek(struct thread * td,struct freebsd32_lseek_args * uap)2042 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
2043 {
2044 int error;
2045 off_t pos;
2046
2047 error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset),
2048 uap->whence);
2049 /* Expand the quad return into two parts for eax and edx */
2050 pos = td->td_uretoff.tdu_off;
2051 td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */
2052 td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */
2053 return error;
2054 }
2055
2056 int
freebsd32_truncate(struct thread * td,struct freebsd32_truncate_args * uap)2057 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
2058 {
2059
2060 return (kern_truncate(td, uap->path, UIO_USERSPACE,
2061 PAIR32TO64(off_t, uap->length)));
2062 }
2063
2064 #ifdef COMPAT_43
2065 int
ofreebsd32_truncate(struct thread * td,struct ofreebsd32_truncate_args * uap)2066 ofreebsd32_truncate(struct thread *td, struct ofreebsd32_truncate_args *uap)
2067 {
2068 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
2069 }
2070 #endif
2071
2072 int
freebsd32_ftruncate(struct thread * td,struct freebsd32_ftruncate_args * uap)2073 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
2074 {
2075
2076 return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)));
2077 }
2078
2079 #ifdef COMPAT_43
2080 int
ofreebsd32_ftruncate(struct thread * td,struct ofreebsd32_ftruncate_args * uap)2081 ofreebsd32_ftruncate(struct thread *td, struct ofreebsd32_ftruncate_args *uap)
2082 {
2083 return (kern_ftruncate(td, uap->fd, uap->length));
2084 }
2085
2086 int
ofreebsd32_getdirentries(struct thread * td,struct ofreebsd32_getdirentries_args * uap)2087 ofreebsd32_getdirentries(struct thread *td,
2088 struct ofreebsd32_getdirentries_args *uap)
2089 {
2090 struct ogetdirentries_args ap;
2091 int error;
2092 long loff;
2093 int32_t loff_cut;
2094
2095 ap.fd = uap->fd;
2096 ap.buf = uap->buf;
2097 ap.count = uap->count;
2098 ap.basep = NULL;
2099 error = kern_ogetdirentries(td, &ap, &loff);
2100 if (error == 0) {
2101 loff_cut = loff;
2102 error = copyout(&loff_cut, uap->basep, sizeof(int32_t));
2103 }
2104 return (error);
2105 }
2106 #endif
2107
2108 #if defined(COMPAT_FREEBSD11)
2109 int
freebsd11_freebsd32_getdirentries(struct thread * td,struct freebsd11_freebsd32_getdirentries_args * uap)2110 freebsd11_freebsd32_getdirentries(struct thread *td,
2111 struct freebsd11_freebsd32_getdirentries_args *uap)
2112 {
2113 long base;
2114 int32_t base32;
2115 int error;
2116
2117 error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
2118 &base, NULL);
2119 if (error)
2120 return (error);
2121 if (uap->basep != NULL) {
2122 base32 = base;
2123 error = copyout(&base32, uap->basep, sizeof(int32_t));
2124 }
2125 return (error);
2126 }
2127 #endif /* COMPAT_FREEBSD11 */
2128
2129 #ifdef COMPAT_FREEBSD6
2130 /* versions with the 'int pad' argument */
2131 int
freebsd6_freebsd32_pread(struct thread * td,struct freebsd6_freebsd32_pread_args * uap)2132 freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
2133 {
2134
2135 return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
2136 PAIR32TO64(off_t, uap->offset)));
2137 }
2138
2139 int
freebsd6_freebsd32_pwrite(struct thread * td,struct freebsd6_freebsd32_pwrite_args * uap)2140 freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
2141 {
2142
2143 return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
2144 PAIR32TO64(off_t, uap->offset)));
2145 }
2146
2147 int
freebsd6_freebsd32_lseek(struct thread * td,struct freebsd6_freebsd32_lseek_args * uap)2148 freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
2149 {
2150 int error;
2151 off_t pos;
2152
2153 error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset),
2154 uap->whence);
2155 /* Expand the quad return into two parts for eax and edx */
2156 pos = *(off_t *)(td->td_retval);
2157 td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */
2158 td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */
2159 return error;
2160 }
2161
2162 int
freebsd6_freebsd32_truncate(struct thread * td,struct freebsd6_freebsd32_truncate_args * uap)2163 freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
2164 {
2165
2166 return (kern_truncate(td, uap->path, UIO_USERSPACE,
2167 PAIR32TO64(off_t, uap->length)));
2168 }
2169
2170 int
freebsd6_freebsd32_ftruncate(struct thread * td,struct freebsd6_freebsd32_ftruncate_args * uap)2171 freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
2172 {
2173
2174 return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)));
2175 }
2176 #endif /* COMPAT_FREEBSD6 */
2177
2178 struct sf_hdtr32 {
2179 uint32_t headers;
2180 int hdr_cnt;
2181 uint32_t trailers;
2182 int trl_cnt;
2183 };
2184
2185 static int
freebsd32_do_sendfile(struct thread * td,struct freebsd32_sendfile_args * uap,int compat)2186 freebsd32_do_sendfile(struct thread *td,
2187 struct freebsd32_sendfile_args *uap, int compat)
2188 {
2189 struct sf_hdtr32 hdtr32;
2190 struct sf_hdtr hdtr;
2191 struct uio *hdr_uio, *trl_uio;
2192 struct file *fp;
2193 cap_rights_t rights;
2194 struct iovec32 *iov32;
2195 off_t offset, sbytes;
2196 int error;
2197
2198 offset = PAIR32TO64(off_t, uap->offset);
2199 if (offset < 0)
2200 return (EINVAL);
2201
2202 hdr_uio = trl_uio = NULL;
2203
2204 if (uap->hdtr != NULL) {
2205 error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
2206 if (error)
2207 goto out;
2208 PTRIN_CP(hdtr32, hdtr, headers);
2209 CP(hdtr32, hdtr, hdr_cnt);
2210 PTRIN_CP(hdtr32, hdtr, trailers);
2211 CP(hdtr32, hdtr, trl_cnt);
2212
2213 if (hdtr.headers != NULL) {
2214 iov32 = PTRIN(hdtr32.headers);
2215 error = freebsd32_copyinuio(iov32,
2216 hdtr32.hdr_cnt, &hdr_uio);
2217 if (error)
2218 goto out;
2219 #ifdef COMPAT_FREEBSD4
2220 /*
2221 * In FreeBSD < 5.0 the nbytes to send also included
2222 * the header. If compat is specified subtract the
2223 * header size from nbytes.
2224 */
2225 if (compat) {
2226 if (uap->nbytes > hdr_uio->uio_resid)
2227 uap->nbytes -= hdr_uio->uio_resid;
2228 else
2229 uap->nbytes = 0;
2230 }
2231 #endif
2232 }
2233 if (hdtr.trailers != NULL) {
2234 iov32 = PTRIN(hdtr32.trailers);
2235 error = freebsd32_copyinuio(iov32,
2236 hdtr32.trl_cnt, &trl_uio);
2237 if (error)
2238 goto out;
2239 }
2240 }
2241
2242 AUDIT_ARG_FD(uap->fd);
2243
2244 if ((error = fget_read(td, uap->fd,
2245 cap_rights_init_one(&rights, CAP_PREAD), &fp)) != 0)
2246 goto out;
2247
2248 error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset,
2249 uap->nbytes, &sbytes, uap->flags, td);
2250 fdrop(fp, td);
2251
2252 if (uap->sbytes != NULL)
2253 (void)copyout(&sbytes, uap->sbytes, sizeof(off_t));
2254
2255 out:
2256 if (hdr_uio)
2257 freeuio(hdr_uio);
2258 if (trl_uio)
2259 freeuio(trl_uio);
2260 return (error);
2261 }
2262
2263 #ifdef COMPAT_FREEBSD4
2264 int
freebsd4_freebsd32_sendfile(struct thread * td,struct freebsd4_freebsd32_sendfile_args * uap)2265 freebsd4_freebsd32_sendfile(struct thread *td,
2266 struct freebsd4_freebsd32_sendfile_args *uap)
2267 {
2268 return (freebsd32_do_sendfile(td,
2269 (struct freebsd32_sendfile_args *)uap, 1));
2270 }
2271 #endif
2272
2273 int
freebsd32_sendfile(struct thread * td,struct freebsd32_sendfile_args * uap)2274 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
2275 {
2276
2277 return (freebsd32_do_sendfile(td, uap, 0));
2278 }
2279
2280 static void
copy_stat(struct stat * in,struct stat32 * out)2281 copy_stat(struct stat *in, struct stat32 *out)
2282 {
2283
2284 #ifndef __amd64__
2285 /*
2286 * 32-bit architectures other than i386 have 64-bit time_t. This
2287 * results in struct timespec32 with 12 bytes for tv_sec and tv_nsec,
2288 * and 4 bytes of padding. Zero the padding holes in struct stat32.
2289 */
2290 bzero(&out->st_atim, sizeof(out->st_atim));
2291 bzero(&out->st_mtim, sizeof(out->st_mtim));
2292 bzero(&out->st_ctim, sizeof(out->st_ctim));
2293 bzero(&out->st_birthtim, sizeof(out->st_birthtim));
2294 #endif
2295 CP(*in, *out, st_dev);
2296 CP(*in, *out, st_ino);
2297 CP(*in, *out, st_mode);
2298 CP(*in, *out, st_nlink);
2299 CP(*in, *out, st_uid);
2300 CP(*in, *out, st_gid);
2301 CP(*in, *out, st_rdev);
2302 TS_CP(*in, *out, st_atim);
2303 TS_CP(*in, *out, st_mtim);
2304 TS_CP(*in, *out, st_ctim);
2305 CP(*in, *out, st_size);
2306 CP(*in, *out, st_blocks);
2307 CP(*in, *out, st_blksize);
2308 CP(*in, *out, st_flags);
2309 CP(*in, *out, st_gen);
2310 CP(*in, *out, st_filerev);
2311 CP(*in, *out, st_bsdflags);
2312 TS_CP(*in, *out, st_birthtim);
2313 out->st_padding1 = 0;
2314 #ifdef __STAT32_TIME_T_EXT
2315 out->st_atim_ext = 0;
2316 out->st_mtim_ext = 0;
2317 out->st_ctim_ext = 0;
2318 out->st_btim_ext = 0;
2319 #endif
2320 bzero(out->st_spare, sizeof(out->st_spare));
2321 }
2322
2323 #ifdef COMPAT_43
2324 static void
copy_ostat(struct stat * in,struct ostat32 * out)2325 copy_ostat(struct stat *in, struct ostat32 *out)
2326 {
2327
2328 bzero(out, sizeof(*out));
2329 CP(*in, *out, st_dev);
2330 CP(*in, *out, st_ino);
2331 CP(*in, *out, st_mode);
2332 CP(*in, *out, st_nlink);
2333 CP(*in, *out, st_uid);
2334 CP(*in, *out, st_gid);
2335 CP(*in, *out, st_rdev);
2336 out->st_size = MIN(in->st_size, INT32_MAX);
2337 TS_CP(*in, *out, st_atim);
2338 TS_CP(*in, *out, st_mtim);
2339 TS_CP(*in, *out, st_ctim);
2340 CP(*in, *out, st_blksize);
2341 CP(*in, *out, st_blocks);
2342 CP(*in, *out, st_flags);
2343 CP(*in, *out, st_gen);
2344 }
2345 #endif
2346
2347 #ifdef COMPAT_43
2348 int
ofreebsd32_stat(struct thread * td,struct ofreebsd32_stat_args * uap)2349 ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
2350 {
2351 struct stat sb;
2352 struct ostat32 sb32;
2353 int error;
2354
2355 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2356 if (error)
2357 return (error);
2358 copy_ostat(&sb, &sb32);
2359 error = copyout(&sb32, uap->ub, sizeof (sb32));
2360 return (error);
2361 }
2362 #endif
2363
2364 int
freebsd32_fstat(struct thread * td,struct freebsd32_fstat_args * uap)2365 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
2366 {
2367 struct stat ub;
2368 struct stat32 ub32;
2369 int error;
2370
2371 error = kern_fstat(td, uap->fd, &ub);
2372 if (error)
2373 return (error);
2374 copy_stat(&ub, &ub32);
2375 error = copyout(&ub32, uap->sb, sizeof(ub32));
2376 return (error);
2377 }
2378
2379 #ifdef COMPAT_43
2380 int
ofreebsd32_fstat(struct thread * td,struct ofreebsd32_fstat_args * uap)2381 ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap)
2382 {
2383 struct stat ub;
2384 struct ostat32 ub32;
2385 int error;
2386
2387 error = kern_fstat(td, uap->fd, &ub);
2388 if (error)
2389 return (error);
2390 copy_ostat(&ub, &ub32);
2391 error = copyout(&ub32, uap->sb, sizeof(ub32));
2392 return (error);
2393 }
2394 #endif
2395
2396 int
freebsd32_fstatat(struct thread * td,struct freebsd32_fstatat_args * uap)2397 freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
2398 {
2399 struct stat ub;
2400 struct stat32 ub32;
2401 int error;
2402
2403 error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
2404 &ub);
2405 if (error)
2406 return (error);
2407 copy_stat(&ub, &ub32);
2408 error = copyout(&ub32, uap->buf, sizeof(ub32));
2409 return (error);
2410 }
2411
2412 #ifdef COMPAT_43
2413 int
ofreebsd32_lstat(struct thread * td,struct ofreebsd32_lstat_args * uap)2414 ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
2415 {
2416 struct stat sb;
2417 struct ostat32 sb32;
2418 int error;
2419
2420 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2421 UIO_USERSPACE, &sb);
2422 if (error)
2423 return (error);
2424 copy_ostat(&sb, &sb32);
2425 error = copyout(&sb32, uap->ub, sizeof (sb32));
2426 return (error);
2427 }
2428 #endif
2429
2430 int
freebsd32_fhstat(struct thread * td,struct freebsd32_fhstat_args * uap)2431 freebsd32_fhstat(struct thread *td, struct freebsd32_fhstat_args *uap)
2432 {
2433 struct stat sb;
2434 struct stat32 sb32;
2435 struct fhandle fh;
2436 int error;
2437
2438 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
2439 if (error != 0)
2440 return (error);
2441 error = kern_fhstat(td, fh, &sb);
2442 if (error != 0)
2443 return (error);
2444 copy_stat(&sb, &sb32);
2445 error = copyout(&sb32, uap->sb, sizeof (sb32));
2446 return (error);
2447 }
2448
2449 #if defined(COMPAT_FREEBSD11)
2450 extern int ino64_trunc_error;
2451
2452 static int
freebsd11_cvtstat32(struct stat * in,struct freebsd11_stat32 * out)2453 freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out)
2454 {
2455
2456 #ifndef __amd64__
2457 /*
2458 * 32-bit architectures other than i386 have 64-bit time_t. This
2459 * results in struct timespec32 with 12 bytes for tv_sec and tv_nsec,
2460 * and 4 bytes of padding. Zero the padding holes in freebsd11_stat32.
2461 */
2462 bzero(&out->st_atim, sizeof(out->st_atim));
2463 bzero(&out->st_mtim, sizeof(out->st_mtim));
2464 bzero(&out->st_ctim, sizeof(out->st_ctim));
2465 bzero(&out->st_birthtim, sizeof(out->st_birthtim));
2466 #endif
2467
2468 CP(*in, *out, st_ino);
2469 if (in->st_ino != out->st_ino) {
2470 switch (ino64_trunc_error) {
2471 default:
2472 case 0:
2473 break;
2474 case 1:
2475 return (EOVERFLOW);
2476 case 2:
2477 out->st_ino = UINT32_MAX;
2478 break;
2479 }
2480 }
2481 CP(*in, *out, st_nlink);
2482 if (in->st_nlink != out->st_nlink) {
2483 switch (ino64_trunc_error) {
2484 default:
2485 case 0:
2486 break;
2487 case 1:
2488 return (EOVERFLOW);
2489 case 2:
2490 out->st_nlink = UINT16_MAX;
2491 break;
2492 }
2493 }
2494 out->st_dev = in->st_dev;
2495 if (out->st_dev != in->st_dev) {
2496 switch (ino64_trunc_error) {
2497 default:
2498 break;
2499 case 1:
2500 return (EOVERFLOW);
2501 }
2502 }
2503 CP(*in, *out, st_mode);
2504 CP(*in, *out, st_uid);
2505 CP(*in, *out, st_gid);
2506 out->st_rdev = in->st_rdev;
2507 if (out->st_rdev != in->st_rdev) {
2508 switch (ino64_trunc_error) {
2509 default:
2510 break;
2511 case 1:
2512 return (EOVERFLOW);
2513 }
2514 }
2515 TS_CP(*in, *out, st_atim);
2516 TS_CP(*in, *out, st_mtim);
2517 TS_CP(*in, *out, st_ctim);
2518 CP(*in, *out, st_size);
2519 CP(*in, *out, st_blocks);
2520 CP(*in, *out, st_blksize);
2521 CP(*in, *out, st_flags);
2522 CP(*in, *out, st_gen);
2523 TS_CP(*in, *out, st_birthtim);
2524 out->st_lspare = 0;
2525 bzero((char *)&out->st_birthtim + sizeof(out->st_birthtim),
2526 sizeof(*out) - offsetof(struct freebsd11_stat32,
2527 st_birthtim) - sizeof(out->st_birthtim));
2528 return (0);
2529 }
2530
2531 int
freebsd11_freebsd32_stat(struct thread * td,struct freebsd11_freebsd32_stat_args * uap)2532 freebsd11_freebsd32_stat(struct thread *td,
2533 struct freebsd11_freebsd32_stat_args *uap)
2534 {
2535 struct stat sb;
2536 struct freebsd11_stat32 sb32;
2537 int error;
2538
2539 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2540 if (error != 0)
2541 return (error);
2542 error = freebsd11_cvtstat32(&sb, &sb32);
2543 if (error == 0)
2544 error = copyout(&sb32, uap->ub, sizeof (sb32));
2545 return (error);
2546 }
2547
2548 int
freebsd11_freebsd32_fstat(struct thread * td,struct freebsd11_freebsd32_fstat_args * uap)2549 freebsd11_freebsd32_fstat(struct thread *td,
2550 struct freebsd11_freebsd32_fstat_args *uap)
2551 {
2552 struct stat sb;
2553 struct freebsd11_stat32 sb32;
2554 int error;
2555
2556 error = kern_fstat(td, uap->fd, &sb);
2557 if (error != 0)
2558 return (error);
2559 error = freebsd11_cvtstat32(&sb, &sb32);
2560 if (error == 0)
2561 error = copyout(&sb32, uap->sb, sizeof (sb32));
2562 return (error);
2563 }
2564
2565 int
freebsd11_freebsd32_fstatat(struct thread * td,struct freebsd11_freebsd32_fstatat_args * uap)2566 freebsd11_freebsd32_fstatat(struct thread *td,
2567 struct freebsd11_freebsd32_fstatat_args *uap)
2568 {
2569 struct stat sb;
2570 struct freebsd11_stat32 sb32;
2571 int error;
2572
2573 error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
2574 &sb);
2575 if (error != 0)
2576 return (error);
2577 error = freebsd11_cvtstat32(&sb, &sb32);
2578 if (error == 0)
2579 error = copyout(&sb32, uap->buf, sizeof (sb32));
2580 return (error);
2581 }
2582
2583 int
freebsd11_freebsd32_lstat(struct thread * td,struct freebsd11_freebsd32_lstat_args * uap)2584 freebsd11_freebsd32_lstat(struct thread *td,
2585 struct freebsd11_freebsd32_lstat_args *uap)
2586 {
2587 struct stat sb;
2588 struct freebsd11_stat32 sb32;
2589 int error;
2590
2591 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2592 UIO_USERSPACE, &sb);
2593 if (error != 0)
2594 return (error);
2595 error = freebsd11_cvtstat32(&sb, &sb32);
2596 if (error == 0)
2597 error = copyout(&sb32, uap->ub, sizeof (sb32));
2598 return (error);
2599 }
2600
2601 int
freebsd11_freebsd32_fhstat(struct thread * td,struct freebsd11_freebsd32_fhstat_args * uap)2602 freebsd11_freebsd32_fhstat(struct thread *td,
2603 struct freebsd11_freebsd32_fhstat_args *uap)
2604 {
2605 struct stat sb;
2606 struct freebsd11_stat32 sb32;
2607 struct fhandle fh;
2608 int error;
2609
2610 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
2611 if (error != 0)
2612 return (error);
2613 error = kern_fhstat(td, fh, &sb);
2614 if (error != 0)
2615 return (error);
2616 error = freebsd11_cvtstat32(&sb, &sb32);
2617 if (error == 0)
2618 error = copyout(&sb32, uap->sb, sizeof (sb32));
2619 return (error);
2620 }
2621
2622 static int
freebsd11_cvtnstat32(struct stat * sb,struct nstat32 * nsb32)2623 freebsd11_cvtnstat32(struct stat *sb, struct nstat32 *nsb32)
2624 {
2625 struct nstat nsb;
2626 int error;
2627
2628 error = freebsd11_cvtnstat(sb, &nsb);
2629 if (error != 0)
2630 return (error);
2631
2632 bzero(nsb32, sizeof(*nsb32));
2633 CP(nsb, *nsb32, st_dev);
2634 CP(nsb, *nsb32, st_ino);
2635 CP(nsb, *nsb32, st_mode);
2636 CP(nsb, *nsb32, st_nlink);
2637 CP(nsb, *nsb32, st_uid);
2638 CP(nsb, *nsb32, st_gid);
2639 CP(nsb, *nsb32, st_rdev);
2640 CP(nsb, *nsb32, st_atim.tv_sec);
2641 CP(nsb, *nsb32, st_atim.tv_nsec);
2642 CP(nsb, *nsb32, st_mtim.tv_sec);
2643 CP(nsb, *nsb32, st_mtim.tv_nsec);
2644 CP(nsb, *nsb32, st_ctim.tv_sec);
2645 CP(nsb, *nsb32, st_ctim.tv_nsec);
2646 CP(nsb, *nsb32, st_size);
2647 CP(nsb, *nsb32, st_blocks);
2648 CP(nsb, *nsb32, st_blksize);
2649 CP(nsb, *nsb32, st_flags);
2650 CP(nsb, *nsb32, st_gen);
2651 CP(nsb, *nsb32, st_birthtim.tv_sec);
2652 CP(nsb, *nsb32, st_birthtim.tv_nsec);
2653 return (0);
2654 }
2655
2656 int
freebsd11_freebsd32_nstat(struct thread * td,struct freebsd11_freebsd32_nstat_args * uap)2657 freebsd11_freebsd32_nstat(struct thread *td,
2658 struct freebsd11_freebsd32_nstat_args *uap)
2659 {
2660 struct stat sb;
2661 struct nstat32 nsb;
2662 int error;
2663
2664 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2665 if (error != 0)
2666 return (error);
2667 error = freebsd11_cvtnstat32(&sb, &nsb);
2668 if (error != 0)
2669 error = copyout(&nsb, uap->ub, sizeof (nsb));
2670 return (error);
2671 }
2672
2673 int
freebsd11_freebsd32_nlstat(struct thread * td,struct freebsd11_freebsd32_nlstat_args * uap)2674 freebsd11_freebsd32_nlstat(struct thread *td,
2675 struct freebsd11_freebsd32_nlstat_args *uap)
2676 {
2677 struct stat sb;
2678 struct nstat32 nsb;
2679 int error;
2680
2681 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2682 UIO_USERSPACE, &sb);
2683 if (error != 0)
2684 return (error);
2685 error = freebsd11_cvtnstat32(&sb, &nsb);
2686 if (error == 0)
2687 error = copyout(&nsb, uap->ub, sizeof (nsb));
2688 return (error);
2689 }
2690
2691 int
freebsd11_freebsd32_nfstat(struct thread * td,struct freebsd11_freebsd32_nfstat_args * uap)2692 freebsd11_freebsd32_nfstat(struct thread *td,
2693 struct freebsd11_freebsd32_nfstat_args *uap)
2694 {
2695 struct nstat32 nub;
2696 struct stat ub;
2697 int error;
2698
2699 error = kern_fstat(td, uap->fd, &ub);
2700 if (error != 0)
2701 return (error);
2702 error = freebsd11_cvtnstat32(&ub, &nub);
2703 if (error == 0)
2704 error = copyout(&nub, uap->sb, sizeof(nub));
2705 return (error);
2706 }
2707 #endif
2708
2709 int
freebsd32___sysctl(struct thread * td,struct freebsd32___sysctl_args * uap)2710 freebsd32___sysctl(struct thread *td, struct freebsd32___sysctl_args *uap)
2711 {
2712 int error, name[CTL_MAXNAME];
2713 size_t j, oldlen;
2714 uint32_t tmp;
2715
2716 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
2717 return (EINVAL);
2718 error = copyin(uap->name, name, uap->namelen * sizeof(int));
2719 if (error)
2720 return (error);
2721 if (uap->oldlenp) {
2722 error = fueword32(uap->oldlenp, &tmp);
2723 oldlen = tmp;
2724 } else {
2725 oldlen = 0;
2726 }
2727 if (error != 0)
2728 return (EFAULT);
2729 error = userland_sysctl(td, name, uap->namelen,
2730 uap->old, &oldlen, 1,
2731 uap->new, uap->newlen, &j, SCTL_MASK32);
2732 if (error)
2733 return (error);
2734 if (uap->oldlenp != NULL && suword32(uap->oldlenp, j) != 0)
2735 error = EFAULT;
2736 return (error);
2737 }
2738
2739 int
freebsd32___sysctlbyname(struct thread * td,struct freebsd32___sysctlbyname_args * uap)2740 freebsd32___sysctlbyname(struct thread *td,
2741 struct freebsd32___sysctlbyname_args *uap)
2742 {
2743 size_t oldlen, rv;
2744 int error;
2745 uint32_t tmp;
2746
2747 if (uap->oldlenp != NULL) {
2748 error = fueword32(uap->oldlenp, &tmp);
2749 oldlen = tmp;
2750 } else {
2751 error = oldlen = 0;
2752 }
2753 if (error != 0)
2754 return (EFAULT);
2755 error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old,
2756 &oldlen, uap->new, uap->newlen, &rv, SCTL_MASK32, 1);
2757 if (error != 0)
2758 return (error);
2759 if (uap->oldlenp != NULL && suword32(uap->oldlenp, rv) != 0)
2760 error = EFAULT;
2761 return (error);
2762 }
2763
2764 int
freebsd32_jail(struct thread * td,struct freebsd32_jail_args * uap)2765 freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
2766 {
2767 uint32_t version;
2768 int error;
2769 struct jail j;
2770
2771 error = copyin(uap->jail, &version, sizeof(uint32_t));
2772 if (error)
2773 return (error);
2774
2775 switch (version) {
2776 case 0:
2777 {
2778 /* FreeBSD single IPv4 jails. */
2779 struct jail32_v0 j32_v0;
2780
2781 bzero(&j, sizeof(struct jail));
2782 error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0));
2783 if (error)
2784 return (error);
2785 CP(j32_v0, j, version);
2786 PTRIN_CP(j32_v0, j, path);
2787 PTRIN_CP(j32_v0, j, hostname);
2788 j.ip4s = htonl(j32_v0.ip_number); /* jail_v0 is host order */
2789 break;
2790 }
2791
2792 case 1:
2793 /*
2794 * Version 1 was used by multi-IPv4 jail implementations
2795 * that never made it into the official kernel.
2796 */
2797 return (EINVAL);
2798
2799 case 2: /* JAIL_API_VERSION */
2800 {
2801 /* FreeBSD multi-IPv4/IPv6,noIP jails. */
2802 struct jail32 j32;
2803
2804 error = copyin(uap->jail, &j32, sizeof(struct jail32));
2805 if (error)
2806 return (error);
2807 CP(j32, j, version);
2808 PTRIN_CP(j32, j, path);
2809 PTRIN_CP(j32, j, hostname);
2810 PTRIN_CP(j32, j, jailname);
2811 CP(j32, j, ip4s);
2812 CP(j32, j, ip6s);
2813 PTRIN_CP(j32, j, ip4);
2814 PTRIN_CP(j32, j, ip6);
2815 break;
2816 }
2817
2818 default:
2819 /* Sci-Fi jails are not supported, sorry. */
2820 return (EINVAL);
2821 }
2822 return (kern_jail(td, &j));
2823 }
2824
2825 int
freebsd32_jail_set(struct thread * td,struct freebsd32_jail_set_args * uap)2826 freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
2827 {
2828 struct uio *auio;
2829 int error;
2830
2831 /* Check that we have an even number of iovecs. */
2832 if (uap->iovcnt & 1)
2833 return (EINVAL);
2834
2835 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2836 if (error)
2837 return (error);
2838 error = kern_jail_set(td, auio, uap->flags);
2839 freeuio(auio);
2840 return (error);
2841 }
2842
2843 int
freebsd32_jail_get(struct thread * td,struct freebsd32_jail_get_args * uap)2844 freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
2845 {
2846 struct iovec32 iov32;
2847 struct uio *auio;
2848 int error, i;
2849
2850 /* Check that we have an even number of iovecs. */
2851 if (uap->iovcnt & 1)
2852 return (EINVAL);
2853
2854 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2855 if (error)
2856 return (error);
2857 error = kern_jail_get(td, auio, uap->flags);
2858 if (error == 0)
2859 for (i = 0; i < uap->iovcnt; i++) {
2860 PTROUT_CP(auio->uio_iov[i], iov32, iov_base);
2861 CP(auio->uio_iov[i], iov32, iov_len);
2862 error = copyout(&iov32, uap->iovp + i, sizeof(iov32));
2863 if (error != 0)
2864 break;
2865 }
2866 freeuio(auio);
2867 return (error);
2868 }
2869
2870 int
freebsd32_sigaction(struct thread * td,struct freebsd32_sigaction_args * uap)2871 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
2872 {
2873 struct sigaction32 s32;
2874 struct sigaction sa, osa, *sap;
2875 int error;
2876
2877 if (uap->act) {
2878 error = copyin(uap->act, &s32, sizeof(s32));
2879 if (error)
2880 return (error);
2881 sa.sa_handler = PTRIN(s32.sa_u);
2882 CP(s32, sa, sa_flags);
2883 CP(s32, sa, sa_mask);
2884 sap = &sa;
2885 } else
2886 sap = NULL;
2887 error = kern_sigaction(td, uap->sig, sap, &osa, 0);
2888 if (error == 0 && uap->oact != NULL) {
2889 s32.sa_u = PTROUT(osa.sa_handler);
2890 CP(osa, s32, sa_flags);
2891 CP(osa, s32, sa_mask);
2892 error = copyout(&s32, uap->oact, sizeof(s32));
2893 }
2894 return (error);
2895 }
2896
2897 #ifdef COMPAT_FREEBSD4
2898 int
freebsd4_freebsd32_sigaction(struct thread * td,struct freebsd4_freebsd32_sigaction_args * uap)2899 freebsd4_freebsd32_sigaction(struct thread *td,
2900 struct freebsd4_freebsd32_sigaction_args *uap)
2901 {
2902 struct sigaction32 s32;
2903 struct sigaction sa, osa, *sap;
2904 int error;
2905
2906 if (uap->act) {
2907 error = copyin(uap->act, &s32, sizeof(s32));
2908 if (error)
2909 return (error);
2910 sa.sa_handler = PTRIN(s32.sa_u);
2911 CP(s32, sa, sa_flags);
2912 CP(s32, sa, sa_mask);
2913 sap = &sa;
2914 } else
2915 sap = NULL;
2916 error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
2917 if (error == 0 && uap->oact != NULL) {
2918 s32.sa_u = PTROUT(osa.sa_handler);
2919 CP(osa, s32, sa_flags);
2920 CP(osa, s32, sa_mask);
2921 error = copyout(&s32, uap->oact, sizeof(s32));
2922 }
2923 return (error);
2924 }
2925 #endif
2926
2927 #ifdef COMPAT_43
2928 struct osigaction32 {
2929 uint32_t sa_u;
2930 osigset_t sa_mask;
2931 int sa_flags;
2932 };
2933
2934 #define ONSIG 32
2935
2936 int
ofreebsd32_sigaction(struct thread * td,struct ofreebsd32_sigaction_args * uap)2937 ofreebsd32_sigaction(struct thread *td,
2938 struct ofreebsd32_sigaction_args *uap)
2939 {
2940 struct osigaction32 s32;
2941 struct sigaction sa, osa, *sap;
2942 int error;
2943
2944 if (uap->signum <= 0 || uap->signum >= ONSIG)
2945 return (EINVAL);
2946
2947 if (uap->nsa) {
2948 error = copyin(uap->nsa, &s32, sizeof(s32));
2949 if (error)
2950 return (error);
2951 sa.sa_handler = PTRIN(s32.sa_u);
2952 CP(s32, sa, sa_flags);
2953 OSIG2SIG(s32.sa_mask, sa.sa_mask);
2954 sap = &sa;
2955 } else
2956 sap = NULL;
2957 error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2958 if (error == 0 && uap->osa != NULL) {
2959 s32.sa_u = PTROUT(osa.sa_handler);
2960 CP(osa, s32, sa_flags);
2961 SIG2OSIG(osa.sa_mask, s32.sa_mask);
2962 error = copyout(&s32, uap->osa, sizeof(s32));
2963 }
2964 return (error);
2965 }
2966
2967 struct sigvec32 {
2968 uint32_t sv_handler;
2969 int sv_mask;
2970 int sv_flags;
2971 };
2972
2973 int
ofreebsd32_sigvec(struct thread * td,struct ofreebsd32_sigvec_args * uap)2974 ofreebsd32_sigvec(struct thread *td,
2975 struct ofreebsd32_sigvec_args *uap)
2976 {
2977 struct sigvec32 vec;
2978 struct sigaction sa, osa, *sap;
2979 int error;
2980
2981 if (uap->signum <= 0 || uap->signum >= ONSIG)
2982 return (EINVAL);
2983
2984 if (uap->nsv) {
2985 error = copyin(uap->nsv, &vec, sizeof(vec));
2986 if (error)
2987 return (error);
2988 sa.sa_handler = PTRIN(vec.sv_handler);
2989 OSIG2SIG(vec.sv_mask, sa.sa_mask);
2990 sa.sa_flags = vec.sv_flags;
2991 sa.sa_flags ^= SA_RESTART;
2992 sap = &sa;
2993 } else
2994 sap = NULL;
2995 error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2996 if (error == 0 && uap->osv != NULL) {
2997 vec.sv_handler = PTROUT(osa.sa_handler);
2998 SIG2OSIG(osa.sa_mask, vec.sv_mask);
2999 vec.sv_flags = osa.sa_flags;
3000 vec.sv_flags &= ~SA_NOCLDWAIT;
3001 vec.sv_flags ^= SA_RESTART;
3002 error = copyout(&vec, uap->osv, sizeof(vec));
3003 }
3004 return (error);
3005 }
3006
3007 struct sigstack32 {
3008 uint32_t ss_sp;
3009 int ss_onstack;
3010 };
3011
3012 int
ofreebsd32_sigstack(struct thread * td,struct ofreebsd32_sigstack_args * uap)3013 ofreebsd32_sigstack(struct thread *td,
3014 struct ofreebsd32_sigstack_args *uap)
3015 {
3016 struct sigstack32 s32;
3017 struct sigstack nss, oss;
3018 int error = 0, unss;
3019
3020 if (uap->nss != NULL) {
3021 error = copyin(uap->nss, &s32, sizeof(s32));
3022 if (error)
3023 return (error);
3024 nss.ss_sp = PTRIN(s32.ss_sp);
3025 CP(s32, nss, ss_onstack);
3026 unss = 1;
3027 } else {
3028 unss = 0;
3029 }
3030 oss.ss_sp = td->td_sigstk.ss_sp;
3031 oss.ss_onstack = sigonstack(cpu_getstack(td));
3032 if (unss) {
3033 td->td_sigstk.ss_sp = nss.ss_sp;
3034 td->td_sigstk.ss_size = 0;
3035 td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
3036 td->td_pflags |= TDP_ALTSTACK;
3037 }
3038 if (uap->oss != NULL) {
3039 s32.ss_sp = PTROUT(oss.ss_sp);
3040 CP(oss, s32, ss_onstack);
3041 error = copyout(&s32, uap->oss, sizeof(s32));
3042 }
3043 return (error);
3044 }
3045 #endif
3046
3047 int
freebsd32_nanosleep(struct thread * td,struct freebsd32_nanosleep_args * uap)3048 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
3049 {
3050
3051 return (freebsd32_user_clock_nanosleep(td, CLOCK_REALTIME,
3052 TIMER_RELTIME, uap->rqtp, uap->rmtp));
3053 }
3054
3055 int
freebsd32_clock_nanosleep(struct thread * td,struct freebsd32_clock_nanosleep_args * uap)3056 freebsd32_clock_nanosleep(struct thread *td,
3057 struct freebsd32_clock_nanosleep_args *uap)
3058 {
3059 int error;
3060
3061 error = freebsd32_user_clock_nanosleep(td, uap->clock_id, uap->flags,
3062 uap->rqtp, uap->rmtp);
3063 return (kern_posix_error(td, error));
3064 }
3065
3066 static int
freebsd32_user_clock_nanosleep(struct thread * td,clockid_t clock_id,int flags,const struct timespec32 * ua_rqtp,struct timespec32 * ua_rmtp)3067 freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
3068 int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp)
3069 {
3070 struct timespec32 rmt32, rqt32;
3071 struct timespec rmt, rqt;
3072 int error, error2;
3073
3074 error = copyin(ua_rqtp, &rqt32, sizeof(rqt32));
3075 if (error)
3076 return (error);
3077
3078 CP(rqt32, rqt, tv_sec);
3079 CP(rqt32, rqt, tv_nsec);
3080
3081 error = kern_clock_nanosleep(td, clock_id, flags, &rqt, &rmt);
3082 if (error == EINTR && ua_rmtp != NULL && (flags & TIMER_ABSTIME) == 0) {
3083 CP(rmt, rmt32, tv_sec);
3084 CP(rmt, rmt32, tv_nsec);
3085
3086 error2 = copyout(&rmt32, ua_rmtp, sizeof(rmt32));
3087 if (error2 != 0)
3088 error = error2;
3089 }
3090 return (error);
3091 }
3092
3093 int
freebsd32_clock_gettime(struct thread * td,struct freebsd32_clock_gettime_args * uap)3094 freebsd32_clock_gettime(struct thread *td,
3095 struct freebsd32_clock_gettime_args *uap)
3096 {
3097 struct timespec ats;
3098 struct timespec32 ats32;
3099 int error;
3100
3101 error = kern_clock_gettime(td, uap->clock_id, &ats);
3102 if (error == 0) {
3103 CP(ats, ats32, tv_sec);
3104 CP(ats, ats32, tv_nsec);
3105 error = copyout(&ats32, uap->tp, sizeof(ats32));
3106 }
3107 return (error);
3108 }
3109
3110 int
freebsd32_clock_settime(struct thread * td,struct freebsd32_clock_settime_args * uap)3111 freebsd32_clock_settime(struct thread *td,
3112 struct freebsd32_clock_settime_args *uap)
3113 {
3114 struct timespec ats;
3115 struct timespec32 ats32;
3116 int error;
3117
3118 error = copyin(uap->tp, &ats32, sizeof(ats32));
3119 if (error)
3120 return (error);
3121 CP(ats32, ats, tv_sec);
3122 CP(ats32, ats, tv_nsec);
3123
3124 return (kern_clock_settime(td, uap->clock_id, &ats));
3125 }
3126
3127 int
freebsd32_clock_getres(struct thread * td,struct freebsd32_clock_getres_args * uap)3128 freebsd32_clock_getres(struct thread *td,
3129 struct freebsd32_clock_getres_args *uap)
3130 {
3131 struct timespec ts;
3132 struct timespec32 ts32;
3133 int error;
3134
3135 if (uap->tp == NULL)
3136 return (0);
3137 error = kern_clock_getres(td, uap->clock_id, &ts);
3138 if (error == 0) {
3139 CP(ts, ts32, tv_sec);
3140 CP(ts, ts32, tv_nsec);
3141 error = copyout(&ts32, uap->tp, sizeof(ts32));
3142 }
3143 return (error);
3144 }
3145
freebsd32_ktimer_create(struct thread * td,struct freebsd32_ktimer_create_args * uap)3146 int freebsd32_ktimer_create(struct thread *td,
3147 struct freebsd32_ktimer_create_args *uap)
3148 {
3149 struct sigevent32 ev32;
3150 struct sigevent ev, *evp;
3151 int error, id;
3152
3153 if (uap->evp == NULL) {
3154 evp = NULL;
3155 } else {
3156 evp = &ev;
3157 error = copyin(uap->evp, &ev32, sizeof(ev32));
3158 if (error != 0)
3159 return (error);
3160 error = convert_sigevent32(&ev32, &ev);
3161 if (error != 0)
3162 return (error);
3163 }
3164 error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
3165 if (error == 0) {
3166 error = copyout(&id, uap->timerid, sizeof(int));
3167 if (error != 0)
3168 kern_ktimer_delete(td, id);
3169 }
3170 return (error);
3171 }
3172
3173 int
freebsd32_ktimer_settime(struct thread * td,struct freebsd32_ktimer_settime_args * uap)3174 freebsd32_ktimer_settime(struct thread *td,
3175 struct freebsd32_ktimer_settime_args *uap)
3176 {
3177 struct itimerspec32 val32, oval32;
3178 struct itimerspec val, oval, *ovalp;
3179 int error;
3180
3181 error = copyin(uap->value, &val32, sizeof(val32));
3182 if (error != 0)
3183 return (error);
3184 ITS_CP(val32, val);
3185 ovalp = uap->ovalue != NULL ? &oval : NULL;
3186 error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
3187 if (error == 0 && uap->ovalue != NULL) {
3188 ITS_CP(oval, oval32);
3189 error = copyout(&oval32, uap->ovalue, sizeof(oval32));
3190 }
3191 return (error);
3192 }
3193
3194 int
freebsd32_ktimer_gettime(struct thread * td,struct freebsd32_ktimer_gettime_args * uap)3195 freebsd32_ktimer_gettime(struct thread *td,
3196 struct freebsd32_ktimer_gettime_args *uap)
3197 {
3198 struct itimerspec32 val32;
3199 struct itimerspec val;
3200 int error;
3201
3202 error = kern_ktimer_gettime(td, uap->timerid, &val);
3203 if (error == 0) {
3204 ITS_CP(val, val32);
3205 error = copyout(&val32, uap->value, sizeof(val32));
3206 }
3207 return (error);
3208 }
3209
3210 int
freebsd32_timerfd_gettime(struct thread * td,struct freebsd32_timerfd_gettime_args * uap)3211 freebsd32_timerfd_gettime(struct thread *td,
3212 struct freebsd32_timerfd_gettime_args *uap)
3213 {
3214 struct itimerspec curr_value;
3215 struct itimerspec32 curr_value32;
3216 int error;
3217
3218 error = kern_timerfd_gettime(td, uap->fd, &curr_value);
3219 if (error == 0) {
3220 CP(curr_value, curr_value32, it_value.tv_sec);
3221 CP(curr_value, curr_value32, it_value.tv_nsec);
3222 CP(curr_value, curr_value32, it_interval.tv_sec);
3223 CP(curr_value, curr_value32, it_interval.tv_nsec);
3224 error = copyout(&curr_value32, uap->curr_value,
3225 sizeof(curr_value32));
3226 }
3227
3228 return (error);
3229 }
3230
3231 int
freebsd32_timerfd_settime(struct thread * td,struct freebsd32_timerfd_settime_args * uap)3232 freebsd32_timerfd_settime(struct thread *td,
3233 struct freebsd32_timerfd_settime_args *uap)
3234 {
3235 struct itimerspec new_value, old_value;
3236 struct itimerspec32 new_value32, old_value32;
3237 int error;
3238
3239 error = copyin(uap->new_value, &new_value32, sizeof(new_value32));
3240 if (error != 0)
3241 return (error);
3242 CP(new_value32, new_value, it_value.tv_sec);
3243 CP(new_value32, new_value, it_value.tv_nsec);
3244 CP(new_value32, new_value, it_interval.tv_sec);
3245 CP(new_value32, new_value, it_interval.tv_nsec);
3246 if (uap->old_value == NULL) {
3247 error = kern_timerfd_settime(td, uap->fd, uap->flags,
3248 &new_value, NULL);
3249 } else {
3250 error = kern_timerfd_settime(td, uap->fd, uap->flags,
3251 &new_value, &old_value);
3252 if (error == 0) {
3253 CP(old_value, old_value32, it_value.tv_sec);
3254 CP(old_value, old_value32, it_value.tv_nsec);
3255 CP(old_value, old_value32, it_interval.tv_sec);
3256 CP(old_value, old_value32, it_interval.tv_nsec);
3257 error = copyout(&old_value32, uap->old_value,
3258 sizeof(old_value32));
3259 }
3260 }
3261 return (error);
3262 }
3263
3264 int
freebsd32_clock_getcpuclockid2(struct thread * td,struct freebsd32_clock_getcpuclockid2_args * uap)3265 freebsd32_clock_getcpuclockid2(struct thread *td,
3266 struct freebsd32_clock_getcpuclockid2_args *uap)
3267 {
3268 clockid_t clk_id;
3269 int error;
3270
3271 error = kern_clock_getcpuclockid2(td, PAIR32TO64(id_t, uap->id),
3272 uap->which, &clk_id);
3273 if (error == 0)
3274 error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t));
3275 return (error);
3276 }
3277
3278 int
freebsd32_thr_new(struct thread * td,struct freebsd32_thr_new_args * uap)3279 freebsd32_thr_new(struct thread *td,
3280 struct freebsd32_thr_new_args *uap)
3281 {
3282 struct thr_param32 param32;
3283 struct thr_param param;
3284 int error;
3285
3286 if (uap->param_size < 0 ||
3287 uap->param_size > sizeof(struct thr_param32))
3288 return (EINVAL);
3289 bzero(¶m, sizeof(struct thr_param));
3290 bzero(¶m32, sizeof(struct thr_param32));
3291 error = copyin(uap->param, ¶m32, uap->param_size);
3292 if (error != 0)
3293 return (error);
3294 param.start_func = PTRIN(param32.start_func);
3295 param.arg = PTRIN(param32.arg);
3296 param.stack_base = PTRIN(param32.stack_base);
3297 param.stack_size = param32.stack_size;
3298 param.tls_base = PTRIN(param32.tls_base);
3299 param.tls_size = param32.tls_size;
3300 param.child_tid = PTRIN(param32.child_tid);
3301 param.parent_tid = PTRIN(param32.parent_tid);
3302 param.flags = param32.flags;
3303 param.rtp = PTRIN(param32.rtp);
3304 param.spare[0] = PTRIN(param32.spare[0]);
3305 param.spare[1] = PTRIN(param32.spare[1]);
3306 param.spare[2] = PTRIN(param32.spare[2]);
3307
3308 return (kern_thr_new(td, ¶m));
3309 }
3310
3311 int
freebsd32_thr_suspend(struct thread * td,struct freebsd32_thr_suspend_args * uap)3312 freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
3313 {
3314 struct timespec32 ts32;
3315 struct timespec ts, *tsp;
3316 int error;
3317
3318 error = 0;
3319 tsp = NULL;
3320 if (uap->timeout != NULL) {
3321 error = copyin((const void *)uap->timeout, (void *)&ts32,
3322 sizeof(struct timespec32));
3323 if (error != 0)
3324 return (error);
3325 ts.tv_sec = ts32.tv_sec;
3326 ts.tv_nsec = ts32.tv_nsec;
3327 tsp = &ts;
3328 }
3329 return (kern_thr_suspend(td, tsp));
3330 }
3331
3332 void
siginfo_to_siginfo32(const siginfo_t * src,struct __siginfo32 * dst)3333 siginfo_to_siginfo32(const siginfo_t *src, struct __siginfo32 *dst)
3334 {
3335 bzero(dst, sizeof(*dst));
3336 dst->si_signo = src->si_signo;
3337 dst->si_errno = src->si_errno;
3338 dst->si_code = src->si_code;
3339 dst->si_pid = src->si_pid;
3340 dst->si_uid = src->si_uid;
3341 dst->si_status = src->si_status;
3342 dst->si_addr = (uintptr_t)src->si_addr;
3343 dst->si_value.sival_int = src->si_value.sival_int;
3344 dst->si_timerid = src->si_timerid;
3345 dst->si_overrun = src->si_overrun;
3346 }
3347
3348 #ifndef _FREEBSD32_SYSPROTO_H_
3349 struct freebsd32_sigqueue_args {
3350 pid_t pid;
3351 int signum;
3352 /* union sigval32 */ int value;
3353 };
3354 #endif
3355 int
freebsd32_sigqueue(struct thread * td,struct freebsd32_sigqueue_args * uap)3356 freebsd32_sigqueue(struct thread *td, struct freebsd32_sigqueue_args *uap)
3357 {
3358 union sigval sv;
3359
3360 /*
3361 * On 32-bit ABIs, sival_int and sival_ptr are the same.
3362 * On 64-bit little-endian ABIs, the low bits are the same.
3363 * In 64-bit big-endian ABIs, sival_int overlaps with
3364 * sival_ptr's HIGH bits. We choose to support sival_int
3365 * rather than sival_ptr in this case as it seems to be
3366 * more common.
3367 */
3368 bzero(&sv, sizeof(sv));
3369 sv.sival_int = (uint32_t)(uint64_t)uap->value;
3370
3371 return (kern_sigqueue(td, uap->pid, uap->signum, &sv));
3372 }
3373
3374 int
freebsd32_sigtimedwait(struct thread * td,struct freebsd32_sigtimedwait_args * uap)3375 freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
3376 {
3377 struct timespec32 ts32;
3378 struct timespec ts;
3379 struct timespec *timeout;
3380 sigset_t set;
3381 ksiginfo_t ksi;
3382 struct __siginfo32 si32;
3383 int error;
3384
3385 if (uap->timeout) {
3386 error = copyin(uap->timeout, &ts32, sizeof(ts32));
3387 if (error)
3388 return (error);
3389 ts.tv_sec = ts32.tv_sec;
3390 ts.tv_nsec = ts32.tv_nsec;
3391 timeout = &ts;
3392 } else
3393 timeout = NULL;
3394
3395 error = copyin(uap->set, &set, sizeof(set));
3396 if (error)
3397 return (error);
3398
3399 error = kern_sigtimedwait(td, set, &ksi, timeout);
3400 if (error)
3401 return (error);
3402
3403 if (uap->info) {
3404 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
3405 error = copyout(&si32, uap->info, sizeof(struct __siginfo32));
3406 }
3407
3408 if (error == 0)
3409 td->td_retval[0] = ksi.ksi_signo;
3410 return (error);
3411 }
3412
3413 /*
3414 * MPSAFE
3415 */
3416 int
freebsd32_sigwaitinfo(struct thread * td,struct freebsd32_sigwaitinfo_args * uap)3417 freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
3418 {
3419 ksiginfo_t ksi;
3420 struct __siginfo32 si32;
3421 sigset_t set;
3422 int error;
3423
3424 error = copyin(uap->set, &set, sizeof(set));
3425 if (error)
3426 return (error);
3427
3428 error = kern_sigtimedwait(td, set, &ksi, NULL);
3429 if (error)
3430 return (error);
3431
3432 if (uap->info) {
3433 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
3434 error = copyout(&si32, uap->info, sizeof(struct __siginfo32));
3435 }
3436 if (error == 0)
3437 td->td_retval[0] = ksi.ksi_signo;
3438 return (error);
3439 }
3440
3441 int
freebsd32_cpuset_setid(struct thread * td,struct freebsd32_cpuset_setid_args * uap)3442 freebsd32_cpuset_setid(struct thread *td,
3443 struct freebsd32_cpuset_setid_args *uap)
3444 {
3445
3446 return (kern_cpuset_setid(td, uap->which,
3447 PAIR32TO64(id_t, uap->id), uap->setid));
3448 }
3449
3450 int
freebsd32_cpuset_getid(struct thread * td,struct freebsd32_cpuset_getid_args * uap)3451 freebsd32_cpuset_getid(struct thread *td,
3452 struct freebsd32_cpuset_getid_args *uap)
3453 {
3454
3455 return (kern_cpuset_getid(td, uap->level, uap->which,
3456 PAIR32TO64(id_t, uap->id), uap->setid));
3457 }
3458
3459 static int
copyin32_set(const void * u,void * k,size_t size)3460 copyin32_set(const void *u, void *k, size_t size)
3461 {
3462 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
3463 int rv;
3464 struct bitset *kb = k;
3465 int *p;
3466
3467 rv = copyin(u, k, size);
3468 if (rv != 0)
3469 return (rv);
3470
3471 p = (int *)kb->__bits;
3472 /* Loop through swapping words.
3473 * `size' is in bytes, we need bits. */
3474 for (int i = 0; i < __bitset_words(size * 8); i++) {
3475 int tmp = p[0];
3476 p[0] = p[1];
3477 p[1] = tmp;
3478 p += 2;
3479 }
3480 return (0);
3481 #else
3482 return (copyin(u, k, size));
3483 #endif
3484 }
3485
3486 static int
copyout32_set(const void * k,void * u,size_t size)3487 copyout32_set(const void *k, void *u, size_t size)
3488 {
3489 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
3490 const struct bitset *kb = k;
3491 struct bitset *ub = u;
3492 const int *kp = (const int *)kb->__bits;
3493 int *up = (int *)ub->__bits;
3494 int rv;
3495
3496 for (int i = 0; i < __bitset_words(CPU_SETSIZE); i++) {
3497 /* `size' is in bytes, we need bits. */
3498 for (int i = 0; i < __bitset_words(size * 8); i++) {
3499 rv = suword32(up, kp[1]);
3500 if (rv == 0)
3501 rv = suword32(up + 1, kp[0]);
3502 if (rv != 0)
3503 return (EFAULT);
3504 }
3505 }
3506 return (0);
3507 #else
3508 return (copyout(k, u, size));
3509 #endif
3510 }
3511
3512 static const struct cpuset_copy_cb cpuset_copy32_cb = {
3513 .cpuset_copyin = copyin32_set,
3514 .cpuset_copyout = copyout32_set
3515 };
3516
3517 int
freebsd32_cpuset_getaffinity(struct thread * td,struct freebsd32_cpuset_getaffinity_args * uap)3518 freebsd32_cpuset_getaffinity(struct thread *td,
3519 struct freebsd32_cpuset_getaffinity_args *uap)
3520 {
3521
3522 return (user_cpuset_getaffinity(td, uap->level, uap->which,
3523 PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask,
3524 &cpuset_copy32_cb));
3525 }
3526
3527 int
freebsd32_cpuset_setaffinity(struct thread * td,struct freebsd32_cpuset_setaffinity_args * uap)3528 freebsd32_cpuset_setaffinity(struct thread *td,
3529 struct freebsd32_cpuset_setaffinity_args *uap)
3530 {
3531
3532 return (user_cpuset_setaffinity(td, uap->level, uap->which,
3533 PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask,
3534 &cpuset_copy32_cb));
3535 }
3536
3537 int
freebsd32_cpuset_getdomain(struct thread * td,struct freebsd32_cpuset_getdomain_args * uap)3538 freebsd32_cpuset_getdomain(struct thread *td,
3539 struct freebsd32_cpuset_getdomain_args *uap)
3540 {
3541
3542 return (kern_cpuset_getdomain(td, uap->level, uap->which,
3543 PAIR32TO64(id_t,uap->id), uap->domainsetsize, uap->mask, uap->policy,
3544 &cpuset_copy32_cb));
3545 }
3546
3547 int
freebsd32_cpuset_setdomain(struct thread * td,struct freebsd32_cpuset_setdomain_args * uap)3548 freebsd32_cpuset_setdomain(struct thread *td,
3549 struct freebsd32_cpuset_setdomain_args *uap)
3550 {
3551
3552 return (kern_cpuset_setdomain(td, uap->level, uap->which,
3553 PAIR32TO64(id_t,uap->id), uap->domainsetsize, uap->mask, uap->policy,
3554 &cpuset_copy32_cb));
3555 }
3556
3557 int
freebsd32_nmount(struct thread * td,struct freebsd32_nmount_args * uap)3558 freebsd32_nmount(struct thread *td,
3559 struct freebsd32_nmount_args /* {
3560 struct iovec *iovp;
3561 unsigned int iovcnt;
3562 int flags;
3563 } */ *uap)
3564 {
3565 struct uio *auio;
3566 uint64_t flags;
3567 int error;
3568
3569 /*
3570 * Mount flags are now 64-bits. On 32-bit archtectures only
3571 * 32-bits are passed in, but from here on everything handles
3572 * 64-bit flags correctly.
3573 */
3574 flags = uap->flags;
3575
3576 AUDIT_ARG_FFLAGS(flags);
3577
3578 /*
3579 * Filter out MNT_ROOTFS. We do not want clients of nmount() in
3580 * userspace to set this flag, but we must filter it out if we want
3581 * MNT_UPDATE on the root file system to work.
3582 * MNT_ROOTFS should only be set by the kernel when mounting its
3583 * root file system.
3584 */
3585 flags &= ~MNT_ROOTFS;
3586
3587 /*
3588 * check that we have an even number of iovec's
3589 * and that we have at least two options.
3590 */
3591 if ((uap->iovcnt & 1) || (uap->iovcnt < 4))
3592 return (EINVAL);
3593
3594 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
3595 if (error)
3596 return (error);
3597 error = vfs_donmount(td, flags, auio);
3598
3599 freeuio(auio);
3600 return error;
3601 }
3602
3603 #if 0
3604 int
3605 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
3606 {
3607 struct yyy32 *p32, s32;
3608 struct yyy *p = NULL, s;
3609 struct xxx_arg ap;
3610 int error;
3611
3612 if (uap->zzz) {
3613 error = copyin(uap->zzz, &s32, sizeof(s32));
3614 if (error)
3615 return (error);
3616 /* translate in */
3617 p = &s;
3618 }
3619 error = kern_xxx(td, p);
3620 if (error)
3621 return (error);
3622 if (uap->zzz) {
3623 /* translate out */
3624 error = copyout(&s32, p32, sizeof(s32));
3625 }
3626 return (error);
3627 }
3628 #endif
3629
3630 int
syscall32_module_handler(struct module * mod,int what,void * arg)3631 syscall32_module_handler(struct module *mod, int what, void *arg)
3632 {
3633
3634 return (kern_syscall_module_handler(freebsd32_sysent, mod, what, arg));
3635 }
3636
3637 int
syscall32_helper_register(struct syscall_helper_data * sd,int flags)3638 syscall32_helper_register(struct syscall_helper_data *sd, int flags)
3639 {
3640
3641 return (kern_syscall_helper_register(freebsd32_sysent, sd, flags));
3642 }
3643
3644 int
syscall32_helper_unregister(struct syscall_helper_data * sd)3645 syscall32_helper_unregister(struct syscall_helper_data *sd)
3646 {
3647
3648 return (kern_syscall_helper_unregister(freebsd32_sysent, sd));
3649 }
3650
3651 int
freebsd32_copyout_strings(struct image_params * imgp,uintptr_t * stack_base)3652 freebsd32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
3653 {
3654 struct sysentvec *sysent;
3655 int argc, envc, i;
3656 uint32_t *vectp;
3657 char *stringp;
3658 uintptr_t destp, ustringp;
3659 struct freebsd32_ps_strings *arginfo;
3660 char canary[sizeof(long) * 8];
3661 int32_t pagesizes32[MAXPAGESIZES];
3662 size_t execpath_len;
3663 int error, szsigcode;
3664
3665 sysent = imgp->sysent;
3666
3667 arginfo = (struct freebsd32_ps_strings *)PROC_PS_STRINGS(imgp->proc);
3668 imgp->ps_strings = arginfo;
3669 destp = (uintptr_t)arginfo;
3670
3671 /*
3672 * Install sigcode.
3673 */
3674 if (!PROC_HAS_SHP(imgp->proc)) {
3675 szsigcode = *sysent->sv_szsigcode;
3676 destp -= szsigcode;
3677 destp = rounddown2(destp, sizeof(uint32_t));
3678 error = copyout(sysent->sv_sigcode, (void *)destp,
3679 szsigcode);
3680 if (error != 0)
3681 return (error);
3682 }
3683
3684 /*
3685 * Copy the image path for the rtld.
3686 */
3687 if (imgp->execpath != NULL && imgp->auxargs != NULL) {
3688 execpath_len = strlen(imgp->execpath) + 1;
3689 destp -= execpath_len;
3690 imgp->execpathp = (void *)destp;
3691 error = copyout(imgp->execpath, imgp->execpathp, execpath_len);
3692 if (error != 0)
3693 return (error);
3694 }
3695
3696 /*
3697 * Prepare the canary for SSP.
3698 */
3699 arc4rand(canary, sizeof(canary), 0);
3700 destp -= sizeof(canary);
3701 imgp->canary = (void *)destp;
3702 error = copyout(canary, imgp->canary, sizeof(canary));
3703 if (error != 0)
3704 return (error);
3705 imgp->canarylen = sizeof(canary);
3706
3707 /*
3708 * Prepare the pagesizes array.
3709 */
3710 for (i = 0; i < MAXPAGESIZES; i++)
3711 pagesizes32[i] = (uint32_t)pagesizes[i];
3712 destp -= sizeof(pagesizes32);
3713 destp = rounddown2(destp, sizeof(uint32_t));
3714 imgp->pagesizes = (void *)destp;
3715 error = copyout(pagesizes32, imgp->pagesizes, sizeof(pagesizes32));
3716 if (error != 0)
3717 return (error);
3718 imgp->pagesizeslen = sizeof(pagesizes32);
3719
3720 /*
3721 * Allocate room for the argument and environment strings.
3722 */
3723 destp -= ARG_MAX - imgp->args->stringspace;
3724 destp = rounddown2(destp, sizeof(uint32_t));
3725 ustringp = destp;
3726
3727 if (imgp->auxargs) {
3728 /*
3729 * Allocate room on the stack for the ELF auxargs
3730 * array. It has up to AT_COUNT entries.
3731 */
3732 destp -= AT_COUNT * sizeof(Elf32_Auxinfo);
3733 destp = rounddown2(destp, sizeof(uint32_t));
3734 }
3735
3736 vectp = (uint32_t *)destp;
3737
3738 /*
3739 * Allocate room for the argv[] and env vectors including the
3740 * terminating NULL pointers.
3741 */
3742 vectp -= imgp->args->argc + 1 + imgp->args->envc + 1;
3743
3744 /*
3745 * vectp also becomes our initial stack base
3746 */
3747 *stack_base = (uintptr_t)vectp;
3748
3749 stringp = imgp->args->begin_argv;
3750 argc = imgp->args->argc;
3751 envc = imgp->args->envc;
3752 /*
3753 * Copy out strings - arguments and environment.
3754 */
3755 error = copyout(stringp, (void *)ustringp,
3756 ARG_MAX - imgp->args->stringspace);
3757 if (error != 0)
3758 return (error);
3759
3760 /*
3761 * Fill in "ps_strings" struct for ps, w, etc.
3762 */
3763 imgp->argv = vectp;
3764 if (suword32(&arginfo->ps_argvstr, (uint32_t)(intptr_t)vectp) != 0 ||
3765 suword32(&arginfo->ps_nargvstr, argc) != 0)
3766 return (EFAULT);
3767
3768 /*
3769 * Fill in argument portion of vector table.
3770 */
3771 for (; argc > 0; --argc) {
3772 if (suword32(vectp++, ustringp) != 0)
3773 return (EFAULT);
3774 while (*stringp++ != 0)
3775 ustringp++;
3776 ustringp++;
3777 }
3778
3779 /* a null vector table pointer separates the argp's from the envp's */
3780 if (suword32(vectp++, 0) != 0)
3781 return (EFAULT);
3782
3783 imgp->envv = vectp;
3784 if (suword32(&arginfo->ps_envstr, (uint32_t)(intptr_t)vectp) != 0 ||
3785 suword32(&arginfo->ps_nenvstr, envc) != 0)
3786 return (EFAULT);
3787
3788 /*
3789 * Fill in environment portion of vector table.
3790 */
3791 for (; envc > 0; --envc) {
3792 if (suword32(vectp++, ustringp) != 0)
3793 return (EFAULT);
3794 while (*stringp++ != 0)
3795 ustringp++;
3796 ustringp++;
3797 }
3798
3799 /* end of vector table is a null pointer */
3800 if (suword32(vectp, 0) != 0)
3801 return (EFAULT);
3802
3803 if (imgp->auxargs) {
3804 vectp++;
3805 error = imgp->sysent->sv_copyout_auxargs(imgp,
3806 (uintptr_t)vectp);
3807 if (error != 0)
3808 return (error);
3809 }
3810
3811 return (0);
3812 }
3813
3814 int
freebsd32_kldstat(struct thread * td,struct freebsd32_kldstat_args * uap)3815 freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap)
3816 {
3817 struct kld_file_stat *stat;
3818 struct kld_file_stat32 *stat32;
3819 int error, version;
3820
3821 if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
3822 != 0)
3823 return (error);
3824 if (version != sizeof(struct kld_file_stat_1_32) &&
3825 version != sizeof(struct kld_file_stat32))
3826 return (EINVAL);
3827
3828 stat = malloc(sizeof(*stat), M_TEMP, M_WAITOK | M_ZERO);
3829 stat32 = malloc(sizeof(*stat32), M_TEMP, M_WAITOK | M_ZERO);
3830 error = kern_kldstat(td, uap->fileid, stat);
3831 if (error == 0) {
3832 bcopy(&stat->name[0], &stat32->name[0], sizeof(stat->name));
3833 CP(*stat, *stat32, refs);
3834 CP(*stat, *stat32, id);
3835 PTROUT_CP(*stat, *stat32, address);
3836 CP(*stat, *stat32, size);
3837 bcopy(&stat->pathname[0], &stat32->pathname[0],
3838 sizeof(stat->pathname));
3839 stat32->version = version;
3840 error = copyout(stat32, uap->stat, version);
3841 }
3842 free(stat, M_TEMP);
3843 free(stat32, M_TEMP);
3844 return (error);
3845 }
3846
3847 int
freebsd32_posix_fallocate(struct thread * td,struct freebsd32_posix_fallocate_args * uap)3848 freebsd32_posix_fallocate(struct thread *td,
3849 struct freebsd32_posix_fallocate_args *uap)
3850 {
3851 int error;
3852
3853 error = kern_posix_fallocate(td, uap->fd,
3854 PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len));
3855 return (kern_posix_error(td, error));
3856 }
3857
3858 int
freebsd32_posix_fadvise(struct thread * td,struct freebsd32_posix_fadvise_args * uap)3859 freebsd32_posix_fadvise(struct thread *td,
3860 struct freebsd32_posix_fadvise_args *uap)
3861 {
3862 int error;
3863
3864 error = kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset),
3865 PAIR32TO64(off_t, uap->len), uap->advice);
3866 return (kern_posix_error(td, error));
3867 }
3868
3869 int
convert_sigevent32(struct sigevent32 * sig32,struct sigevent * sig)3870 convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig)
3871 {
3872
3873 CP(*sig32, *sig, sigev_notify);
3874 switch (sig->sigev_notify) {
3875 case SIGEV_NONE:
3876 break;
3877 case SIGEV_THREAD_ID:
3878 CP(*sig32, *sig, sigev_notify_thread_id);
3879 /* FALLTHROUGH */
3880 case SIGEV_SIGNAL:
3881 CP(*sig32, *sig, sigev_signo);
3882 PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
3883 break;
3884 case SIGEV_KEVENT:
3885 CP(*sig32, *sig, sigev_notify_kqueue);
3886 CP(*sig32, *sig, sigev_notify_kevent_flags);
3887 PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
3888 break;
3889 default:
3890 return (EINVAL);
3891 }
3892 return (0);
3893 }
3894
3895 int
freebsd32_procctl(struct thread * td,struct freebsd32_procctl_args * uap)3896 freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap)
3897 {
3898 void *data;
3899 union {
3900 struct procctl_reaper_status rs;
3901 struct procctl_reaper_pids rp;
3902 struct procctl_reaper_kill rk;
3903 } x;
3904 union {
3905 struct procctl_reaper_pids32 rp;
3906 } x32;
3907 int error, error1, flags, signum;
3908
3909 if (uap->com >= PROC_PROCCTL_MD_MIN)
3910 return (cpu_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id),
3911 uap->com, PTRIN(uap->data)));
3912
3913 switch (uap->com) {
3914 case PROC_ASLR_CTL:
3915 case PROC_PROTMAX_CTL:
3916 case PROC_SPROTECT:
3917 case PROC_STACKGAP_CTL:
3918 case PROC_TRACE_CTL:
3919 case PROC_TRAPCAP_CTL:
3920 case PROC_NO_NEW_PRIVS_CTL:
3921 case PROC_WXMAP_CTL:
3922 case PROC_LOGSIGEXIT_CTL:
3923 error = copyin(PTRIN(uap->data), &flags, sizeof(flags));
3924 if (error != 0)
3925 return (error);
3926 data = &flags;
3927 break;
3928 case PROC_REAP_ACQUIRE:
3929 case PROC_REAP_RELEASE:
3930 if (uap->data != NULL)
3931 return (EINVAL);
3932 data = NULL;
3933 break;
3934 case PROC_REAP_STATUS:
3935 data = &x.rs;
3936 break;
3937 case PROC_REAP_GETPIDS:
3938 error = copyin(uap->data, &x32.rp, sizeof(x32.rp));
3939 if (error != 0)
3940 return (error);
3941 CP(x32.rp, x.rp, rp_count);
3942 PTRIN_CP(x32.rp, x.rp, rp_pids);
3943 data = &x.rp;
3944 break;
3945 case PROC_REAP_KILL:
3946 error = copyin(uap->data, &x.rk, sizeof(x.rk));
3947 if (error != 0)
3948 return (error);
3949 data = &x.rk;
3950 break;
3951 case PROC_ASLR_STATUS:
3952 case PROC_PROTMAX_STATUS:
3953 case PROC_STACKGAP_STATUS:
3954 case PROC_TRACE_STATUS:
3955 case PROC_TRAPCAP_STATUS:
3956 case PROC_NO_NEW_PRIVS_STATUS:
3957 case PROC_WXMAP_STATUS:
3958 case PROC_LOGSIGEXIT_STATUS:
3959 data = &flags;
3960 break;
3961 case PROC_PDEATHSIG_CTL:
3962 error = copyin(uap->data, &signum, sizeof(signum));
3963 if (error != 0)
3964 return (error);
3965 data = &signum;
3966 break;
3967 case PROC_PDEATHSIG_STATUS:
3968 data = &signum;
3969 break;
3970 default:
3971 return (EINVAL);
3972 }
3973 error = kern_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id),
3974 uap->com, data);
3975 switch (uap->com) {
3976 case PROC_REAP_STATUS:
3977 if (error == 0)
3978 error = copyout(&x.rs, uap->data, sizeof(x.rs));
3979 break;
3980 case PROC_REAP_KILL:
3981 error1 = copyout(&x.rk, uap->data, sizeof(x.rk));
3982 if (error == 0)
3983 error = error1;
3984 break;
3985 case PROC_ASLR_STATUS:
3986 case PROC_PROTMAX_STATUS:
3987 case PROC_STACKGAP_STATUS:
3988 case PROC_TRACE_STATUS:
3989 case PROC_TRAPCAP_STATUS:
3990 case PROC_NO_NEW_PRIVS_STATUS:
3991 case PROC_WXMAP_STATUS:
3992 case PROC_LOGSIGEXIT_STATUS:
3993 if (error == 0)
3994 error = copyout(&flags, uap->data, sizeof(flags));
3995 break;
3996 case PROC_PDEATHSIG_STATUS:
3997 if (error == 0)
3998 error = copyout(&signum, uap->data, sizeof(signum));
3999 break;
4000 }
4001 return (error);
4002 }
4003
4004 int
freebsd32_fcntl(struct thread * td,struct freebsd32_fcntl_args * uap)4005 freebsd32_fcntl(struct thread *td, struct freebsd32_fcntl_args *uap)
4006 {
4007 intptr_t tmp;
4008
4009 switch (uap->cmd) {
4010 /*
4011 * Do unsigned conversion for arg when operation
4012 * interprets it as flags or pointer.
4013 */
4014 case F_SETLK_REMOTE:
4015 case F_SETLKW:
4016 case F_SETLK:
4017 case F_GETLK:
4018 case F_SETFD:
4019 case F_SETFL:
4020 case F_OGETLK:
4021 case F_OSETLK:
4022 case F_OSETLKW:
4023 case F_KINFO:
4024 tmp = (unsigned int)(uap->arg);
4025 break;
4026 default:
4027 tmp = uap->arg;
4028 break;
4029 }
4030 return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp));
4031 }
4032
4033 int
freebsd32_ppoll(struct thread * td,struct freebsd32_ppoll_args * uap)4034 freebsd32_ppoll(struct thread *td, struct freebsd32_ppoll_args *uap)
4035 {
4036 struct timespec32 ts32;
4037 struct timespec ts, *tsp;
4038 sigset_t set, *ssp;
4039 int error;
4040
4041 if (uap->ts != NULL) {
4042 error = copyin(uap->ts, &ts32, sizeof(ts32));
4043 if (error != 0)
4044 return (error);
4045 CP(ts32, ts, tv_sec);
4046 CP(ts32, ts, tv_nsec);
4047 tsp = &ts;
4048 } else
4049 tsp = NULL;
4050 if (uap->set != NULL) {
4051 error = copyin(uap->set, &set, sizeof(set));
4052 if (error != 0)
4053 return (error);
4054 ssp = &set;
4055 } else
4056 ssp = NULL;
4057
4058 return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
4059 }
4060
4061 int
freebsd32_sched_rr_get_interval(struct thread * td,struct freebsd32_sched_rr_get_interval_args * uap)4062 freebsd32_sched_rr_get_interval(struct thread *td,
4063 struct freebsd32_sched_rr_get_interval_args *uap)
4064 {
4065 struct timespec ts;
4066 struct timespec32 ts32;
4067 int error;
4068
4069 error = kern_sched_rr_get_interval(td, uap->pid, &ts);
4070 if (error == 0) {
4071 CP(ts, ts32, tv_sec);
4072 CP(ts, ts32, tv_nsec);
4073 error = copyout(&ts32, uap->interval, sizeof(ts32));
4074 }
4075 return (error);
4076 }
4077
4078 static void
timex_to_32(struct timex32 * dst,struct timex * src)4079 timex_to_32(struct timex32 *dst, struct timex *src)
4080 {
4081 CP(*src, *dst, modes);
4082 CP(*src, *dst, offset);
4083 CP(*src, *dst, freq);
4084 CP(*src, *dst, maxerror);
4085 CP(*src, *dst, esterror);
4086 CP(*src, *dst, status);
4087 CP(*src, *dst, constant);
4088 CP(*src, *dst, precision);
4089 CP(*src, *dst, tolerance);
4090 CP(*src, *dst, ppsfreq);
4091 CP(*src, *dst, jitter);
4092 CP(*src, *dst, shift);
4093 CP(*src, *dst, stabil);
4094 CP(*src, *dst, jitcnt);
4095 CP(*src, *dst, calcnt);
4096 CP(*src, *dst, errcnt);
4097 CP(*src, *dst, stbcnt);
4098 }
4099
4100 static void
timex_from_32(struct timex * dst,struct timex32 * src)4101 timex_from_32(struct timex *dst, struct timex32 *src)
4102 {
4103 CP(*src, *dst, modes);
4104 CP(*src, *dst, offset);
4105 CP(*src, *dst, freq);
4106 CP(*src, *dst, maxerror);
4107 CP(*src, *dst, esterror);
4108 CP(*src, *dst, status);
4109 CP(*src, *dst, constant);
4110 CP(*src, *dst, precision);
4111 CP(*src, *dst, tolerance);
4112 CP(*src, *dst, ppsfreq);
4113 CP(*src, *dst, jitter);
4114 CP(*src, *dst, shift);
4115 CP(*src, *dst, stabil);
4116 CP(*src, *dst, jitcnt);
4117 CP(*src, *dst, calcnt);
4118 CP(*src, *dst, errcnt);
4119 CP(*src, *dst, stbcnt);
4120 }
4121
4122 int
freebsd32_ntp_adjtime(struct thread * td,struct freebsd32_ntp_adjtime_args * uap)4123 freebsd32_ntp_adjtime(struct thread *td, struct freebsd32_ntp_adjtime_args *uap)
4124 {
4125 struct timex tx;
4126 struct timex32 tx32;
4127 int error, retval;
4128
4129 error = copyin(uap->tp, &tx32, sizeof(tx32));
4130 if (error == 0) {
4131 timex_from_32(&tx, &tx32);
4132 error = kern_ntp_adjtime(td, &tx, &retval);
4133 if (error == 0) {
4134 timex_to_32(&tx32, &tx);
4135 error = copyout(&tx32, uap->tp, sizeof(tx32));
4136 if (error == 0)
4137 td->td_retval[0] = retval;
4138 }
4139 }
4140 return (error);
4141 }
4142
4143 #ifdef FFCLOCK
4144 extern struct mtx ffclock_mtx;
4145 extern struct ffclock_estimate ffclock_estimate;
4146 extern int8_t ffclock_updated;
4147
4148 int
freebsd32_ffclock_setestimate(struct thread * td,struct freebsd32_ffclock_setestimate_args * uap)4149 freebsd32_ffclock_setestimate(struct thread *td,
4150 struct freebsd32_ffclock_setestimate_args *uap)
4151 {
4152 struct ffclock_estimate cest;
4153 struct ffclock_estimate32 cest32;
4154 int error;
4155
4156 /* Reuse of PRIV_CLOCK_SETTIME. */
4157 if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0)
4158 return (error);
4159
4160 if ((error = copyin(uap->cest, &cest32,
4161 sizeof(struct ffclock_estimate32))) != 0)
4162 return (error);
4163
4164 CP(cest.update_time, cest32.update_time, sec);
4165 memcpy(&cest.update_time.frac, &cest32.update_time.frac, sizeof(uint64_t));
4166 CP(cest, cest32, update_ffcount);
4167 CP(cest, cest32, leapsec_next);
4168 CP(cest, cest32, period);
4169 CP(cest, cest32, errb_abs);
4170 CP(cest, cest32, errb_rate);
4171 CP(cest, cest32, status);
4172 CP(cest, cest32, leapsec_total);
4173 CP(cest, cest32, leapsec);
4174
4175 mtx_lock(&ffclock_mtx);
4176 memcpy(&ffclock_estimate, &cest, sizeof(struct ffclock_estimate));
4177 ffclock_updated++;
4178 mtx_unlock(&ffclock_mtx);
4179 return (error);
4180 }
4181
4182 int
freebsd32_ffclock_getestimate(struct thread * td,struct freebsd32_ffclock_getestimate_args * uap)4183 freebsd32_ffclock_getestimate(struct thread *td,
4184 struct freebsd32_ffclock_getestimate_args *uap)
4185 {
4186 struct ffclock_estimate cest;
4187 struct ffclock_estimate32 cest32;
4188 int error;
4189
4190 mtx_lock(&ffclock_mtx);
4191 memcpy(&cest, &ffclock_estimate, sizeof(struct ffclock_estimate));
4192 mtx_unlock(&ffclock_mtx);
4193
4194 CP(cest32.update_time, cest.update_time, sec);
4195 memcpy(&cest32.update_time.frac, &cest.update_time.frac, sizeof(uint64_t));
4196 CP(cest32, cest, update_ffcount);
4197 CP(cest32, cest, leapsec_next);
4198 CP(cest32, cest, period);
4199 CP(cest32, cest, errb_abs);
4200 CP(cest32, cest, errb_rate);
4201 CP(cest32, cest, status);
4202 CP(cest32, cest, leapsec_total);
4203 CP(cest32, cest, leapsec);
4204
4205 error = copyout(&cest32, uap->cest, sizeof(struct ffclock_estimate32));
4206 return (error);
4207 }
4208 #else /* !FFCLOCK */
4209 int
freebsd32_ffclock_setestimate(struct thread * td,struct freebsd32_ffclock_setestimate_args * uap)4210 freebsd32_ffclock_setestimate(struct thread *td,
4211 struct freebsd32_ffclock_setestimate_args *uap)
4212 {
4213 return (ENOSYS);
4214 }
4215
4216 int
freebsd32_ffclock_getestimate(struct thread * td,struct freebsd32_ffclock_getestimate_args * uap)4217 freebsd32_ffclock_getestimate(struct thread *td,
4218 struct freebsd32_ffclock_getestimate_args *uap)
4219 {
4220 return (ENOSYS);
4221 }
4222 #endif /* FFCLOCK */
4223
4224 #ifdef COMPAT_43
4225 int
ofreebsd32_sethostid(struct thread * td,struct ofreebsd32_sethostid_args * uap)4226 ofreebsd32_sethostid(struct thread *td, struct ofreebsd32_sethostid_args *uap)
4227 {
4228 int name[] = { CTL_KERN, KERN_HOSTID };
4229 long hostid;
4230
4231 hostid = uap->hostid;
4232 return (kernel_sysctl(td, name, nitems(name), NULL, NULL, &hostid,
4233 sizeof(hostid), NULL, 0));
4234 }
4235 #endif
4236
4237 int
freebsd32_setcred(struct thread * td,struct freebsd32_setcred_args * uap)4238 freebsd32_setcred(struct thread *td, struct freebsd32_setcred_args *uap)
4239 {
4240 /* Last argument is 'is_32bit'. */
4241 return (user_setcred(td, uap->flags, uap->wcred, uap->size, true));
4242 }
4243