1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2017 Dell EMC 5 * Copyright (c) 2000 David O'Brien 6 * Copyright (c) 1995-1996 Søren Schmidt 7 * Copyright (c) 1996 Peter Wemm 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer 15 * in this position and unchanged. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include "opt_capsicum.h" 38 #include "opt_compat.h" 39 #include "opt_gzio.h" 40 41 #include <sys/param.h> 42 #include <sys/capsicum.h> 43 #include <sys/exec.h> 44 #include <sys/fcntl.h> 45 #include <sys/gzio.h> 46 #include <sys/imgact.h> 47 #include <sys/imgact_elf.h> 48 #include <sys/jail.h> 49 #include <sys/kernel.h> 50 #include <sys/lock.h> 51 #include <sys/malloc.h> 52 #include <sys/mount.h> 53 #include <sys/mman.h> 54 #include <sys/namei.h> 55 #include <sys/pioctl.h> 56 #include <sys/proc.h> 57 #include <sys/procfs.h> 58 #include <sys/ptrace.h> 59 #include <sys/racct.h> 60 #include <sys/resourcevar.h> 61 #include <sys/rwlock.h> 62 #include <sys/sbuf.h> 63 #include <sys/sf_buf.h> 64 #include <sys/smp.h> 65 #include <sys/systm.h> 66 #include <sys/signalvar.h> 67 #include <sys/stat.h> 68 #include <sys/sx.h> 69 #include <sys/syscall.h> 70 #include <sys/sysctl.h> 71 #include <sys/sysent.h> 72 #include <sys/vnode.h> 73 #include <sys/syslog.h> 74 #include <sys/eventhandler.h> 75 #include <sys/user.h> 76 77 #include <vm/vm.h> 78 #include <vm/vm_kern.h> 79 #include <vm/vm_param.h> 80 #include <vm/pmap.h> 81 #include <vm/vm_map.h> 82 #include <vm/vm_object.h> 83 #include <vm/vm_extern.h> 84 85 #include <machine/elf.h> 86 #include <machine/md_var.h> 87 88 #define ELF_NOTE_ROUNDSIZE 4 89 #define OLD_EI_BRAND 8 90 91 static int __elfN(check_header)(const Elf_Ehdr *hdr); 92 static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp, 93 const char *interp, int interp_name_len, int32_t *osrel); 94 static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr, 95 u_long *entry, size_t pagesize); 96 static int __elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset, 97 caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot, 98 size_t pagesize); 99 static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp); 100 static boolean_t __elfN(freebsd_trans_osrel)(const Elf_Note *note, 101 int32_t *osrel); 102 static boolean_t kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel); 103 static boolean_t __elfN(check_note)(struct image_params *imgp, 104 Elf_Brandnote *checknote, int32_t *osrel); 105 static vm_prot_t __elfN(trans_prot)(Elf_Word); 106 static Elf_Word __elfN(untrans_prot)(vm_prot_t); 107 108 SYSCTL_NODE(_kern, OID_AUTO, __CONCAT(elf, __ELF_WORD_SIZE), CTLFLAG_RW, 0, 109 ""); 110 111 #define CORE_BUF_SIZE (16 * 1024) 112 113 int __elfN(fallback_brand) = -1; 114 SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, 115 fallback_brand, CTLFLAG_RWTUN, &__elfN(fallback_brand), 0, 116 __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) " brand of last resort"); 117 118 static int elf_legacy_coredump = 0; 119 SYSCTL_INT(_debug, OID_AUTO, __elfN(legacy_coredump), CTLFLAG_RW, 120 &elf_legacy_coredump, 0, 121 "include all and only RW pages in core dumps"); 122 123 int __elfN(nxstack) = 124 #if defined(__amd64__) || defined(__powerpc64__) /* both 64 and 32 bit */ || \ 125 (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__) 126 1; 127 #else 128 0; 129 #endif 130 SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, 131 nxstack, CTLFLAG_RW, &__elfN(nxstack), 0, 132 __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) ": enable non-executable stack"); 133 134 #if __ELF_WORD_SIZE == 32 135 #if defined(__amd64__) 136 int i386_read_exec = 0; 137 SYSCTL_INT(_kern_elf32, OID_AUTO, read_exec, CTLFLAG_RW, &i386_read_exec, 0, 138 "enable execution from readable segments"); 139 #endif 140 #endif 141 142 static Elf_Brandinfo *elf_brand_list[MAX_BRANDS]; 143 144 #define trunc_page_ps(va, ps) rounddown2(va, ps) 145 #define round_page_ps(va, ps) roundup2(va, ps) 146 #define aligned(a, t) (trunc_page_ps((u_long)(a), sizeof(t)) == (u_long)(a)) 147 148 static const char FREEBSD_ABI_VENDOR[] = "FreeBSD"; 149 150 Elf_Brandnote __elfN(freebsd_brandnote) = { 151 .hdr.n_namesz = sizeof(FREEBSD_ABI_VENDOR), 152 .hdr.n_descsz = sizeof(int32_t), 153 .hdr.n_type = NT_FREEBSD_ABI_TAG, 154 .vendor = FREEBSD_ABI_VENDOR, 155 .flags = BN_TRANSLATE_OSREL, 156 .trans_osrel = __elfN(freebsd_trans_osrel) 157 }; 158 159 static boolean_t 160 __elfN(freebsd_trans_osrel)(const Elf_Note *note, int32_t *osrel) 161 { 162 uintptr_t p; 163 164 p = (uintptr_t)(note + 1); 165 p += roundup2(note->n_namesz, ELF_NOTE_ROUNDSIZE); 166 *osrel = *(const int32_t *)(p); 167 168 return (TRUE); 169 } 170 171 static const char GNU_ABI_VENDOR[] = "GNU"; 172 static int GNU_KFREEBSD_ABI_DESC = 3; 173 174 Elf_Brandnote __elfN(kfreebsd_brandnote) = { 175 .hdr.n_namesz = sizeof(GNU_ABI_VENDOR), 176 .hdr.n_descsz = 16, /* XXX at least 16 */ 177 .hdr.n_type = 1, 178 .vendor = GNU_ABI_VENDOR, 179 .flags = BN_TRANSLATE_OSREL, 180 .trans_osrel = kfreebsd_trans_osrel 181 }; 182 183 static boolean_t 184 kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel) 185 { 186 const Elf32_Word *desc; 187 uintptr_t p; 188 189 p = (uintptr_t)(note + 1); 190 p += roundup2(note->n_namesz, ELF_NOTE_ROUNDSIZE); 191 192 desc = (const Elf32_Word *)p; 193 if (desc[0] != GNU_KFREEBSD_ABI_DESC) 194 return (FALSE); 195 196 /* 197 * Debian GNU/kFreeBSD embed the earliest compatible kernel version 198 * (__FreeBSD_version: <major><two digit minor>Rxx) in the LSB way. 199 */ 200 *osrel = desc[1] * 100000 + desc[2] * 1000 + desc[3]; 201 202 return (TRUE); 203 } 204 205 int 206 __elfN(insert_brand_entry)(Elf_Brandinfo *entry) 207 { 208 int i; 209 210 for (i = 0; i < MAX_BRANDS; i++) { 211 if (elf_brand_list[i] == NULL) { 212 elf_brand_list[i] = entry; 213 break; 214 } 215 } 216 if (i == MAX_BRANDS) { 217 printf("WARNING: %s: could not insert brandinfo entry: %p\n", 218 __func__, entry); 219 return (-1); 220 } 221 return (0); 222 } 223 224 int 225 __elfN(remove_brand_entry)(Elf_Brandinfo *entry) 226 { 227 int i; 228 229 for (i = 0; i < MAX_BRANDS; i++) { 230 if (elf_brand_list[i] == entry) { 231 elf_brand_list[i] = NULL; 232 break; 233 } 234 } 235 if (i == MAX_BRANDS) 236 return (-1); 237 return (0); 238 } 239 240 int 241 __elfN(brand_inuse)(Elf_Brandinfo *entry) 242 { 243 struct proc *p; 244 int rval = FALSE; 245 246 sx_slock(&allproc_lock); 247 FOREACH_PROC_IN_SYSTEM(p) { 248 if (p->p_sysent == entry->sysvec) { 249 rval = TRUE; 250 break; 251 } 252 } 253 sx_sunlock(&allproc_lock); 254 255 return (rval); 256 } 257 258 static Elf_Brandinfo * 259 __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, 260 int interp_name_len, int32_t *osrel) 261 { 262 const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header; 263 Elf_Brandinfo *bi, *bi_m; 264 boolean_t ret; 265 int i; 266 267 /* 268 * We support four types of branding -- (1) the ELF EI_OSABI field 269 * that SCO added to the ELF spec, (2) FreeBSD 3.x's traditional string 270 * branding w/in the ELF header, (3) path of the `interp_path' 271 * field, and (4) the ".note.ABI-tag" ELF section. 272 */ 273 274 /* Look for an ".note.ABI-tag" ELF section */ 275 bi_m = NULL; 276 for (i = 0; i < MAX_BRANDS; i++) { 277 bi = elf_brand_list[i]; 278 if (bi == NULL) 279 continue; 280 if (interp != NULL && (bi->flags & BI_BRAND_ONLY_STATIC) != 0) 281 continue; 282 if (hdr->e_machine == bi->machine && (bi->flags & 283 (BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) { 284 ret = __elfN(check_note)(imgp, bi->brand_note, osrel); 285 /* Give brand a chance to veto check_note's guess */ 286 if (ret && bi->header_supported) 287 ret = bi->header_supported(imgp); 288 /* 289 * If note checker claimed the binary, but the 290 * interpreter path in the image does not 291 * match default one for the brand, try to 292 * search for other brands with the same 293 * interpreter. Either there is better brand 294 * with the right interpreter, or, failing 295 * this, we return first brand which accepted 296 * our note and, optionally, header. 297 */ 298 if (ret && bi_m == NULL && interp != NULL && 299 (bi->interp_path == NULL || 300 (strlen(bi->interp_path) + 1 != interp_name_len || 301 strncmp(interp, bi->interp_path, interp_name_len) 302 != 0))) { 303 bi_m = bi; 304 ret = 0; 305 } 306 if (ret) 307 return (bi); 308 } 309 } 310 if (bi_m != NULL) 311 return (bi_m); 312 313 /* If the executable has a brand, search for it in the brand list. */ 314 for (i = 0; i < MAX_BRANDS; i++) { 315 bi = elf_brand_list[i]; 316 if (bi == NULL || (bi->flags & BI_BRAND_NOTE_MANDATORY) != 0 || 317 (interp != NULL && (bi->flags & BI_BRAND_ONLY_STATIC) != 0)) 318 continue; 319 if (hdr->e_machine == bi->machine && 320 (hdr->e_ident[EI_OSABI] == bi->brand || 321 (bi->compat_3_brand != NULL && 322 strcmp((const char *)&hdr->e_ident[OLD_EI_BRAND], 323 bi->compat_3_brand) == 0))) { 324 /* Looks good, but give brand a chance to veto */ 325 if (!bi->header_supported || 326 bi->header_supported(imgp)) { 327 /* 328 * Again, prefer strictly matching 329 * interpreter path. 330 */ 331 if (interp_name_len == 0 && 332 bi->interp_path == NULL) 333 return (bi); 334 if (bi->interp_path != NULL && 335 strlen(bi->interp_path) + 1 == 336 interp_name_len && strncmp(interp, 337 bi->interp_path, interp_name_len) == 0) 338 return (bi); 339 if (bi_m == NULL) 340 bi_m = bi; 341 } 342 } 343 } 344 if (bi_m != NULL) 345 return (bi_m); 346 347 /* No known brand, see if the header is recognized by any brand */ 348 for (i = 0; i < MAX_BRANDS; i++) { 349 bi = elf_brand_list[i]; 350 if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY || 351 bi->header_supported == NULL) 352 continue; 353 if (hdr->e_machine == bi->machine) { 354 ret = bi->header_supported(imgp); 355 if (ret) 356 return (bi); 357 } 358 } 359 360 /* Lacking a known brand, search for a recognized interpreter. */ 361 if (interp != NULL) { 362 for (i = 0; i < MAX_BRANDS; i++) { 363 bi = elf_brand_list[i]; 364 if (bi == NULL || (bi->flags & 365 (BI_BRAND_NOTE_MANDATORY | BI_BRAND_ONLY_STATIC)) 366 != 0) 367 continue; 368 if (hdr->e_machine == bi->machine && 369 bi->interp_path != NULL && 370 /* ELF image p_filesz includes terminating zero */ 371 strlen(bi->interp_path) + 1 == interp_name_len && 372 strncmp(interp, bi->interp_path, interp_name_len) 373 == 0) 374 return (bi); 375 } 376 } 377 378 /* Lacking a recognized interpreter, try the default brand */ 379 for (i = 0; i < MAX_BRANDS; i++) { 380 bi = elf_brand_list[i]; 381 if (bi == NULL || (bi->flags & BI_BRAND_NOTE_MANDATORY) != 0 || 382 (interp != NULL && (bi->flags & BI_BRAND_ONLY_STATIC) != 0)) 383 continue; 384 if (hdr->e_machine == bi->machine && 385 __elfN(fallback_brand) == bi->brand) 386 return (bi); 387 } 388 return (NULL); 389 } 390 391 static int 392 __elfN(check_header)(const Elf_Ehdr *hdr) 393 { 394 Elf_Brandinfo *bi; 395 int i; 396 397 if (!IS_ELF(*hdr) || 398 hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 399 hdr->e_ident[EI_DATA] != ELF_TARG_DATA || 400 hdr->e_ident[EI_VERSION] != EV_CURRENT || 401 hdr->e_phentsize != sizeof(Elf_Phdr) || 402 hdr->e_version != ELF_TARG_VER) 403 return (ENOEXEC); 404 405 /* 406 * Make sure we have at least one brand for this machine. 407 */ 408 409 for (i = 0; i < MAX_BRANDS; i++) { 410 bi = elf_brand_list[i]; 411 if (bi != NULL && bi->machine == hdr->e_machine) 412 break; 413 } 414 if (i == MAX_BRANDS) 415 return (ENOEXEC); 416 417 return (0); 418 } 419 420 static int 421 __elfN(map_partial)(vm_map_t map, vm_object_t object, vm_ooffset_t offset, 422 vm_offset_t start, vm_offset_t end, vm_prot_t prot) 423 { 424 struct sf_buf *sf; 425 int error; 426 vm_offset_t off; 427 428 /* 429 * Create the page if it doesn't exist yet. Ignore errors. 430 */ 431 vm_map_fixed(map, NULL, 0, trunc_page(start), round_page(end) - 432 trunc_page(start), VM_PROT_ALL, VM_PROT_ALL, MAP_CHECK_EXCL); 433 434 /* 435 * Find the page from the underlying object. 436 */ 437 if (object != NULL) { 438 sf = vm_imgact_map_page(object, offset); 439 if (sf == NULL) 440 return (KERN_FAILURE); 441 off = offset - trunc_page(offset); 442 error = copyout((caddr_t)sf_buf_kva(sf) + off, (caddr_t)start, 443 end - start); 444 vm_imgact_unmap_page(sf); 445 if (error != 0) 446 return (KERN_FAILURE); 447 } 448 449 return (KERN_SUCCESS); 450 } 451 452 static int 453 __elfN(map_insert)(struct image_params *imgp, vm_map_t map, vm_object_t object, 454 vm_ooffset_t offset, vm_offset_t start, vm_offset_t end, vm_prot_t prot, 455 int cow) 456 { 457 struct sf_buf *sf; 458 vm_offset_t off; 459 vm_size_t sz; 460 int error, locked, rv; 461 462 if (start != trunc_page(start)) { 463 rv = __elfN(map_partial)(map, object, offset, start, 464 round_page(start), prot); 465 if (rv != KERN_SUCCESS) 466 return (rv); 467 offset += round_page(start) - start; 468 start = round_page(start); 469 } 470 if (end != round_page(end)) { 471 rv = __elfN(map_partial)(map, object, offset + 472 trunc_page(end) - start, trunc_page(end), end, prot); 473 if (rv != KERN_SUCCESS) 474 return (rv); 475 end = trunc_page(end); 476 } 477 if (start >= end) 478 return (KERN_SUCCESS); 479 if ((offset & PAGE_MASK) != 0) { 480 /* 481 * The mapping is not page aligned. This means that we have 482 * to copy the data. 483 */ 484 rv = vm_map_fixed(map, NULL, 0, start, end - start, 485 prot | VM_PROT_WRITE, VM_PROT_ALL, MAP_CHECK_EXCL); 486 if (rv != KERN_SUCCESS) 487 return (rv); 488 if (object == NULL) 489 return (KERN_SUCCESS); 490 for (; start < end; start += sz) { 491 sf = vm_imgact_map_page(object, offset); 492 if (sf == NULL) 493 return (KERN_FAILURE); 494 off = offset - trunc_page(offset); 495 sz = end - start; 496 if (sz > PAGE_SIZE - off) 497 sz = PAGE_SIZE - off; 498 error = copyout((caddr_t)sf_buf_kva(sf) + off, 499 (caddr_t)start, sz); 500 vm_imgact_unmap_page(sf); 501 if (error != 0) 502 return (KERN_FAILURE); 503 offset += sz; 504 } 505 } else { 506 vm_object_reference(object); 507 rv = vm_map_fixed(map, object, offset, start, end - start, 508 prot, VM_PROT_ALL, cow | MAP_CHECK_EXCL); 509 if (rv != KERN_SUCCESS) { 510 locked = VOP_ISLOCKED(imgp->vp); 511 VOP_UNLOCK(imgp->vp, 0); 512 vm_object_deallocate(object); 513 vn_lock(imgp->vp, locked | LK_RETRY); 514 return (rv); 515 } 516 } 517 return (KERN_SUCCESS); 518 } 519 520 static int 521 __elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset, 522 caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot, 523 size_t pagesize) 524 { 525 struct sf_buf *sf; 526 size_t map_len; 527 vm_map_t map; 528 vm_object_t object; 529 vm_offset_t off, map_addr; 530 int error, rv, cow; 531 size_t copy_len; 532 vm_ooffset_t file_addr; 533 534 /* 535 * It's necessary to fail if the filsz + offset taken from the 536 * header is greater than the actual file pager object's size. 537 * If we were to allow this, then the vm_map_find() below would 538 * walk right off the end of the file object and into the ether. 539 * 540 * While I'm here, might as well check for something else that 541 * is invalid: filsz cannot be greater than memsz. 542 */ 543 if ((filsz != 0 && (off_t)filsz + offset > imgp->attr->va_size) || 544 filsz > memsz) { 545 uprintf("elf_load_section: truncated ELF file\n"); 546 return (ENOEXEC); 547 } 548 549 object = imgp->object; 550 map = &imgp->proc->p_vmspace->vm_map; 551 map_addr = trunc_page_ps((vm_offset_t)vmaddr, pagesize); 552 file_addr = trunc_page_ps(offset, pagesize); 553 554 /* 555 * We have two choices. We can either clear the data in the last page 556 * of an oversized mapping, or we can start the anon mapping a page 557 * early and copy the initialized data into that first page. We 558 * choose the second. 559 */ 560 if (filsz == 0) 561 map_len = 0; 562 else if (memsz > filsz) 563 map_len = trunc_page_ps(offset + filsz, pagesize) - file_addr; 564 else 565 map_len = round_page_ps(offset + filsz, pagesize) - file_addr; 566 567 if (map_len != 0) { 568 /* cow flags: don't dump readonly sections in core */ 569 cow = MAP_COPY_ON_WRITE | MAP_PREFAULT | 570 (prot & VM_PROT_WRITE ? 0 : MAP_DISABLE_COREDUMP); 571 572 rv = __elfN(map_insert)(imgp, map, 573 object, 574 file_addr, /* file offset */ 575 map_addr, /* virtual start */ 576 map_addr + map_len,/* virtual end */ 577 prot, 578 cow); 579 if (rv != KERN_SUCCESS) 580 return (EINVAL); 581 582 /* we can stop now if we've covered it all */ 583 if (memsz == filsz) 584 return (0); 585 } 586 587 588 /* 589 * We have to get the remaining bit of the file into the first part 590 * of the oversized map segment. This is normally because the .data 591 * segment in the file is extended to provide bss. It's a neat idea 592 * to try and save a page, but it's a pain in the behind to implement. 593 */ 594 copy_len = filsz == 0 ? 0 : (offset + filsz) - trunc_page_ps(offset + 595 filsz, pagesize); 596 map_addr = trunc_page_ps((vm_offset_t)vmaddr + filsz, pagesize); 597 map_len = round_page_ps((vm_offset_t)vmaddr + memsz, pagesize) - 598 map_addr; 599 600 /* This had damn well better be true! */ 601 if (map_len != 0) { 602 rv = __elfN(map_insert)(imgp, map, NULL, 0, map_addr, 603 map_addr + map_len, prot, 0); 604 if (rv != KERN_SUCCESS) 605 return (EINVAL); 606 } 607 608 if (copy_len != 0) { 609 sf = vm_imgact_map_page(object, offset + filsz); 610 if (sf == NULL) 611 return (EIO); 612 613 /* send the page fragment to user space */ 614 off = trunc_page_ps(offset + filsz, pagesize) - 615 trunc_page(offset + filsz); 616 error = copyout((caddr_t)sf_buf_kva(sf) + off, 617 (caddr_t)map_addr, copy_len); 618 vm_imgact_unmap_page(sf); 619 if (error != 0) 620 return (error); 621 } 622 623 /* 624 * Remove write access to the page if it was only granted by map_insert 625 * to allow copyout. 626 */ 627 if ((prot & VM_PROT_WRITE) == 0) 628 vm_map_protect(map, trunc_page(map_addr), round_page(map_addr + 629 map_len), prot, FALSE); 630 631 return (0); 632 } 633 634 /* 635 * Load the file "file" into memory. It may be either a shared object 636 * or an executable. 637 * 638 * The "addr" reference parameter is in/out. On entry, it specifies 639 * the address where a shared object should be loaded. If the file is 640 * an executable, this value is ignored. On exit, "addr" specifies 641 * where the file was actually loaded. 642 * 643 * The "entry" reference parameter is out only. On exit, it specifies 644 * the entry point for the loaded file. 645 */ 646 static int 647 __elfN(load_file)(struct proc *p, const char *file, u_long *addr, 648 u_long *entry, size_t pagesize) 649 { 650 struct { 651 struct nameidata nd; 652 struct vattr attr; 653 struct image_params image_params; 654 } *tempdata; 655 const Elf_Ehdr *hdr = NULL; 656 const Elf_Phdr *phdr = NULL; 657 struct nameidata *nd; 658 struct vattr *attr; 659 struct image_params *imgp; 660 vm_prot_t prot; 661 u_long rbase; 662 u_long base_addr = 0; 663 int error, i, numsegs; 664 665 #ifdef CAPABILITY_MODE 666 /* 667 * XXXJA: This check can go away once we are sufficiently confident 668 * that the checks in namei() are correct. 669 */ 670 if (IN_CAPABILITY_MODE(curthread)) 671 return (ECAPMODE); 672 #endif 673 674 tempdata = malloc(sizeof(*tempdata), M_TEMP, M_WAITOK); 675 nd = &tempdata->nd; 676 attr = &tempdata->attr; 677 imgp = &tempdata->image_params; 678 679 /* 680 * Initialize part of the common data 681 */ 682 imgp->proc = p; 683 imgp->attr = attr; 684 imgp->firstpage = NULL; 685 imgp->image_header = NULL; 686 imgp->object = NULL; 687 imgp->execlabel = NULL; 688 689 NDINIT(nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_SYSSPACE, file, curthread); 690 if ((error = namei(nd)) != 0) { 691 nd->ni_vp = NULL; 692 goto fail; 693 } 694 NDFREE(nd, NDF_ONLY_PNBUF); 695 imgp->vp = nd->ni_vp; 696 697 /* 698 * Check permissions, modes, uid, etc on the file, and "open" it. 699 */ 700 error = exec_check_permissions(imgp); 701 if (error) 702 goto fail; 703 704 error = exec_map_first_page(imgp); 705 if (error) 706 goto fail; 707 708 /* 709 * Also make certain that the interpreter stays the same, so set 710 * its VV_TEXT flag, too. 711 */ 712 VOP_SET_TEXT(nd->ni_vp); 713 714 imgp->object = nd->ni_vp->v_object; 715 716 hdr = (const Elf_Ehdr *)imgp->image_header; 717 if ((error = __elfN(check_header)(hdr)) != 0) 718 goto fail; 719 if (hdr->e_type == ET_DYN) 720 rbase = *addr; 721 else if (hdr->e_type == ET_EXEC) 722 rbase = 0; 723 else { 724 error = ENOEXEC; 725 goto fail; 726 } 727 728 /* Only support headers that fit within first page for now */ 729 if ((hdr->e_phoff > PAGE_SIZE) || 730 (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) { 731 error = ENOEXEC; 732 goto fail; 733 } 734 735 phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); 736 if (!aligned(phdr, Elf_Addr)) { 737 error = ENOEXEC; 738 goto fail; 739 } 740 741 for (i = 0, numsegs = 0; i < hdr->e_phnum; i++) { 742 if (phdr[i].p_type == PT_LOAD && phdr[i].p_memsz != 0) { 743 /* Loadable segment */ 744 prot = __elfN(trans_prot)(phdr[i].p_flags); 745 error = __elfN(load_section)(imgp, phdr[i].p_offset, 746 (caddr_t)(uintptr_t)phdr[i].p_vaddr + rbase, 747 phdr[i].p_memsz, phdr[i].p_filesz, prot, pagesize); 748 if (error != 0) 749 goto fail; 750 /* 751 * Establish the base address if this is the 752 * first segment. 753 */ 754 if (numsegs == 0) 755 base_addr = trunc_page(phdr[i].p_vaddr + 756 rbase); 757 numsegs++; 758 } 759 } 760 *addr = base_addr; 761 *entry = (unsigned long)hdr->e_entry + rbase; 762 763 fail: 764 if (imgp->firstpage) 765 exec_unmap_first_page(imgp); 766 767 if (nd->ni_vp) 768 vput(nd->ni_vp); 769 770 free(tempdata, M_TEMP); 771 772 return (error); 773 } 774 775 static int 776 __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) 777 { 778 struct thread *td; 779 const Elf_Ehdr *hdr; 780 const Elf_Phdr *phdr; 781 Elf_Auxargs *elf_auxargs; 782 struct vmspace *vmspace; 783 const char *err_str, *newinterp; 784 char *interp, *interp_buf, *path; 785 Elf_Brandinfo *brand_info; 786 struct sysentvec *sv; 787 vm_prot_t prot; 788 u_long text_size, data_size, total_size, text_addr, data_addr; 789 u_long seg_size, seg_addr, addr, baddr, et_dyn_addr, entry, proghdr; 790 int32_t osrel; 791 int error, i, n, interp_name_len, have_interp; 792 793 hdr = (const Elf_Ehdr *)imgp->image_header; 794 795 /* 796 * Do we have a valid ELF header ? 797 * 798 * Only allow ET_EXEC & ET_DYN here, reject ET_DYN later 799 * if particular brand doesn't support it. 800 */ 801 if (__elfN(check_header)(hdr) != 0 || 802 (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN)) 803 return (-1); 804 805 /* 806 * From here on down, we return an errno, not -1, as we've 807 * detected an ELF file. 808 */ 809 810 if ((hdr->e_phoff > PAGE_SIZE) || 811 (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) { 812 /* Only support headers in first page for now */ 813 uprintf("Program headers not in the first page\n"); 814 return (ENOEXEC); 815 } 816 phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); 817 if (!aligned(phdr, Elf_Addr)) { 818 uprintf("Unaligned program headers\n"); 819 return (ENOEXEC); 820 } 821 822 n = error = 0; 823 baddr = 0; 824 osrel = 0; 825 text_size = data_size = total_size = text_addr = data_addr = 0; 826 entry = proghdr = 0; 827 interp_name_len = 0; 828 err_str = newinterp = NULL; 829 interp = interp_buf = NULL; 830 td = curthread; 831 832 for (i = 0; i < hdr->e_phnum; i++) { 833 switch (phdr[i].p_type) { 834 case PT_LOAD: 835 if (n == 0) 836 baddr = phdr[i].p_vaddr; 837 n++; 838 break; 839 case PT_INTERP: 840 /* Path to interpreter */ 841 if (phdr[i].p_filesz > MAXPATHLEN) { 842 uprintf("Invalid PT_INTERP\n"); 843 error = ENOEXEC; 844 goto ret; 845 } 846 if (interp != NULL) { 847 uprintf("Multiple PT_INTERP headers\n"); 848 error = ENOEXEC; 849 goto ret; 850 } 851 interp_name_len = phdr[i].p_filesz; 852 if (phdr[i].p_offset > PAGE_SIZE || 853 interp_name_len > PAGE_SIZE - phdr[i].p_offset) { 854 VOP_UNLOCK(imgp->vp, 0); 855 interp_buf = malloc(interp_name_len + 1, M_TEMP, 856 M_WAITOK); 857 vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); 858 error = vn_rdwr(UIO_READ, imgp->vp, interp_buf, 859 interp_name_len, phdr[i].p_offset, 860 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, 861 NOCRED, NULL, td); 862 if (error != 0) { 863 uprintf("i/o error PT_INTERP\n"); 864 goto ret; 865 } 866 interp_buf[interp_name_len] = '\0'; 867 interp = interp_buf; 868 } else { 869 interp = __DECONST(char *, imgp->image_header) + 870 phdr[i].p_offset; 871 } 872 break; 873 case PT_GNU_STACK: 874 if (__elfN(nxstack)) 875 imgp->stack_prot = 876 __elfN(trans_prot)(phdr[i].p_flags); 877 imgp->stack_sz = phdr[i].p_memsz; 878 break; 879 } 880 } 881 882 brand_info = __elfN(get_brandinfo)(imgp, interp, interp_name_len, 883 &osrel); 884 if (brand_info == NULL) { 885 uprintf("ELF binary type \"%u\" not known.\n", 886 hdr->e_ident[EI_OSABI]); 887 error = ENOEXEC; 888 goto ret; 889 } 890 et_dyn_addr = 0; 891 if (hdr->e_type == ET_DYN) { 892 if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) { 893 uprintf("Cannot execute shared object\n"); 894 error = ENOEXEC; 895 goto ret; 896 } 897 /* 898 * Honour the base load address from the dso if it is 899 * non-zero for some reason. 900 */ 901 if (baddr == 0) 902 et_dyn_addr = ET_DYN_LOAD_ADDR; 903 } 904 sv = brand_info->sysvec; 905 if (interp != NULL && brand_info->interp_newpath != NULL) 906 newinterp = brand_info->interp_newpath; 907 908 /* 909 * Avoid a possible deadlock if the current address space is destroyed 910 * and that address space maps the locked vnode. In the common case, 911 * the locked vnode's v_usecount is decremented but remains greater 912 * than zero. Consequently, the vnode lock is not needed by vrele(). 913 * However, in cases where the vnode lock is external, such as nullfs, 914 * v_usecount may become zero. 915 * 916 * The VV_TEXT flag prevents modifications to the executable while 917 * the vnode is unlocked. 918 */ 919 VOP_UNLOCK(imgp->vp, 0); 920 921 error = exec_new_vmspace(imgp, sv); 922 imgp->proc->p_sysent = sv; 923 924 vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); 925 if (error != 0) 926 goto ret; 927 928 for (i = 0; i < hdr->e_phnum; i++) { 929 switch (phdr[i].p_type) { 930 case PT_LOAD: /* Loadable segment */ 931 if (phdr[i].p_memsz == 0) 932 break; 933 prot = __elfN(trans_prot)(phdr[i].p_flags); 934 error = __elfN(load_section)(imgp, phdr[i].p_offset, 935 (caddr_t)(uintptr_t)phdr[i].p_vaddr + et_dyn_addr, 936 phdr[i].p_memsz, phdr[i].p_filesz, prot, 937 sv->sv_pagesize); 938 if (error != 0) 939 goto ret; 940 941 /* 942 * If this segment contains the program headers, 943 * remember their virtual address for the AT_PHDR 944 * aux entry. Static binaries don't usually include 945 * a PT_PHDR entry. 946 */ 947 if (phdr[i].p_offset == 0 && 948 hdr->e_phoff + hdr->e_phnum * hdr->e_phentsize 949 <= phdr[i].p_filesz) 950 proghdr = phdr[i].p_vaddr + hdr->e_phoff + 951 et_dyn_addr; 952 953 seg_addr = trunc_page(phdr[i].p_vaddr + et_dyn_addr); 954 seg_size = round_page(phdr[i].p_memsz + 955 phdr[i].p_vaddr + et_dyn_addr - seg_addr); 956 957 /* 958 * Make the largest executable segment the official 959 * text segment and all others data. 960 * 961 * Note that obreak() assumes that data_addr + 962 * data_size == end of data load area, and the ELF 963 * file format expects segments to be sorted by 964 * address. If multiple data segments exist, the 965 * last one will be used. 966 */ 967 968 if (phdr[i].p_flags & PF_X && text_size < seg_size) { 969 text_size = seg_size; 970 text_addr = seg_addr; 971 } else { 972 data_size = seg_size; 973 data_addr = seg_addr; 974 } 975 total_size += seg_size; 976 break; 977 case PT_PHDR: /* Program header table info */ 978 proghdr = phdr[i].p_vaddr + et_dyn_addr; 979 break; 980 default: 981 break; 982 } 983 } 984 985 if (data_addr == 0 && data_size == 0) { 986 data_addr = text_addr; 987 data_size = text_size; 988 } 989 990 entry = (u_long)hdr->e_entry + et_dyn_addr; 991 992 /* 993 * Check limits. It should be safe to check the 994 * limits after loading the segments since we do 995 * not actually fault in all the segments pages. 996 */ 997 PROC_LOCK(imgp->proc); 998 if (data_size > lim_cur_proc(imgp->proc, RLIMIT_DATA)) 999 err_str = "Data segment size exceeds process limit"; 1000 else if (text_size > maxtsiz) 1001 err_str = "Text segment size exceeds system limit"; 1002 else if (total_size > lim_cur_proc(imgp->proc, RLIMIT_VMEM)) 1003 err_str = "Total segment size exceeds process limit"; 1004 else if (racct_set(imgp->proc, RACCT_DATA, data_size) != 0) 1005 err_str = "Data segment size exceeds resource limit"; 1006 else if (racct_set(imgp->proc, RACCT_VMEM, total_size) != 0) 1007 err_str = "Total segment size exceeds resource limit"; 1008 if (err_str != NULL) { 1009 PROC_UNLOCK(imgp->proc); 1010 uprintf("%s\n", err_str); 1011 error = ENOMEM; 1012 goto ret; 1013 } 1014 1015 vmspace = imgp->proc->p_vmspace; 1016 vmspace->vm_tsize = text_size >> PAGE_SHIFT; 1017 vmspace->vm_taddr = (caddr_t)(uintptr_t)text_addr; 1018 vmspace->vm_dsize = data_size >> PAGE_SHIFT; 1019 vmspace->vm_daddr = (caddr_t)(uintptr_t)data_addr; 1020 1021 /* 1022 * We load the dynamic linker where a userland call 1023 * to mmap(0, ...) would put it. The rationale behind this 1024 * calculation is that it leaves room for the heap to grow to 1025 * its maximum allowed size. 1026 */ 1027 addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(td, 1028 RLIMIT_DATA)); 1029 PROC_UNLOCK(imgp->proc); 1030 1031 imgp->entry_addr = entry; 1032 1033 if (interp != NULL) { 1034 have_interp = FALSE; 1035 VOP_UNLOCK(imgp->vp, 0); 1036 if (brand_info->emul_path != NULL && 1037 brand_info->emul_path[0] != '\0') { 1038 path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 1039 snprintf(path, MAXPATHLEN, "%s%s", 1040 brand_info->emul_path, interp); 1041 error = __elfN(load_file)(imgp->proc, path, &addr, 1042 &imgp->entry_addr, sv->sv_pagesize); 1043 free(path, M_TEMP); 1044 if (error == 0) 1045 have_interp = TRUE; 1046 } 1047 if (!have_interp && newinterp != NULL && 1048 (brand_info->interp_path == NULL || 1049 strcmp(interp, brand_info->interp_path) == 0)) { 1050 error = __elfN(load_file)(imgp->proc, newinterp, &addr, 1051 &imgp->entry_addr, sv->sv_pagesize); 1052 if (error == 0) 1053 have_interp = TRUE; 1054 } 1055 if (!have_interp) { 1056 error = __elfN(load_file)(imgp->proc, interp, &addr, 1057 &imgp->entry_addr, sv->sv_pagesize); 1058 } 1059 vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); 1060 if (error != 0) { 1061 uprintf("ELF interpreter %s not found, error %d\n", 1062 interp, error); 1063 goto ret; 1064 } 1065 } else 1066 addr = et_dyn_addr; 1067 1068 /* 1069 * Construct auxargs table (used by the fixup routine) 1070 */ 1071 elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_WAITOK); 1072 elf_auxargs->execfd = -1; 1073 elf_auxargs->phdr = proghdr; 1074 elf_auxargs->phent = hdr->e_phentsize; 1075 elf_auxargs->phnum = hdr->e_phnum; 1076 elf_auxargs->pagesz = PAGE_SIZE; 1077 elf_auxargs->base = addr; 1078 elf_auxargs->flags = 0; 1079 elf_auxargs->entry = entry; 1080 elf_auxargs->hdr_eflags = hdr->e_flags; 1081 1082 imgp->auxargs = elf_auxargs; 1083 imgp->interpreted = 0; 1084 imgp->reloc_base = addr; 1085 imgp->proc->p_osrel = osrel; 1086 imgp->proc->p_elf_machine = hdr->e_machine; 1087 imgp->proc->p_elf_flags = hdr->e_flags; 1088 1089 ret: 1090 free(interp_buf, M_TEMP); 1091 return (error); 1092 } 1093 1094 #define suword __CONCAT(suword, __ELF_WORD_SIZE) 1095 1096 int 1097 __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) 1098 { 1099 Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; 1100 Elf_Addr *base; 1101 Elf_Addr *pos; 1102 1103 base = (Elf_Addr *)*stack_base; 1104 pos = base + (imgp->args->argc + imgp->args->envc + 2); 1105 1106 if (args->execfd != -1) 1107 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 1108 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 1109 AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 1110 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 1111 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 1112 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 1113 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 1114 AUXARGS_ENTRY(pos, AT_BASE, args->base); 1115 AUXARGS_ENTRY(pos, AT_EHDRFLAGS, args->hdr_eflags); 1116 if (imgp->execpathp != 0) 1117 AUXARGS_ENTRY(pos, AT_EXECPATH, imgp->execpathp); 1118 AUXARGS_ENTRY(pos, AT_OSRELDATE, 1119 imgp->proc->p_ucred->cr_prison->pr_osreldate); 1120 if (imgp->canary != 0) { 1121 AUXARGS_ENTRY(pos, AT_CANARY, imgp->canary); 1122 AUXARGS_ENTRY(pos, AT_CANARYLEN, imgp->canarylen); 1123 } 1124 AUXARGS_ENTRY(pos, AT_NCPUS, mp_ncpus); 1125 if (imgp->pagesizes != 0) { 1126 AUXARGS_ENTRY(pos, AT_PAGESIZES, imgp->pagesizes); 1127 AUXARGS_ENTRY(pos, AT_PAGESIZESLEN, imgp->pagesizeslen); 1128 } 1129 if (imgp->sysent->sv_timekeep_base != 0) { 1130 AUXARGS_ENTRY(pos, AT_TIMEKEEP, 1131 imgp->sysent->sv_timekeep_base); 1132 } 1133 AUXARGS_ENTRY(pos, AT_STACKPROT, imgp->sysent->sv_shared_page_obj 1134 != NULL && imgp->stack_prot != 0 ? imgp->stack_prot : 1135 imgp->sysent->sv_stackprot); 1136 if (imgp->sysent->sv_hwcap != NULL) 1137 AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap); 1138 if (imgp->sysent->sv_hwcap2 != NULL) 1139 AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2); 1140 AUXARGS_ENTRY(pos, AT_NULL, 0); 1141 1142 free(imgp->auxargs, M_TEMP); 1143 imgp->auxargs = NULL; 1144 1145 base--; 1146 suword(base, (long)imgp->args->argc); 1147 *stack_base = (register_t *)base; 1148 return (0); 1149 } 1150 1151 /* 1152 * Code for generating ELF core dumps. 1153 */ 1154 1155 typedef void (*segment_callback)(vm_map_entry_t, void *); 1156 1157 /* Closure for cb_put_phdr(). */ 1158 struct phdr_closure { 1159 Elf_Phdr *phdr; /* Program header to fill in */ 1160 Elf_Off offset; /* Offset of segment in core file */ 1161 }; 1162 1163 /* Closure for cb_size_segment(). */ 1164 struct sseg_closure { 1165 int count; /* Count of writable segments. */ 1166 size_t size; /* Total size of all writable segments. */ 1167 }; 1168 1169 typedef void (*outfunc_t)(void *, struct sbuf *, size_t *); 1170 1171 struct note_info { 1172 int type; /* Note type. */ 1173 outfunc_t outfunc; /* Output function. */ 1174 void *outarg; /* Argument for the output function. */ 1175 size_t outsize; /* Output size. */ 1176 TAILQ_ENTRY(note_info) link; /* Link to the next note info. */ 1177 }; 1178 1179 TAILQ_HEAD(note_info_list, note_info); 1180 1181 /* Coredump output parameters. */ 1182 struct coredump_params { 1183 off_t offset; 1184 struct ucred *active_cred; 1185 struct ucred *file_cred; 1186 struct thread *td; 1187 struct vnode *vp; 1188 struct gzio_stream *gzs; 1189 }; 1190 1191 static void cb_put_phdr(vm_map_entry_t, void *); 1192 static void cb_size_segment(vm_map_entry_t, void *); 1193 static int core_write(struct coredump_params *, const void *, size_t, off_t, 1194 enum uio_seg); 1195 static void each_dumpable_segment(struct thread *, segment_callback, void *); 1196 static int __elfN(corehdr)(struct coredump_params *, int, void *, size_t, 1197 struct note_info_list *, size_t); 1198 static void __elfN(prepare_notes)(struct thread *, struct note_info_list *, 1199 size_t *); 1200 static void __elfN(puthdr)(struct thread *, void *, size_t, int, size_t); 1201 static void __elfN(putnote)(struct note_info *, struct sbuf *); 1202 static size_t register_note(struct note_info_list *, int, outfunc_t, void *); 1203 static int sbuf_drain_core_output(void *, const char *, int); 1204 static int sbuf_drain_count(void *arg, const char *data, int len); 1205 1206 static void __elfN(note_fpregset)(void *, struct sbuf *, size_t *); 1207 static void __elfN(note_prpsinfo)(void *, struct sbuf *, size_t *); 1208 static void __elfN(note_prstatus)(void *, struct sbuf *, size_t *); 1209 static void __elfN(note_threadmd)(void *, struct sbuf *, size_t *); 1210 static void __elfN(note_thrmisc)(void *, struct sbuf *, size_t *); 1211 static void __elfN(note_ptlwpinfo)(void *, struct sbuf *, size_t *); 1212 static void __elfN(note_procstat_auxv)(void *, struct sbuf *, size_t *); 1213 static void __elfN(note_procstat_proc)(void *, struct sbuf *, size_t *); 1214 static void __elfN(note_procstat_psstrings)(void *, struct sbuf *, size_t *); 1215 static void note_procstat_files(void *, struct sbuf *, size_t *); 1216 static void note_procstat_groups(void *, struct sbuf *, size_t *); 1217 static void note_procstat_osrel(void *, struct sbuf *, size_t *); 1218 static void note_procstat_rlimit(void *, struct sbuf *, size_t *); 1219 static void note_procstat_umask(void *, struct sbuf *, size_t *); 1220 static void note_procstat_vmmap(void *, struct sbuf *, size_t *); 1221 1222 #ifdef GZIO 1223 extern int compress_user_cores_gzlevel; 1224 1225 /* 1226 * Write out a core segment to the compression stream. 1227 */ 1228 static int 1229 compress_chunk(struct coredump_params *p, char *base, char *buf, u_int len) 1230 { 1231 u_int chunk_len; 1232 int error; 1233 1234 while (len > 0) { 1235 chunk_len = MIN(len, CORE_BUF_SIZE); 1236 1237 /* 1238 * We can get EFAULT error here. 1239 * In that case zero out the current chunk of the segment. 1240 */ 1241 error = copyin(base, buf, chunk_len); 1242 if (error != 0) 1243 bzero(buf, chunk_len); 1244 error = gzio_write(p->gzs, buf, chunk_len); 1245 if (error != 0) 1246 break; 1247 base += chunk_len; 1248 len -= chunk_len; 1249 } 1250 return (error); 1251 } 1252 1253 static int 1254 core_gz_write(void *base, size_t len, off_t offset, void *arg) 1255 { 1256 1257 return (core_write((struct coredump_params *)arg, base, len, offset, 1258 UIO_SYSSPACE)); 1259 } 1260 #endif /* GZIO */ 1261 1262 static int 1263 core_write(struct coredump_params *p, const void *base, size_t len, 1264 off_t offset, enum uio_seg seg) 1265 { 1266 1267 return (vn_rdwr_inchunks(UIO_WRITE, p->vp, __DECONST(void *, base), 1268 len, offset, seg, IO_UNIT | IO_DIRECT | IO_RANGELOCKED, 1269 p->active_cred, p->file_cred, NULL, p->td)); 1270 } 1271 1272 static int 1273 core_output(void *base, size_t len, off_t offset, struct coredump_params *p, 1274 void *tmpbuf) 1275 { 1276 int error; 1277 1278 #ifdef GZIO 1279 if (p->gzs != NULL) 1280 return (compress_chunk(p, base, tmpbuf, len)); 1281 #endif 1282 /* 1283 * EFAULT is a non-fatal error that we can get, for example, 1284 * if the segment is backed by a file but extends beyond its 1285 * end. 1286 */ 1287 error = core_write(p, base, len, offset, UIO_USERSPACE); 1288 if (error == EFAULT) { 1289 log(LOG_WARNING, "Failed to fully fault in a core file segment " 1290 "at VA %p with size 0x%zx to be written at offset 0x%jx " 1291 "for process %s\n", base, len, offset, curproc->p_comm); 1292 1293 /* 1294 * Write a "real" zero byte at the end of the target region 1295 * in the case this is the last segment. 1296 * The intermediate space will be implicitly zero-filled. 1297 */ 1298 error = core_write(p, zero_region, 1, offset + len - 1, 1299 UIO_SYSSPACE); 1300 } 1301 return (error); 1302 } 1303 1304 /* 1305 * Drain into a core file. 1306 */ 1307 static int 1308 sbuf_drain_core_output(void *arg, const char *data, int len) 1309 { 1310 struct coredump_params *p; 1311 int error, locked; 1312 1313 p = (struct coredump_params *)arg; 1314 1315 /* 1316 * Some kern_proc out routines that print to this sbuf may 1317 * call us with the process lock held. Draining with the 1318 * non-sleepable lock held is unsafe. The lock is needed for 1319 * those routines when dumping a live process. In our case we 1320 * can safely release the lock before draining and acquire 1321 * again after. 1322 */ 1323 locked = PROC_LOCKED(p->td->td_proc); 1324 if (locked) 1325 PROC_UNLOCK(p->td->td_proc); 1326 #ifdef GZIO 1327 if (p->gzs != NULL) 1328 error = gzio_write(p->gzs, __DECONST(char *, data), len); 1329 else 1330 #endif 1331 error = core_write(p, __DECONST(void *, data), len, p->offset, 1332 UIO_SYSSPACE); 1333 if (locked) 1334 PROC_LOCK(p->td->td_proc); 1335 if (error != 0) 1336 return (-error); 1337 p->offset += len; 1338 return (len); 1339 } 1340 1341 /* 1342 * Drain into a counter. 1343 */ 1344 static int 1345 sbuf_drain_count(void *arg, const char *data __unused, int len) 1346 { 1347 size_t *sizep; 1348 1349 sizep = (size_t *)arg; 1350 *sizep += len; 1351 return (len); 1352 } 1353 1354 int 1355 __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags) 1356 { 1357 struct ucred *cred = td->td_ucred; 1358 int error = 0; 1359 struct sseg_closure seginfo; 1360 struct note_info_list notelst; 1361 struct coredump_params params; 1362 struct note_info *ninfo; 1363 void *hdr, *tmpbuf; 1364 size_t hdrsize, notesz, coresize; 1365 #ifdef GZIO 1366 boolean_t compress; 1367 1368 compress = (flags & IMGACT_CORE_COMPRESS) != 0; 1369 #endif 1370 hdr = NULL; 1371 tmpbuf = NULL; 1372 TAILQ_INIT(¬elst); 1373 1374 /* Size the program segments. */ 1375 seginfo.count = 0; 1376 seginfo.size = 0; 1377 each_dumpable_segment(td, cb_size_segment, &seginfo); 1378 1379 /* 1380 * Collect info about the core file header area. 1381 */ 1382 hdrsize = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * (1 + seginfo.count); 1383 if (seginfo.count + 1 >= PN_XNUM) 1384 hdrsize += sizeof(Elf_Shdr); 1385 __elfN(prepare_notes)(td, ¬elst, ¬esz); 1386 coresize = round_page(hdrsize + notesz) + seginfo.size; 1387 1388 /* Set up core dump parameters. */ 1389 params.offset = 0; 1390 params.active_cred = cred; 1391 params.file_cred = NOCRED; 1392 params.td = td; 1393 params.vp = vp; 1394 params.gzs = NULL; 1395 1396 #ifdef RACCT 1397 if (racct_enable) { 1398 PROC_LOCK(td->td_proc); 1399 error = racct_add(td->td_proc, RACCT_CORE, coresize); 1400 PROC_UNLOCK(td->td_proc); 1401 if (error != 0) { 1402 error = EFAULT; 1403 goto done; 1404 } 1405 } 1406 #endif 1407 if (coresize >= limit) { 1408 error = EFAULT; 1409 goto done; 1410 } 1411 1412 #ifdef GZIO 1413 /* Create a compression stream if necessary. */ 1414 if (compress) { 1415 params.gzs = gzio_init(core_gz_write, GZIO_DEFLATE, 1416 CORE_BUF_SIZE, compress_user_cores_gzlevel, ¶ms); 1417 if (params.gzs == NULL) { 1418 error = EFAULT; 1419 goto done; 1420 } 1421 tmpbuf = malloc(CORE_BUF_SIZE, M_TEMP, M_WAITOK | M_ZERO); 1422 } 1423 #endif 1424 1425 /* 1426 * Allocate memory for building the header, fill it up, 1427 * and write it out following the notes. 1428 */ 1429 hdr = malloc(hdrsize, M_TEMP, M_WAITOK); 1430 error = __elfN(corehdr)(¶ms, seginfo.count, hdr, hdrsize, ¬elst, 1431 notesz); 1432 1433 /* Write the contents of all of the writable segments. */ 1434 if (error == 0) { 1435 Elf_Phdr *php; 1436 off_t offset; 1437 int i; 1438 1439 php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1; 1440 offset = round_page(hdrsize + notesz); 1441 for (i = 0; i < seginfo.count; i++) { 1442 error = core_output((caddr_t)(uintptr_t)php->p_vaddr, 1443 php->p_filesz, offset, ¶ms, tmpbuf); 1444 if (error != 0) 1445 break; 1446 offset += php->p_filesz; 1447 php++; 1448 } 1449 #ifdef GZIO 1450 if (error == 0 && compress) 1451 error = gzio_flush(params.gzs); 1452 #endif 1453 } 1454 if (error) { 1455 log(LOG_WARNING, 1456 "Failed to write core file for process %s (error %d)\n", 1457 curproc->p_comm, error); 1458 } 1459 1460 done: 1461 #ifdef GZIO 1462 if (compress) { 1463 free(tmpbuf, M_TEMP); 1464 if (params.gzs != NULL) 1465 gzio_fini(params.gzs); 1466 } 1467 #endif 1468 while ((ninfo = TAILQ_FIRST(¬elst)) != NULL) { 1469 TAILQ_REMOVE(¬elst, ninfo, link); 1470 free(ninfo, M_TEMP); 1471 } 1472 if (hdr != NULL) 1473 free(hdr, M_TEMP); 1474 1475 return (error); 1476 } 1477 1478 /* 1479 * A callback for each_dumpable_segment() to write out the segment's 1480 * program header entry. 1481 */ 1482 static void 1483 cb_put_phdr(entry, closure) 1484 vm_map_entry_t entry; 1485 void *closure; 1486 { 1487 struct phdr_closure *phc = (struct phdr_closure *)closure; 1488 Elf_Phdr *phdr = phc->phdr; 1489 1490 phc->offset = round_page(phc->offset); 1491 1492 phdr->p_type = PT_LOAD; 1493 phdr->p_offset = phc->offset; 1494 phdr->p_vaddr = entry->start; 1495 phdr->p_paddr = 0; 1496 phdr->p_filesz = phdr->p_memsz = entry->end - entry->start; 1497 phdr->p_align = PAGE_SIZE; 1498 phdr->p_flags = __elfN(untrans_prot)(entry->protection); 1499 1500 phc->offset += phdr->p_filesz; 1501 phc->phdr++; 1502 } 1503 1504 /* 1505 * A callback for each_dumpable_segment() to gather information about 1506 * the number of segments and their total size. 1507 */ 1508 static void 1509 cb_size_segment(vm_map_entry_t entry, void *closure) 1510 { 1511 struct sseg_closure *ssc = (struct sseg_closure *)closure; 1512 1513 ssc->count++; 1514 ssc->size += entry->end - entry->start; 1515 } 1516 1517 /* 1518 * For each writable segment in the process's memory map, call the given 1519 * function with a pointer to the map entry and some arbitrary 1520 * caller-supplied data. 1521 */ 1522 static void 1523 each_dumpable_segment(struct thread *td, segment_callback func, void *closure) 1524 { 1525 struct proc *p = td->td_proc; 1526 vm_map_t map = &p->p_vmspace->vm_map; 1527 vm_map_entry_t entry; 1528 vm_object_t backing_object, object; 1529 boolean_t ignore_entry; 1530 1531 vm_map_lock_read(map); 1532 for (entry = map->header.next; entry != &map->header; 1533 entry = entry->next) { 1534 /* 1535 * Don't dump inaccessible mappings, deal with legacy 1536 * coredump mode. 1537 * 1538 * Note that read-only segments related to the elf binary 1539 * are marked MAP_ENTRY_NOCOREDUMP now so we no longer 1540 * need to arbitrarily ignore such segments. 1541 */ 1542 if (elf_legacy_coredump) { 1543 if ((entry->protection & VM_PROT_RW) != VM_PROT_RW) 1544 continue; 1545 } else { 1546 if ((entry->protection & VM_PROT_ALL) == 0) 1547 continue; 1548 } 1549 1550 /* 1551 * Dont include memory segment in the coredump if 1552 * MAP_NOCORE is set in mmap(2) or MADV_NOCORE in 1553 * madvise(2). Do not dump submaps (i.e. parts of the 1554 * kernel map). 1555 */ 1556 if (entry->eflags & (MAP_ENTRY_NOCOREDUMP|MAP_ENTRY_IS_SUB_MAP)) 1557 continue; 1558 1559 if ((object = entry->object.vm_object) == NULL) 1560 continue; 1561 1562 /* Ignore memory-mapped devices and such things. */ 1563 VM_OBJECT_RLOCK(object); 1564 while ((backing_object = object->backing_object) != NULL) { 1565 VM_OBJECT_RLOCK(backing_object); 1566 VM_OBJECT_RUNLOCK(object); 1567 object = backing_object; 1568 } 1569 ignore_entry = object->type != OBJT_DEFAULT && 1570 object->type != OBJT_SWAP && object->type != OBJT_VNODE && 1571 object->type != OBJT_PHYS; 1572 VM_OBJECT_RUNLOCK(object); 1573 if (ignore_entry) 1574 continue; 1575 1576 (*func)(entry, closure); 1577 } 1578 vm_map_unlock_read(map); 1579 } 1580 1581 /* 1582 * Write the core file header to the file, including padding up to 1583 * the page boundary. 1584 */ 1585 static int 1586 __elfN(corehdr)(struct coredump_params *p, int numsegs, void *hdr, 1587 size_t hdrsize, struct note_info_list *notelst, size_t notesz) 1588 { 1589 struct note_info *ninfo; 1590 struct sbuf *sb; 1591 int error; 1592 1593 /* Fill in the header. */ 1594 bzero(hdr, hdrsize); 1595 __elfN(puthdr)(p->td, hdr, hdrsize, numsegs, notesz); 1596 1597 sb = sbuf_new(NULL, NULL, CORE_BUF_SIZE, SBUF_FIXEDLEN); 1598 sbuf_set_drain(sb, sbuf_drain_core_output, p); 1599 sbuf_start_section(sb, NULL); 1600 sbuf_bcat(sb, hdr, hdrsize); 1601 TAILQ_FOREACH(ninfo, notelst, link) 1602 __elfN(putnote)(ninfo, sb); 1603 /* Align up to a page boundary for the program segments. */ 1604 sbuf_end_section(sb, -1, PAGE_SIZE, 0); 1605 error = sbuf_finish(sb); 1606 sbuf_delete(sb); 1607 1608 return (error); 1609 } 1610 1611 static void 1612 __elfN(prepare_notes)(struct thread *td, struct note_info_list *list, 1613 size_t *sizep) 1614 { 1615 struct proc *p; 1616 struct thread *thr; 1617 size_t size; 1618 1619 p = td->td_proc; 1620 size = 0; 1621 1622 size += register_note(list, NT_PRPSINFO, __elfN(note_prpsinfo), p); 1623 1624 /* 1625 * To have the debugger select the right thread (LWP) as the initial 1626 * thread, we dump the state of the thread passed to us in td first. 1627 * This is the thread that causes the core dump and thus likely to 1628 * be the right thread one wants to have selected in the debugger. 1629 */ 1630 thr = td; 1631 while (thr != NULL) { 1632 size += register_note(list, NT_PRSTATUS, 1633 __elfN(note_prstatus), thr); 1634 size += register_note(list, NT_FPREGSET, 1635 __elfN(note_fpregset), thr); 1636 size += register_note(list, NT_THRMISC, 1637 __elfN(note_thrmisc), thr); 1638 size += register_note(list, NT_PTLWPINFO, 1639 __elfN(note_ptlwpinfo), thr); 1640 size += register_note(list, -1, 1641 __elfN(note_threadmd), thr); 1642 1643 thr = (thr == td) ? TAILQ_FIRST(&p->p_threads) : 1644 TAILQ_NEXT(thr, td_plist); 1645 if (thr == td) 1646 thr = TAILQ_NEXT(thr, td_plist); 1647 } 1648 1649 size += register_note(list, NT_PROCSTAT_PROC, 1650 __elfN(note_procstat_proc), p); 1651 size += register_note(list, NT_PROCSTAT_FILES, 1652 note_procstat_files, p); 1653 size += register_note(list, NT_PROCSTAT_VMMAP, 1654 note_procstat_vmmap, p); 1655 size += register_note(list, NT_PROCSTAT_GROUPS, 1656 note_procstat_groups, p); 1657 size += register_note(list, NT_PROCSTAT_UMASK, 1658 note_procstat_umask, p); 1659 size += register_note(list, NT_PROCSTAT_RLIMIT, 1660 note_procstat_rlimit, p); 1661 size += register_note(list, NT_PROCSTAT_OSREL, 1662 note_procstat_osrel, p); 1663 size += register_note(list, NT_PROCSTAT_PSSTRINGS, 1664 __elfN(note_procstat_psstrings), p); 1665 size += register_note(list, NT_PROCSTAT_AUXV, 1666 __elfN(note_procstat_auxv), p); 1667 1668 *sizep = size; 1669 } 1670 1671 static void 1672 __elfN(puthdr)(struct thread *td, void *hdr, size_t hdrsize, int numsegs, 1673 size_t notesz) 1674 { 1675 Elf_Ehdr *ehdr; 1676 Elf_Phdr *phdr; 1677 Elf_Shdr *shdr; 1678 struct phdr_closure phc; 1679 1680 ehdr = (Elf_Ehdr *)hdr; 1681 1682 ehdr->e_ident[EI_MAG0] = ELFMAG0; 1683 ehdr->e_ident[EI_MAG1] = ELFMAG1; 1684 ehdr->e_ident[EI_MAG2] = ELFMAG2; 1685 ehdr->e_ident[EI_MAG3] = ELFMAG3; 1686 ehdr->e_ident[EI_CLASS] = ELF_CLASS; 1687 ehdr->e_ident[EI_DATA] = ELF_DATA; 1688 ehdr->e_ident[EI_VERSION] = EV_CURRENT; 1689 ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 1690 ehdr->e_ident[EI_ABIVERSION] = 0; 1691 ehdr->e_ident[EI_PAD] = 0; 1692 ehdr->e_type = ET_CORE; 1693 ehdr->e_machine = td->td_proc->p_elf_machine; 1694 ehdr->e_version = EV_CURRENT; 1695 ehdr->e_entry = 0; 1696 ehdr->e_phoff = sizeof(Elf_Ehdr); 1697 ehdr->e_flags = td->td_proc->p_elf_flags; 1698 ehdr->e_ehsize = sizeof(Elf_Ehdr); 1699 ehdr->e_phentsize = sizeof(Elf_Phdr); 1700 ehdr->e_shentsize = sizeof(Elf_Shdr); 1701 ehdr->e_shstrndx = SHN_UNDEF; 1702 if (numsegs + 1 < PN_XNUM) { 1703 ehdr->e_phnum = numsegs + 1; 1704 ehdr->e_shnum = 0; 1705 } else { 1706 ehdr->e_phnum = PN_XNUM; 1707 ehdr->e_shnum = 1; 1708 1709 ehdr->e_shoff = ehdr->e_phoff + 1710 (numsegs + 1) * ehdr->e_phentsize; 1711 KASSERT(ehdr->e_shoff == hdrsize - sizeof(Elf_Shdr), 1712 ("e_shoff: %zu, hdrsize - shdr: %zu", 1713 (size_t)ehdr->e_shoff, hdrsize - sizeof(Elf_Shdr))); 1714 1715 shdr = (Elf_Shdr *)((char *)hdr + ehdr->e_shoff); 1716 memset(shdr, 0, sizeof(*shdr)); 1717 /* 1718 * A special first section is used to hold large segment and 1719 * section counts. This was proposed by Sun Microsystems in 1720 * Solaris and has been adopted by Linux; the standard ELF 1721 * tools are already familiar with the technique. 1722 * 1723 * See table 7-7 of the Solaris "Linker and Libraries Guide" 1724 * (or 12-7 depending on the version of the document) for more 1725 * details. 1726 */ 1727 shdr->sh_type = SHT_NULL; 1728 shdr->sh_size = ehdr->e_shnum; 1729 shdr->sh_link = ehdr->e_shstrndx; 1730 shdr->sh_info = numsegs + 1; 1731 } 1732 1733 /* 1734 * Fill in the program header entries. 1735 */ 1736 phdr = (Elf_Phdr *)((char *)hdr + ehdr->e_phoff); 1737 1738 /* The note segement. */ 1739 phdr->p_type = PT_NOTE; 1740 phdr->p_offset = hdrsize; 1741 phdr->p_vaddr = 0; 1742 phdr->p_paddr = 0; 1743 phdr->p_filesz = notesz; 1744 phdr->p_memsz = 0; 1745 phdr->p_flags = PF_R; 1746 phdr->p_align = ELF_NOTE_ROUNDSIZE; 1747 phdr++; 1748 1749 /* All the writable segments from the program. */ 1750 phc.phdr = phdr; 1751 phc.offset = round_page(hdrsize + notesz); 1752 each_dumpable_segment(td, cb_put_phdr, &phc); 1753 } 1754 1755 static size_t 1756 register_note(struct note_info_list *list, int type, outfunc_t out, void *arg) 1757 { 1758 struct note_info *ninfo; 1759 size_t size, notesize; 1760 1761 size = 0; 1762 out(arg, NULL, &size); 1763 ninfo = malloc(sizeof(*ninfo), M_TEMP, M_ZERO | M_WAITOK); 1764 ninfo->type = type; 1765 ninfo->outfunc = out; 1766 ninfo->outarg = arg; 1767 ninfo->outsize = size; 1768 TAILQ_INSERT_TAIL(list, ninfo, link); 1769 1770 if (type == -1) 1771 return (size); 1772 1773 notesize = sizeof(Elf_Note) + /* note header */ 1774 roundup2(sizeof(FREEBSD_ABI_VENDOR), ELF_NOTE_ROUNDSIZE) + 1775 /* note name */ 1776 roundup2(size, ELF_NOTE_ROUNDSIZE); /* note description */ 1777 1778 return (notesize); 1779 } 1780 1781 static size_t 1782 append_note_data(const void *src, void *dst, size_t len) 1783 { 1784 size_t padded_len; 1785 1786 padded_len = roundup2(len, ELF_NOTE_ROUNDSIZE); 1787 if (dst != NULL) { 1788 bcopy(src, dst, len); 1789 bzero((char *)dst + len, padded_len - len); 1790 } 1791 return (padded_len); 1792 } 1793 1794 size_t 1795 __elfN(populate_note)(int type, void *src, void *dst, size_t size, void **descp) 1796 { 1797 Elf_Note *note; 1798 char *buf; 1799 size_t notesize; 1800 1801 buf = dst; 1802 if (buf != NULL) { 1803 note = (Elf_Note *)buf; 1804 note->n_namesz = sizeof(FREEBSD_ABI_VENDOR); 1805 note->n_descsz = size; 1806 note->n_type = type; 1807 buf += sizeof(*note); 1808 buf += append_note_data(FREEBSD_ABI_VENDOR, buf, 1809 sizeof(FREEBSD_ABI_VENDOR)); 1810 append_note_data(src, buf, size); 1811 if (descp != NULL) 1812 *descp = buf; 1813 } 1814 1815 notesize = sizeof(Elf_Note) + /* note header */ 1816 roundup2(sizeof(FREEBSD_ABI_VENDOR), ELF_NOTE_ROUNDSIZE) + 1817 /* note name */ 1818 roundup2(size, ELF_NOTE_ROUNDSIZE); /* note description */ 1819 1820 return (notesize); 1821 } 1822 1823 static void 1824 __elfN(putnote)(struct note_info *ninfo, struct sbuf *sb) 1825 { 1826 Elf_Note note; 1827 ssize_t old_len, sect_len; 1828 size_t new_len, descsz, i; 1829 1830 if (ninfo->type == -1) { 1831 ninfo->outfunc(ninfo->outarg, sb, &ninfo->outsize); 1832 return; 1833 } 1834 1835 note.n_namesz = sizeof(FREEBSD_ABI_VENDOR); 1836 note.n_descsz = ninfo->outsize; 1837 note.n_type = ninfo->type; 1838 1839 sbuf_bcat(sb, ¬e, sizeof(note)); 1840 sbuf_start_section(sb, &old_len); 1841 sbuf_bcat(sb, FREEBSD_ABI_VENDOR, sizeof(FREEBSD_ABI_VENDOR)); 1842 sbuf_end_section(sb, old_len, ELF_NOTE_ROUNDSIZE, 0); 1843 if (note.n_descsz == 0) 1844 return; 1845 sbuf_start_section(sb, &old_len); 1846 ninfo->outfunc(ninfo->outarg, sb, &ninfo->outsize); 1847 sect_len = sbuf_end_section(sb, old_len, ELF_NOTE_ROUNDSIZE, 0); 1848 if (sect_len < 0) 1849 return; 1850 1851 new_len = (size_t)sect_len; 1852 descsz = roundup(note.n_descsz, ELF_NOTE_ROUNDSIZE); 1853 if (new_len < descsz) { 1854 /* 1855 * It is expected that individual note emitters will correctly 1856 * predict their expected output size and fill up to that size 1857 * themselves, padding in a format-specific way if needed. 1858 * However, in case they don't, just do it here with zeros. 1859 */ 1860 for (i = 0; i < descsz - new_len; i++) 1861 sbuf_putc(sb, 0); 1862 } else if (new_len > descsz) { 1863 /* 1864 * We can't always truncate sb -- we may have drained some 1865 * of it already. 1866 */ 1867 KASSERT(new_len == descsz, ("%s: Note type %u changed as we " 1868 "read it (%zu > %zu). Since it is longer than " 1869 "expected, this coredump's notes are corrupt. THIS " 1870 "IS A BUG in the note_procstat routine for type %u.\n", 1871 __func__, (unsigned)note.n_type, new_len, descsz, 1872 (unsigned)note.n_type)); 1873 } 1874 } 1875 1876 /* 1877 * Miscellaneous note out functions. 1878 */ 1879 1880 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32 1881 #include <compat/freebsd32/freebsd32.h> 1882 #include <compat/freebsd32/freebsd32_signal.h> 1883 1884 typedef struct prstatus32 elf_prstatus_t; 1885 typedef struct prpsinfo32 elf_prpsinfo_t; 1886 typedef struct fpreg32 elf_prfpregset_t; 1887 typedef struct fpreg32 elf_fpregset_t; 1888 typedef struct reg32 elf_gregset_t; 1889 typedef struct thrmisc32 elf_thrmisc_t; 1890 #define ELF_KERN_PROC_MASK KERN_PROC_MASK32 1891 typedef struct kinfo_proc32 elf_kinfo_proc_t; 1892 typedef uint32_t elf_ps_strings_t; 1893 #else 1894 typedef prstatus_t elf_prstatus_t; 1895 typedef prpsinfo_t elf_prpsinfo_t; 1896 typedef prfpregset_t elf_prfpregset_t; 1897 typedef prfpregset_t elf_fpregset_t; 1898 typedef gregset_t elf_gregset_t; 1899 typedef thrmisc_t elf_thrmisc_t; 1900 #define ELF_KERN_PROC_MASK 0 1901 typedef struct kinfo_proc elf_kinfo_proc_t; 1902 typedef vm_offset_t elf_ps_strings_t; 1903 #endif 1904 1905 static void 1906 __elfN(note_prpsinfo)(void *arg, struct sbuf *sb, size_t *sizep) 1907 { 1908 struct sbuf sbarg; 1909 size_t len; 1910 char *cp, *end; 1911 struct proc *p; 1912 elf_prpsinfo_t *psinfo; 1913 int error; 1914 1915 p = (struct proc *)arg; 1916 if (sb != NULL) { 1917 KASSERT(*sizep == sizeof(*psinfo), ("invalid size")); 1918 psinfo = malloc(sizeof(*psinfo), M_TEMP, M_ZERO | M_WAITOK); 1919 psinfo->pr_version = PRPSINFO_VERSION; 1920 psinfo->pr_psinfosz = sizeof(elf_prpsinfo_t); 1921 strlcpy(psinfo->pr_fname, p->p_comm, sizeof(psinfo->pr_fname)); 1922 PROC_LOCK(p); 1923 if (p->p_args != NULL) { 1924 len = sizeof(psinfo->pr_psargs) - 1; 1925 if (len > p->p_args->ar_length) 1926 len = p->p_args->ar_length; 1927 memcpy(psinfo->pr_psargs, p->p_args->ar_args, len); 1928 PROC_UNLOCK(p); 1929 error = 0; 1930 } else { 1931 _PHOLD(p); 1932 PROC_UNLOCK(p); 1933 sbuf_new(&sbarg, psinfo->pr_psargs, 1934 sizeof(psinfo->pr_psargs), SBUF_FIXEDLEN); 1935 error = proc_getargv(curthread, p, &sbarg); 1936 PRELE(p); 1937 if (sbuf_finish(&sbarg) == 0) 1938 len = sbuf_len(&sbarg) - 1; 1939 else 1940 len = sizeof(psinfo->pr_psargs) - 1; 1941 sbuf_delete(&sbarg); 1942 } 1943 if (error || len == 0) 1944 strlcpy(psinfo->pr_psargs, p->p_comm, 1945 sizeof(psinfo->pr_psargs)); 1946 else { 1947 KASSERT(len < sizeof(psinfo->pr_psargs), 1948 ("len is too long: %zu vs %zu", len, 1949 sizeof(psinfo->pr_psargs))); 1950 cp = psinfo->pr_psargs; 1951 end = cp + len - 1; 1952 for (;;) { 1953 cp = memchr(cp, '\0', end - cp); 1954 if (cp == NULL) 1955 break; 1956 *cp = ' '; 1957 } 1958 } 1959 psinfo->pr_pid = p->p_pid; 1960 sbuf_bcat(sb, psinfo, sizeof(*psinfo)); 1961 free(psinfo, M_TEMP); 1962 } 1963 *sizep = sizeof(*psinfo); 1964 } 1965 1966 static void 1967 __elfN(note_prstatus)(void *arg, struct sbuf *sb, size_t *sizep) 1968 { 1969 struct thread *td; 1970 elf_prstatus_t *status; 1971 1972 td = (struct thread *)arg; 1973 if (sb != NULL) { 1974 KASSERT(*sizep == sizeof(*status), ("invalid size")); 1975 status = malloc(sizeof(*status), M_TEMP, M_ZERO | M_WAITOK); 1976 status->pr_version = PRSTATUS_VERSION; 1977 status->pr_statussz = sizeof(elf_prstatus_t); 1978 status->pr_gregsetsz = sizeof(elf_gregset_t); 1979 status->pr_fpregsetsz = sizeof(elf_fpregset_t); 1980 status->pr_osreldate = osreldate; 1981 status->pr_cursig = td->td_proc->p_sig; 1982 status->pr_pid = td->td_tid; 1983 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32 1984 fill_regs32(td, &status->pr_reg); 1985 #else 1986 fill_regs(td, &status->pr_reg); 1987 #endif 1988 sbuf_bcat(sb, status, sizeof(*status)); 1989 free(status, M_TEMP); 1990 } 1991 *sizep = sizeof(*status); 1992 } 1993 1994 static void 1995 __elfN(note_fpregset)(void *arg, struct sbuf *sb, size_t *sizep) 1996 { 1997 struct thread *td; 1998 elf_prfpregset_t *fpregset; 1999 2000 td = (struct thread *)arg; 2001 if (sb != NULL) { 2002 KASSERT(*sizep == sizeof(*fpregset), ("invalid size")); 2003 fpregset = malloc(sizeof(*fpregset), M_TEMP, M_ZERO | M_WAITOK); 2004 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32 2005 fill_fpregs32(td, fpregset); 2006 #else 2007 fill_fpregs(td, fpregset); 2008 #endif 2009 sbuf_bcat(sb, fpregset, sizeof(*fpregset)); 2010 free(fpregset, M_TEMP); 2011 } 2012 *sizep = sizeof(*fpregset); 2013 } 2014 2015 static void 2016 __elfN(note_thrmisc)(void *arg, struct sbuf *sb, size_t *sizep) 2017 { 2018 struct thread *td; 2019 elf_thrmisc_t thrmisc; 2020 2021 td = (struct thread *)arg; 2022 if (sb != NULL) { 2023 KASSERT(*sizep == sizeof(thrmisc), ("invalid size")); 2024 bzero(&thrmisc._pad, sizeof(thrmisc._pad)); 2025 strcpy(thrmisc.pr_tname, td->td_name); 2026 sbuf_bcat(sb, &thrmisc, sizeof(thrmisc)); 2027 } 2028 *sizep = sizeof(thrmisc); 2029 } 2030 2031 static void 2032 __elfN(note_ptlwpinfo)(void *arg, struct sbuf *sb, size_t *sizep) 2033 { 2034 struct thread *td; 2035 size_t size; 2036 int structsize; 2037 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32 2038 struct ptrace_lwpinfo32 pl; 2039 #else 2040 struct ptrace_lwpinfo pl; 2041 #endif 2042 2043 td = (struct thread *)arg; 2044 size = sizeof(structsize) + sizeof(pl); 2045 if (sb != NULL) { 2046 KASSERT(*sizep == size, ("invalid size")); 2047 structsize = sizeof(pl); 2048 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2049 bzero(&pl, sizeof(pl)); 2050 pl.pl_lwpid = td->td_tid; 2051 pl.pl_event = PL_EVENT_NONE; 2052 pl.pl_sigmask = td->td_sigmask; 2053 pl.pl_siglist = td->td_siglist; 2054 if (td->td_si.si_signo != 0) { 2055 pl.pl_event = PL_EVENT_SIGNAL; 2056 pl.pl_flags |= PL_FLAG_SI; 2057 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32 2058 siginfo_to_siginfo32(&td->td_si, &pl.pl_siginfo); 2059 #else 2060 pl.pl_siginfo = td->td_si; 2061 #endif 2062 } 2063 strcpy(pl.pl_tdname, td->td_name); 2064 /* XXX TODO: supply more information in struct ptrace_lwpinfo*/ 2065 sbuf_bcat(sb, &pl, sizeof(pl)); 2066 } 2067 *sizep = size; 2068 } 2069 2070 /* 2071 * Allow for MD specific notes, as well as any MD 2072 * specific preparations for writing MI notes. 2073 */ 2074 static void 2075 __elfN(note_threadmd)(void *arg, struct sbuf *sb, size_t *sizep) 2076 { 2077 struct thread *td; 2078 void *buf; 2079 size_t size; 2080 2081 td = (struct thread *)arg; 2082 size = *sizep; 2083 if (size != 0 && sb != NULL) 2084 buf = malloc(size, M_TEMP, M_ZERO | M_WAITOK); 2085 else 2086 buf = NULL; 2087 size = 0; 2088 __elfN(dump_thread)(td, buf, &size); 2089 KASSERT(sb == NULL || *sizep == size, ("invalid size")); 2090 if (size != 0 && sb != NULL) 2091 sbuf_bcat(sb, buf, size); 2092 free(buf, M_TEMP); 2093 *sizep = size; 2094 } 2095 2096 #ifdef KINFO_PROC_SIZE 2097 CTASSERT(sizeof(struct kinfo_proc) == KINFO_PROC_SIZE); 2098 #endif 2099 2100 static void 2101 __elfN(note_procstat_proc)(void *arg, struct sbuf *sb, size_t *sizep) 2102 { 2103 struct proc *p; 2104 size_t size; 2105 int structsize; 2106 2107 p = (struct proc *)arg; 2108 size = sizeof(structsize) + p->p_numthreads * 2109 sizeof(elf_kinfo_proc_t); 2110 2111 if (sb != NULL) { 2112 KASSERT(*sizep == size, ("invalid size")); 2113 structsize = sizeof(elf_kinfo_proc_t); 2114 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2115 sx_slock(&proctree_lock); 2116 PROC_LOCK(p); 2117 kern_proc_out(p, sb, ELF_KERN_PROC_MASK); 2118 sx_sunlock(&proctree_lock); 2119 } 2120 *sizep = size; 2121 } 2122 2123 #ifdef KINFO_FILE_SIZE 2124 CTASSERT(sizeof(struct kinfo_file) == KINFO_FILE_SIZE); 2125 #endif 2126 2127 static void 2128 note_procstat_files(void *arg, struct sbuf *sb, size_t *sizep) 2129 { 2130 struct proc *p; 2131 size_t size, sect_sz, i; 2132 ssize_t start_len, sect_len; 2133 int structsize, filedesc_flags; 2134 2135 if (coredump_pack_fileinfo) 2136 filedesc_flags = KERN_FILEDESC_PACK_KINFO; 2137 else 2138 filedesc_flags = 0; 2139 2140 p = (struct proc *)arg; 2141 structsize = sizeof(struct kinfo_file); 2142 if (sb == NULL) { 2143 size = 0; 2144 sb = sbuf_new(NULL, NULL, 128, SBUF_FIXEDLEN); 2145 sbuf_set_drain(sb, sbuf_drain_count, &size); 2146 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2147 PROC_LOCK(p); 2148 kern_proc_filedesc_out(p, sb, -1, filedesc_flags); 2149 sbuf_finish(sb); 2150 sbuf_delete(sb); 2151 *sizep = size; 2152 } else { 2153 sbuf_start_section(sb, &start_len); 2154 2155 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2156 PROC_LOCK(p); 2157 kern_proc_filedesc_out(p, sb, *sizep - sizeof(structsize), 2158 filedesc_flags); 2159 2160 sect_len = sbuf_end_section(sb, start_len, 0, 0); 2161 if (sect_len < 0) 2162 return; 2163 sect_sz = sect_len; 2164 2165 KASSERT(sect_sz <= *sizep, 2166 ("kern_proc_filedesc_out did not respect maxlen; " 2167 "requested %zu, got %zu", *sizep - sizeof(structsize), 2168 sect_sz - sizeof(structsize))); 2169 2170 for (i = 0; i < *sizep - sect_sz && sb->s_error == 0; i++) 2171 sbuf_putc(sb, 0); 2172 } 2173 } 2174 2175 #ifdef KINFO_VMENTRY_SIZE 2176 CTASSERT(sizeof(struct kinfo_vmentry) == KINFO_VMENTRY_SIZE); 2177 #endif 2178 2179 static void 2180 note_procstat_vmmap(void *arg, struct sbuf *sb, size_t *sizep) 2181 { 2182 struct proc *p; 2183 size_t size; 2184 int structsize, vmmap_flags; 2185 2186 if (coredump_pack_vmmapinfo) 2187 vmmap_flags = KERN_VMMAP_PACK_KINFO; 2188 else 2189 vmmap_flags = 0; 2190 2191 p = (struct proc *)arg; 2192 structsize = sizeof(struct kinfo_vmentry); 2193 if (sb == NULL) { 2194 size = 0; 2195 sb = sbuf_new(NULL, NULL, 128, SBUF_FIXEDLEN); 2196 sbuf_set_drain(sb, sbuf_drain_count, &size); 2197 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2198 PROC_LOCK(p); 2199 kern_proc_vmmap_out(p, sb, -1, vmmap_flags); 2200 sbuf_finish(sb); 2201 sbuf_delete(sb); 2202 *sizep = size; 2203 } else { 2204 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2205 PROC_LOCK(p); 2206 kern_proc_vmmap_out(p, sb, *sizep - sizeof(structsize), 2207 vmmap_flags); 2208 } 2209 } 2210 2211 static void 2212 note_procstat_groups(void *arg, struct sbuf *sb, size_t *sizep) 2213 { 2214 struct proc *p; 2215 size_t size; 2216 int structsize; 2217 2218 p = (struct proc *)arg; 2219 size = sizeof(structsize) + p->p_ucred->cr_ngroups * sizeof(gid_t); 2220 if (sb != NULL) { 2221 KASSERT(*sizep == size, ("invalid size")); 2222 structsize = sizeof(gid_t); 2223 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2224 sbuf_bcat(sb, p->p_ucred->cr_groups, p->p_ucred->cr_ngroups * 2225 sizeof(gid_t)); 2226 } 2227 *sizep = size; 2228 } 2229 2230 static void 2231 note_procstat_umask(void *arg, struct sbuf *sb, size_t *sizep) 2232 { 2233 struct proc *p; 2234 size_t size; 2235 int structsize; 2236 2237 p = (struct proc *)arg; 2238 size = sizeof(structsize) + sizeof(p->p_fd->fd_cmask); 2239 if (sb != NULL) { 2240 KASSERT(*sizep == size, ("invalid size")); 2241 structsize = sizeof(p->p_fd->fd_cmask); 2242 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2243 sbuf_bcat(sb, &p->p_fd->fd_cmask, sizeof(p->p_fd->fd_cmask)); 2244 } 2245 *sizep = size; 2246 } 2247 2248 static void 2249 note_procstat_rlimit(void *arg, struct sbuf *sb, size_t *sizep) 2250 { 2251 struct proc *p; 2252 struct rlimit rlim[RLIM_NLIMITS]; 2253 size_t size; 2254 int structsize, i; 2255 2256 p = (struct proc *)arg; 2257 size = sizeof(structsize) + sizeof(rlim); 2258 if (sb != NULL) { 2259 KASSERT(*sizep == size, ("invalid size")); 2260 structsize = sizeof(rlim); 2261 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2262 PROC_LOCK(p); 2263 for (i = 0; i < RLIM_NLIMITS; i++) 2264 lim_rlimit_proc(p, i, &rlim[i]); 2265 PROC_UNLOCK(p); 2266 sbuf_bcat(sb, rlim, sizeof(rlim)); 2267 } 2268 *sizep = size; 2269 } 2270 2271 static void 2272 note_procstat_osrel(void *arg, struct sbuf *sb, size_t *sizep) 2273 { 2274 struct proc *p; 2275 size_t size; 2276 int structsize; 2277 2278 p = (struct proc *)arg; 2279 size = sizeof(structsize) + sizeof(p->p_osrel); 2280 if (sb != NULL) { 2281 KASSERT(*sizep == size, ("invalid size")); 2282 structsize = sizeof(p->p_osrel); 2283 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2284 sbuf_bcat(sb, &p->p_osrel, sizeof(p->p_osrel)); 2285 } 2286 *sizep = size; 2287 } 2288 2289 static void 2290 __elfN(note_procstat_psstrings)(void *arg, struct sbuf *sb, size_t *sizep) 2291 { 2292 struct proc *p; 2293 elf_ps_strings_t ps_strings; 2294 size_t size; 2295 int structsize; 2296 2297 p = (struct proc *)arg; 2298 size = sizeof(structsize) + sizeof(ps_strings); 2299 if (sb != NULL) { 2300 KASSERT(*sizep == size, ("invalid size")); 2301 structsize = sizeof(ps_strings); 2302 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32 2303 ps_strings = PTROUT(p->p_sysent->sv_psstrings); 2304 #else 2305 ps_strings = p->p_sysent->sv_psstrings; 2306 #endif 2307 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2308 sbuf_bcat(sb, &ps_strings, sizeof(ps_strings)); 2309 } 2310 *sizep = size; 2311 } 2312 2313 static void 2314 __elfN(note_procstat_auxv)(void *arg, struct sbuf *sb, size_t *sizep) 2315 { 2316 struct proc *p; 2317 size_t size; 2318 int structsize; 2319 2320 p = (struct proc *)arg; 2321 if (sb == NULL) { 2322 size = 0; 2323 sb = sbuf_new(NULL, NULL, 128, SBUF_FIXEDLEN); 2324 sbuf_set_drain(sb, sbuf_drain_count, &size); 2325 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2326 PHOLD(p); 2327 proc_getauxv(curthread, p, sb); 2328 PRELE(p); 2329 sbuf_finish(sb); 2330 sbuf_delete(sb); 2331 *sizep = size; 2332 } else { 2333 structsize = sizeof(Elf_Auxinfo); 2334 sbuf_bcat(sb, &structsize, sizeof(structsize)); 2335 PHOLD(p); 2336 proc_getauxv(curthread, p, sb); 2337 PRELE(p); 2338 } 2339 } 2340 2341 static boolean_t 2342 __elfN(parse_notes)(struct image_params *imgp, Elf_Brandnote *checknote, 2343 int32_t *osrel, const Elf_Phdr *pnote) 2344 { 2345 const Elf_Note *note, *note0, *note_end; 2346 const char *note_name; 2347 char *buf; 2348 int i, error; 2349 boolean_t res; 2350 2351 /* We need some limit, might as well use PAGE_SIZE. */ 2352 if (pnote == NULL || pnote->p_filesz > PAGE_SIZE) 2353 return (FALSE); 2354 ASSERT_VOP_LOCKED(imgp->vp, "parse_notes"); 2355 if (pnote->p_offset > PAGE_SIZE || 2356 pnote->p_filesz > PAGE_SIZE - pnote->p_offset) { 2357 VOP_UNLOCK(imgp->vp, 0); 2358 buf = malloc(pnote->p_filesz, M_TEMP, M_WAITOK); 2359 vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); 2360 error = vn_rdwr(UIO_READ, imgp->vp, buf, pnote->p_filesz, 2361 pnote->p_offset, UIO_SYSSPACE, IO_NODELOCKED, 2362 curthread->td_ucred, NOCRED, NULL, curthread); 2363 if (error != 0) { 2364 uprintf("i/o error PT_NOTE\n"); 2365 res = FALSE; 2366 goto ret; 2367 } 2368 note = note0 = (const Elf_Note *)buf; 2369 note_end = (const Elf_Note *)(buf + pnote->p_filesz); 2370 } else { 2371 note = note0 = (const Elf_Note *)(imgp->image_header + 2372 pnote->p_offset); 2373 note_end = (const Elf_Note *)(imgp->image_header + 2374 pnote->p_offset + pnote->p_filesz); 2375 buf = NULL; 2376 } 2377 for (i = 0; i < 100 && note >= note0 && note < note_end; i++) { 2378 if (!aligned(note, Elf32_Addr) || (const char *)note_end - 2379 (const char *)note < sizeof(Elf_Note)) { 2380 res = FALSE; 2381 goto ret; 2382 } 2383 if (note->n_namesz != checknote->hdr.n_namesz || 2384 note->n_descsz != checknote->hdr.n_descsz || 2385 note->n_type != checknote->hdr.n_type) 2386 goto nextnote; 2387 note_name = (const char *)(note + 1); 2388 if (note_name + checknote->hdr.n_namesz >= 2389 (const char *)note_end || strncmp(checknote->vendor, 2390 note_name, checknote->hdr.n_namesz) != 0) 2391 goto nextnote; 2392 2393 /* 2394 * Fetch the osreldate for binary 2395 * from the ELF OSABI-note if necessary. 2396 */ 2397 if ((checknote->flags & BN_TRANSLATE_OSREL) != 0 && 2398 checknote->trans_osrel != NULL) { 2399 res = checknote->trans_osrel(note, osrel); 2400 goto ret; 2401 } 2402 res = TRUE; 2403 goto ret; 2404 nextnote: 2405 note = (const Elf_Note *)((const char *)(note + 1) + 2406 roundup2(note->n_namesz, ELF_NOTE_ROUNDSIZE) + 2407 roundup2(note->n_descsz, ELF_NOTE_ROUNDSIZE)); 2408 } 2409 res = FALSE; 2410 ret: 2411 free(buf, M_TEMP); 2412 return (res); 2413 } 2414 2415 /* 2416 * Try to find the appropriate ABI-note section for checknote, 2417 * fetch the osreldate for binary from the ELF OSABI-note. Only the 2418 * first page of the image is searched, the same as for headers. 2419 */ 2420 static boolean_t 2421 __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *checknote, 2422 int32_t *osrel) 2423 { 2424 const Elf_Phdr *phdr; 2425 const Elf_Ehdr *hdr; 2426 int i; 2427 2428 hdr = (const Elf_Ehdr *)imgp->image_header; 2429 phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); 2430 2431 for (i = 0; i < hdr->e_phnum; i++) { 2432 if (phdr[i].p_type == PT_NOTE && 2433 __elfN(parse_notes)(imgp, checknote, osrel, &phdr[i])) 2434 return (TRUE); 2435 } 2436 return (FALSE); 2437 2438 } 2439 2440 /* 2441 * Tell kern_execve.c about it, with a little help from the linker. 2442 */ 2443 static struct execsw __elfN(execsw) = { 2444 __CONCAT(exec_, __elfN(imgact)), 2445 __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) 2446 }; 2447 EXEC_SET(__CONCAT(elf, __ELF_WORD_SIZE), __elfN(execsw)); 2448 2449 static vm_prot_t 2450 __elfN(trans_prot)(Elf_Word flags) 2451 { 2452 vm_prot_t prot; 2453 2454 prot = 0; 2455 if (flags & PF_X) 2456 prot |= VM_PROT_EXECUTE; 2457 if (flags & PF_W) 2458 prot |= VM_PROT_WRITE; 2459 if (flags & PF_R) 2460 prot |= VM_PROT_READ; 2461 #if __ELF_WORD_SIZE == 32 2462 #if defined(__amd64__) 2463 if (i386_read_exec && (flags & PF_R)) 2464 prot |= VM_PROT_EXECUTE; 2465 #endif 2466 #endif 2467 return (prot); 2468 } 2469 2470 static Elf_Word 2471 __elfN(untrans_prot)(vm_prot_t prot) 2472 { 2473 Elf_Word flags; 2474 2475 flags = 0; 2476 if (prot & VM_PROT_EXECUTE) 2477 flags |= PF_X; 2478 if (prot & VM_PROT_READ) 2479 flags |= PF_R; 2480 if (prot & VM_PROT_WRITE) 2481 flags |= PF_W; 2482 return (flags); 2483 } 2484