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