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