37#include "opt_capsicum.h"
40#include <sys/capsicum.h>
41#include <sys/compressor.h>
44#include <sys/imgact.h>
45#include <sys/imgact_elf.h>
47#include <sys/kernel.h>
49#include <sys/malloc.h>
54#include <sys/procfs.h>
55#include <sys/ptrace.h>
58#include <sys/resourcevar.h>
59#include <sys/rwlock.h>
61#include <sys/sf_buf.h>
64#include <sys/signalvar.h>
67#include <sys/syscall.h>
68#include <sys/sysctl.h>
69#include <sys/sysent.h>
71#include <sys/syslog.h>
72#include <sys/eventhandler.h>
76#include <vm/vm_kern.h>
77#include <vm/vm_param.h>
80#include <vm/vm_object.h>
81#include <vm/vm_extern.h>
83#include <machine/elf.h>
84#include <machine/md_var.h>
86#define ELF_NOTE_ROUNDSIZE 4
91 const char *interp, int32_t *osrel, uint32_t *fctl0);
95 caddr_t vmaddr,
size_t memsz,
size_t filsz, vm_prot_t prot);
101 Elf_Brandnote *checknote, int32_t *osrel,
bool *has_fctl0,
106 struct note_info_list *list,
struct thread *target_td);
109 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
112int __elfN(fallback_brand) = -1;
114 fallback_brand, CTLFLAG_RWTUN, &
__elfN(fallback_brand), 0,
117static int elf_legacy_coredump = 0;
119 &elf_legacy_coredump, 0,
120 "include all and only RW pages in core dumps");
123#if defined(__amd64__) || defined(__powerpc64__) || \
124 (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__) || \
131 nxstack, CTLFLAG_RW, &
__elfN(nxstack), 0,
134#if defined(__amd64__)
135static int __elfN(vdso) = 1;
137 vdso, CTLFLAG_RWTUN, &
__elfN(vdso), 0,
140static int __elfN(vdso) = 0;
143#if __ELF_WORD_SIZE == 32 && (defined(__amd64__) || defined(__i386__))
144int i386_read_exec = 0;
145SYSCTL_INT(_kern_elf32, OID_AUTO, read_exec, CTLFLAG_RW, &i386_read_exec, 0,
146 "enable execution from readable segments");
149static u_long
__elfN(pie_base) = ET_DYN_LOAD_ADDR;
151sysctl_pie_base(SYSCTL_HANDLER_ARGS)
158 if (error != 0 || req->newptr == NULL)
160 if ((val & PAGE_MASK) != 0)
166 CTLTYPE_ULONG | CTLFLAG_MPSAFE | CTLFLAG_RW, NULL, 0,
167 sysctl_pie_base,
"LU",
168 "PIE load base without randomization");
171 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
173#define ASLR_NODE_OID __CONCAT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), _aslr)
185 ": enable address map randomization");
192 &
__elfN(pie_aslr_enabled), 0,
194 ": enable address map randomization for PIE binaries");
203 &
__elfN(aslr_honor_sbrk), 0,
210 ": enable stack address randomization");
214 CTLFLAG_RWTUN, &
__elfN(sigfastblock), 0,
215 "enable sigfastblock for new processes");
219 CTLFLAG_RWTUN, &
__elfN(allow_wx), 0,
220 "Allow pages to be mapped simultaneously writable and executable");
224#define aligned(a, t) (rounddown2((u_long)(a), sizeof(t)) == (u_long)(a))
226Elf_Brandnote
__elfN(freebsd_brandnote) = {
227 .hdr.n_namesz =
sizeof(FREEBSD_ABI_VENDOR),
228 .hdr.n_descsz =
sizeof(int32_t),
229 .hdr.n_type = NT_FREEBSD_ABI_TAG,
230 .vendor = FREEBSD_ABI_VENDOR,
231 .flags = BN_TRANSLATE_OSREL,
240 p = (uintptr_t)(note + 1);
242 *osrel = *(
const int32_t *)(p);
250Elf_Brandnote
__elfN(kfreebsd_brandnote) = {
255 .flags = BN_TRANSLATE_OSREL,
262 const Elf32_Word *desc;
265 p = (uintptr_t)(note + 1);
268 desc = (
const Elf32_Word *)p;
276 *osrel = desc[1] * 100000 + desc[2] * 1000 + desc[3];
286 for (i = 0; i < MAX_BRANDS; i++) {
292 if (i == MAX_BRANDS) {
293 printf(
"WARNING: %s: could not insert brandinfo entry: %p\n",
305 for (i = 0; i < MAX_BRANDS; i++) {
323 FOREACH_PROC_IN_SYSTEM(p) {
324 if (p->p_sysent == entry->sysvec) {
334static Elf_Brandinfo *
336 int32_t *osrel, uint32_t *fctl0)
338 const Elf_Ehdr *hdr = (
const Elf_Ehdr *)imgp->image_header;
339 Elf_Brandinfo *bi, *bi_m;
341 int i, interp_name_len;
343 interp_name_len = interp != NULL ? strlen(interp) + 1 : 0;
354 for (i = 0; i < MAX_BRANDS; i++) {
358 if (interp != NULL && (bi->flags & BI_BRAND_ONLY_STATIC) != 0)
360 if (hdr->e_machine == bi->machine && (bi->flags &
361 (BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) {
368 if (ret && bi->header_supported) {
369 ret = bi->header_supported(imgp, osrel,
370 has_fctl0 ? fctl0 : NULL);
382 if (ret && bi_m == NULL && interp != NULL &&
383 (bi->interp_path == NULL ||
384 (strlen(bi->interp_path) + 1 != interp_name_len ||
385 strncmp(interp, bi->interp_path, interp_name_len)
398 for (i = 0; i < MAX_BRANDS; i++) {
400 if (bi == NULL || (bi->flags & BI_BRAND_NOTE_MANDATORY) != 0 ||
401 (interp != NULL && (bi->flags & BI_BRAND_ONLY_STATIC) != 0))
403 if (hdr->e_machine == bi->machine &&
404 (hdr->e_ident[EI_OSABI] == bi->brand ||
405 (bi->compat_3_brand != NULL &&
407 bi->compat_3_brand) == 0))) {
409 if (bi->header_supported == NULL ||
410 bi->header_supported(imgp, NULL, NULL)) {
415 if (interp_name_len == 0 &&
416 bi->interp_path == NULL)
418 if (bi->interp_path != NULL &&
419 strlen(bi->interp_path) + 1 ==
420 interp_name_len && strncmp(interp,
421 bi->interp_path, interp_name_len) == 0)
432 for (i = 0; i < MAX_BRANDS; i++) {
434 if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY ||
435 bi->header_supported == NULL)
437 if (hdr->e_machine == bi->machine) {
438 ret = bi->header_supported(imgp, NULL, NULL);
445 if (interp != NULL) {
446 for (i = 0; i < MAX_BRANDS; i++) {
448 if (bi == NULL || (bi->flags &
449 (BI_BRAND_NOTE_MANDATORY | BI_BRAND_ONLY_STATIC))
452 if (hdr->e_machine == bi->machine &&
453 bi->interp_path != NULL &&
455 strlen(bi->interp_path) + 1 == interp_name_len &&
456 strncmp(interp, bi->interp_path, interp_name_len)
457 == 0 && (bi->header_supported == NULL ||
458 bi->header_supported(imgp, NULL, NULL)))
464 for (i = 0; i < MAX_BRANDS; i++) {
466 if (bi == NULL || (bi->flags & BI_BRAND_NOTE_MANDATORY) != 0 ||
467 (interp != NULL && (bi->flags & BI_BRAND_ONLY_STATIC) != 0))
469 if (hdr->e_machine == bi->machine &&
470 __elfN(fallback_brand) == bi->brand &&
471 (bi->header_supported == NULL ||
472 bi->header_supported(imgp, NULL, NULL)))
481 return (hdr->e_phoff <= PAGE_SIZE &&
482 (u_int)hdr->e_phentsize * hdr->e_phnum <= PAGE_SIZE - hdr->e_phoff);
492 hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
493 hdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
494 hdr->e_ident[EI_VERSION] != EV_CURRENT ||
495 hdr->e_phentsize !=
sizeof(Elf_Phdr) ||
496 hdr->e_version != ELF_TARG_VER)
503 for (i = 0; i < MAX_BRANDS; i++) {
505 if (bi != NULL && bi->machine == hdr->e_machine)
516 vm_offset_t
start, vm_offset_t end, vm_prot_t prot)
525 vm_map_fixed(map, NULL, 0, trunc_page(
start), round_page(end) -
526 trunc_page(
start), VM_PROT_ALL, VM_PROT_ALL, MAP_CHECK_EXCL);
531 if (
object != NULL) {
532 sf = vm_imgact_map_page(
object, offset);
534 return (KERN_FAILURE);
535 off = offset - trunc_page(offset);
536 error = copyout((caddr_t)sf_buf_kva(sf) + off, (caddr_t)
start,
538 vm_imgact_unmap_page(sf);
540 return (KERN_FAILURE);
543 return (KERN_SUCCESS);
548 vm_ooffset_t offset, vm_offset_t
start, vm_offset_t end, vm_prot_t prot,
554 int error, locked, rv;
558 round_page(
start), prot);
559 if (rv != KERN_SUCCESS)
564 if (end != round_page(end)) {
566 trunc_page(end) -
start, trunc_page(end), end, prot);
567 if (rv != KERN_SUCCESS)
569 end = trunc_page(end);
572 return (KERN_SUCCESS);
573 if ((offset & PAGE_MASK) != 0) {
578 rv = vm_map_fixed(map, NULL, 0,
start, end -
start,
579 prot | VM_PROT_WRITE, VM_PROT_ALL, MAP_CHECK_EXCL);
580 if (rv != KERN_SUCCESS)
583 return (KERN_SUCCESS);
585 sf = vm_imgact_map_page(
object, offset);
587 return (KERN_FAILURE);
588 off = offset - trunc_page(offset);
590 if (sz > PAGE_SIZE - off)
591 sz = PAGE_SIZE - off;
592 error = copyout((caddr_t)sf_buf_kva(sf) + off,
594 vm_imgact_unmap_page(sf);
596 return (KERN_FAILURE);
600 vm_object_reference(
object);
601 rv = vm_map_fixed(map,
object, offset,
start, end -
start,
602 prot, VM_PROT_ALL, cow | MAP_CHECK_EXCL |
603 (
object != NULL ? MAP_VN_EXEC : 0));
604 if (rv != KERN_SUCCESS) {
605 locked = VOP_ISLOCKED(imgp->vp);
606 VOP_UNLOCK(imgp->vp);
607 vm_object_deallocate(
object);
608 vn_lock(imgp->vp, locked | LK_RETRY);
610 }
else if (
object != NULL) {
611 MPASS(imgp->vp->v_object ==
object);
612 VOP_SET_TEXT_CHECKED(imgp->vp);
615 return (KERN_SUCCESS);
620 caddr_t vmaddr,
size_t memsz,
size_t filsz, vm_prot_t prot)
626 vm_offset_t map_addr;
629 vm_ooffset_t file_addr;
640 if ((filsz != 0 && (off_t)filsz + offset > imgp->attr->va_size) ||
642 uprintf(
"elf_load_section: truncated ELF file\n");
646 object = imgp->object;
647 map = &imgp->proc->p_vmspace->vm_map;
648 map_addr = trunc_page((vm_offset_t)vmaddr);
649 file_addr = trunc_page(offset);
659 else if (memsz > filsz)
660 map_len = trunc_page(offset + filsz) - file_addr;
662 map_len = round_page(offset + filsz) - file_addr;
666 cow = MAP_COPY_ON_WRITE | MAP_PREFAULT |
667 (prot & VM_PROT_WRITE ? 0 : MAP_DISABLE_COREDUMP);
670 map_addr, map_addr + map_len, prot, cow);
671 if (rv != KERN_SUCCESS)
685 copy_len = filsz == 0 ? 0 : (offset + filsz) - trunc_page(offset +
687 map_addr = trunc_page((vm_offset_t)vmaddr + filsz);
688 map_len = round_page((vm_offset_t)vmaddr + memsz) - map_addr;
693 map_addr + map_len, prot, 0);
694 if (rv != KERN_SUCCESS)
699 sf = vm_imgact_map_page(
object, offset + filsz);
704 error = copyout((caddr_t)sf_buf_kva(sf), (caddr_t)map_addr,
706 vm_imgact_unmap_page(sf);
715 if ((prot & VM_PROT_WRITE) == 0)
716 vm_map_protect(map, trunc_page(map_addr), round_page(map_addr +
717 map_len), prot, 0, VM_MAP_PROTECT_SET_PROT);
724 const Elf_Phdr *phdr, u_long rbase, u_long *base_addrp)
731 ASSERT_VOP_LOCKED(imgp->vp, __func__);
736 for (i = 0; i < hdr->e_phnum; i++) {
737 if (phdr[i].p_type != PT_LOAD || phdr[i].p_memsz == 0)
743 (caddr_t)(uintptr_t)phdr[i].p_vaddr + rbase,
744 phdr[i].p_memsz, phdr[i].p_filesz, prot);
752 base_addr = trunc_page(phdr[i].p_vaddr + rbase);
757 if (base_addrp != NULL)
758 *base_addrp = base_addr;
782 struct image_params image_params;
784 const Elf_Ehdr *hdr = NULL;
785 const Elf_Phdr *phdr = NULL;
786 struct nameidata *nd;
788 struct image_params *imgp;
790 u_long base_addr = 0;
793#ifdef CAPABILITY_MODE
798 if (IN_CAPABILITY_MODE(curthread))
802 tempdata =
malloc(
sizeof(*tempdata), M_TEMP, M_WAITOK | M_ZERO);
804 attr = &tempdata->attr;
805 imgp = &tempdata->image_params;
813 NDINIT(nd, LOOKUP, ISOPEN | FOLLOW | LOCKSHARED | LOCKLEAF,
815 if ((error =
namei(nd)) != 0) {
819 NDFREE(nd, NDF_ONLY_PNBUF);
820 imgp->vp = nd->ni_vp;
833 imgp->object = nd->ni_vp->v_object;
835 hdr = (
const Elf_Ehdr *)imgp->image_header;
838 if (hdr->e_type == ET_DYN)
840 else if (hdr->e_type == ET_EXEC)
853 phdr = (
const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
854 if (!
aligned(phdr, Elf_Addr)) {
864 *entry = (
unsigned long)hdr->e_entry + rbase;
872 VOP_UNSET_TEXT_CHECKED(nd->ni_vp);
875 free(tempdata, M_TEMP);
892 u_int align, u_long *resp)
896 MPASS(vm_map_min(map) <= minv);
898 if (minv >= maxv || minv + align >= maxv || maxv > vm_map_max(map)) {
899 uprintf(
"Invalid ELF segments layout\n");
903 arc4rand(&rbase,
sizeof(rbase), 0);
904 res = roundup(minv, (u_long)align) + rbase % (maxv - minv);
905 res &= ~((u_long)align - 1);
910 (
"res %#lx < minv %#lx, maxv %#lx rbase %#lx",
911 res, minv, maxv, rbase));
913 (
"res %#lx > maxv %#lx, minv %#lx rbase %#lx",
914 res, maxv, minv, rbase));
922 const Elf_Phdr *phdr, u_long et_dyn_addr)
924 struct vmspace *vmspace;
926 u_long text_size, data_size, total_size, text_addr, data_addr;
927 u_long seg_size, seg_addr;
931 text_size = data_size = total_size = text_addr = data_addr = 0;
933 for (i = 0; i < hdr->e_phnum; i++) {
934 if (phdr[i].p_type != PT_LOAD || phdr[i].p_memsz == 0)
937 seg_addr = trunc_page(phdr[i].p_vaddr + et_dyn_addr);
938 seg_size = round_page(phdr[i].p_memsz +
939 phdr[i].p_vaddr + et_dyn_addr - seg_addr);
951 if ((phdr[i].p_flags & PF_X) != 0 && text_size < seg_size) {
952 text_size = seg_size;
953 text_addr = seg_addr;
955 data_size = seg_size;
956 data_addr = seg_addr;
958 total_size += seg_size;
961 if (data_addr == 0 && data_size == 0) {
962 data_addr = text_addr;
963 data_size = text_size;
971 PROC_LOCK(imgp->proc);
973 err_str =
"Data segment size exceeds process limit";
975 err_str =
"Text segment size exceeds system limit";
976 else if (total_size >
lim_cur_proc(imgp->proc, RLIMIT_VMEM))
977 err_str =
"Total segment size exceeds process limit";
978 else if (racct_set(imgp->proc, RACCT_DATA, data_size) != 0)
979 err_str =
"Data segment size exceeds resource limit";
980 else if (racct_set(imgp->proc, RACCT_VMEM, total_size) != 0)
981 err_str =
"Total segment size exceeds resource limit";
982 PROC_UNLOCK(imgp->proc);
983 if (err_str != NULL) {
988 vmspace = imgp->proc->p_vmspace;
989 vmspace->vm_tsize = text_size >> PAGE_SHIFT;
990 vmspace->vm_taddr = (caddr_t)(uintptr_t)text_addr;
991 vmspace->vm_dsize = data_size >> PAGE_SHIFT;
992 vmspace->vm_daddr = (caddr_t)(uintptr_t)data_addr;
999 char **interpp,
bool *free_interpp)
1003 int error, interp_name_len;
1005 KASSERT(phdr->p_type == PT_INTERP,
1006 (
"%s: p_type %u != PT_INTERP", __func__, phdr->p_type));
1007 ASSERT_VOP_LOCKED(imgp->vp, __func__);
1012 if (phdr->p_filesz < 2 || phdr->p_filesz > MAXPATHLEN) {
1013 uprintf(
"Invalid PT_INTERP\n");
1017 interp_name_len = phdr->p_filesz;
1018 if (phdr->p_offset > PAGE_SIZE ||
1019 interp_name_len > PAGE_SIZE - phdr->p_offset) {
1029 interp =
malloc(interp_name_len + 1, M_TEMP, M_NOWAIT);
1030 if (interp == NULL) {
1031 VOP_UNLOCK(imgp->vp);
1032 interp =
malloc(interp_name_len + 1, M_TEMP, M_WAITOK);
1033 vn_lock(imgp->vp, LK_SHARED | LK_RETRY);
1036 error =
vn_rdwr(UIO_READ, imgp->vp, interp,
1037 interp_name_len, phdr->p_offset,
1038 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
1041 free(interp, M_TEMP);
1042 uprintf(
"i/o error PT_INTERP %d\n", error);
1045 interp[interp_name_len] =
'\0';
1048 *free_interpp =
true;
1052 interp = __DECONST(
char *, imgp->image_header) + phdr->p_offset;
1053 if (interp[interp_name_len - 1] !=
'\0') {
1054 uprintf(
"Invalid PT_INTERP\n");
1059 *free_interpp =
false;
1065 const char *interp, u_long *
addr, u_long *entry)
1070 if (brand_info->emul_path != NULL &&
1071 brand_info->emul_path[0] !=
'\0') {
1074 brand_info->emul_path, interp);
1081 if (brand_info->interp_newpath != NULL &&
1082 (brand_info->interp_path == NULL ||
1083 strcmp(interp, brand_info->interp_path) == 0)) {
1085 brand_info->interp_newpath,
addr, entry);
1094 uprintf(
"ELF interpreter %s not found, error %d\n", interp, error);
1102#define ET_DYN_ADDR_RAND 1
1108 const Elf_Ehdr *hdr;
1109 const Elf_Phdr *phdr;
1110 Elf_Auxargs *elf_auxargs;
1111 struct vmspace *vmspace;
1114 Elf_Brandinfo *brand_info;
1115 struct sysentvec *sv;
1116 u_long
addr, baddr, et_dyn_addr, entry, proghdr;
1117 u_long maxalign, maxsalign, mapsz, maxv, maxv1, anon_loc;
1123 hdr = (
const Elf_Ehdr *)imgp->image_header;
1132 (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN))
1141 uprintf(
"Program headers not in the first page\n");
1144 phdr = (
const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
1145 if (!
aligned(phdr, Elf_Addr)) {
1146 uprintf(
"Unaligned program headers\n");
1154 entry = proghdr = 0;
1156 free_interp =
false;
1165 maxalign = PAGE_SIZE;
1166 maxsalign = PAGE_SIZE * 1024;
1167 for (i = MAXPAGESIZES - 1; i > 0; i--) {
1174 for (i = 0; i < hdr->e_phnum; i++) {
1175 switch (phdr[i].p_type) {
1178 baddr = phdr[i].p_vaddr;
1179 if (!powerof2(phdr[i].p_align) ||
1180 phdr[i].p_align > maxsalign) {
1181 uprintf(
"Invalid segment alignment\n");
1185 if (phdr[i].p_align > maxalign)
1186 maxalign = phdr[i].p_align;
1187 if (mapsz + phdr[i].p_memsz < mapsz) {
1188 uprintf(
"Mapsize overflow\n");
1192 mapsz += phdr[i].p_memsz;
1201 if (phdr[i].p_offset == 0 &&
1202 hdr->e_phoff + hdr->e_phnum * hdr->e_phentsize <=
1204 proghdr = phdr[i].p_vaddr + hdr->e_phoff;
1208 if (interp != NULL) {
1209 uprintf(
"Multiple PT_INTERP headers\n");
1222 imgp->stack_sz = phdr[i].p_memsz;
1225 proghdr = phdr[i].p_vaddr;
1231 if (brand_info == NULL) {
1232 uprintf(
"ELF binary type \"%u\" not known.\n",
1233 hdr->e_ident[EI_OSABI]);
1237 sv = brand_info->sysvec;
1239 if (hdr->e_type == ET_DYN) {
1240 if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) {
1241 uprintf(
"Cannot execute shared object\n");
1250 if ((sv->sv_flags & SV_ASLR) == 0 ||
1251 (fctl0 & NT_FREEBSD_FCTL_ASLR_DISABLE) != 0)
1252 et_dyn_addr =
__elfN(pie_base);
1253 else if ((
__elfN(pie_aslr_enabled) &&
1254 (imgp->proc->p_flag2 & P2_ASLR_DISABLE) == 0) ||
1255 (imgp->proc->p_flag2 & P2_ASLR_ENABLE) != 0)
1258 et_dyn_addr =
__elfN(pie_base);
1273 VOP_UNLOCK(imgp->vp);
1282 if (imgp->credential_setid) {
1283 PROC_LOCK(imgp->proc);
1284 imgp->proc->p_flag2 &= ~(P2_ASLR_ENABLE | P2_ASLR_DISABLE |
1285 P2_WXORX_DISABLE | P2_WXORX_ENABLE_EXEC);
1286 PROC_UNLOCK(imgp->proc);
1288 if ((sv->sv_flags & SV_ASLR) == 0 ||
1289 (imgp->proc->p_flag2 & P2_ASLR_DISABLE) != 0 ||
1290 (fctl0 & NT_FREEBSD_FCTL_ASLR_DISABLE) != 0) {
1292 (
"et_dyn_addr == RAND and !ASLR"));
1293 }
else if ((imgp->proc->p_flag2 & P2_ASLR_ENABLE) != 0 ||
1294 (
__elfN(aslr_enabled) && hdr->e_type == ET_EXEC) ||
1296 imgp->map_flags |= MAP_ASLR;
1303 if (!
__elfN(aslr_honor_sbrk) ||
1304 (imgp->proc->p_flag2 & P2_ASLR_IGNSTART) != 0)
1305 imgp->map_flags |= MAP_ASLR_IGNSTART;
1307 imgp->map_flags |= MAP_ASLR_STACK;
1310 if ((!
__elfN(allow_wx) && (fctl0 & NT_FREEBSD_FCTL_WXNEEDED) == 0 &&
1311 (imgp->proc->p_flag2 & P2_WXORX_DISABLE) == 0) ||
1312 (imgp->proc->p_flag2 & P2_WXORX_ENABLE_EXEC) != 0)
1313 imgp->map_flags |= MAP_WXORX;
1317 imgp->proc->p_sysent = sv;
1318 imgp->proc->p_elf_brandinfo = brand_info;
1320 vmspace = imgp->proc->p_vmspace;
1321 map = &vmspace->vm_map;
1322 maxv = sv->sv_usrstack;
1323 if ((imgp->map_flags & MAP_ASLR_STACK) == 0)
1324 maxv -=
lim_max(td, RLIMIT_STACK);
1325 if (error == 0 && mapsz >= maxv - vm_map_min(map)) {
1326 uprintf(
"Excessive mapping size\n");
1331 KASSERT((map->flags & MAP_ASLR) != 0,
1332 (
"ET_DYN_ADDR_RAND but !MAP_ASLR"));
1334 vm_map_min(map) + mapsz +
lim_max(td, RLIMIT_DATA),
1336 maxv / 2, maxalign, &et_dyn_addr);
1339 vn_lock(imgp->vp, LK_SHARED | LK_RETRY);
1357 addr = round_page((vm_offset_t)vmspace->vm_daddr +
lim_max(td,
1359 if ((map->flags & MAP_ASLR) != 0) {
1360 maxv1 = maxv / 2 +
addr / 2;
1362 (MAXPAGESIZES > 1 &&
pagesizes[1] != 0) ?
1366 map->anon_loc = anon_loc;
1368 map->anon_loc =
addr;
1371 entry = (u_long)hdr->e_entry + et_dyn_addr;
1372 imgp->entry_addr = entry;
1374 if (interp != NULL) {
1375 VOP_UNLOCK(imgp->vp);
1376 if ((map->flags & MAP_ASLR) != 0) {
1378 maxv1 = maxv / 2 +
addr / 2;
1380 maxv1, PAGE_SIZE, &
addr);
1384 &
addr, &imgp->entry_addr);
1386 vn_lock(imgp->vp, LK_SHARED | LK_RETRY);
1399 elf_auxargs =
malloc(
sizeof(Elf_Auxargs), M_TEMP, M_NOWAIT);
1400 if (elf_auxargs == NULL) {
1401 VOP_UNLOCK(imgp->vp);
1402 elf_auxargs =
malloc(
sizeof(Elf_Auxargs), M_TEMP, M_WAITOK);
1403 vn_lock(imgp->vp, LK_SHARED | LK_RETRY);
1405 elf_auxargs->execfd = -1;
1406 elf_auxargs->phdr = proghdr + et_dyn_addr;
1407 elf_auxargs->phent = hdr->e_phentsize;
1408 elf_auxargs->phnum = hdr->e_phnum;
1409 elf_auxargs->pagesz = PAGE_SIZE;
1410 elf_auxargs->base =
addr;
1411 elf_auxargs->flags = 0;
1412 elf_auxargs->entry = entry;
1413 elf_auxargs->hdr_eflags = hdr->e_flags;
1415 imgp->auxargs = elf_auxargs;
1416 imgp->interpreted = 0;
1417 imgp->reloc_base =
addr;
1418 imgp->proc->p_osrel = osrel;
1419 imgp->proc->p_fctl0 = fctl0;
1420 imgp->proc->p_elf_flags = hdr->e_flags;
1423 ASSERT_VOP_LOCKED(imgp->vp,
"skipped relock");
1425 free(interp, M_TEMP);
1429#define elf_suword __CONCAT(suword, __ELF_WORD_SIZE)
1434 Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs;
1435 Elf_Auxinfo *argarray, *pos;
1438 argarray = pos =
malloc(AT_COUNT *
sizeof(*pos), M_TEMP,
1441 if (args->execfd != -1)
1442 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
1443 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
1444 AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
1445 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
1446 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
1447 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
1448 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
1449 AUXARGS_ENTRY(pos, AT_BASE, args->base);
1450 AUXARGS_ENTRY(pos, AT_EHDRFLAGS, args->hdr_eflags);
1451 if (imgp->execpathp != 0)
1452 AUXARGS_ENTRY_PTR(pos, AT_EXECPATH, imgp->execpathp);
1453 AUXARGS_ENTRY(pos, AT_OSRELDATE,
1454 imgp->proc->p_ucred->cr_prison->pr_osreldate);
1455 if (imgp->canary != 0) {
1456 AUXARGS_ENTRY_PTR(pos, AT_CANARY, imgp->canary);
1457 AUXARGS_ENTRY(pos, AT_CANARYLEN, imgp->canarylen);
1459 AUXARGS_ENTRY(pos, AT_NCPUS,
mp_ncpus);
1460 if (imgp->pagesizes != 0) {
1461 AUXARGS_ENTRY_PTR(pos, AT_PAGESIZES, imgp->pagesizes);
1462 AUXARGS_ENTRY(pos, AT_PAGESIZESLEN, imgp->pagesizeslen);
1464 if (imgp->sysent->sv_timekeep_base != 0) {
1465 AUXARGS_ENTRY(pos, AT_TIMEKEEP,
1466 imgp->sysent->sv_timekeep_base);
1468 AUXARGS_ENTRY(pos, AT_STACKPROT, imgp->sysent->sv_shared_page_obj
1469 != NULL && imgp->stack_prot != 0 ? imgp->stack_prot :
1470 imgp->sysent->sv_stackprot);
1471 if (imgp->sysent->sv_hwcap != NULL)
1472 AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap);
1473 if (imgp->sysent->sv_hwcap2 != NULL)
1474 AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2);
1475 AUXARGS_ENTRY(pos, AT_BSDFLAGS,
__elfN(sigfastblock) ?
1476 ELF_BSDF_SIGFASTBLK : 0);
1477 AUXARGS_ENTRY(pos, AT_ARGC, imgp->args->argc);
1478 AUXARGS_ENTRY_PTR(pos, AT_ARGV, imgp->argv);
1479 AUXARGS_ENTRY(pos, AT_ENVC, imgp->args->envc);
1480 AUXARGS_ENTRY_PTR(pos, AT_ENVV, imgp->envv);
1481 AUXARGS_ENTRY_PTR(pos, AT_PS_STRINGS, imgp->ps_strings);
1482 if (imgp->sysent->sv_fxrng_gen_base != 0)
1483 AUXARGS_ENTRY(pos, AT_FXRNG, imgp->sysent->sv_fxrng_gen_base);
1484 if (imgp->sysent->sv_vdso_base != 0 &&
__elfN(vdso) != 0)
1485 AUXARGS_ENTRY(pos, AT_KPRELOAD, imgp->sysent->sv_vdso_base);
1486 AUXARGS_ENTRY(pos, AT_NULL, 0);
1488 free(imgp->auxargs, M_TEMP);
1489 imgp->auxargs = NULL;
1490 KASSERT(pos - argarray <= AT_COUNT, (
"Too many auxargs"));
1492 error = copyout(argarray, (
void *)base,
sizeof(*argarray) * AT_COUNT);
1493 free(argarray, M_TEMP);
1502 base = (Elf_Addr *)*stack_base;
1504 if (
elf_suword(base, imgp->args->argc) == -1)
1506 *stack_base = (uintptr_t)base;
1540static int __elfN(
corehdr)(
struct coredump_params *, int,
void *, size_t,
1541 struct note_info_list *, size_t, int);
1562 return (
core_write((
struct coredump_params *)arg, base, len, offset,
1563 UIO_SYSSPACE, NULL));
1569 struct ucred *cred = td->td_ucred;
1570 int compm, error = 0;
1571 struct sseg_closure seginfo;
1572 struct note_info_list notelst;
1573 struct coredump_params params;
1576 size_t hdrsize, notesz, coresize;
1580 TAILQ_INIT(¬elst);
1588 hdrsize =
sizeof(Elf_Ehdr) +
sizeof(Elf_Phdr) * (1 + seginfo.count);
1589 if (seginfo.count + 1 >= PN_XNUM)
1590 hdrsize +=
sizeof(Elf_Shdr);
1591 td->td_proc->p_sysent->sv_elf_core_prepare_notes(td, ¬elst, ¬esz);
1592 coresize = round_page(hdrsize + notesz) + seginfo.size;
1596 params.active_cred = cred;
1597 params.file_cred = NOCRED;
1604 PROC_LOCK(td->td_proc);
1605 error = racct_add(td->td_proc, RACCT_CORE, coresize);
1606 PROC_UNLOCK(td->td_proc);
1613 if (coresize >= limit) {
1620 if ((
flags & (SVC_PT_COREDUMP | SVC_NOCOMPRESS)) == SVC_PT_COREDUMP &&
1622 compm = COMPRESS_GZIP;
1625 compm, CORE_BUF_SIZE,
1627 if (params.comp == NULL) {
1631 tmpbuf =
malloc(CORE_BUF_SIZE, M_TEMP, M_WAITOK | M_ZERO);
1638 hdr =
malloc(hdrsize, M_TEMP, M_WAITOK);
1639 error =
__elfN(
corehdr)(¶ms, seginfo.count, hdr, hdrsize, ¬elst,
1648 php = (Elf_Phdr *)((
char *)hdr +
sizeof(Elf_Ehdr)) + 1;
1649 offset = round_page(hdrsize + notesz);
1650 for (i = 0; i < seginfo.count; i++) {
1651 error =
core_output((
char *)(uintptr_t)php->p_vaddr,
1652 php->p_filesz, offset, ¶ms, tmpbuf);
1655 offset += php->p_filesz;
1658 if (error == 0 && params.comp != NULL)
1663 "Failed to write core file for process %s (error %d)\n",
1664 curproc->p_comm, error);
1668 free(tmpbuf, M_TEMP);
1669 if (params.comp != NULL)
1671 while ((ninfo = TAILQ_FIRST(¬elst)) != NULL) {
1672 TAILQ_REMOVE(¬elst, ninfo, link);
1673 free(ninfo, M_TEMP);
1693 phdr->p_type = PT_LOAD;
1695 phdr->p_vaddr = entry->start;
1697 phdr->p_filesz =
phdr->p_memsz = entry->end - entry->start;
1698 phdr->p_align = PAGE_SIZE;
1712 struct sseg_closure *ssc = (
struct sseg_closure *)closure;
1715 ssc->size += entry->end - entry->start;
1737 struct proc *p = td->td_proc;
1738 vm_map_t map = &p->p_vmspace->vm_map;
1739 vm_map_entry_t entry;
1740 vm_object_t backing_object, object;
1743 vm_map_lock_read(map);
1744 VM_MAP_ENTRY_FOREACH(entry, map) {
1753 if ((
flags & SVC_ALL) == 0) {
1754 if (elf_legacy_coredump) {
1755 if ((entry->protection & VM_PROT_RW) !=
1759 if ((entry->protection & VM_PROT_ALL) == 0)
1770 if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0)
1772 if ((entry->eflags & MAP_ENTRY_NOCOREDUMP) != 0 &&
1773 (
flags & SVC_ALL) == 0)
1775 if ((
object = entry->object.vm_object) == NULL)
1779 VM_OBJECT_RLOCK(
object);
1780 while ((backing_object = object->backing_object) != NULL) {
1781 VM_OBJECT_RLOCK(backing_object);
1782 VM_OBJECT_RUNLOCK(
object);
1783 object = backing_object;
1785 ignore_entry = (
object->flags & OBJ_FICTITIOUS) != 0;
1786 VM_OBJECT_RUNLOCK(
object);
1790 (*func)(entry, closure);
1792 vm_map_unlock_read(map);
1801 size_t hdrsize,
struct note_info_list *notelst,
size_t notesz,
1809 bzero(hdr, hdrsize);
1812 sb =
sbuf_new(NULL, NULL, CORE_BUF_SIZE, SBUF_FIXEDLEN);
1816 TAILQ_FOREACH(ninfo, notelst, link)
1847 while (thr != NULL) {
1856 thr = thr == td ? TAILQ_FIRST(&p->p_threads) :
1857 TAILQ_NEXT(thr, td_plist);
1859 thr = TAILQ_NEXT(thr, td_plist);
1886 size_t notesz,
int flags)
1894 ehdr = (Elf_Ehdr *)hdr;
1895 bi = td->td_proc->p_elf_brandinfo;
1897 ehdr->e_ident[EI_MAG0] = ELFMAG0;
1898 ehdr->e_ident[EI_MAG1] = ELFMAG1;
1899 ehdr->e_ident[EI_MAG2] = ELFMAG2;
1900 ehdr->e_ident[EI_MAG3] = ELFMAG3;
1901 ehdr->e_ident[EI_CLASS] = ELF_CLASS;
1902 ehdr->e_ident[EI_DATA] = ELF_DATA;
1903 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
1904 ehdr->e_ident[EI_OSABI] = td->td_proc->p_sysent->sv_elf_core_osabi;
1905 ehdr->e_ident[EI_ABIVERSION] = 0;
1906 ehdr->e_ident[EI_PAD] = 0;
1907 ehdr->e_type = ET_CORE;
1908 ehdr->e_machine = bi->machine;
1909 ehdr->e_version = EV_CURRENT;
1911 ehdr->e_phoff =
sizeof(Elf_Ehdr);
1912 ehdr->e_flags = td->td_proc->p_elf_flags;
1913 ehdr->e_ehsize =
sizeof(Elf_Ehdr);
1914 ehdr->e_phentsize =
sizeof(Elf_Phdr);
1915 ehdr->e_shentsize =
sizeof(Elf_Shdr);
1916 ehdr->e_shstrndx = SHN_UNDEF;
1917 if (numsegs + 1 < PN_XNUM) {
1918 ehdr->e_phnum = numsegs + 1;
1921 ehdr->e_phnum = PN_XNUM;
1924 ehdr->e_shoff = ehdr->e_phoff +
1925 (numsegs + 1) * ehdr->e_phentsize;
1926 KASSERT(ehdr->e_shoff == hdrsize -
sizeof(Elf_Shdr),
1927 (
"e_shoff: %zu, hdrsize - shdr: %zu",
1928 (size_t)ehdr->e_shoff, hdrsize -
sizeof(Elf_Shdr)));
1930 shdr = (Elf_Shdr *)((
char *)hdr + ehdr->e_shoff);
1931 memset(shdr, 0,
sizeof(*shdr));
1942 shdr->sh_type = SHT_NULL;
1943 shdr->sh_size = ehdr->e_shnum;
1944 shdr->sh_link = ehdr->e_shstrndx;
1945 shdr->sh_info = numsegs + 1;
1951 phdr = (Elf_Phdr *)((
char *)hdr + ehdr->e_phoff);
1954 phdr->p_type = PT_NOTE;
1955 phdr->p_offset = hdrsize;
1958 phdr->p_filesz = notesz;
1960 phdr->p_flags = PF_R;
1966 phc.
offset = round_page(hdrsize + notesz);
1972 struct regset *regset,
struct thread *target_td)
1974 const struct sysentvec *sv;
1976 size_t size, notesize;
1979 if (!
regset->get(
regset, target_td, NULL, &size) || size == 0)
1982 ninfo =
malloc(
sizeof(*ninfo), M_TEMP, M_ZERO | M_WAITOK);
1985 ninfo->
outarg = target_td;
1987 TAILQ_INSERT_TAIL(list, ninfo, link);
1989 sv = td->td_proc->p_sysent;
1990 notesize =
sizeof(Elf_Note) +
2000 int type, outfunc_t out,
void *arg)
2002 const struct sysentvec *sv;
2004 size_t size, notesize;
2006 sv = td->td_proc->p_sysent;
2008 out(arg, NULL, &size);
2009 ninfo =
malloc(
sizeof(*ninfo), M_TEMP, M_ZERO | M_WAITOK);
2014 TAILQ_INSERT_TAIL(list, ninfo, link);
2019 notesize =
sizeof(Elf_Note) +
2034 bcopy(
src, dst, len);
2035 bzero((
char *)dst + len, padded_len - len);
2037 return (padded_len);
2049 note = (Elf_Note *)
buf;
2050 note->n_namesz =
sizeof(FREEBSD_ABI_VENDOR);
2051 note->n_descsz = size;
2052 note->n_type =
type;
2053 buf +=
sizeof(*note);
2055 sizeof(FREEBSD_ABI_VENDOR));
2061 notesize =
sizeof(Elf_Note) +
2073 const struct sysentvec *sv;
2074 ssize_t old_len, sect_len;
2075 size_t new_len, descsz, i;
2077 if (ninfo->
type == -1) {
2082 sv = td->td_proc->p_sysent;
2084 note.n_namesz = strlen(sv->sv_elf_core_abi_vendor) + 1;
2085 note.n_descsz = ninfo->
outsize;
2086 note.n_type = ninfo->
type;
2090 sbuf_bcat(sb, sv->sv_elf_core_abi_vendor,
2091 strlen(sv->sv_elf_core_abi_vendor) + 1);
2093 if (note.n_descsz == 0)
2096 if (ninfo->
regset != NULL) {
2097 struct regset *regset = ninfo->
regset;
2110 new_len = (size_t)sect_len;
2112 if (new_len < descsz) {
2119 for (i = 0; i < descsz - new_len; i++)
2121 }
else if (new_len > descsz) {
2126 KASSERT(new_len == descsz, (
"%s: Note type %u changed as we "
2127 "read it (%zu > %zu). Since it is longer than "
2128 "expected, this coredump's notes are corrupt. THIS "
2129 "IS A BUG in the note_procstat routine for type %u.\n",
2130 __func__, (
unsigned)note.n_type, new_len, descsz,
2131 (
unsigned)note.n_type));
2139#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
2140#include <compat/freebsd32/freebsd32.h>
2141#include <compat/freebsd32/freebsd32_signal.h>
2149#define ELF_KERN_PROC_MASK KERN_PROC_MASK32
2159#define ELF_KERN_PROC_MASK 0
2176 KASSERT(*sizep ==
sizeof(*psinfo), (
"invalid size"));
2177 psinfo =
malloc(
sizeof(*psinfo), M_TEMP, M_ZERO | M_WAITOK);
2178 psinfo->pr_version = PRPSINFO_VERSION;
2180 strlcpy(psinfo->pr_fname, p->p_comm,
sizeof(psinfo->pr_fname));
2182 if (p->p_args != NULL) {
2183 len =
sizeof(psinfo->pr_psargs) - 1;
2184 if (len > p->p_args->ar_length)
2185 len = p->p_args->ar_length;
2186 memcpy(psinfo->pr_psargs, p->p_args->ar_args, len);
2192 sbuf_new(&sbarg, psinfo->pr_psargs,
2193 sizeof(psinfo->pr_psargs), SBUF_FIXEDLEN);
2199 len =
sizeof(psinfo->pr_psargs) - 1;
2202 if (error || len == 0)
2203 strlcpy(psinfo->pr_psargs, p->p_comm,
2204 sizeof(psinfo->pr_psargs));
2206 KASSERT(len <
sizeof(psinfo->pr_psargs),
2207 (
"len is too long: %zu vs %zu", len,
2208 sizeof(psinfo->pr_psargs)));
2209 cp = psinfo->pr_psargs;
2212 cp = memchr(cp,
'\0', end - cp);
2218 psinfo->pr_pid = p->p_pid;
2220 free(psinfo, M_TEMP);
2222 *sizep =
sizeof(*psinfo);
2232 KASSERT(*sizep ==
sizeof(*status), (
"%s: invalid size",
2235 status->pr_version = PRSTATUS_VERSION;
2239 status->pr_osreldate = osreldate;
2240 status->pr_cursig = td->td_proc->p_sig;
2241 status->pr_pid = td->td_tid;
2242#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
2243 fill_regs32(td, &status->pr_reg);
2245 fill_regs(td, &status->pr_reg);
2248 *sizep =
sizeof(*status);
2258 KASSERT(size ==
sizeof(*status), (
"%s: invalid size", __func__));
2260#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
2261 set_regs32(td, &status->pr_reg);
2263 set_regs(td, &status->pr_reg);
2268static struct regset
__elfN(regset_prstatus) = {
2269 .note = NT_PRSTATUS,
2283 KASSERT(*sizep ==
sizeof(*fpregset), (
"%s: invalid size",
2286#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
2287 fill_fpregs32(td, fpregset);
2289 fill_fpregs(td, fpregset);
2292 *sizep =
sizeof(*fpregset);
2303 KASSERT(size ==
sizeof(*fpregset), (
"%s: invalid size", __func__));
2304#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
2305 set_fpregs32(td, fpregset);
2307 set_fpregs(td, fpregset);
2312static struct regset
__elfN(regset_fpregset) = {
2313 .note = NT_FPREGSET,
2322 struct thread *target_td)
2324 struct sysentvec *sv = td->td_proc->p_sysent;
2325 struct regset **regsetp, **regset_end, *regset;
2334 regsetp = sv->sv_regset_begin;
2335 if (regsetp == NULL) {
2338 &
__elfN(regset_fpregset), target_td);
2341 regset_end = sv->sv_regset_end;
2342 MPASS(regset_end != NULL);
2343 for (; regsetp < regset_end; regsetp++) {
2345 if (regset->note == NT_PRSTATUS)
2361 KASSERT(*sizep ==
sizeof(thrmisc), (
"invalid size"));
2362 bzero(&thrmisc,
sizeof(thrmisc));
2363 strcpy(thrmisc.pr_tname, td->td_name);
2364 sbuf_bcat(sb, &thrmisc,
sizeof(thrmisc));
2366 *sizep =
sizeof(thrmisc);
2375#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
2376 struct ptrace_lwpinfo32 pl;
2378 struct ptrace_lwpinfo pl;
2382 size =
sizeof(structsize) +
sizeof(pl);
2384 KASSERT(*sizep == size, (
"invalid size"));
2385 structsize =
sizeof(pl);
2386 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2387 bzero(&pl,
sizeof(pl));
2388 pl.pl_lwpid = td->td_tid;
2389 pl.pl_event = PL_EVENT_NONE;
2390 pl.pl_sigmask = td->td_sigmask;
2391 pl.pl_siglist = td->td_siglist;
2392 if (td->td_si.si_signo != 0) {
2393 pl.pl_event = PL_EVENT_SIGNAL;
2394 pl.pl_flags |= PL_FLAG_SI;
2395#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
2396 siginfo_to_siginfo32(&td->td_si, &pl.pl_siginfo);
2398 pl.pl_siginfo = td->td_si;
2401 strcpy(pl.pl_tdname, td->td_name);
2419 td = (
struct thread *)arg;
2421 if (size != 0 && sb != NULL)
2422 buf =
malloc(size, M_TEMP, M_ZERO | M_WAITOK);
2427 KASSERT(sb == NULL || *sizep == size, (
"invalid size"));
2428 if (size != 0 && sb != NULL)
2434#ifdef KINFO_PROC_SIZE
2435CTASSERT(
sizeof(
struct kinfo_proc) == KINFO_PROC_SIZE);
2446 size =
sizeof(structsize) + p->p_numthreads *
2450 KASSERT(*sizep == size, (
"invalid size"));
2452 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2461#ifdef KINFO_FILE_SIZE
2462CTASSERT(
sizeof(
struct kinfo_file) == KINFO_FILE_SIZE);
2469 size_t size, sect_sz, i;
2470 ssize_t start_len, sect_len;
2471 int structsize, filedesc_flags;
2474 filedesc_flags = KERN_FILEDESC_PACK_KINFO;
2479 structsize =
sizeof(
struct kinfo_file);
2482 sb =
sbuf_new(NULL, NULL, 128, SBUF_FIXEDLEN);
2484 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2493 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2503 KASSERT(sect_sz <= *sizep,
2504 (
"kern_proc_filedesc_out did not respect maxlen; "
2505 "requested %zu, got %zu", *sizep -
sizeof(structsize),
2506 sect_sz -
sizeof(structsize)));
2508 for (i = 0; i < *sizep - sect_sz && sb->s_error == 0; i++)
2513#ifdef KINFO_VMENTRY_SIZE
2514CTASSERT(
sizeof(
struct kinfo_vmentry) == KINFO_VMENTRY_SIZE);
2522 int structsize, vmmap_flags;
2525 vmmap_flags = KERN_VMMAP_PACK_KINFO;
2530 structsize =
sizeof(
struct kinfo_vmentry);
2533 sb =
sbuf_new(NULL, NULL, 128, SBUF_FIXEDLEN);
2535 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2542 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2557 size =
sizeof(structsize) + p->p_ucred->cr_ngroups *
sizeof(gid_t);
2559 KASSERT(*sizep == size, (
"invalid size"));
2560 structsize =
sizeof(gid_t);
2561 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2562 sbuf_bcat(sb, p->p_ucred->cr_groups, p->p_ucred->cr_ngroups *
2576 size =
sizeof(structsize) +
sizeof(p->p_pd->pd_cmask);
2578 KASSERT(*sizep == size, (
"invalid size"));
2579 structsize =
sizeof(p->p_pd->pd_cmask);
2580 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2581 sbuf_bcat(sb, &p->p_pd->pd_cmask,
sizeof(p->p_pd->pd_cmask));
2590 struct rlimit rlim[RLIM_NLIMITS];
2595 size =
sizeof(structsize) +
sizeof(rlim);
2597 KASSERT(*sizep == size, (
"invalid size"));
2598 structsize =
sizeof(rlim);
2599 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2601 for (i = 0; i < RLIM_NLIMITS; i++)
2617 size =
sizeof(structsize) +
sizeof(p->p_osrel);
2619 KASSERT(*sizep == size, (
"invalid size"));
2620 structsize =
sizeof(p->p_osrel);
2621 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2622 sbuf_bcat(sb, &p->p_osrel,
sizeof(p->p_osrel));
2636 size =
sizeof(structsize) +
sizeof(ps_strings);
2638 KASSERT(*sizep == size, (
"invalid size"));
2639 structsize =
sizeof(ps_strings);
2640#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
2641 ps_strings = PTROUT(PROC_PS_STRINGS(p));
2643 ps_strings = PROC_PS_STRINGS(p);
2645 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2646 sbuf_bcat(sb, &ps_strings,
sizeof(ps_strings));
2661 sb =
sbuf_new(NULL, NULL, AT_COUNT *
sizeof(Elf_Auxinfo),
2664 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2672 structsize =
sizeof(Elf_Auxinfo);
2673 sbuf_bcat(sb, &structsize,
sizeof(structsize));
2682 const char *note_vendor,
const Elf_Phdr *pnote,
2683 bool (*cb)(
const Elf_Note *,
void *,
bool *),
void *cb_arg)
2685 const Elf_Note *note, *note0, *note_end;
2686 const char *note_name;
2692 if (pnote == NULL || pnote->p_filesz > PAGE_SIZE)
2694 ASSERT_VOP_LOCKED(imgp->vp,
"parse_notes");
2695 if (pnote->p_offset > PAGE_SIZE ||
2696 pnote->p_filesz > PAGE_SIZE - pnote->p_offset) {
2697 buf =
malloc(pnote->p_filesz, M_TEMP, M_NOWAIT);
2699 VOP_UNLOCK(imgp->vp);
2700 buf =
malloc(pnote->p_filesz, M_TEMP, M_WAITOK);
2701 vn_lock(imgp->vp, LK_SHARED | LK_RETRY);
2703 error =
vn_rdwr(UIO_READ, imgp->vp,
buf, pnote->p_filesz,
2704 pnote->p_offset, UIO_SYSSPACE, IO_NODELOCKED,
2705 curthread->td_ucred, NOCRED, NULL, curthread);
2707 uprintf(
"i/o error PT_NOTE\n");
2710 note = note0 = (
const Elf_Note *)
buf;
2711 note_end = (
const Elf_Note *)(
buf + pnote->p_filesz);
2713 note = note0 = (
const Elf_Note *)(imgp->image_header +
2715 note_end = (
const Elf_Note *)(imgp->image_header +
2716 pnote->p_offset + pnote->p_filesz);
2719 for (i = 0; i < 100 && note >= note0 && note < note_end; i++) {
2720 if (!
aligned(note, Elf32_Addr) || (
const char *)note_end -
2721 (
const char *)note <
sizeof(Elf_Note)) {
2724 if (note->n_namesz != checknote->n_namesz ||
2725 note->n_descsz != checknote->n_descsz ||
2726 note->n_type != checknote->n_type)
2728 note_name = (
const char *)(note + 1);
2729 if (note_name + checknote->n_namesz >=
2730 (
const char *)note_end || strncmp(note_vendor,
2731 note_name, checknote->n_namesz) != 0)
2734 if (cb(note, cb_arg, &
res))
2737 note = (
const Elf_Note *)((
const char *)(note + 1) +
2764 *
res = (arg->
brandnote->flags & BN_TRANSLATE_OSREL) != 0 &&
2772 .n_namesz =
sizeof(FREEBSD_ABI_VENDOR),
2773 .n_descsz =
sizeof(uint32_t),
2774 .n_type = NT_FREEBSD_FEATURE_CTL,
2786 const Elf32_Word *desc;
2790 p = (uintptr_t)(note + 1);
2792 desc = (
const Elf32_Word *)p;
2794 *arg->
fctl0 = desc[0];
2807 int32_t *osrel,
bool *has_fctl0, uint32_t *fctl0)
2809 const Elf_Phdr *phdr;
2810 const Elf_Ehdr *hdr;
2815 hdr = (
const Elf_Ehdr *)imgp->image_header;
2816 phdr = (
const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
2818 b_arg.
osrel = osrel;
2822 for (i = 0; i < hdr->e_phnum; i++) {
2824 &brandnote->hdr, brandnote->vendor, &phdr[i],
brandnote_cb,
2826 for (j = 0; j < hdr->e_phnum; j++) {
2827 if (phdr[j].p_type == PT_NOTE &&
2829 FREEBSD_ABI_VENDOR, &phdr[j],
2856 prot |= VM_PROT_EXECUTE;
2858 prot |= VM_PROT_WRITE;
2860 prot |= VM_PROT_READ;
2861#if __ELF_WORD_SIZE == 32 && (defined(__amd64__) || defined(__i386__))
2862 if (i386_read_exec && (
flags & PF_R))
2863 prot |= VM_PROT_EXECUTE;
2874 if (prot & VM_PROT_EXECUTE)
2876 if (prot & VM_PROT_READ)
2878 if (prot & VM_PROT_WRITE)
device_property_type_t type
#define ELF_NOTE_ROUNDSIZE
TAILQ_HEAD(note_info_list, note_info)
static int __elfN() load_interp(struct image_params *imgp, const Elf_Brandinfo *brand_info, const char *interp, u_long *addr, u_long *entry)
static int __elfN() load_section(struct image_params *imgp, vm_ooffset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot)
static void __elfN() putnote(struct thread *td, struct note_info *, struct sbuf *)
int compress_user_cores_level
void __elfN() size_segments(struct thread *td, struct sseg_closure *seginfo, int flags)
static bool __elfN() set_fpregset(struct regset *rs, struct thread *td, void *buf, size_t size)
static void cb_put_phdr(vm_map_entry_t, void *)
static int __elfN() get_interp(struct image_params *imgp, const Elf_Phdr *phdr, char **interpp, bool *free_interpp)
int __elfN() freebsd_copyout_auxargs(struct image_params *imgp, uintptr_t base)
ELF_REGSET(__elfN(regset_prstatus))
SYSCTL_NODE(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, aslr, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "")
int __elfN() remove_brand_entry(Elf_Brandinfo *entry)
int __elfN() freebsd_fixup(uintptr_t *stack_base, struct image_params *imgp)
prfpregset_t elf_fpregset_t
static void each_dumpable_segment(struct thread *, segment_callback, void *, int)
static void note_procstat_groups(void *, struct sbuf *, size_t *)
static void __elfN() note_prpsinfo(void *, struct sbuf *, size_t *)
void __elfN() prepare_notes(struct thread *td, struct note_info_list *list, size_t *sizep)
SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, enable, CTLFLAG_RWTUN, &__elfN(aslr_enabled), 0, ": enable address map randomization")
int __elfN() coredump(struct thread *td, struct vnode *vp, off_t limit, int flags)
prpsinfo_t elf_prpsinfo_t
static size_t append_note_data(const void *src, void *dst, size_t len)
void __elfN() puthdr(struct thread *td, void *hdr, size_t hdrsize, int numsegs, size_t notesz, int flags)
static void __elfN() note_procstat_proc(void *, struct sbuf *, size_t *)
static int __elfN() map_insert(struct image_params *imgp, vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_offset_t start, vm_offset_t end, vm_prot_t prot, int cow)
static int __elfN() enforce_limits(struct image_params *imgp, const Elf_Ehdr *hdr, const Elf_Phdr *phdr, u_long et_dyn_addr)
static bool __elfN() parse_notes(struct image_params *imgp, Elf_Note *checknote, const char *note_vendor, const Elf_Phdr *pnote, bool(*cb)(const Elf_Note *, void *, bool *), void *cb_arg)
static Elf_Word __elfN() untrans_prot(vm_prot_t prot)
static void note_procstat_osrel(void *, struct sbuf *, size_t *)
static vm_prot_t __elfN() trans_prot(Elf_Word flags)
static void note_procstat_umask(void *, struct sbuf *, size_t *)
static void __elfN() note_threadmd(void *, struct sbuf *, size_t *)
bool __elfN() brand_inuse(Elf_Brandinfo *entry)
static void __elfN() note_procstat_auxv(void *, struct sbuf *, size_t *)
static void note_procstat_vmmap(void *, struct sbuf *, size_t *)
static void note_procstat_rlimit(void *, struct sbuf *, size_t *)
static int __elfN(aslr_enabled)
static const char GNU_ABI_VENDOR[]
prstatus_t elf_prstatus_t
static Elf_Note fctl_note
static bool __elfN() freebsd_trans_osrel(const Elf_Note *note, int32_t *osrel)
static void __elfN() note_thrmisc(void *, struct sbuf *, size_t *)
vm_offset_t elf_ps_strings_t
static bool __elfN() check_note(struct image_params *imgp, Elf_Brandnote *brandnote, int32_t *osrel, bool *has_fctl0, uint32_t *fctl0)
static int __elfN() map_partial(vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_offset_t start, vm_offset_t end, vm_prot_t prot)
static bool __elfN() set_prstatus(struct regset *rs, struct thread *td, void *buf, size_t size)
static int core_compressed_write(void *base, size_t len, off_t offset, void *arg)
SYSCTL_BOOL(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, allow_wx, CTLFLAG_RWTUN, &__elfN(allow_wx), 0, "Allow pages to be mapped simultaneously writable and executable")
static Elf_Brandinfo *__elfN() get_brandinfo(struct image_params *imgp, const char *interp, int32_t *osrel, uint32_t *fctl0)
static void note_procstat_files(void *, struct sbuf *, size_t *)
static int __CONCAT(exec_, __elfN(imgact))
static void __elfN() note_procstat_psstrings(void *, struct sbuf *, size_t *)
static bool brandnote_cb(const Elf_Note *note, void *arg0, bool *res)
static bool __elfN() get_fpregset(struct regset *rs, struct thread *td, void *buf, size_t *sizep)
EXEC_SET(__CONCAT(elf, __ELF_WORD_SIZE), __elfN(execsw))
static int __elfN() corehdr(struct coredump_params *, int, void *, size_t, struct note_info_list *, size_t, int)
static bool __elfN() get_prstatus(struct regset *rs, struct thread *td, void *buf, size_t *sizep)
static int __elfN() check_header(const Elf_Ehdr *hdr)
static bool kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel)
SYSCTL_PROC(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, pie_base, CTLTYPE_ULONG|CTLFLAG_MPSAFE|CTLFLAG_RW, NULL, 0, sysctl_pie_base, "LU", "PIE load base without randomization")
static bool note_fctl_cb(const Elf_Note *note, void *arg0, bool *res)
struct kinfo_proc elf_kinfo_proc_t
static int __elfN() load_file(struct proc *p, const char *file, u_long *addr, u_long *entry)
size_t __elfN() populate_note(int type, void *src, void *dst, size_t size, void **descp)
static void cb_size_segment(vm_map_entry_t, void *)
static Elf_Brandinfo * elf_brand_list[MAX_BRANDS]
void(* segment_callback)(vm_map_entry_t, void *)
#define ELF_KERN_PROC_MASK
static size_t __elfN() register_regset_note(struct thread *td, struct note_info_list *list, struct regset *regset, struct thread *target_td)
size_t __elfN() register_note(struct thread *td, struct note_info_list *list, int type, outfunc_t out, void *arg)
prfpregset_t elf_prfpregset_t
static bool __elfN() phdr_in_zero_page(const Elf_Ehdr *hdr)
static size_t __elfN() prepare_register_notes(struct thread *td, struct note_info_list *list, struct thread *target_td)
int __elfN() insert_brand_entry(Elf_Brandinfo *entry)
static void __elfN() note_ptlwpinfo(void *, struct sbuf *, size_t *)
static int __elfN() load_sections(struct image_params *imgp, const Elf_Ehdr *hdr, const Elf_Phdr *phdr, u_long rbase, u_long *base_addrp)
static int GNU_KFREEBSD_ABI_DESC
CTASSERT(MAXSHELLCMDLEN >=MAXINTERP+3)
int kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen, int flags)
int exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
int coredump_pack_vmmapinfo
int coredump_pack_fileinfo
void exec_unmap_first_page(struct image_params *imgp)
static const struct execsw ** execsw
int exec_check_permissions(struct image_params *imgp)
int exec_map_stack(struct image_params *imgp)
int exec_map_first_page(struct image_params *imgp)
int sbuf_drain_core_output(void *arg, const char *data, int len)
int core_output(char *base, size_t len, off_t offset, struct coredump_params *cp, void *tmpbuf)
int core_write(struct coredump_params *cp, const void *base, size_t len, off_t offset, enum uio_seg seg, size_t *resid)
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void free(void *addr, struct malloc_type *mtp)
u_long pagesizes[MAXPAGESIZES]
int kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen, int flags)
int proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb)
struct sx __exclusive_cache_line proctree_lock
int kern_proc_out(struct proc *p, struct sbuf *sb, int flags)
int proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb)
struct sx __exclusive_cache_line allproc_lock
rlim_t lim_cur_proc(struct proc *p, int which)
rlim_t lim_max(struct thread *td, int which)
void lim_rlimit_proc(struct proc *p, int which, struct rlimit *rlp)
int sysctl_handle_long(SYSCTL_HANDLER_ARGS)
struct intr_irqsrc ** src
Elf_Brandnote * brandnote
int compressor_flush(struct compressor *stream)
void compressor_fini(struct compressor *stream)
struct compressor * compressor_init(compressor_cb_t cb, int format, size_t maxiosize, int level, void *arg)
int printf(const char *fmt,...)
int snprintf(char *str, size_t size, const char *format,...)
int uprintf(const char *fmt,...)
void log(int level, const char *fmt,...)
int sbuf_finish(struct sbuf *s)
void sbuf_start_section(struct sbuf *s, ssize_t *old_lenp)
int sbuf_putc(struct sbuf *s, int c)
ssize_t sbuf_end_section(struct sbuf *s, ssize_t old_len, size_t pad, int c)
void sbuf_delete(struct sbuf *s)
void sbuf_set_drain(struct sbuf *s, sbuf_drain_func *func, void *ctx)
int sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
ssize_t sbuf_len(struct sbuf *s)
int sbuf_count_drain(void *arg, const char *data __unused, int len)
struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags)
void() NDFREE(struct nameidata *ndp, const u_int flags)
int namei(struct nameidata *ndp)
void vput(struct vnode *vp)
int vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base, int len, off_t offset, enum uio_seg segflg, int ioflg, struct ucred *active_cred, struct ucred *file_cred, ssize_t *aresid, struct thread *td)