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