xref: /freebsd/sys/compat/freebsd32/freebsd32_misc.c (revision ee609560ad2a5fa7cacf06a3879987e118588625)
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 = &delta;
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(&param, sizeof(struct thr_param));
3293 	bzero(&param32, sizeof(struct thr_param32));
3294 	error = copyin(uap->param, &param32, 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, &param));
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