Project

General

Profile

Submit #2854 » pie_sysctl.patch

shamaz, 12/25/2015 07:57 AM

View differences:

sys/kern/imgact_elf.c
93 93
    Elf_Brandnote *checknote, int32_t *osrel, const Elf_Phdr * pnote);
94 94
static boolean_t extract_interpreter(struct image_params *imgp,
95 95
    const Elf_Phdr *pinterpreter, char *data);
96
static u_long pie_base_hint(struct proc *p);
96 97

  
97 98
static int elf_legacy_coredump = 0;
98 99
static int __elfN(fallback_brand) = -1;
100
static int elf_pie_base_mmap = 0;
99 101
#if defined(__x86_64__)
100 102
SYSCTL_NODE(_kern, OID_AUTO, elf64, CTLFLAG_RW, 0, "");
101 103
SYSCTL_INT(_debug, OID_AUTO, elf64_legacy_coredump, CTLFLAG_RW,
......
103 105
SYSCTL_INT(_kern_elf64, OID_AUTO, fallback_brand, CTLFLAG_RW,
104 106
    &elf64_fallback_brand, 0, "ELF64 brand of last resort");
105 107
TUNABLE_INT("kern.elf64.fallback_brand", &elf64_fallback_brand);
108
SYSCTL_INT(_kern_elf64, OID_AUTO, pie_base_mmap, CTLFLAG_RW,
109
    &elf_pie_base_mmap, 0,
110
    "choose a base address for PIE as if it is mapped with mmap()");
111
TUNABLE_INT("kern.elf64.pie_base_mmap", &elf_pie_base_mmap);
106 112
#else /* i386 assumed */
107 113
SYSCTL_NODE(_kern, OID_AUTO, elf32, CTLFLAG_RW, 0, "");
108 114
SYSCTL_INT(_debug, OID_AUTO, elf32_legacy_coredump, CTLFLAG_RW,
......
110 116
SYSCTL_INT(_kern_elf32, OID_AUTO, fallback_brand, CTLFLAG_RW,
111 117
    &elf32_fallback_brand, 0, "ELF32 brand of last resort");
112 118
TUNABLE_INT("kern.elf32.fallback_brand", &elf32_fallback_brand);
119
SYSCTL_INT(_kern_elf32, OID_AUTO, pie_base_mmap, CTLFLAG_RW,
120
    &elf_pie_base_mmap, 0,
121
    "choose a base address for PIE as if it is mapped with mmap()");
122
TUNABLE_INT("kern.elf32.pie_base_mmap", &elf_pie_base_mmap);
113 123
#endif
114 124

  
115 125
static Elf_Brandinfo *elf_brand_list[MAX_BRANDS];
......
610 620
	u_long text_size = 0, data_size = 0, total_size = 0;
611 621
	u_long text_addr = 0, data_addr = 0;
612 622
	u_long seg_size, seg_addr;
613
	u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0;
623
	u_long addr, baddr, et_dyn_addr = 0, entry = 0, proghdr = 0;
614 624
	int32_t osrel = 0;
615 625
	int error = 0, i, n;
616 626
	boolean_t failure;
......
680 690
		uprintf("ELF binary type \"%u\" not known.\n",
681 691
		    hdr->e_ident[EI_OSABI]);
682 692
		if (interp != NULL)
683
		        kfree(interp, M_TEMP);
693
			kfree(interp, M_TEMP);
684 694
		return (ENOEXEC);
685 695
	}
686 696
	if (hdr->e_type == ET_DYN) {
687 697
		if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) {
688
		        if (interp != NULL)
689
		                kfree(interp, M_TEMP);
698
			if (interp != NULL)
699
				kfree(interp, M_TEMP);
690 700
			return (ENOEXEC);
691
                }
701
		}
692 702
		/*
693
		 * Honour the base load address from the dso if it is
694
		 * non-zero for some reason.
703
		 * If p_vaddr field of PT_LOAD program header is zero and type of an
704
		 * executale is ET_DYN, then it must be a position independent
705
		 * executable (PIE). In this case the system needs to pick a base
706
		 * address for us. Set et_dyn_addr to non-zero and choose the actual
707
		 * address when we are ready.
695 708
		 */
696 709
		if (baddr == 0)
697
			et_dyn_addr = ET_DYN_LOAD_ADDR;
698
		else
699
			et_dyn_addr = 0;
700
	} else
701
		et_dyn_addr = 0;
710
			et_dyn_addr = 1;
711
	}
702 712

  
703 713
	if (interp != NULL && brand_info->interp_newpath != NULL)
704 714
		newinterp = brand_info->interp_newpath;
......
714 724
	vsetflags(imgp->vp, VTEXT);
715 725

  
716 726
	vmspace = imgp->proc->p_vmspace;
727
	/* Choose the base address for dynamic executables if we need to. */
728
	if (et_dyn_addr)
729
		et_dyn_addr = pie_base_hint(imgp->proc);
717 730

  
718 731
	for (i = 0; i < hdr->e_phnum; i++) {
719 732
		switch (phdr[i].p_type) {
......
1916 1929
		flags |= PF_W;
1917 1930
	return (flags);
1918 1931
}
1932

  
1933
static u_long
1934
pie_base_hint(struct proc *p)
1935
{
1936
	u_long base;
1937

  
1938
	if (elf_pie_base_mmap)
1939
		base = vm_map_hint(p, 0, VM_PROT_READ | VM_PROT_EXECUTE);
1940
	else
1941
		base = ET_DYN_LOAD_ADDR;
1942
	return base;
1943
}
(4-4/4)