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 case PTINTERNAL_FIRST ... PTINTERNAL_LAST:
1181 error = EINVAL;
1182 break;
1183 default:
1184 addr = uap->addr;
1185 break;
1186 }
1187 if (error)
1188 return (error);
1189
1190 error = kern_ptrace(td, uap->req, uap->pid, addr, data);
1191 if (error)
1192 return (error);
1193
1194 switch (uap->req) {
1195 case PT_VM_ENTRY:
1196 CP(r.pve, r32.pve, pve_entry);
1197 CP(r.pve, r32.pve, pve_timestamp);
1198 CP(r.pve, r32.pve, pve_start);
1199 CP(r.pve, r32.pve, pve_end);
1200 CP(r.pve, r32.pve, pve_offset);
1201 CP(r.pve, r32.pve, pve_prot);
1202 CP(r.pve, r32.pve, pve_pathlen);
1203 CP(r.pve, r32.pve, pve_fileid);
1204 CP(r.pve, r32.pve, pve_fsid);
1205 error = copyout(&r32.pve, uap->addr, sizeof(r32.pve));
1206 break;
1207 case PT_IO:
1208 CP(r.piod, r32.piod, piod_len);
1209 error = copyout(&r32.piod, uap->addr, sizeof(r32.piod));
1210 break;
1211 case PT_GETREGS:
1212 error = copyout(&r.reg, uap->addr, sizeof(r.reg));
1213 break;
1214 case PT_GETFPREGS:
1215 error = copyout(&r.fpreg, uap->addr, sizeof(r.fpreg));
1216 break;
1217 case PT_GETDBREGS:
1218 error = copyout(&r.dbreg, uap->addr, sizeof(r.dbreg));
1219 break;
1220 case PT_GETREGSET:
1221 r32.vec.iov_len = r.vec.iov_len;
1222 error = copyout(&r32.vec, uap->addr, sizeof(r32.vec));
1223 break;
1224 case PT_GET_EVENT_MASK:
1225 /* NB: The size in uap->data is validated in kern_ptrace(). */
1226 error = copyout(&r.ptevents, uap->addr, uap->data);
1227 break;
1228 case PT_LWPINFO:
1229 ptrace_lwpinfo_to32(&r.pl, &r32.pl);
1230 error = copyout(&r32.pl, uap->addr, uap->data);
1231 break;
1232 case PT_GET_SC_ARGS:
1233 for (i = 0; i < nitems(r.args); i++)
1234 r32.args[i] = (uint32_t)r.args[i];
1235 error = copyout(r32.args, uap->addr, MIN(uap->data,
1236 sizeof(r32.args)));
1237 break;
1238 case PT_GET_SC_RET:
1239 ptrace_sc_ret_to32(&r.psr, &r32.psr);
1240 error = copyout(&r32.psr, uap->addr, MIN(uap->data,
1241 sizeof(r32.psr)));
1242 break;
1243 case PT_SC_REMOTE:
1244 ptrace_sc_ret_to32(&r.sr.pscr_ret, &r32.sr.pscr_ret);
1245 error = copyout(&r32.sr.pscr_ret, uap->addr +
1246 offsetof(struct ptrace_sc_remote32, pscr_ret),
1247 sizeof(r32.psr));
1248 break;
1249 }
1250
1251 return (error);
1252 }
1253
1254 int
freebsd32_copyinuio(const struct iovec32 * iovp,u_int iovcnt,struct uio ** uiop)1255 freebsd32_copyinuio(const struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
1256 {
1257 struct iovec32 iov32;
1258 struct iovec *iov;
1259 struct uio *uio;
1260 int error, i;
1261
1262 *uiop = NULL;
1263 if (iovcnt > UIO_MAXIOV)
1264 return (EINVAL);
1265 uio = allocuio(iovcnt);
1266 iov = uio->uio_iov;
1267 for (i = 0; i < iovcnt; i++) {
1268 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
1269 if (error) {
1270 freeuio(uio);
1271 return (error);
1272 }
1273 iov[i].iov_base = PTRIN(iov32.iov_base);
1274 iov[i].iov_len = iov32.iov_len;
1275 }
1276 uio->uio_iovcnt = iovcnt;
1277 uio->uio_segflg = UIO_USERSPACE;
1278 uio->uio_offset = -1;
1279 uio->uio_resid = 0;
1280 for (i = 0; i < iovcnt; i++) {
1281 if (iov->iov_len > INT_MAX - uio->uio_resid) {
1282 freeuio(uio);
1283 return (EINVAL);
1284 }
1285 uio->uio_resid += iov->iov_len;
1286 iov++;
1287 }
1288 *uiop = uio;
1289 return (0);
1290 }
1291
1292 int
freebsd32_readv(struct thread * td,struct freebsd32_readv_args * uap)1293 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
1294 {
1295 struct uio *auio;
1296 int error;
1297
1298 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1299 if (error)
1300 return (error);
1301 error = kern_readv(td, uap->fd, auio);
1302 freeuio(auio);
1303 return (error);
1304 }
1305
1306 int
freebsd32_writev(struct thread * td,struct freebsd32_writev_args * uap)1307 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
1308 {
1309 struct uio *auio;
1310 int error;
1311
1312 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1313 if (error)
1314 return (error);
1315 error = kern_writev(td, uap->fd, auio);
1316 freeuio(auio);
1317 return (error);
1318 }
1319
1320 int
freebsd32_preadv(struct thread * td,struct freebsd32_preadv_args * uap)1321 freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
1322 {
1323 struct uio *auio;
1324 int error;
1325
1326 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1327 if (error)
1328 return (error);
1329 error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
1330 freeuio(auio);
1331 return (error);
1332 }
1333
1334 int
freebsd32_pwritev(struct thread * td,struct freebsd32_pwritev_args * uap)1335 freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
1336 {
1337 struct uio *auio;
1338 int error;
1339
1340 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1341 if (error)
1342 return (error);
1343 error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
1344 freeuio(auio);
1345 return (error);
1346 }
1347
1348 int
freebsd32_copyiniov(struct iovec32 * iovp32,u_int iovcnt,struct iovec ** iovp,int error)1349 freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
1350 int error)
1351 {
1352 struct iovec32 iov32;
1353 struct iovec *iov;
1354 u_int iovlen;
1355 int i;
1356
1357 *iovp = NULL;
1358 if (iovcnt > UIO_MAXIOV)
1359 return (error);
1360 iovlen = iovcnt * sizeof(struct iovec);
1361 iov = malloc(iovlen, M_IOV, M_WAITOK);
1362 for (i = 0; i < iovcnt; i++) {
1363 error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
1364 if (error) {
1365 free(iov, M_IOV);
1366 return (error);
1367 }
1368 iov[i].iov_base = PTRIN(iov32.iov_base);
1369 iov[i].iov_len = iov32.iov_len;
1370 }
1371 *iovp = iov;
1372 return (0);
1373 }
1374
1375 static int
freebsd32_copyinmsghdr(const struct msghdr32 * msg32,struct msghdr * msg)1376 freebsd32_copyinmsghdr(const struct msghdr32 *msg32, struct msghdr *msg)
1377 {
1378 struct msghdr32 m32;
1379 int error;
1380
1381 error = copyin(msg32, &m32, sizeof(m32));
1382 if (error)
1383 return (error);
1384 msg->msg_name = PTRIN(m32.msg_name);
1385 msg->msg_namelen = m32.msg_namelen;
1386 msg->msg_iov = PTRIN(m32.msg_iov);
1387 msg->msg_iovlen = m32.msg_iovlen;
1388 msg->msg_control = PTRIN(m32.msg_control);
1389 msg->msg_controllen = m32.msg_controllen;
1390 msg->msg_flags = m32.msg_flags;
1391 return (0);
1392 }
1393
1394 static int
freebsd32_copyoutmsghdr(struct msghdr * msg,struct msghdr32 * msg32)1395 freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
1396 {
1397 struct msghdr32 m32;
1398 int error;
1399
1400 m32.msg_name = PTROUT(msg->msg_name);
1401 m32.msg_namelen = msg->msg_namelen;
1402 m32.msg_iov = PTROUT(msg->msg_iov);
1403 m32.msg_iovlen = msg->msg_iovlen;
1404 m32.msg_control = PTROUT(msg->msg_control);
1405 m32.msg_controllen = msg->msg_controllen;
1406 m32.msg_flags = msg->msg_flags;
1407 error = copyout(&m32, msg32, sizeof(m32));
1408 return (error);
1409 }
1410
1411 #define FREEBSD32_ALIGNBYTES (sizeof(int) - 1)
1412 #define FREEBSD32_ALIGN(p) \
1413 (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
1414 #define FREEBSD32_CMSG_SPACE(l) \
1415 (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
1416
1417 #define FREEBSD32_CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \
1418 FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
1419
1420 static size_t
freebsd32_cmsg_convert(const struct cmsghdr * cm,void * data,socklen_t datalen)1421 freebsd32_cmsg_convert(const struct cmsghdr *cm, void *data, socklen_t datalen)
1422 {
1423 size_t copylen;
1424 union {
1425 struct timespec32 ts;
1426 struct timeval32 tv;
1427 struct bintime32 bt;
1428 } tmp32;
1429
1430 union {
1431 struct timespec ts;
1432 struct timeval tv;
1433 struct bintime bt;
1434 } *in;
1435
1436 in = data;
1437 copylen = 0;
1438 switch (cm->cmsg_level) {
1439 case SOL_SOCKET:
1440 switch (cm->cmsg_type) {
1441 case SCM_TIMESTAMP:
1442 TV_CP(*in, tmp32, tv);
1443 copylen = sizeof(tmp32.tv);
1444 break;
1445
1446 case SCM_BINTIME:
1447 BT_CP(*in, tmp32, bt);
1448 copylen = sizeof(tmp32.bt);
1449 break;
1450
1451 case SCM_REALTIME:
1452 case SCM_MONOTONIC:
1453 TS_CP(*in, tmp32, ts);
1454 copylen = sizeof(tmp32.ts);
1455 break;
1456
1457 default:
1458 break;
1459 }
1460
1461 default:
1462 break;
1463 }
1464
1465 if (copylen == 0)
1466 return (datalen);
1467
1468 KASSERT((datalen >= copylen), ("corrupted cmsghdr"));
1469
1470 bcopy(&tmp32, data, copylen);
1471 return (copylen);
1472 }
1473
1474 static int
freebsd32_copy_msg_out(struct msghdr * msg,struct mbuf * control)1475 freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
1476 {
1477 struct cmsghdr *cm;
1478 void *data;
1479 socklen_t clen, datalen, datalen_out, oldclen;
1480 int error;
1481 caddr_t ctlbuf;
1482 int len, copylen;
1483 struct mbuf *m;
1484 error = 0;
1485
1486 len = msg->msg_controllen;
1487 msg->msg_controllen = 0;
1488
1489 ctlbuf = msg->msg_control;
1490 for (m = control; m != NULL && len > 0; m = m->m_next) {
1491 cm = mtod(m, struct cmsghdr *);
1492 clen = m->m_len;
1493 while (cm != NULL) {
1494 if (sizeof(struct cmsghdr) > clen ||
1495 cm->cmsg_len > clen) {
1496 error = EINVAL;
1497 break;
1498 }
1499
1500 data = CMSG_DATA(cm);
1501 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1502 datalen_out = freebsd32_cmsg_convert(cm, data, datalen);
1503
1504 /*
1505 * Copy out the message header. Preserve the native
1506 * message size in case we need to inspect the message
1507 * contents later.
1508 */
1509 copylen = sizeof(struct cmsghdr);
1510 if (len < copylen) {
1511 msg->msg_flags |= MSG_CTRUNC;
1512 m_dispose_extcontrolm(m);
1513 goto exit;
1514 }
1515 oldclen = cm->cmsg_len;
1516 cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
1517 datalen_out;
1518 error = copyout(cm, ctlbuf, copylen);
1519 cm->cmsg_len = oldclen;
1520 if (error != 0)
1521 goto exit;
1522
1523 ctlbuf += FREEBSD32_ALIGN(copylen);
1524 len -= FREEBSD32_ALIGN(copylen);
1525
1526 copylen = datalen_out;
1527 if (len < copylen) {
1528 msg->msg_flags |= MSG_CTRUNC;
1529 m_dispose_extcontrolm(m);
1530 break;
1531 }
1532
1533 /* Copy out the message data. */
1534 error = copyout(data, ctlbuf, copylen);
1535 if (error)
1536 goto exit;
1537
1538 ctlbuf += FREEBSD32_ALIGN(copylen);
1539 len -= FREEBSD32_ALIGN(copylen);
1540
1541 if (CMSG_SPACE(datalen) < clen) {
1542 clen -= CMSG_SPACE(datalen);
1543 cm = (struct cmsghdr *)
1544 ((caddr_t)cm + CMSG_SPACE(datalen));
1545 } else {
1546 clen = 0;
1547 cm = NULL;
1548 }
1549
1550 msg->msg_controllen +=
1551 FREEBSD32_CMSG_SPACE(datalen_out);
1552 }
1553 }
1554 if (len == 0 && m != NULL) {
1555 msg->msg_flags |= MSG_CTRUNC;
1556 m_dispose_extcontrolm(m);
1557 }
1558
1559 exit:
1560 return (error);
1561 }
1562
1563 int
freebsd32_recvmsg(struct thread * td,struct freebsd32_recvmsg_args * uap)1564 freebsd32_recvmsg(struct thread *td, struct freebsd32_recvmsg_args *uap)
1565 {
1566 struct msghdr msg;
1567 struct iovec *uiov, *iov;
1568 struct mbuf *control = NULL;
1569 struct mbuf **controlp;
1570 int error;
1571
1572 error = freebsd32_copyinmsghdr(uap->msg, &msg);
1573 if (error)
1574 return (error);
1575 error = freebsd32_copyiniov((void *)msg.msg_iov, msg.msg_iovlen, &iov,
1576 EMSGSIZE);
1577 if (error)
1578 return (error);
1579 msg.msg_flags = uap->flags;
1580 uiov = msg.msg_iov;
1581 msg.msg_iov = iov;
1582
1583 controlp = (msg.msg_control != NULL) ? &control : NULL;
1584 error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
1585 if (error == 0) {
1586 msg.msg_iov = uiov;
1587
1588 if (control != NULL)
1589 error = freebsd32_copy_msg_out(&msg, control);
1590 else
1591 msg.msg_controllen = 0;
1592
1593 if (error == 0)
1594 error = freebsd32_copyoutmsghdr(&msg, uap->msg);
1595 }
1596 free(iov, M_IOV);
1597
1598 if (control != NULL) {
1599 if (error != 0)
1600 m_dispose_extcontrolm(control);
1601 m_freem(control);
1602 }
1603
1604 return (error);
1605 }
1606
1607 #ifdef COMPAT_43
1608 int
ofreebsd32_recvmsg(struct thread * td,struct ofreebsd32_recvmsg_args * uap)1609 ofreebsd32_recvmsg(struct thread *td, struct ofreebsd32_recvmsg_args *uap)
1610 {
1611 return (ENOSYS);
1612 }
1613 #endif
1614
1615 /*
1616 * Copy-in the array of control messages constructed using alignment
1617 * and padding suitable for a 32-bit environment and construct an
1618 * mbuf using alignment and padding suitable for a 64-bit kernel.
1619 * The alignment and padding are defined indirectly by CMSG_DATA(),
1620 * CMSG_SPACE() and CMSG_LEN().
1621 */
1622 static int
freebsd32_copyin_control(struct mbuf ** mp,caddr_t buf,u_int buflen)1623 freebsd32_copyin_control(struct mbuf **mp, caddr_t buf, u_int buflen)
1624 {
1625 struct cmsghdr *cm;
1626 struct mbuf *m;
1627 void *in, *in1, *md;
1628 u_int msglen, outlen;
1629 int error;
1630
1631 /* Enforce the size limit of the native implementation. */
1632 if (buflen > MCLBYTES)
1633 return (EINVAL);
1634
1635 in = malloc(buflen, M_TEMP, M_WAITOK);
1636 error = copyin(buf, in, buflen);
1637 if (error != 0)
1638 goto out;
1639
1640 /*
1641 * Make a pass over the input buffer to determine the amount of space
1642 * required for 64 bit-aligned copies of the control messages.
1643 */
1644 in1 = in;
1645 outlen = 0;
1646 while (buflen > 0) {
1647 if (buflen < sizeof(*cm)) {
1648 error = EINVAL;
1649 break;
1650 }
1651 cm = (struct cmsghdr *)in1;
1652 if (cm->cmsg_len < FREEBSD32_ALIGN(sizeof(*cm)) ||
1653 cm->cmsg_len > buflen) {
1654 error = EINVAL;
1655 break;
1656 }
1657 msglen = FREEBSD32_ALIGN(cm->cmsg_len);
1658 if (msglen < cm->cmsg_len) {
1659 error = EINVAL;
1660 break;
1661 }
1662 /* The native ABI permits the final padding to be omitted. */
1663 if (msglen > buflen)
1664 msglen = buflen;
1665 buflen -= msglen;
1666
1667 in1 = (char *)in1 + msglen;
1668 outlen += CMSG_ALIGN(sizeof(*cm)) +
1669 CMSG_ALIGN(msglen - FREEBSD32_ALIGN(sizeof(*cm)));
1670 }
1671 if (error != 0)
1672 goto out;
1673
1674 /*
1675 * Allocate up to MJUMPAGESIZE space for the re-aligned and
1676 * re-padded control messages. This allows a full MCLBYTES of
1677 * 32-bit sized and aligned messages to fit and avoids an ABI
1678 * mismatch with the native implementation.
1679 */
1680 m = m_get2(outlen, M_WAITOK, MT_CONTROL, 0);
1681 if (m == NULL) {
1682 error = EINVAL;
1683 goto out;
1684 }
1685 m->m_len = outlen;
1686 md = mtod(m, void *);
1687
1688 /*
1689 * Make a second pass over input messages, copying them into the output
1690 * buffer.
1691 */
1692 in1 = in;
1693 while (outlen > 0) {
1694 /* Copy the message header and align the length field. */
1695 cm = md;
1696 memcpy(cm, in1, sizeof(*cm));
1697 msglen = cm->cmsg_len - FREEBSD32_ALIGN(sizeof(*cm));
1698 cm->cmsg_len = CMSG_ALIGN(sizeof(*cm)) + msglen;
1699
1700 /* Copy the message body. */
1701 in1 = (char *)in1 + FREEBSD32_ALIGN(sizeof(*cm));
1702 md = (char *)md + CMSG_ALIGN(sizeof(*cm));
1703 memcpy(md, in1, msglen);
1704 in1 = (char *)in1 + FREEBSD32_ALIGN(msglen);
1705 md = (char *)md + CMSG_ALIGN(msglen);
1706 KASSERT(outlen >= CMSG_ALIGN(sizeof(*cm)) + CMSG_ALIGN(msglen),
1707 ("outlen %u underflow, msglen %u", outlen, msglen));
1708 outlen -= CMSG_ALIGN(sizeof(*cm)) + CMSG_ALIGN(msglen);
1709 }
1710
1711 *mp = m;
1712 out:
1713 free(in, M_TEMP);
1714 return (error);
1715 }
1716
1717 int
freebsd32_sendmsg(struct thread * td,struct freebsd32_sendmsg_args * uap)1718 freebsd32_sendmsg(struct thread *td, struct freebsd32_sendmsg_args *uap)
1719 {
1720 struct msghdr msg;
1721 struct iovec *iov;
1722 struct mbuf *control = NULL;
1723 struct sockaddr *to = NULL;
1724 int error;
1725
1726 error = freebsd32_copyinmsghdr(uap->msg, &msg);
1727 if (error)
1728 return (error);
1729 error = freebsd32_copyiniov((void *)msg.msg_iov, msg.msg_iovlen, &iov,
1730 EMSGSIZE);
1731 if (error)
1732 return (error);
1733 msg.msg_iov = iov;
1734 if (msg.msg_name != NULL) {
1735 error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
1736 if (error) {
1737 to = NULL;
1738 goto out;
1739 }
1740 msg.msg_name = to;
1741 }
1742
1743 if (msg.msg_control) {
1744 if (msg.msg_controllen < sizeof(struct cmsghdr)) {
1745 error = EINVAL;
1746 goto out;
1747 }
1748
1749 error = freebsd32_copyin_control(&control, msg.msg_control,
1750 msg.msg_controllen);
1751 if (error)
1752 goto out;
1753
1754 msg.msg_control = NULL;
1755 msg.msg_controllen = 0;
1756 }
1757
1758 error = kern_sendit(td, uap->s, &msg, uap->flags, control,
1759 UIO_USERSPACE);
1760
1761 out:
1762 free(iov, M_IOV);
1763 if (to)
1764 free(to, M_SONAME);
1765 return (error);
1766 }
1767
1768 #ifdef COMPAT_43
1769 int
ofreebsd32_sendmsg(struct thread * td,struct ofreebsd32_sendmsg_args * uap)1770 ofreebsd32_sendmsg(struct thread *td, struct ofreebsd32_sendmsg_args *uap)
1771 {
1772 return (ENOSYS);
1773 }
1774 #endif
1775
1776
1777 int
freebsd32_settimeofday(struct thread * td,struct freebsd32_settimeofday_args * uap)1778 freebsd32_settimeofday(struct thread *td,
1779 struct freebsd32_settimeofday_args *uap)
1780 {
1781 struct timeval32 tv32;
1782 struct timeval tv, *tvp;
1783 struct timezone tz, *tzp;
1784 int error;
1785
1786 if (uap->tv) {
1787 error = copyin(uap->tv, &tv32, sizeof(tv32));
1788 if (error)
1789 return (error);
1790 CP(tv32, tv, tv_sec);
1791 CP(tv32, tv, tv_usec);
1792 tvp = &tv;
1793 } else
1794 tvp = NULL;
1795 if (uap->tzp) {
1796 error = copyin(uap->tzp, &tz, sizeof(tz));
1797 if (error)
1798 return (error);
1799 tzp = &tz;
1800 } else
1801 tzp = NULL;
1802 return (kern_settimeofday(td, tvp, tzp));
1803 }
1804
1805 int
freebsd32_utimes(struct thread * td,struct freebsd32_utimes_args * uap)1806 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
1807 {
1808 struct timeval32 s32[2];
1809 struct timeval s[2], *sp;
1810 int error;
1811
1812 if (uap->tptr != NULL) {
1813 error = copyin(uap->tptr, s32, sizeof(s32));
1814 if (error)
1815 return (error);
1816 CP(s32[0], s[0], tv_sec);
1817 CP(s32[0], s[0], tv_usec);
1818 CP(s32[1], s[1], tv_sec);
1819 CP(s32[1], s[1], tv_usec);
1820 sp = s;
1821 } else
1822 sp = NULL;
1823 return (kern_utimesat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
1824 sp, UIO_SYSSPACE));
1825 }
1826
1827 int
freebsd32_lutimes(struct thread * td,struct freebsd32_lutimes_args * uap)1828 freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
1829 {
1830 struct timeval32 s32[2];
1831 struct timeval s[2], *sp;
1832 int error;
1833
1834 if (uap->tptr != NULL) {
1835 error = copyin(uap->tptr, s32, sizeof(s32));
1836 if (error)
1837 return (error);
1838 CP(s32[0], s[0], tv_sec);
1839 CP(s32[0], s[0], tv_usec);
1840 CP(s32[1], s[1], tv_sec);
1841 CP(s32[1], s[1], tv_usec);
1842 sp = s;
1843 } else
1844 sp = NULL;
1845 return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1846 }
1847
1848 int
freebsd32_futimes(struct thread * td,struct freebsd32_futimes_args * uap)1849 freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
1850 {
1851 struct timeval32 s32[2];
1852 struct timeval s[2], *sp;
1853 int error;
1854
1855 if (uap->tptr != NULL) {
1856 error = copyin(uap->tptr, s32, sizeof(s32));
1857 if (error)
1858 return (error);
1859 CP(s32[0], s[0], tv_sec);
1860 CP(s32[0], s[0], tv_usec);
1861 CP(s32[1], s[1], tv_sec);
1862 CP(s32[1], s[1], tv_usec);
1863 sp = s;
1864 } else
1865 sp = NULL;
1866 return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
1867 }
1868
1869 int
freebsd32_futimesat(struct thread * td,struct freebsd32_futimesat_args * uap)1870 freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap)
1871 {
1872 struct timeval32 s32[2];
1873 struct timeval s[2], *sp;
1874 int error;
1875
1876 if (uap->times != NULL) {
1877 error = copyin(uap->times, s32, sizeof(s32));
1878 if (error)
1879 return (error);
1880 CP(s32[0], s[0], tv_sec);
1881 CP(s32[0], s[0], tv_usec);
1882 CP(s32[1], s[1], tv_sec);
1883 CP(s32[1], s[1], tv_usec);
1884 sp = s;
1885 } else
1886 sp = NULL;
1887 return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
1888 sp, UIO_SYSSPACE));
1889 }
1890
1891 int
freebsd32_futimens(struct thread * td,struct freebsd32_futimens_args * uap)1892 freebsd32_futimens(struct thread *td, struct freebsd32_futimens_args *uap)
1893 {
1894 struct timespec32 ts32[2];
1895 struct timespec ts[2], *tsp;
1896 int error;
1897
1898 if (uap->times != NULL) {
1899 error = copyin(uap->times, ts32, sizeof(ts32));
1900 if (error)
1901 return (error);
1902 CP(ts32[0], ts[0], tv_sec);
1903 CP(ts32[0], ts[0], tv_nsec);
1904 CP(ts32[1], ts[1], tv_sec);
1905 CP(ts32[1], ts[1], tv_nsec);
1906 tsp = ts;
1907 } else
1908 tsp = NULL;
1909 return (kern_futimens(td, uap->fd, tsp, UIO_SYSSPACE));
1910 }
1911
1912 int
freebsd32_utimensat(struct thread * td,struct freebsd32_utimensat_args * uap)1913 freebsd32_utimensat(struct thread *td, struct freebsd32_utimensat_args *uap)
1914 {
1915 struct timespec32 ts32[2];
1916 struct timespec ts[2], *tsp;
1917 int error;
1918
1919 if (uap->times != NULL) {
1920 error = copyin(uap->times, ts32, sizeof(ts32));
1921 if (error)
1922 return (error);
1923 CP(ts32[0], ts[0], tv_sec);
1924 CP(ts32[0], ts[0], tv_nsec);
1925 CP(ts32[1], ts[1], tv_sec);
1926 CP(ts32[1], ts[1], tv_nsec);
1927 tsp = ts;
1928 } else
1929 tsp = NULL;
1930 return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE,
1931 tsp, UIO_SYSSPACE, uap->flag));
1932 }
1933
1934 int
freebsd32_adjtime(struct thread * td,struct freebsd32_adjtime_args * uap)1935 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
1936 {
1937 struct timeval32 tv32;
1938 struct timeval delta, olddelta, *deltap;
1939 int error;
1940
1941 if (uap->delta) {
1942 error = copyin(uap->delta, &tv32, sizeof(tv32));
1943 if (error)
1944 return (error);
1945 CP(tv32, delta, tv_sec);
1946 CP(tv32, delta, tv_usec);
1947 deltap = δ
1948 } else
1949 deltap = NULL;
1950 error = kern_adjtime(td, deltap, &olddelta);
1951 if (uap->olddelta && error == 0) {
1952 CP(olddelta, tv32, tv_sec);
1953 CP(olddelta, tv32, tv_usec);
1954 error = copyout(&tv32, uap->olddelta, sizeof(tv32));
1955 }
1956 return (error);
1957 }
1958
1959 #ifdef COMPAT_FREEBSD4
1960 int
freebsd4_freebsd32_statfs(struct thread * td,struct freebsd4_freebsd32_statfs_args * uap)1961 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
1962 {
1963 struct ostatfs32 s32;
1964 struct statfs *sp;
1965 int error;
1966
1967 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
1968 error = kern_statfs(td, uap->path, UIO_USERSPACE, sp);
1969 if (error == 0) {
1970 copy_statfs(sp, &s32);
1971 error = copyout(&s32, uap->buf, sizeof(s32));
1972 }
1973 free(sp, M_STATFS);
1974 return (error);
1975 }
1976 #endif
1977
1978 #ifdef COMPAT_FREEBSD4
1979 int
freebsd4_freebsd32_fstatfs(struct thread * td,struct freebsd4_freebsd32_fstatfs_args * uap)1980 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
1981 {
1982 struct ostatfs32 s32;
1983 struct statfs *sp;
1984 int error;
1985
1986 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
1987 error = kern_fstatfs(td, uap->fd, sp);
1988 if (error == 0) {
1989 copy_statfs(sp, &s32);
1990 error = copyout(&s32, uap->buf, sizeof(s32));
1991 }
1992 free(sp, M_STATFS);
1993 return (error);
1994 }
1995 #endif
1996
1997 #ifdef COMPAT_FREEBSD4
1998 int
freebsd4_freebsd32_fhstatfs(struct thread * td,struct freebsd4_freebsd32_fhstatfs_args * uap)1999 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
2000 {
2001 struct ostatfs32 s32;
2002 struct statfs *sp;
2003 fhandle_t fh;
2004 int error;
2005
2006 if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
2007 return (error);
2008 sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
2009 error = kern_fhstatfs(td, fh, sp);
2010 if (error == 0) {
2011 copy_statfs(sp, &s32);
2012 error = copyout(&s32, uap->buf, sizeof(s32));
2013 }
2014 free(sp, M_STATFS);
2015 return (error);
2016 }
2017 #endif
2018
2019 int
freebsd32_pread(struct thread * td,struct freebsd32_pread_args * uap)2020 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
2021 {
2022
2023 return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
2024 PAIR32TO64(off_t, uap->offset)));
2025 }
2026
2027 int
freebsd32_pwrite(struct thread * td,struct freebsd32_pwrite_args * uap)2028 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
2029 {
2030
2031 return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
2032 PAIR32TO64(off_t, uap->offset)));
2033 }
2034
2035 #ifdef COMPAT_43
2036 int
ofreebsd32_lseek(struct thread * td,struct ofreebsd32_lseek_args * uap)2037 ofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap)
2038 {
2039
2040 return (kern_lseek(td, uap->fd, uap->offset, uap->whence));
2041 }
2042 #endif
2043
2044 int
freebsd32_lseek(struct thread * td,struct freebsd32_lseek_args * uap)2045 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
2046 {
2047 int error;
2048 off_t pos;
2049
2050 error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset),
2051 uap->whence);
2052 /* Expand the quad return into two parts for eax and edx */
2053 pos = td->td_uretoff.tdu_off;
2054 td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */
2055 td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */
2056 return error;
2057 }
2058
2059 int
freebsd32_truncate(struct thread * td,struct freebsd32_truncate_args * uap)2060 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
2061 {
2062
2063 return (kern_truncate(td, uap->path, UIO_USERSPACE,
2064 PAIR32TO64(off_t, uap->length)));
2065 }
2066
2067 #ifdef COMPAT_43
2068 int
ofreebsd32_truncate(struct thread * td,struct ofreebsd32_truncate_args * uap)2069 ofreebsd32_truncate(struct thread *td, struct ofreebsd32_truncate_args *uap)
2070 {
2071 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
2072 }
2073 #endif
2074
2075 int
freebsd32_ftruncate(struct thread * td,struct freebsd32_ftruncate_args * uap)2076 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
2077 {
2078
2079 return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)));
2080 }
2081
2082 #ifdef COMPAT_43
2083 int
ofreebsd32_ftruncate(struct thread * td,struct ofreebsd32_ftruncate_args * uap)2084 ofreebsd32_ftruncate(struct thread *td, struct ofreebsd32_ftruncate_args *uap)
2085 {
2086 return (kern_ftruncate(td, uap->fd, uap->length));
2087 }
2088
2089 int
ofreebsd32_getdirentries(struct thread * td,struct ofreebsd32_getdirentries_args * uap)2090 ofreebsd32_getdirentries(struct thread *td,
2091 struct ofreebsd32_getdirentries_args *uap)
2092 {
2093 struct ogetdirentries_args ap;
2094 int error;
2095 long loff;
2096 int32_t loff_cut;
2097
2098 ap.fd = uap->fd;
2099 ap.buf = uap->buf;
2100 ap.count = uap->count;
2101 ap.basep = NULL;
2102 error = kern_ogetdirentries(td, &ap, &loff);
2103 if (error == 0) {
2104 loff_cut = loff;
2105 error = copyout(&loff_cut, uap->basep, sizeof(int32_t));
2106 }
2107 return (error);
2108 }
2109 #endif
2110
2111 #if defined(COMPAT_FREEBSD11)
2112 int
freebsd11_freebsd32_getdirentries(struct thread * td,struct freebsd11_freebsd32_getdirentries_args * uap)2113 freebsd11_freebsd32_getdirentries(struct thread *td,
2114 struct freebsd11_freebsd32_getdirentries_args *uap)
2115 {
2116 long base;
2117 int32_t base32;
2118 int error;
2119
2120 error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
2121 &base, NULL);
2122 if (error)
2123 return (error);
2124 if (uap->basep != NULL) {
2125 base32 = base;
2126 error = copyout(&base32, uap->basep, sizeof(int32_t));
2127 }
2128 return (error);
2129 }
2130 #endif /* COMPAT_FREEBSD11 */
2131
2132 #ifdef COMPAT_FREEBSD6
2133 /* versions with the 'int pad' argument */
2134 int
freebsd6_freebsd32_pread(struct thread * td,struct freebsd6_freebsd32_pread_args * uap)2135 freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
2136 {
2137
2138 return (kern_pread(td, uap->fd, uap->buf, uap->nbyte,
2139 PAIR32TO64(off_t, uap->offset)));
2140 }
2141
2142 int
freebsd6_freebsd32_pwrite(struct thread * td,struct freebsd6_freebsd32_pwrite_args * uap)2143 freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
2144 {
2145
2146 return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte,
2147 PAIR32TO64(off_t, uap->offset)));
2148 }
2149
2150 int
freebsd6_freebsd32_lseek(struct thread * td,struct freebsd6_freebsd32_lseek_args * uap)2151 freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
2152 {
2153 int error;
2154 off_t pos;
2155
2156 error = kern_lseek(td, uap->fd, PAIR32TO64(off_t, uap->offset),
2157 uap->whence);
2158 /* Expand the quad return into two parts for eax and edx */
2159 pos = *(off_t *)(td->td_retval);
2160 td->td_retval[RETVAL_LO] = pos & 0xffffffff; /* %eax */
2161 td->td_retval[RETVAL_HI] = pos >> 32; /* %edx */
2162 return error;
2163 }
2164
2165 int
freebsd6_freebsd32_truncate(struct thread * td,struct freebsd6_freebsd32_truncate_args * uap)2166 freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
2167 {
2168
2169 return (kern_truncate(td, uap->path, UIO_USERSPACE,
2170 PAIR32TO64(off_t, uap->length)));
2171 }
2172
2173 int
freebsd6_freebsd32_ftruncate(struct thread * td,struct freebsd6_freebsd32_ftruncate_args * uap)2174 freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
2175 {
2176
2177 return (kern_ftruncate(td, uap->fd, PAIR32TO64(off_t, uap->length)));
2178 }
2179 #endif /* COMPAT_FREEBSD6 */
2180
2181 struct sf_hdtr32 {
2182 uint32_t headers;
2183 int hdr_cnt;
2184 uint32_t trailers;
2185 int trl_cnt;
2186 };
2187
2188 static int
freebsd32_do_sendfile(struct thread * td,struct freebsd32_sendfile_args * uap,int compat)2189 freebsd32_do_sendfile(struct thread *td,
2190 struct freebsd32_sendfile_args *uap, int compat)
2191 {
2192 struct sf_hdtr32 hdtr32;
2193 struct sf_hdtr hdtr;
2194 struct uio *hdr_uio, *trl_uio;
2195 struct file *fp;
2196 cap_rights_t rights;
2197 struct iovec32 *iov32;
2198 off_t offset, sbytes;
2199 int error;
2200
2201 offset = PAIR32TO64(off_t, uap->offset);
2202 if (offset < 0)
2203 return (EINVAL);
2204
2205 hdr_uio = trl_uio = NULL;
2206
2207 if (uap->hdtr != NULL) {
2208 error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
2209 if (error)
2210 goto out;
2211 PTRIN_CP(hdtr32, hdtr, headers);
2212 CP(hdtr32, hdtr, hdr_cnt);
2213 PTRIN_CP(hdtr32, hdtr, trailers);
2214 CP(hdtr32, hdtr, trl_cnt);
2215
2216 if (hdtr.headers != NULL) {
2217 iov32 = PTRIN(hdtr32.headers);
2218 error = freebsd32_copyinuio(iov32,
2219 hdtr32.hdr_cnt, &hdr_uio);
2220 if (error)
2221 goto out;
2222 #ifdef COMPAT_FREEBSD4
2223 /*
2224 * In FreeBSD < 5.0 the nbytes to send also included
2225 * the header. If compat is specified subtract the
2226 * header size from nbytes.
2227 */
2228 if (compat) {
2229 if (uap->nbytes > hdr_uio->uio_resid)
2230 uap->nbytes -= hdr_uio->uio_resid;
2231 else
2232 uap->nbytes = 0;
2233 }
2234 #endif
2235 }
2236 if (hdtr.trailers != NULL) {
2237 iov32 = PTRIN(hdtr32.trailers);
2238 error = freebsd32_copyinuio(iov32,
2239 hdtr32.trl_cnt, &trl_uio);
2240 if (error)
2241 goto out;
2242 }
2243 }
2244
2245 AUDIT_ARG_FD(uap->fd);
2246
2247 if ((error = fget_read(td, uap->fd,
2248 cap_rights_init_one(&rights, CAP_PREAD), &fp)) != 0)
2249 goto out;
2250
2251 error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset,
2252 uap->nbytes, &sbytes, uap->flags, td);
2253 fdrop(fp, td);
2254
2255 if (uap->sbytes != NULL)
2256 (void)copyout(&sbytes, uap->sbytes, sizeof(off_t));
2257
2258 out:
2259 if (hdr_uio)
2260 freeuio(hdr_uio);
2261 if (trl_uio)
2262 freeuio(trl_uio);
2263 return (error);
2264 }
2265
2266 #ifdef COMPAT_FREEBSD4
2267 int
freebsd4_freebsd32_sendfile(struct thread * td,struct freebsd4_freebsd32_sendfile_args * uap)2268 freebsd4_freebsd32_sendfile(struct thread *td,
2269 struct freebsd4_freebsd32_sendfile_args *uap)
2270 {
2271 return (freebsd32_do_sendfile(td,
2272 (struct freebsd32_sendfile_args *)uap, 1));
2273 }
2274 #endif
2275
2276 int
freebsd32_sendfile(struct thread * td,struct freebsd32_sendfile_args * uap)2277 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
2278 {
2279
2280 return (freebsd32_do_sendfile(td, uap, 0));
2281 }
2282
2283 static void
copy_stat(struct stat * in,struct stat32 * out)2284 copy_stat(struct stat *in, struct stat32 *out)
2285 {
2286
2287 #ifndef __amd64__
2288 /*
2289 * 32-bit architectures other than i386 have 64-bit time_t. This
2290 * results in struct timespec32 with 12 bytes for tv_sec and tv_nsec,
2291 * and 4 bytes of padding. Zero the padding holes in struct stat32.
2292 */
2293 bzero(&out->st_atim, sizeof(out->st_atim));
2294 bzero(&out->st_mtim, sizeof(out->st_mtim));
2295 bzero(&out->st_ctim, sizeof(out->st_ctim));
2296 bzero(&out->st_birthtim, sizeof(out->st_birthtim));
2297 #endif
2298 CP(*in, *out, st_dev);
2299 CP(*in, *out, st_ino);
2300 CP(*in, *out, st_mode);
2301 CP(*in, *out, st_nlink);
2302 CP(*in, *out, st_uid);
2303 CP(*in, *out, st_gid);
2304 CP(*in, *out, st_rdev);
2305 TS_CP(*in, *out, st_atim);
2306 TS_CP(*in, *out, st_mtim);
2307 TS_CP(*in, *out, st_ctim);
2308 CP(*in, *out, st_size);
2309 CP(*in, *out, st_blocks);
2310 CP(*in, *out, st_blksize);
2311 CP(*in, *out, st_flags);
2312 CP(*in, *out, st_gen);
2313 CP(*in, *out, st_filerev);
2314 CP(*in, *out, st_bsdflags);
2315 TS_CP(*in, *out, st_birthtim);
2316 out->st_padding1 = 0;
2317 #ifdef __STAT32_TIME_T_EXT
2318 out->st_atim_ext = 0;
2319 out->st_mtim_ext = 0;
2320 out->st_ctim_ext = 0;
2321 out->st_btim_ext = 0;
2322 #endif
2323 bzero(out->st_spare, sizeof(out->st_spare));
2324 }
2325
2326 #ifdef COMPAT_43
2327 static void
copy_ostat(struct stat * in,struct ostat32 * out)2328 copy_ostat(struct stat *in, struct ostat32 *out)
2329 {
2330
2331 bzero(out, sizeof(*out));
2332 CP(*in, *out, st_dev);
2333 CP(*in, *out, st_ino);
2334 CP(*in, *out, st_mode);
2335 CP(*in, *out, st_nlink);
2336 CP(*in, *out, st_uid);
2337 CP(*in, *out, st_gid);
2338 CP(*in, *out, st_rdev);
2339 out->st_size = MIN(in->st_size, INT32_MAX);
2340 TS_CP(*in, *out, st_atim);
2341 TS_CP(*in, *out, st_mtim);
2342 TS_CP(*in, *out, st_ctim);
2343 CP(*in, *out, st_blksize);
2344 CP(*in, *out, st_blocks);
2345 CP(*in, *out, st_flags);
2346 CP(*in, *out, st_gen);
2347 }
2348 #endif
2349
2350 #ifdef COMPAT_43
2351 int
ofreebsd32_stat(struct thread * td,struct ofreebsd32_stat_args * uap)2352 ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
2353 {
2354 struct stat sb;
2355 struct ostat32 sb32;
2356 int error;
2357
2358 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2359 if (error)
2360 return (error);
2361 copy_ostat(&sb, &sb32);
2362 error = copyout(&sb32, uap->ub, sizeof (sb32));
2363 return (error);
2364 }
2365 #endif
2366
2367 int
freebsd32_fstat(struct thread * td,struct freebsd32_fstat_args * uap)2368 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
2369 {
2370 struct stat ub;
2371 struct stat32 ub32;
2372 int error;
2373
2374 error = kern_fstat(td, uap->fd, &ub);
2375 if (error)
2376 return (error);
2377 copy_stat(&ub, &ub32);
2378 error = copyout(&ub32, uap->sb, sizeof(ub32));
2379 return (error);
2380 }
2381
2382 #ifdef COMPAT_43
2383 int
ofreebsd32_fstat(struct thread * td,struct ofreebsd32_fstat_args * uap)2384 ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap)
2385 {
2386 struct stat ub;
2387 struct ostat32 ub32;
2388 int error;
2389
2390 error = kern_fstat(td, uap->fd, &ub);
2391 if (error)
2392 return (error);
2393 copy_ostat(&ub, &ub32);
2394 error = copyout(&ub32, uap->sb, sizeof(ub32));
2395 return (error);
2396 }
2397 #endif
2398
2399 int
freebsd32_fstatat(struct thread * td,struct freebsd32_fstatat_args * uap)2400 freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
2401 {
2402 struct stat ub;
2403 struct stat32 ub32;
2404 int error;
2405
2406 error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
2407 &ub);
2408 if (error)
2409 return (error);
2410 copy_stat(&ub, &ub32);
2411 error = copyout(&ub32, uap->buf, sizeof(ub32));
2412 return (error);
2413 }
2414
2415 #ifdef COMPAT_43
2416 int
ofreebsd32_lstat(struct thread * td,struct ofreebsd32_lstat_args * uap)2417 ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
2418 {
2419 struct stat sb;
2420 struct ostat32 sb32;
2421 int error;
2422
2423 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2424 UIO_USERSPACE, &sb);
2425 if (error)
2426 return (error);
2427 copy_ostat(&sb, &sb32);
2428 error = copyout(&sb32, uap->ub, sizeof (sb32));
2429 return (error);
2430 }
2431 #endif
2432
2433 int
freebsd32_fhstat(struct thread * td,struct freebsd32_fhstat_args * uap)2434 freebsd32_fhstat(struct thread *td, struct freebsd32_fhstat_args *uap)
2435 {
2436 struct stat sb;
2437 struct stat32 sb32;
2438 struct fhandle fh;
2439 int error;
2440
2441 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
2442 if (error != 0)
2443 return (error);
2444 error = kern_fhstat(td, fh, &sb);
2445 if (error != 0)
2446 return (error);
2447 copy_stat(&sb, &sb32);
2448 error = copyout(&sb32, uap->sb, sizeof (sb32));
2449 return (error);
2450 }
2451
2452 #if defined(COMPAT_FREEBSD11)
2453 extern int ino64_trunc_error;
2454
2455 static int
freebsd11_cvtstat32(struct stat * in,struct freebsd11_stat32 * out)2456 freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out)
2457 {
2458
2459 #ifndef __amd64__
2460 /*
2461 * 32-bit architectures other than i386 have 64-bit time_t. This
2462 * results in struct timespec32 with 12 bytes for tv_sec and tv_nsec,
2463 * and 4 bytes of padding. Zero the padding holes in freebsd11_stat32.
2464 */
2465 bzero(&out->st_atim, sizeof(out->st_atim));
2466 bzero(&out->st_mtim, sizeof(out->st_mtim));
2467 bzero(&out->st_ctim, sizeof(out->st_ctim));
2468 bzero(&out->st_birthtim, sizeof(out->st_birthtim));
2469 #endif
2470
2471 CP(*in, *out, st_ino);
2472 if (in->st_ino != out->st_ino) {
2473 switch (ino64_trunc_error) {
2474 default:
2475 case 0:
2476 break;
2477 case 1:
2478 return (EOVERFLOW);
2479 case 2:
2480 out->st_ino = UINT32_MAX;
2481 break;
2482 }
2483 }
2484 CP(*in, *out, st_nlink);
2485 if (in->st_nlink != out->st_nlink) {
2486 switch (ino64_trunc_error) {
2487 default:
2488 case 0:
2489 break;
2490 case 1:
2491 return (EOVERFLOW);
2492 case 2:
2493 out->st_nlink = UINT16_MAX;
2494 break;
2495 }
2496 }
2497 out->st_dev = in->st_dev;
2498 if (out->st_dev != in->st_dev) {
2499 switch (ino64_trunc_error) {
2500 default:
2501 break;
2502 case 1:
2503 return (EOVERFLOW);
2504 }
2505 }
2506 CP(*in, *out, st_mode);
2507 CP(*in, *out, st_uid);
2508 CP(*in, *out, st_gid);
2509 out->st_rdev = in->st_rdev;
2510 if (out->st_rdev != in->st_rdev) {
2511 switch (ino64_trunc_error) {
2512 default:
2513 break;
2514 case 1:
2515 return (EOVERFLOW);
2516 }
2517 }
2518 TS_CP(*in, *out, st_atim);
2519 TS_CP(*in, *out, st_mtim);
2520 TS_CP(*in, *out, st_ctim);
2521 CP(*in, *out, st_size);
2522 CP(*in, *out, st_blocks);
2523 CP(*in, *out, st_blksize);
2524 CP(*in, *out, st_flags);
2525 CP(*in, *out, st_gen);
2526 TS_CP(*in, *out, st_birthtim);
2527 out->st_lspare = 0;
2528 bzero((char *)&out->st_birthtim + sizeof(out->st_birthtim),
2529 sizeof(*out) - offsetof(struct freebsd11_stat32,
2530 st_birthtim) - sizeof(out->st_birthtim));
2531 return (0);
2532 }
2533
2534 int
freebsd11_freebsd32_stat(struct thread * td,struct freebsd11_freebsd32_stat_args * uap)2535 freebsd11_freebsd32_stat(struct thread *td,
2536 struct freebsd11_freebsd32_stat_args *uap)
2537 {
2538 struct stat sb;
2539 struct freebsd11_stat32 sb32;
2540 int error;
2541
2542 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2543 if (error != 0)
2544 return (error);
2545 error = freebsd11_cvtstat32(&sb, &sb32);
2546 if (error == 0)
2547 error = copyout(&sb32, uap->ub, sizeof (sb32));
2548 return (error);
2549 }
2550
2551 int
freebsd11_freebsd32_fstat(struct thread * td,struct freebsd11_freebsd32_fstat_args * uap)2552 freebsd11_freebsd32_fstat(struct thread *td,
2553 struct freebsd11_freebsd32_fstat_args *uap)
2554 {
2555 struct stat sb;
2556 struct freebsd11_stat32 sb32;
2557 int error;
2558
2559 error = kern_fstat(td, uap->fd, &sb);
2560 if (error != 0)
2561 return (error);
2562 error = freebsd11_cvtstat32(&sb, &sb32);
2563 if (error == 0)
2564 error = copyout(&sb32, uap->sb, sizeof (sb32));
2565 return (error);
2566 }
2567
2568 int
freebsd11_freebsd32_fstatat(struct thread * td,struct freebsd11_freebsd32_fstatat_args * uap)2569 freebsd11_freebsd32_fstatat(struct thread *td,
2570 struct freebsd11_freebsd32_fstatat_args *uap)
2571 {
2572 struct stat sb;
2573 struct freebsd11_stat32 sb32;
2574 int error;
2575
2576 error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
2577 &sb);
2578 if (error != 0)
2579 return (error);
2580 error = freebsd11_cvtstat32(&sb, &sb32);
2581 if (error == 0)
2582 error = copyout(&sb32, uap->buf, sizeof (sb32));
2583 return (error);
2584 }
2585
2586 int
freebsd11_freebsd32_lstat(struct thread * td,struct freebsd11_freebsd32_lstat_args * uap)2587 freebsd11_freebsd32_lstat(struct thread *td,
2588 struct freebsd11_freebsd32_lstat_args *uap)
2589 {
2590 struct stat sb;
2591 struct freebsd11_stat32 sb32;
2592 int error;
2593
2594 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2595 UIO_USERSPACE, &sb);
2596 if (error != 0)
2597 return (error);
2598 error = freebsd11_cvtstat32(&sb, &sb32);
2599 if (error == 0)
2600 error = copyout(&sb32, uap->ub, sizeof (sb32));
2601 return (error);
2602 }
2603
2604 int
freebsd11_freebsd32_fhstat(struct thread * td,struct freebsd11_freebsd32_fhstat_args * uap)2605 freebsd11_freebsd32_fhstat(struct thread *td,
2606 struct freebsd11_freebsd32_fhstat_args *uap)
2607 {
2608 struct stat sb;
2609 struct freebsd11_stat32 sb32;
2610 struct fhandle fh;
2611 int error;
2612
2613 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
2614 if (error != 0)
2615 return (error);
2616 error = kern_fhstat(td, fh, &sb);
2617 if (error != 0)
2618 return (error);
2619 error = freebsd11_cvtstat32(&sb, &sb32);
2620 if (error == 0)
2621 error = copyout(&sb32, uap->sb, sizeof (sb32));
2622 return (error);
2623 }
2624
2625 static int
freebsd11_cvtnstat32(struct stat * sb,struct nstat32 * nsb32)2626 freebsd11_cvtnstat32(struct stat *sb, struct nstat32 *nsb32)
2627 {
2628 struct nstat nsb;
2629 int error;
2630
2631 error = freebsd11_cvtnstat(sb, &nsb);
2632 if (error != 0)
2633 return (error);
2634
2635 bzero(nsb32, sizeof(*nsb32));
2636 CP(nsb, *nsb32, st_dev);
2637 CP(nsb, *nsb32, st_ino);
2638 CP(nsb, *nsb32, st_mode);
2639 CP(nsb, *nsb32, st_nlink);
2640 CP(nsb, *nsb32, st_uid);
2641 CP(nsb, *nsb32, st_gid);
2642 CP(nsb, *nsb32, st_rdev);
2643 CP(nsb, *nsb32, st_atim.tv_sec);
2644 CP(nsb, *nsb32, st_atim.tv_nsec);
2645 CP(nsb, *nsb32, st_mtim.tv_sec);
2646 CP(nsb, *nsb32, st_mtim.tv_nsec);
2647 CP(nsb, *nsb32, st_ctim.tv_sec);
2648 CP(nsb, *nsb32, st_ctim.tv_nsec);
2649 CP(nsb, *nsb32, st_size);
2650 CP(nsb, *nsb32, st_blocks);
2651 CP(nsb, *nsb32, st_blksize);
2652 CP(nsb, *nsb32, st_flags);
2653 CP(nsb, *nsb32, st_gen);
2654 CP(nsb, *nsb32, st_birthtim.tv_sec);
2655 CP(nsb, *nsb32, st_birthtim.tv_nsec);
2656 return (0);
2657 }
2658
2659 int
freebsd11_freebsd32_nstat(struct thread * td,struct freebsd11_freebsd32_nstat_args * uap)2660 freebsd11_freebsd32_nstat(struct thread *td,
2661 struct freebsd11_freebsd32_nstat_args *uap)
2662 {
2663 struct stat sb;
2664 struct nstat32 nsb;
2665 int error;
2666
2667 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2668 if (error != 0)
2669 return (error);
2670 error = freebsd11_cvtnstat32(&sb, &nsb);
2671 if (error != 0)
2672 error = copyout(&nsb, uap->ub, sizeof (nsb));
2673 return (error);
2674 }
2675
2676 int
freebsd11_freebsd32_nlstat(struct thread * td,struct freebsd11_freebsd32_nlstat_args * uap)2677 freebsd11_freebsd32_nlstat(struct thread *td,
2678 struct freebsd11_freebsd32_nlstat_args *uap)
2679 {
2680 struct stat sb;
2681 struct nstat32 nsb;
2682 int error;
2683
2684 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2685 UIO_USERSPACE, &sb);
2686 if (error != 0)
2687 return (error);
2688 error = freebsd11_cvtnstat32(&sb, &nsb);
2689 if (error == 0)
2690 error = copyout(&nsb, uap->ub, sizeof (nsb));
2691 return (error);
2692 }
2693
2694 int
freebsd11_freebsd32_nfstat(struct thread * td,struct freebsd11_freebsd32_nfstat_args * uap)2695 freebsd11_freebsd32_nfstat(struct thread *td,
2696 struct freebsd11_freebsd32_nfstat_args *uap)
2697 {
2698 struct nstat32 nub;
2699 struct stat ub;
2700 int error;
2701
2702 error = kern_fstat(td, uap->fd, &ub);
2703 if (error != 0)
2704 return (error);
2705 error = freebsd11_cvtnstat32(&ub, &nub);
2706 if (error == 0)
2707 error = copyout(&nub, uap->sb, sizeof(nub));
2708 return (error);
2709 }
2710 #endif
2711
2712 int
freebsd32___sysctl(struct thread * td,struct freebsd32___sysctl_args * uap)2713 freebsd32___sysctl(struct thread *td, struct freebsd32___sysctl_args *uap)
2714 {
2715 int error, name[CTL_MAXNAME];
2716 size_t j, oldlen;
2717 uint32_t tmp;
2718
2719 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
2720 return (EINVAL);
2721 error = copyin(uap->name, name, uap->namelen * sizeof(int));
2722 if (error)
2723 return (error);
2724 if (uap->oldlenp) {
2725 error = fueword32(uap->oldlenp, &tmp);
2726 oldlen = tmp;
2727 } else {
2728 oldlen = 0;
2729 }
2730 if (error != 0)
2731 return (EFAULT);
2732 error = userland_sysctl(td, name, uap->namelen,
2733 uap->old, &oldlen, 1,
2734 uap->new, uap->newlen, &j, SCTL_MASK32);
2735 if (error)
2736 return (error);
2737 if (uap->oldlenp != NULL && suword32(uap->oldlenp, j) != 0)
2738 error = EFAULT;
2739 return (error);
2740 }
2741
2742 int
freebsd32___sysctlbyname(struct thread * td,struct freebsd32___sysctlbyname_args * uap)2743 freebsd32___sysctlbyname(struct thread *td,
2744 struct freebsd32___sysctlbyname_args *uap)
2745 {
2746 size_t oldlen, rv;
2747 int error;
2748 uint32_t tmp;
2749
2750 if (uap->oldlenp != NULL) {
2751 error = fueword32(uap->oldlenp, &tmp);
2752 oldlen = tmp;
2753 } else {
2754 error = oldlen = 0;
2755 }
2756 if (error != 0)
2757 return (EFAULT);
2758 error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old,
2759 &oldlen, uap->new, uap->newlen, &rv, SCTL_MASK32, 1);
2760 if (error != 0)
2761 return (error);
2762 if (uap->oldlenp != NULL && suword32(uap->oldlenp, rv) != 0)
2763 error = EFAULT;
2764 return (error);
2765 }
2766
2767 int
freebsd32_jail(struct thread * td,struct freebsd32_jail_args * uap)2768 freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
2769 {
2770 uint32_t version;
2771 int error;
2772 struct jail j;
2773
2774 error = copyin(uap->jail, &version, sizeof(uint32_t));
2775 if (error)
2776 return (error);
2777
2778 switch (version) {
2779 case 0:
2780 {
2781 /* FreeBSD single IPv4 jails. */
2782 struct jail32_v0 j32_v0;
2783
2784 bzero(&j, sizeof(struct jail));
2785 error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0));
2786 if (error)
2787 return (error);
2788 CP(j32_v0, j, version);
2789 PTRIN_CP(j32_v0, j, path);
2790 PTRIN_CP(j32_v0, j, hostname);
2791 j.ip4s = htonl(j32_v0.ip_number); /* jail_v0 is host order */
2792 break;
2793 }
2794
2795 case 1:
2796 /*
2797 * Version 1 was used by multi-IPv4 jail implementations
2798 * that never made it into the official kernel.
2799 */
2800 return (EINVAL);
2801
2802 case 2: /* JAIL_API_VERSION */
2803 {
2804 /* FreeBSD multi-IPv4/IPv6,noIP jails. */
2805 struct jail32 j32;
2806
2807 error = copyin(uap->jail, &j32, sizeof(struct jail32));
2808 if (error)
2809 return (error);
2810 CP(j32, j, version);
2811 PTRIN_CP(j32, j, path);
2812 PTRIN_CP(j32, j, hostname);
2813 PTRIN_CP(j32, j, jailname);
2814 CP(j32, j, ip4s);
2815 CP(j32, j, ip6s);
2816 PTRIN_CP(j32, j, ip4);
2817 PTRIN_CP(j32, j, ip6);
2818 break;
2819 }
2820
2821 default:
2822 /* Sci-Fi jails are not supported, sorry. */
2823 return (EINVAL);
2824 }
2825 return (kern_jail(td, &j));
2826 }
2827
2828 int
freebsd32_jail_set(struct thread * td,struct freebsd32_jail_set_args * uap)2829 freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
2830 {
2831 struct uio *auio;
2832 int error;
2833
2834 /* Check that we have an even number of iovecs. */
2835 if (uap->iovcnt & 1)
2836 return (EINVAL);
2837
2838 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2839 if (error)
2840 return (error);
2841 error = kern_jail_set(td, auio, uap->flags);
2842 freeuio(auio);
2843 return (error);
2844 }
2845
2846 int
freebsd32_jail_get(struct thread * td,struct freebsd32_jail_get_args * uap)2847 freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
2848 {
2849 struct iovec32 iov32;
2850 struct uio *auio;
2851 int error, i;
2852
2853 /* Check that we have an even number of iovecs. */
2854 if (uap->iovcnt & 1)
2855 return (EINVAL);
2856
2857 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2858 if (error)
2859 return (error);
2860 error = kern_jail_get(td, auio, uap->flags);
2861 if (error == 0)
2862 for (i = 0; i < uap->iovcnt; i++) {
2863 PTROUT_CP(auio->uio_iov[i], iov32, iov_base);
2864 CP(auio->uio_iov[i], iov32, iov_len);
2865 error = copyout(&iov32, uap->iovp + i, sizeof(iov32));
2866 if (error != 0)
2867 break;
2868 }
2869 freeuio(auio);
2870 return (error);
2871 }
2872
2873 int
freebsd32_sigaction(struct thread * td,struct freebsd32_sigaction_args * uap)2874 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
2875 {
2876 struct sigaction32 s32;
2877 struct sigaction sa, osa, *sap;
2878 int error;
2879
2880 if (uap->act) {
2881 error = copyin(uap->act, &s32, sizeof(s32));
2882 if (error)
2883 return (error);
2884 sa.sa_handler = PTRIN(s32.sa_u);
2885 CP(s32, sa, sa_flags);
2886 CP(s32, sa, sa_mask);
2887 sap = &sa;
2888 } else
2889 sap = NULL;
2890 error = kern_sigaction(td, uap->sig, sap, &osa, 0);
2891 if (error == 0 && uap->oact != NULL) {
2892 s32.sa_u = PTROUT(osa.sa_handler);
2893 CP(osa, s32, sa_flags);
2894 CP(osa, s32, sa_mask);
2895 error = copyout(&s32, uap->oact, sizeof(s32));
2896 }
2897 return (error);
2898 }
2899
2900 #ifdef COMPAT_FREEBSD4
2901 int
freebsd4_freebsd32_sigaction(struct thread * td,struct freebsd4_freebsd32_sigaction_args * uap)2902 freebsd4_freebsd32_sigaction(struct thread *td,
2903 struct freebsd4_freebsd32_sigaction_args *uap)
2904 {
2905 struct sigaction32 s32;
2906 struct sigaction sa, osa, *sap;
2907 int error;
2908
2909 if (uap->act) {
2910 error = copyin(uap->act, &s32, sizeof(s32));
2911 if (error)
2912 return (error);
2913 sa.sa_handler = PTRIN(s32.sa_u);
2914 CP(s32, sa, sa_flags);
2915 CP(s32, sa, sa_mask);
2916 sap = &sa;
2917 } else
2918 sap = NULL;
2919 error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
2920 if (error == 0 && uap->oact != NULL) {
2921 s32.sa_u = PTROUT(osa.sa_handler);
2922 CP(osa, s32, sa_flags);
2923 CP(osa, s32, sa_mask);
2924 error = copyout(&s32, uap->oact, sizeof(s32));
2925 }
2926 return (error);
2927 }
2928 #endif
2929
2930 #ifdef COMPAT_43
2931 struct osigaction32 {
2932 uint32_t sa_u;
2933 osigset_t sa_mask;
2934 int sa_flags;
2935 };
2936
2937 #define ONSIG 32
2938
2939 int
ofreebsd32_sigaction(struct thread * td,struct ofreebsd32_sigaction_args * uap)2940 ofreebsd32_sigaction(struct thread *td,
2941 struct ofreebsd32_sigaction_args *uap)
2942 {
2943 struct osigaction32 s32;
2944 struct sigaction sa, osa, *sap;
2945 int error;
2946
2947 if (uap->signum <= 0 || uap->signum >= ONSIG)
2948 return (EINVAL);
2949
2950 if (uap->nsa) {
2951 error = copyin(uap->nsa, &s32, sizeof(s32));
2952 if (error)
2953 return (error);
2954 sa.sa_handler = PTRIN(s32.sa_u);
2955 CP(s32, sa, sa_flags);
2956 OSIG2SIG(s32.sa_mask, sa.sa_mask);
2957 sap = &sa;
2958 } else
2959 sap = NULL;
2960 error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2961 if (error == 0 && uap->osa != NULL) {
2962 s32.sa_u = PTROUT(osa.sa_handler);
2963 CP(osa, s32, sa_flags);
2964 SIG2OSIG(osa.sa_mask, s32.sa_mask);
2965 error = copyout(&s32, uap->osa, sizeof(s32));
2966 }
2967 return (error);
2968 }
2969
2970 struct sigvec32 {
2971 uint32_t sv_handler;
2972 int sv_mask;
2973 int sv_flags;
2974 };
2975
2976 int
ofreebsd32_sigvec(struct thread * td,struct ofreebsd32_sigvec_args * uap)2977 ofreebsd32_sigvec(struct thread *td,
2978 struct ofreebsd32_sigvec_args *uap)
2979 {
2980 struct sigvec32 vec;
2981 struct sigaction sa, osa, *sap;
2982 int error;
2983
2984 if (uap->signum <= 0 || uap->signum >= ONSIG)
2985 return (EINVAL);
2986
2987 if (uap->nsv) {
2988 error = copyin(uap->nsv, &vec, sizeof(vec));
2989 if (error)
2990 return (error);
2991 sa.sa_handler = PTRIN(vec.sv_handler);
2992 OSIG2SIG(vec.sv_mask, sa.sa_mask);
2993 sa.sa_flags = vec.sv_flags;
2994 sa.sa_flags ^= SA_RESTART;
2995 sap = &sa;
2996 } else
2997 sap = NULL;
2998 error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2999 if (error == 0 && uap->osv != NULL) {
3000 vec.sv_handler = PTROUT(osa.sa_handler);
3001 SIG2OSIG(osa.sa_mask, vec.sv_mask);
3002 vec.sv_flags = osa.sa_flags;
3003 vec.sv_flags &= ~SA_NOCLDWAIT;
3004 vec.sv_flags ^= SA_RESTART;
3005 error = copyout(&vec, uap->osv, sizeof(vec));
3006 }
3007 return (error);
3008 }
3009
3010 struct sigstack32 {
3011 uint32_t ss_sp;
3012 int ss_onstack;
3013 };
3014
3015 int
ofreebsd32_sigstack(struct thread * td,struct ofreebsd32_sigstack_args * uap)3016 ofreebsd32_sigstack(struct thread *td,
3017 struct ofreebsd32_sigstack_args *uap)
3018 {
3019 struct sigstack32 s32;
3020 struct sigstack nss, oss;
3021 int error = 0, unss;
3022
3023 if (uap->nss != NULL) {
3024 error = copyin(uap->nss, &s32, sizeof(s32));
3025 if (error)
3026 return (error);
3027 nss.ss_sp = PTRIN(s32.ss_sp);
3028 CP(s32, nss, ss_onstack);
3029 unss = 1;
3030 } else {
3031 unss = 0;
3032 }
3033 oss.ss_sp = td->td_sigstk.ss_sp;
3034 oss.ss_onstack = sigonstack(cpu_getstack(td));
3035 if (unss) {
3036 td->td_sigstk.ss_sp = nss.ss_sp;
3037 td->td_sigstk.ss_size = 0;
3038 td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
3039 td->td_pflags |= TDP_ALTSTACK;
3040 }
3041 if (uap->oss != NULL) {
3042 s32.ss_sp = PTROUT(oss.ss_sp);
3043 CP(oss, s32, ss_onstack);
3044 error = copyout(&s32, uap->oss, sizeof(s32));
3045 }
3046 return (error);
3047 }
3048 #endif
3049
3050 int
freebsd32_nanosleep(struct thread * td,struct freebsd32_nanosleep_args * uap)3051 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
3052 {
3053
3054 return (freebsd32_user_clock_nanosleep(td, CLOCK_REALTIME,
3055 TIMER_RELTIME, uap->rqtp, uap->rmtp));
3056 }
3057
3058 int
freebsd32_clock_nanosleep(struct thread * td,struct freebsd32_clock_nanosleep_args * uap)3059 freebsd32_clock_nanosleep(struct thread *td,
3060 struct freebsd32_clock_nanosleep_args *uap)
3061 {
3062 int error;
3063
3064 error = freebsd32_user_clock_nanosleep(td, uap->clock_id, uap->flags,
3065 uap->rqtp, uap->rmtp);
3066 return (kern_posix_error(td, error));
3067 }
3068
3069 static int
freebsd32_user_clock_nanosleep(struct thread * td,clockid_t clock_id,int flags,const struct timespec32 * ua_rqtp,struct timespec32 * ua_rmtp)3070 freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id,
3071 int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp)
3072 {
3073 struct timespec32 rmt32, rqt32;
3074 struct timespec rmt, rqt;
3075 int error, error2;
3076
3077 error = copyin(ua_rqtp, &rqt32, sizeof(rqt32));
3078 if (error)
3079 return (error);
3080
3081 CP(rqt32, rqt, tv_sec);
3082 CP(rqt32, rqt, tv_nsec);
3083
3084 error = kern_clock_nanosleep(td, clock_id, flags, &rqt, &rmt);
3085 if (error == EINTR && ua_rmtp != NULL && (flags & TIMER_ABSTIME) == 0) {
3086 CP(rmt, rmt32, tv_sec);
3087 CP(rmt, rmt32, tv_nsec);
3088
3089 error2 = copyout(&rmt32, ua_rmtp, sizeof(rmt32));
3090 if (error2 != 0)
3091 error = error2;
3092 }
3093 return (error);
3094 }
3095
3096 int
freebsd32_clock_gettime(struct thread * td,struct freebsd32_clock_gettime_args * uap)3097 freebsd32_clock_gettime(struct thread *td,
3098 struct freebsd32_clock_gettime_args *uap)
3099 {
3100 struct timespec ats;
3101 struct timespec32 ats32;
3102 int error;
3103
3104 error = kern_clock_gettime(td, uap->clock_id, &ats);
3105 if (error == 0) {
3106 CP(ats, ats32, tv_sec);
3107 CP(ats, ats32, tv_nsec);
3108 error = copyout(&ats32, uap->tp, sizeof(ats32));
3109 }
3110 return (error);
3111 }
3112
3113 int
freebsd32_clock_settime(struct thread * td,struct freebsd32_clock_settime_args * uap)3114 freebsd32_clock_settime(struct thread *td,
3115 struct freebsd32_clock_settime_args *uap)
3116 {
3117 struct timespec ats;
3118 struct timespec32 ats32;
3119 int error;
3120
3121 error = copyin(uap->tp, &ats32, sizeof(ats32));
3122 if (error)
3123 return (error);
3124 CP(ats32, ats, tv_sec);
3125 CP(ats32, ats, tv_nsec);
3126
3127 return (kern_clock_settime(td, uap->clock_id, &ats));
3128 }
3129
3130 int
freebsd32_clock_getres(struct thread * td,struct freebsd32_clock_getres_args * uap)3131 freebsd32_clock_getres(struct thread *td,
3132 struct freebsd32_clock_getres_args *uap)
3133 {
3134 struct timespec ts;
3135 struct timespec32 ts32;
3136 int error;
3137
3138 if (uap->tp == NULL)
3139 return (0);
3140 error = kern_clock_getres(td, uap->clock_id, &ts);
3141 if (error == 0) {
3142 CP(ts, ts32, tv_sec);
3143 CP(ts, ts32, tv_nsec);
3144 error = copyout(&ts32, uap->tp, sizeof(ts32));
3145 }
3146 return (error);
3147 }
3148
freebsd32_ktimer_create(struct thread * td,struct freebsd32_ktimer_create_args * uap)3149 int freebsd32_ktimer_create(struct thread *td,
3150 struct freebsd32_ktimer_create_args *uap)
3151 {
3152 struct sigevent32 ev32;
3153 struct sigevent ev, *evp;
3154 int error, id;
3155
3156 if (uap->evp == NULL) {
3157 evp = NULL;
3158 } else {
3159 evp = &ev;
3160 error = copyin(uap->evp, &ev32, sizeof(ev32));
3161 if (error != 0)
3162 return (error);
3163 error = convert_sigevent32(&ev32, &ev);
3164 if (error != 0)
3165 return (error);
3166 }
3167 error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
3168 if (error == 0) {
3169 error = copyout(&id, uap->timerid, sizeof(int));
3170 if (error != 0)
3171 kern_ktimer_delete(td, id);
3172 }
3173 return (error);
3174 }
3175
3176 int
freebsd32_ktimer_settime(struct thread * td,struct freebsd32_ktimer_settime_args * uap)3177 freebsd32_ktimer_settime(struct thread *td,
3178 struct freebsd32_ktimer_settime_args *uap)
3179 {
3180 struct itimerspec32 val32, oval32;
3181 struct itimerspec val, oval, *ovalp;
3182 int error;
3183
3184 error = copyin(uap->value, &val32, sizeof(val32));
3185 if (error != 0)
3186 return (error);
3187 ITS_CP(val32, val);
3188 ovalp = uap->ovalue != NULL ? &oval : NULL;
3189 error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
3190 if (error == 0 && uap->ovalue != NULL) {
3191 ITS_CP(oval, oval32);
3192 error = copyout(&oval32, uap->ovalue, sizeof(oval32));
3193 }
3194 return (error);
3195 }
3196
3197 int
freebsd32_ktimer_gettime(struct thread * td,struct freebsd32_ktimer_gettime_args * uap)3198 freebsd32_ktimer_gettime(struct thread *td,
3199 struct freebsd32_ktimer_gettime_args *uap)
3200 {
3201 struct itimerspec32 val32;
3202 struct itimerspec val;
3203 int error;
3204
3205 error = kern_ktimer_gettime(td, uap->timerid, &val);
3206 if (error == 0) {
3207 ITS_CP(val, val32);
3208 error = copyout(&val32, uap->value, sizeof(val32));
3209 }
3210 return (error);
3211 }
3212
3213 int
freebsd32_timerfd_gettime(struct thread * td,struct freebsd32_timerfd_gettime_args * uap)3214 freebsd32_timerfd_gettime(struct thread *td,
3215 struct freebsd32_timerfd_gettime_args *uap)
3216 {
3217 struct itimerspec curr_value;
3218 struct itimerspec32 curr_value32;
3219 int error;
3220
3221 error = kern_timerfd_gettime(td, uap->fd, &curr_value);
3222 if (error == 0) {
3223 CP(curr_value, curr_value32, it_value.tv_sec);
3224 CP(curr_value, curr_value32, it_value.tv_nsec);
3225 CP(curr_value, curr_value32, it_interval.tv_sec);
3226 CP(curr_value, curr_value32, it_interval.tv_nsec);
3227 error = copyout(&curr_value32, uap->curr_value,
3228 sizeof(curr_value32));
3229 }
3230
3231 return (error);
3232 }
3233
3234 int
freebsd32_timerfd_settime(struct thread * td,struct freebsd32_timerfd_settime_args * uap)3235 freebsd32_timerfd_settime(struct thread *td,
3236 struct freebsd32_timerfd_settime_args *uap)
3237 {
3238 struct itimerspec new_value, old_value;
3239 struct itimerspec32 new_value32, old_value32;
3240 int error;
3241
3242 error = copyin(uap->new_value, &new_value32, sizeof(new_value32));
3243 if (error != 0)
3244 return (error);
3245 CP(new_value32, new_value, it_value.tv_sec);
3246 CP(new_value32, new_value, it_value.tv_nsec);
3247 CP(new_value32, new_value, it_interval.tv_sec);
3248 CP(new_value32, new_value, it_interval.tv_nsec);
3249 if (uap->old_value == NULL) {
3250 error = kern_timerfd_settime(td, uap->fd, uap->flags,
3251 &new_value, NULL);
3252 } else {
3253 error = kern_timerfd_settime(td, uap->fd, uap->flags,
3254 &new_value, &old_value);
3255 if (error == 0) {
3256 CP(old_value, old_value32, it_value.tv_sec);
3257 CP(old_value, old_value32, it_value.tv_nsec);
3258 CP(old_value, old_value32, it_interval.tv_sec);
3259 CP(old_value, old_value32, it_interval.tv_nsec);
3260 error = copyout(&old_value32, uap->old_value,
3261 sizeof(old_value32));
3262 }
3263 }
3264 return (error);
3265 }
3266
3267 int
freebsd32_clock_getcpuclockid2(struct thread * td,struct freebsd32_clock_getcpuclockid2_args * uap)3268 freebsd32_clock_getcpuclockid2(struct thread *td,
3269 struct freebsd32_clock_getcpuclockid2_args *uap)
3270 {
3271 clockid_t clk_id;
3272 int error;
3273
3274 error = kern_clock_getcpuclockid2(td, PAIR32TO64(id_t, uap->id),
3275 uap->which, &clk_id);
3276 if (error == 0)
3277 error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t));
3278 return (error);
3279 }
3280
3281 int
freebsd32_thr_new(struct thread * td,struct freebsd32_thr_new_args * uap)3282 freebsd32_thr_new(struct thread *td,
3283 struct freebsd32_thr_new_args *uap)
3284 {
3285 struct thr_param32 param32;
3286 struct thr_param param;
3287 int error;
3288
3289 if (uap->param_size < 0 ||
3290 uap->param_size > sizeof(struct thr_param32))
3291 return (EINVAL);
3292 bzero(¶m, sizeof(struct thr_param));
3293 bzero(¶m32, sizeof(struct thr_param32));
3294 error = copyin(uap->param, ¶m32, uap->param_size);
3295 if (error != 0)
3296 return (error);
3297 param.start_func = PTRIN(param32.start_func);
3298 param.arg = PTRIN(param32.arg);
3299 param.stack_base = PTRIN(param32.stack_base);
3300 param.stack_size = param32.stack_size;
3301 param.tls_base = PTRIN(param32.tls_base);
3302 param.tls_size = param32.tls_size;
3303 param.child_tid = PTRIN(param32.child_tid);
3304 param.parent_tid = PTRIN(param32.parent_tid);
3305 param.flags = param32.flags;
3306 param.rtp = PTRIN(param32.rtp);
3307 param.spare[0] = PTRIN(param32.spare[0]);
3308 param.spare[1] = PTRIN(param32.spare[1]);
3309 param.spare[2] = PTRIN(param32.spare[2]);
3310
3311 return (kern_thr_new(td, ¶m));
3312 }
3313
3314 int
freebsd32_thr_suspend(struct thread * td,struct freebsd32_thr_suspend_args * uap)3315 freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
3316 {
3317 struct timespec32 ts32;
3318 struct timespec ts, *tsp;
3319 int error;
3320
3321 error = 0;
3322 tsp = NULL;
3323 if (uap->timeout != NULL) {
3324 error = copyin((const void *)uap->timeout, (void *)&ts32,
3325 sizeof(struct timespec32));
3326 if (error != 0)
3327 return (error);
3328 ts.tv_sec = ts32.tv_sec;
3329 ts.tv_nsec = ts32.tv_nsec;
3330 tsp = &ts;
3331 }
3332 return (kern_thr_suspend(td, tsp));
3333 }
3334
3335 void
siginfo_to_siginfo32(const siginfo_t * src,struct __siginfo32 * dst)3336 siginfo_to_siginfo32(const siginfo_t *src, struct __siginfo32 *dst)
3337 {
3338 bzero(dst, sizeof(*dst));
3339 dst->si_signo = src->si_signo;
3340 dst->si_errno = src->si_errno;
3341 dst->si_code = src->si_code;
3342 dst->si_pid = src->si_pid;
3343 dst->si_uid = src->si_uid;
3344 dst->si_status = src->si_status;
3345 dst->si_addr = (uintptr_t)src->si_addr;
3346 dst->si_value.sival_int = src->si_value.sival_int;
3347 dst->si_timerid = src->si_timerid;
3348 dst->si_overrun = src->si_overrun;
3349 }
3350
3351 #ifndef _FREEBSD32_SYSPROTO_H_
3352 struct freebsd32_sigqueue_args {
3353 pid_t pid;
3354 int signum;
3355 /* union sigval32 */ int value;
3356 };
3357 #endif
3358 int
freebsd32_sigqueue(struct thread * td,struct freebsd32_sigqueue_args * uap)3359 freebsd32_sigqueue(struct thread *td, struct freebsd32_sigqueue_args *uap)
3360 {
3361 union sigval sv;
3362
3363 /*
3364 * On 32-bit ABIs, sival_int and sival_ptr are the same.
3365 * On 64-bit little-endian ABIs, the low bits are the same.
3366 * In 64-bit big-endian ABIs, sival_int overlaps with
3367 * sival_ptr's HIGH bits. We choose to support sival_int
3368 * rather than sival_ptr in this case as it seems to be
3369 * more common.
3370 */
3371 bzero(&sv, sizeof(sv));
3372 sv.sival_int = (uint32_t)(uint64_t)uap->value;
3373
3374 return (kern_sigqueue(td, uap->pid, uap->signum, &sv));
3375 }
3376
3377 int
freebsd32_sigtimedwait(struct thread * td,struct freebsd32_sigtimedwait_args * uap)3378 freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
3379 {
3380 struct timespec32 ts32;
3381 struct timespec ts;
3382 struct timespec *timeout;
3383 sigset_t set;
3384 ksiginfo_t ksi;
3385 struct __siginfo32 si32;
3386 int error;
3387
3388 if (uap->timeout) {
3389 error = copyin(uap->timeout, &ts32, sizeof(ts32));
3390 if (error)
3391 return (error);
3392 ts.tv_sec = ts32.tv_sec;
3393 ts.tv_nsec = ts32.tv_nsec;
3394 timeout = &ts;
3395 } else
3396 timeout = NULL;
3397
3398 error = copyin(uap->set, &set, sizeof(set));
3399 if (error)
3400 return (error);
3401
3402 error = kern_sigtimedwait(td, set, &ksi, timeout);
3403 if (error)
3404 return (error);
3405
3406 if (uap->info) {
3407 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
3408 error = copyout(&si32, uap->info, sizeof(struct __siginfo32));
3409 }
3410
3411 if (error == 0)
3412 td->td_retval[0] = ksi.ksi_signo;
3413 return (error);
3414 }
3415
3416 /*
3417 * MPSAFE
3418 */
3419 int
freebsd32_sigwaitinfo(struct thread * td,struct freebsd32_sigwaitinfo_args * uap)3420 freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
3421 {
3422 ksiginfo_t ksi;
3423 struct __siginfo32 si32;
3424 sigset_t set;
3425 int error;
3426
3427 error = copyin(uap->set, &set, sizeof(set));
3428 if (error)
3429 return (error);
3430
3431 error = kern_sigtimedwait(td, set, &ksi, NULL);
3432 if (error)
3433 return (error);
3434
3435 if (uap->info) {
3436 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
3437 error = copyout(&si32, uap->info, sizeof(struct __siginfo32));
3438 }
3439 if (error == 0)
3440 td->td_retval[0] = ksi.ksi_signo;
3441 return (error);
3442 }
3443
3444 int
freebsd32_cpuset_setid(struct thread * td,struct freebsd32_cpuset_setid_args * uap)3445 freebsd32_cpuset_setid(struct thread *td,
3446 struct freebsd32_cpuset_setid_args *uap)
3447 {
3448
3449 return (kern_cpuset_setid(td, uap->which,
3450 PAIR32TO64(id_t, uap->id), uap->setid));
3451 }
3452
3453 int
freebsd32_cpuset_getid(struct thread * td,struct freebsd32_cpuset_getid_args * uap)3454 freebsd32_cpuset_getid(struct thread *td,
3455 struct freebsd32_cpuset_getid_args *uap)
3456 {
3457
3458 return (kern_cpuset_getid(td, uap->level, uap->which,
3459 PAIR32TO64(id_t, uap->id), uap->setid));
3460 }
3461
3462 static int
copyin32_set(const void * u,void * k,size_t size)3463 copyin32_set(const void *u, void *k, size_t size)
3464 {
3465 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
3466 int rv;
3467 struct bitset *kb = k;
3468 int *p;
3469
3470 rv = copyin(u, k, size);
3471 if (rv != 0)
3472 return (rv);
3473
3474 p = (int *)kb->__bits;
3475 /* Loop through swapping words.
3476 * `size' is in bytes, we need bits. */
3477 for (int i = 0; i < __bitset_words(size * 8); i++) {
3478 int tmp = p[0];
3479 p[0] = p[1];
3480 p[1] = tmp;
3481 p += 2;
3482 }
3483 return (0);
3484 #else
3485 return (copyin(u, k, size));
3486 #endif
3487 }
3488
3489 static int
copyout32_set(const void * k,void * u,size_t size)3490 copyout32_set(const void *k, void *u, size_t size)
3491 {
3492 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
3493 const struct bitset *kb = k;
3494 struct bitset *ub = u;
3495 const int *kp = (const int *)kb->__bits;
3496 int *up = (int *)ub->__bits;
3497 int rv;
3498
3499 for (int i = 0; i < __bitset_words(CPU_SETSIZE); i++) {
3500 /* `size' is in bytes, we need bits. */
3501 for (int i = 0; i < __bitset_words(size * 8); i++) {
3502 rv = suword32(up, kp[1]);
3503 if (rv == 0)
3504 rv = suword32(up + 1, kp[0]);
3505 if (rv != 0)
3506 return (EFAULT);
3507 }
3508 }
3509 return (0);
3510 #else
3511 return (copyout(k, u, size));
3512 #endif
3513 }
3514
3515 static const struct cpuset_copy_cb cpuset_copy32_cb = {
3516 .cpuset_copyin = copyin32_set,
3517 .cpuset_copyout = copyout32_set
3518 };
3519
3520 int
freebsd32_cpuset_getaffinity(struct thread * td,struct freebsd32_cpuset_getaffinity_args * uap)3521 freebsd32_cpuset_getaffinity(struct thread *td,
3522 struct freebsd32_cpuset_getaffinity_args *uap)
3523 {
3524
3525 return (user_cpuset_getaffinity(td, uap->level, uap->which,
3526 PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask,
3527 &cpuset_copy32_cb));
3528 }
3529
3530 int
freebsd32_cpuset_setaffinity(struct thread * td,struct freebsd32_cpuset_setaffinity_args * uap)3531 freebsd32_cpuset_setaffinity(struct thread *td,
3532 struct freebsd32_cpuset_setaffinity_args *uap)
3533 {
3534
3535 return (user_cpuset_setaffinity(td, uap->level, uap->which,
3536 PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask,
3537 &cpuset_copy32_cb));
3538 }
3539
3540 int
freebsd32_cpuset_getdomain(struct thread * td,struct freebsd32_cpuset_getdomain_args * uap)3541 freebsd32_cpuset_getdomain(struct thread *td,
3542 struct freebsd32_cpuset_getdomain_args *uap)
3543 {
3544
3545 return (kern_cpuset_getdomain(td, uap->level, uap->which,
3546 PAIR32TO64(id_t,uap->id), uap->domainsetsize, uap->mask, uap->policy,
3547 &cpuset_copy32_cb));
3548 }
3549
3550 int
freebsd32_cpuset_setdomain(struct thread * td,struct freebsd32_cpuset_setdomain_args * uap)3551 freebsd32_cpuset_setdomain(struct thread *td,
3552 struct freebsd32_cpuset_setdomain_args *uap)
3553 {
3554
3555 return (kern_cpuset_setdomain(td, uap->level, uap->which,
3556 PAIR32TO64(id_t,uap->id), uap->domainsetsize, uap->mask, uap->policy,
3557 &cpuset_copy32_cb));
3558 }
3559
3560 int
freebsd32_nmount(struct thread * td,struct freebsd32_nmount_args * uap)3561 freebsd32_nmount(struct thread *td,
3562 struct freebsd32_nmount_args /* {
3563 struct iovec *iovp;
3564 unsigned int iovcnt;
3565 int flags;
3566 } */ *uap)
3567 {
3568 struct uio *auio;
3569 uint64_t flags;
3570 int error;
3571
3572 /*
3573 * Mount flags are now 64-bits. On 32-bit archtectures only
3574 * 32-bits are passed in, but from here on everything handles
3575 * 64-bit flags correctly.
3576 */
3577 flags = uap->flags;
3578
3579 AUDIT_ARG_FFLAGS(flags);
3580
3581 /*
3582 * Filter out MNT_ROOTFS. We do not want clients of nmount() in
3583 * userspace to set this flag, but we must filter it out if we want
3584 * MNT_UPDATE on the root file system to work.
3585 * MNT_ROOTFS should only be set by the kernel when mounting its
3586 * root file system.
3587 */
3588 flags &= ~MNT_ROOTFS;
3589
3590 /*
3591 * check that we have an even number of iovec's
3592 * and that we have at least two options.
3593 */
3594 if ((uap->iovcnt & 1) || (uap->iovcnt < 4))
3595 return (EINVAL);
3596
3597 error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
3598 if (error)
3599 return (error);
3600 error = vfs_donmount(td, flags, auio);
3601
3602 freeuio(auio);
3603 return error;
3604 }
3605
3606 #if 0
3607 int
3608 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
3609 {
3610 struct yyy32 *p32, s32;
3611 struct yyy *p = NULL, s;
3612 struct xxx_arg ap;
3613 int error;
3614
3615 if (uap->zzz) {
3616 error = copyin(uap->zzz, &s32, sizeof(s32));
3617 if (error)
3618 return (error);
3619 /* translate in */
3620 p = &s;
3621 }
3622 error = kern_xxx(td, p);
3623 if (error)
3624 return (error);
3625 if (uap->zzz) {
3626 /* translate out */
3627 error = copyout(&s32, p32, sizeof(s32));
3628 }
3629 return (error);
3630 }
3631 #endif
3632
3633 int
syscall32_module_handler(struct module * mod,int what,void * arg)3634 syscall32_module_handler(struct module *mod, int what, void *arg)
3635 {
3636
3637 return (kern_syscall_module_handler(freebsd32_sysent, mod, what, arg));
3638 }
3639
3640 int
syscall32_helper_register(struct syscall_helper_data * sd,int flags)3641 syscall32_helper_register(struct syscall_helper_data *sd, int flags)
3642 {
3643
3644 return (kern_syscall_helper_register(freebsd32_sysent, sd, flags));
3645 }
3646
3647 int
syscall32_helper_unregister(struct syscall_helper_data * sd)3648 syscall32_helper_unregister(struct syscall_helper_data *sd)
3649 {
3650
3651 return (kern_syscall_helper_unregister(freebsd32_sysent, sd));
3652 }
3653
3654 int
freebsd32_copyout_strings(struct image_params * imgp,uintptr_t * stack_base)3655 freebsd32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
3656 {
3657 struct sysentvec *sysent;
3658 int argc, envc, i;
3659 uint32_t *vectp;
3660 char *stringp;
3661 uintptr_t destp, ustringp;
3662 struct freebsd32_ps_strings *arginfo;
3663 char canary[sizeof(long) * 8];
3664 int32_t pagesizes32[MAXPAGESIZES];
3665 size_t execpath_len;
3666 int error, szsigcode;
3667
3668 sysent = imgp->sysent;
3669
3670 arginfo = (struct freebsd32_ps_strings *)PROC_PS_STRINGS(imgp->proc);
3671 imgp->ps_strings = arginfo;
3672 destp = (uintptr_t)arginfo;
3673
3674 /*
3675 * Install sigcode.
3676 */
3677 if (!PROC_HAS_SHP(imgp->proc)) {
3678 szsigcode = *sysent->sv_szsigcode;
3679 destp -= szsigcode;
3680 destp = rounddown2(destp, sizeof(uint32_t));
3681 error = copyout(sysent->sv_sigcode, (void *)destp,
3682 szsigcode);
3683 if (error != 0)
3684 return (error);
3685 }
3686
3687 /*
3688 * Copy the image path for the rtld.
3689 */
3690 if (imgp->execpath != NULL && imgp->auxargs != NULL) {
3691 execpath_len = strlen(imgp->execpath) + 1;
3692 destp -= execpath_len;
3693 imgp->execpathp = (void *)destp;
3694 error = copyout(imgp->execpath, imgp->execpathp, execpath_len);
3695 if (error != 0)
3696 return (error);
3697 }
3698
3699 /*
3700 * Prepare the canary for SSP.
3701 */
3702 arc4rand(canary, sizeof(canary), 0);
3703 destp -= sizeof(canary);
3704 imgp->canary = (void *)destp;
3705 error = copyout(canary, imgp->canary, sizeof(canary));
3706 if (error != 0)
3707 return (error);
3708 imgp->canarylen = sizeof(canary);
3709
3710 /*
3711 * Prepare the pagesizes array.
3712 */
3713 for (i = 0; i < MAXPAGESIZES; i++)
3714 pagesizes32[i] = (uint32_t)pagesizes[i];
3715 destp -= sizeof(pagesizes32);
3716 destp = rounddown2(destp, sizeof(uint32_t));
3717 imgp->pagesizes = (void *)destp;
3718 error = copyout(pagesizes32, imgp->pagesizes, sizeof(pagesizes32));
3719 if (error != 0)
3720 return (error);
3721 imgp->pagesizeslen = sizeof(pagesizes32);
3722
3723 /*
3724 * Allocate room for the argument and environment strings.
3725 */
3726 destp -= ARG_MAX - imgp->args->stringspace;
3727 destp = rounddown2(destp, sizeof(uint32_t));
3728 ustringp = destp;
3729
3730 if (imgp->auxargs) {
3731 /*
3732 * Allocate room on the stack for the ELF auxargs
3733 * array. It has up to AT_COUNT entries.
3734 */
3735 destp -= AT_COUNT * sizeof(Elf32_Auxinfo);
3736 destp = rounddown2(destp, sizeof(uint32_t));
3737 }
3738
3739 vectp = (uint32_t *)destp;
3740
3741 /*
3742 * Allocate room for the argv[] and env vectors including the
3743 * terminating NULL pointers.
3744 */
3745 vectp -= imgp->args->argc + 1 + imgp->args->envc + 1;
3746
3747 /*
3748 * vectp also becomes our initial stack base
3749 */
3750 *stack_base = (uintptr_t)vectp;
3751
3752 stringp = imgp->args->begin_argv;
3753 argc = imgp->args->argc;
3754 envc = imgp->args->envc;
3755 /*
3756 * Copy out strings - arguments and environment.
3757 */
3758 error = copyout(stringp, (void *)ustringp,
3759 ARG_MAX - imgp->args->stringspace);
3760 if (error != 0)
3761 return (error);
3762
3763 /*
3764 * Fill in "ps_strings" struct for ps, w, etc.
3765 */
3766 imgp->argv = vectp;
3767 if (suword32(&arginfo->ps_argvstr, (uint32_t)(intptr_t)vectp) != 0 ||
3768 suword32(&arginfo->ps_nargvstr, argc) != 0)
3769 return (EFAULT);
3770
3771 /*
3772 * Fill in argument portion of vector table.
3773 */
3774 for (; argc > 0; --argc) {
3775 if (suword32(vectp++, ustringp) != 0)
3776 return (EFAULT);
3777 while (*stringp++ != 0)
3778 ustringp++;
3779 ustringp++;
3780 }
3781
3782 /* a null vector table pointer separates the argp's from the envp's */
3783 if (suword32(vectp++, 0) != 0)
3784 return (EFAULT);
3785
3786 imgp->envv = vectp;
3787 if (suword32(&arginfo->ps_envstr, (uint32_t)(intptr_t)vectp) != 0 ||
3788 suword32(&arginfo->ps_nenvstr, envc) != 0)
3789 return (EFAULT);
3790
3791 /*
3792 * Fill in environment portion of vector table.
3793 */
3794 for (; envc > 0; --envc) {
3795 if (suword32(vectp++, ustringp) != 0)
3796 return (EFAULT);
3797 while (*stringp++ != 0)
3798 ustringp++;
3799 ustringp++;
3800 }
3801
3802 /* end of vector table is a null pointer */
3803 if (suword32(vectp, 0) != 0)
3804 return (EFAULT);
3805
3806 if (imgp->auxargs) {
3807 vectp++;
3808 error = imgp->sysent->sv_copyout_auxargs(imgp,
3809 (uintptr_t)vectp);
3810 if (error != 0)
3811 return (error);
3812 }
3813
3814 return (0);
3815 }
3816
3817 int
freebsd32_kldstat(struct thread * td,struct freebsd32_kldstat_args * uap)3818 freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap)
3819 {
3820 struct kld_file_stat *stat;
3821 struct kld_file_stat32 *stat32;
3822 int error, version;
3823
3824 if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
3825 != 0)
3826 return (error);
3827 if (version != sizeof(struct kld_file_stat_1_32) &&
3828 version != sizeof(struct kld_file_stat32))
3829 return (EINVAL);
3830
3831 stat = malloc(sizeof(*stat), M_TEMP, M_WAITOK | M_ZERO);
3832 stat32 = malloc(sizeof(*stat32), M_TEMP, M_WAITOK | M_ZERO);
3833 error = kern_kldstat(td, uap->fileid, stat);
3834 if (error == 0) {
3835 bcopy(&stat->name[0], &stat32->name[0], sizeof(stat->name));
3836 CP(*stat, *stat32, refs);
3837 CP(*stat, *stat32, id);
3838 PTROUT_CP(*stat, *stat32, address);
3839 CP(*stat, *stat32, size);
3840 bcopy(&stat->pathname[0], &stat32->pathname[0],
3841 sizeof(stat->pathname));
3842 stat32->version = version;
3843 error = copyout(stat32, uap->stat, version);
3844 }
3845 free(stat, M_TEMP);
3846 free(stat32, M_TEMP);
3847 return (error);
3848 }
3849
3850 int
freebsd32_posix_fallocate(struct thread * td,struct freebsd32_posix_fallocate_args * uap)3851 freebsd32_posix_fallocate(struct thread *td,
3852 struct freebsd32_posix_fallocate_args *uap)
3853 {
3854 int error;
3855
3856 error = kern_posix_fallocate(td, uap->fd,
3857 PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len));
3858 return (kern_posix_error(td, error));
3859 }
3860
3861 int
freebsd32_posix_fadvise(struct thread * td,struct freebsd32_posix_fadvise_args * uap)3862 freebsd32_posix_fadvise(struct thread *td,
3863 struct freebsd32_posix_fadvise_args *uap)
3864 {
3865 int error;
3866
3867 error = kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset),
3868 PAIR32TO64(off_t, uap->len), uap->advice);
3869 return (kern_posix_error(td, error));
3870 }
3871
3872 int
convert_sigevent32(struct sigevent32 * sig32,struct sigevent * sig)3873 convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig)
3874 {
3875
3876 CP(*sig32, *sig, sigev_notify);
3877 switch (sig->sigev_notify) {
3878 case SIGEV_NONE:
3879 break;
3880 case SIGEV_THREAD_ID:
3881 CP(*sig32, *sig, sigev_notify_thread_id);
3882 /* FALLTHROUGH */
3883 case SIGEV_SIGNAL:
3884 CP(*sig32, *sig, sigev_signo);
3885 PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
3886 break;
3887 case SIGEV_KEVENT:
3888 CP(*sig32, *sig, sigev_notify_kqueue);
3889 CP(*sig32, *sig, sigev_notify_kevent_flags);
3890 PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
3891 break;
3892 default:
3893 return (EINVAL);
3894 }
3895 return (0);
3896 }
3897
3898 int
freebsd32_procctl(struct thread * td,struct freebsd32_procctl_args * uap)3899 freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap)
3900 {
3901 void *data;
3902 union {
3903 struct procctl_reaper_status rs;
3904 struct procctl_reaper_pids rp;
3905 struct procctl_reaper_kill rk;
3906 } x;
3907 union {
3908 struct procctl_reaper_pids32 rp;
3909 } x32;
3910 int error, error1, flags, signum;
3911
3912 if (uap->com >= PROC_PROCCTL_MD_MIN)
3913 return (cpu_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id),
3914 uap->com, PTRIN(uap->data)));
3915
3916 switch (uap->com) {
3917 case PROC_ASLR_CTL:
3918 case PROC_PROTMAX_CTL:
3919 case PROC_SPROTECT:
3920 case PROC_STACKGAP_CTL:
3921 case PROC_TRACE_CTL:
3922 case PROC_TRAPCAP_CTL:
3923 case PROC_NO_NEW_PRIVS_CTL:
3924 case PROC_WXMAP_CTL:
3925 case PROC_LOGSIGEXIT_CTL:
3926 error = copyin(PTRIN(uap->data), &flags, sizeof(flags));
3927 if (error != 0)
3928 return (error);
3929 data = &flags;
3930 break;
3931 case PROC_REAP_ACQUIRE:
3932 case PROC_REAP_RELEASE:
3933 if (uap->data != NULL)
3934 return (EINVAL);
3935 data = NULL;
3936 break;
3937 case PROC_REAP_STATUS:
3938 data = &x.rs;
3939 break;
3940 case PROC_REAP_GETPIDS:
3941 error = copyin(uap->data, &x32.rp, sizeof(x32.rp));
3942 if (error != 0)
3943 return (error);
3944 CP(x32.rp, x.rp, rp_count);
3945 PTRIN_CP(x32.rp, x.rp, rp_pids);
3946 data = &x.rp;
3947 break;
3948 case PROC_REAP_KILL:
3949 error = copyin(uap->data, &x.rk, sizeof(x.rk));
3950 if (error != 0)
3951 return (error);
3952 data = &x.rk;
3953 break;
3954 case PROC_ASLR_STATUS:
3955 case PROC_PROTMAX_STATUS:
3956 case PROC_STACKGAP_STATUS:
3957 case PROC_TRACE_STATUS:
3958 case PROC_TRAPCAP_STATUS:
3959 case PROC_NO_NEW_PRIVS_STATUS:
3960 case PROC_WXMAP_STATUS:
3961 case PROC_LOGSIGEXIT_STATUS:
3962 data = &flags;
3963 break;
3964 case PROC_PDEATHSIG_CTL:
3965 error = copyin(uap->data, &signum, sizeof(signum));
3966 if (error != 0)
3967 return (error);
3968 data = &signum;
3969 break;
3970 case PROC_PDEATHSIG_STATUS:
3971 data = &signum;
3972 break;
3973 default:
3974 return (EINVAL);
3975 }
3976 error = kern_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id),
3977 uap->com, data);
3978 switch (uap->com) {
3979 case PROC_REAP_STATUS:
3980 if (error == 0)
3981 error = copyout(&x.rs, uap->data, sizeof(x.rs));
3982 break;
3983 case PROC_REAP_KILL:
3984 error1 = copyout(&x.rk, uap->data, sizeof(x.rk));
3985 if (error == 0)
3986 error = error1;
3987 break;
3988 case PROC_ASLR_STATUS:
3989 case PROC_PROTMAX_STATUS:
3990 case PROC_STACKGAP_STATUS:
3991 case PROC_TRACE_STATUS:
3992 case PROC_TRAPCAP_STATUS:
3993 case PROC_NO_NEW_PRIVS_STATUS:
3994 case PROC_WXMAP_STATUS:
3995 case PROC_LOGSIGEXIT_STATUS:
3996 if (error == 0)
3997 error = copyout(&flags, uap->data, sizeof(flags));
3998 break;
3999 case PROC_PDEATHSIG_STATUS:
4000 if (error == 0)
4001 error = copyout(&signum, uap->data, sizeof(signum));
4002 break;
4003 }
4004 return (error);
4005 }
4006
4007 int
freebsd32_fcntl(struct thread * td,struct freebsd32_fcntl_args * uap)4008 freebsd32_fcntl(struct thread *td, struct freebsd32_fcntl_args *uap)
4009 {
4010 intptr_t tmp;
4011
4012 switch (uap->cmd) {
4013 /*
4014 * Do unsigned conversion for arg when operation
4015 * interprets it as flags or pointer.
4016 */
4017 case F_SETLK_REMOTE:
4018 case F_SETLKW:
4019 case F_SETLK:
4020 case F_GETLK:
4021 case F_SETFD:
4022 case F_SETFL:
4023 case F_OGETLK:
4024 case F_OSETLK:
4025 case F_OSETLKW:
4026 case F_KINFO:
4027 tmp = (unsigned int)(uap->arg);
4028 break;
4029 default:
4030 tmp = uap->arg;
4031 break;
4032 }
4033 return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp));
4034 }
4035
4036 int
freebsd32_ppoll(struct thread * td,struct freebsd32_ppoll_args * uap)4037 freebsd32_ppoll(struct thread *td, struct freebsd32_ppoll_args *uap)
4038 {
4039 struct timespec32 ts32;
4040 struct timespec ts, *tsp;
4041 sigset_t set, *ssp;
4042 int error;
4043
4044 if (uap->ts != NULL) {
4045 error = copyin(uap->ts, &ts32, sizeof(ts32));
4046 if (error != 0)
4047 return (error);
4048 CP(ts32, ts, tv_sec);
4049 CP(ts32, ts, tv_nsec);
4050 tsp = &ts;
4051 } else
4052 tsp = NULL;
4053 if (uap->set != NULL) {
4054 error = copyin(uap->set, &set, sizeof(set));
4055 if (error != 0)
4056 return (error);
4057 ssp = &set;
4058 } else
4059 ssp = NULL;
4060
4061 return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
4062 }
4063
4064 int
freebsd32_sched_rr_get_interval(struct thread * td,struct freebsd32_sched_rr_get_interval_args * uap)4065 freebsd32_sched_rr_get_interval(struct thread *td,
4066 struct freebsd32_sched_rr_get_interval_args *uap)
4067 {
4068 struct timespec ts;
4069 struct timespec32 ts32;
4070 int error;
4071
4072 error = kern_sched_rr_get_interval(td, uap->pid, &ts);
4073 if (error == 0) {
4074 CP(ts, ts32, tv_sec);
4075 CP(ts, ts32, tv_nsec);
4076 error = copyout(&ts32, uap->interval, sizeof(ts32));
4077 }
4078 return (error);
4079 }
4080
4081 static void
timex_to_32(struct timex32 * dst,struct timex * src)4082 timex_to_32(struct timex32 *dst, struct timex *src)
4083 {
4084 CP(*src, *dst, modes);
4085 CP(*src, *dst, offset);
4086 CP(*src, *dst, freq);
4087 CP(*src, *dst, maxerror);
4088 CP(*src, *dst, esterror);
4089 CP(*src, *dst, status);
4090 CP(*src, *dst, constant);
4091 CP(*src, *dst, precision);
4092 CP(*src, *dst, tolerance);
4093 CP(*src, *dst, ppsfreq);
4094 CP(*src, *dst, jitter);
4095 CP(*src, *dst, shift);
4096 CP(*src, *dst, stabil);
4097 CP(*src, *dst, jitcnt);
4098 CP(*src, *dst, calcnt);
4099 CP(*src, *dst, errcnt);
4100 CP(*src, *dst, stbcnt);
4101 }
4102
4103 static void
timex_from_32(struct timex * dst,struct timex32 * src)4104 timex_from_32(struct timex *dst, struct timex32 *src)
4105 {
4106 CP(*src, *dst, modes);
4107 CP(*src, *dst, offset);
4108 CP(*src, *dst, freq);
4109 CP(*src, *dst, maxerror);
4110 CP(*src, *dst, esterror);
4111 CP(*src, *dst, status);
4112 CP(*src, *dst, constant);
4113 CP(*src, *dst, precision);
4114 CP(*src, *dst, tolerance);
4115 CP(*src, *dst, ppsfreq);
4116 CP(*src, *dst, jitter);
4117 CP(*src, *dst, shift);
4118 CP(*src, *dst, stabil);
4119 CP(*src, *dst, jitcnt);
4120 CP(*src, *dst, calcnt);
4121 CP(*src, *dst, errcnt);
4122 CP(*src, *dst, stbcnt);
4123 }
4124
4125 int
freebsd32_ntp_adjtime(struct thread * td,struct freebsd32_ntp_adjtime_args * uap)4126 freebsd32_ntp_adjtime(struct thread *td, struct freebsd32_ntp_adjtime_args *uap)
4127 {
4128 struct timex tx;
4129 struct timex32 tx32;
4130 int error, retval;
4131
4132 error = copyin(uap->tp, &tx32, sizeof(tx32));
4133 if (error == 0) {
4134 timex_from_32(&tx, &tx32);
4135 error = kern_ntp_adjtime(td, &tx, &retval);
4136 if (error == 0) {
4137 timex_to_32(&tx32, &tx);
4138 error = copyout(&tx32, uap->tp, sizeof(tx32));
4139 if (error == 0)
4140 td->td_retval[0] = retval;
4141 }
4142 }
4143 return (error);
4144 }
4145
4146 #ifdef FFCLOCK
4147 extern struct mtx ffclock_mtx;
4148 extern struct ffclock_estimate ffclock_estimate;
4149 extern int8_t ffclock_updated;
4150
4151 int
freebsd32_ffclock_setestimate(struct thread * td,struct freebsd32_ffclock_setestimate_args * uap)4152 freebsd32_ffclock_setestimate(struct thread *td,
4153 struct freebsd32_ffclock_setestimate_args *uap)
4154 {
4155 struct ffclock_estimate cest;
4156 struct ffclock_estimate32 cest32;
4157 int error;
4158
4159 /* Reuse of PRIV_CLOCK_SETTIME. */
4160 if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0)
4161 return (error);
4162
4163 if ((error = copyin(uap->cest, &cest32,
4164 sizeof(struct ffclock_estimate32))) != 0)
4165 return (error);
4166
4167 CP(cest.update_time, cest32.update_time, sec);
4168 memcpy(&cest.update_time.frac, &cest32.update_time.frac, sizeof(uint64_t));
4169 CP(cest, cest32, update_ffcount);
4170 CP(cest, cest32, leapsec_next);
4171 CP(cest, cest32, period);
4172 CP(cest, cest32, errb_abs);
4173 CP(cest, cest32, errb_rate);
4174 CP(cest, cest32, status);
4175 CP(cest, cest32, leapsec_total);
4176 CP(cest, cest32, leapsec);
4177
4178 mtx_lock(&ffclock_mtx);
4179 memcpy(&ffclock_estimate, &cest, sizeof(struct ffclock_estimate));
4180 ffclock_updated++;
4181 mtx_unlock(&ffclock_mtx);
4182 return (error);
4183 }
4184
4185 int
freebsd32_ffclock_getestimate(struct thread * td,struct freebsd32_ffclock_getestimate_args * uap)4186 freebsd32_ffclock_getestimate(struct thread *td,
4187 struct freebsd32_ffclock_getestimate_args *uap)
4188 {
4189 struct ffclock_estimate cest;
4190 struct ffclock_estimate32 cest32;
4191 int error;
4192
4193 mtx_lock(&ffclock_mtx);
4194 memcpy(&cest, &ffclock_estimate, sizeof(struct ffclock_estimate));
4195 mtx_unlock(&ffclock_mtx);
4196
4197 CP(cest32.update_time, cest.update_time, sec);
4198 memcpy(&cest32.update_time.frac, &cest.update_time.frac, sizeof(uint64_t));
4199 CP(cest32, cest, update_ffcount);
4200 CP(cest32, cest, leapsec_next);
4201 CP(cest32, cest, period);
4202 CP(cest32, cest, errb_abs);
4203 CP(cest32, cest, errb_rate);
4204 CP(cest32, cest, status);
4205 CP(cest32, cest, leapsec_total);
4206 CP(cest32, cest, leapsec);
4207
4208 error = copyout(&cest32, uap->cest, sizeof(struct ffclock_estimate32));
4209 return (error);
4210 }
4211 #else /* !FFCLOCK */
4212 int
freebsd32_ffclock_setestimate(struct thread * td,struct freebsd32_ffclock_setestimate_args * uap)4213 freebsd32_ffclock_setestimate(struct thread *td,
4214 struct freebsd32_ffclock_setestimate_args *uap)
4215 {
4216 return (ENOSYS);
4217 }
4218
4219 int
freebsd32_ffclock_getestimate(struct thread * td,struct freebsd32_ffclock_getestimate_args * uap)4220 freebsd32_ffclock_getestimate(struct thread *td,
4221 struct freebsd32_ffclock_getestimate_args *uap)
4222 {
4223 return (ENOSYS);
4224 }
4225 #endif /* FFCLOCK */
4226
4227 #ifdef COMPAT_43
4228 int
ofreebsd32_sethostid(struct thread * td,struct ofreebsd32_sethostid_args * uap)4229 ofreebsd32_sethostid(struct thread *td, struct ofreebsd32_sethostid_args *uap)
4230 {
4231 int name[] = { CTL_KERN, KERN_HOSTID };
4232 long hostid;
4233
4234 hostid = uap->hostid;
4235 return (kernel_sysctl(td, name, nitems(name), NULL, NULL, &hostid,
4236 sizeof(hostid), NULL, 0));
4237 }
4238 #endif
4239
4240 int
freebsd32_setcred(struct thread * td,struct freebsd32_setcred_args * uap)4241 freebsd32_setcred(struct thread *td, struct freebsd32_setcred_args *uap)
4242 {
4243 /* Last argument is 'is_32bit'. */
4244 return (user_setcred(td, uap->flags, uap->wcred, uap->size, true));
4245 }
4246