Page MenuHomeFreeBSD

D19741.id55566.diff
No OneTemporary

D19741.id55566.diff

Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -945,6 +945,80 @@
return (0);
}
+static int
+__elfN(load_interp)(struct image_params *imgp, const Elf_Brandinfo *brand_info,
+ const char *interp, u_long maxv, u_long *addrp)
+{
+ struct vmspace *vmspace;
+ const char *newinterp;
+ char *path;
+ vm_map_t map;
+ u_long addr, maxv1;
+ int error;
+
+ vmspace = imgp->proc->p_vmspace;
+ map = &vmspace->vm_map;
+
+ if (interp != NULL && brand_info->interp_newpath != NULL)
+ newinterp = brand_info->interp_newpath;
+ else
+ newinterp = NULL;
+
+ /*
+ * We load the dynamic linker where a userland call to mmap(0, ...)
+ * would put it. The rationale behind this calculation is that
+ * it leaves room for the heap to grow to its maximum allowed size.
+ */
+ addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(curthread,
+ RLIMIT_DATA));
+ if ((map->flags & MAP_ASLR) != 0) {
+ maxv1 = maxv / 2 + addr / 2;
+ MPASS(maxv1 >= addr); /* No overflow */
+ map->anon_loc = __CONCAT(rnd_, __elfN(base))(map, addr, maxv1,
+ MAXPAGESIZES > 1 ? pagesizes[1] : pagesizes[0]);
+ } else {
+ map->anon_loc = addr;
+ }
+
+ VOP_UNLOCK(imgp->vp, 0);
+ if ((map->flags & MAP_ASLR) != 0) {
+ /* Assume that interpeter fits into 1/4 of AS */
+ maxv1 = maxv / 2 + addr / 2;
+ MPASS(maxv1 >= addr); /* No overflow */
+ addr = __CONCAT(rnd_, __elfN(base))(map, addr,
+ maxv1, PAGE_SIZE);
+ }
+ if (brand_info->emul_path != NULL &&
+ brand_info->emul_path[0] != '\0') {
+ path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+ snprintf(path, MAXPATHLEN, "%s%s",
+ brand_info->emul_path, interp);
+ error = __elfN(load_file)(imgp->proc, path, &addr,
+ &imgp->entry_addr);
+ free(path, M_TEMP);
+ if (error == 0)
+ goto done;
+ }
+ if (newinterp != NULL && (brand_info->interp_path == NULL ||
+ strcmp(interp, brand_info->interp_path) == 0)) {
+ error = __elfN(load_file)(imgp->proc, newinterp, &addr,
+ &imgp->entry_addr);
+ if (error == 0)
+ goto done;
+ }
+ error = __elfN(load_file)(imgp->proc, interp, &addr,
+ &imgp->entry_addr);
+done:
+ vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+ if (error != 0) {
+ uprintf("ELF interpreter %s not found, error %d\n",
+ interp, error);
+ }
+
+ *addrp = addr;
+ return (error);
+}
+
/*
* Impossible et_dyn_addr initial value indicating that the real base
* must be calculated later with some randomization applied.
@@ -960,17 +1034,16 @@
Elf_Auxargs *elf_auxargs;
struct vmspace *vmspace;
vm_map_t map;
- const char *newinterp;
- char *interp, *path;
+ char *interp;
Elf_Brandinfo *brand_info;
struct sysentvec *sv;
vm_prot_t prot;
u_long addr, baddr, et_dyn_addr, entry, proghdr;
- u_long maxalign, mapsz, maxv, maxv1;
+ u_long maxalign, mapsz, maxv;
uint32_t fctl0;
int32_t osrel;
bool free_interp;
- int error, i, n, have_interp;
+ int error, i, n;
hdr = (const Elf_Ehdr *)imgp->image_header;
@@ -1006,7 +1079,7 @@
osrel = 0;
fctl0 = 0;
entry = proghdr = 0;
- newinterp = interp = NULL;
+ interp = NULL;
free_interp = false;
td = curthread;
maxalign = PAGE_SIZE;
@@ -1074,8 +1147,6 @@
et_dyn_addr = ET_DYN_LOAD_ADDR;
}
}
- if (interp != NULL && brand_info->interp_newpath != NULL)
- newinterp = brand_info->interp_newpath;
/*
* Avoid a possible deadlock if the current address space is destroyed
@@ -1180,64 +1251,13 @@
entry = (u_long)hdr->e_entry + et_dyn_addr;
- /*
- * We load the dynamic linker where a userland call
- * to mmap(0, ...) would put it. The rationale behind this
- * calculation is that it leaves room for the heap to grow to
- * its maximum allowed size.
- */
- addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(td,
- RLIMIT_DATA));
- if ((map->flags & MAP_ASLR) != 0) {
- maxv1 = maxv / 2 + addr / 2;
- MPASS(maxv1 >= addr); /* No overflow */
- map->anon_loc = __CONCAT(rnd_, __elfN(base))(map, addr, maxv1,
- MAXPAGESIZES > 1 ? pagesizes[1] : pagesizes[0]);
- } else {
- map->anon_loc = addr;
- }
-
imgp->entry_addr = entry;
if (interp != NULL) {
- have_interp = FALSE;
- VOP_UNLOCK(imgp->vp, 0);
- if ((map->flags & MAP_ASLR) != 0) {
- /* Assume that interpeter fits into 1/4 of AS */
- maxv1 = maxv / 2 + addr / 2;
- MPASS(maxv1 >= addr); /* No overflow */
- addr = __CONCAT(rnd_, __elfN(base))(map, addr,
- maxv1, PAGE_SIZE);
- }
- if (brand_info->emul_path != NULL &&
- brand_info->emul_path[0] != '\0') {
- path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
- snprintf(path, MAXPATHLEN, "%s%s",
- brand_info->emul_path, interp);
- error = __elfN(load_file)(imgp->proc, path, &addr,
- &imgp->entry_addr);
- free(path, M_TEMP);
- if (error == 0)
- have_interp = TRUE;
- }
- if (!have_interp && newinterp != NULL &&
- (brand_info->interp_path == NULL ||
- strcmp(interp, brand_info->interp_path) == 0)) {
- error = __elfN(load_file)(imgp->proc, newinterp, &addr,
- &imgp->entry_addr);
- if (error == 0)
- have_interp = TRUE;
- }
- if (!have_interp) {
- error = __elfN(load_file)(imgp->proc, interp, &addr,
- &imgp->entry_addr);
- }
- vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
- if (error != 0) {
- uprintf("ELF interpreter %s not found, error %d\n",
- interp, error);
+ error = __elfN(load_interp)(imgp, brand_info, interp, maxv,
+ &addr);
+ if (error != 0)
goto ret;
- }
} else
addr = et_dyn_addr;

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 24, 8:26 PM (15 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32058504
Default Alt Text
D19741.id55566.diff (5 KB)

Event Timeline