aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/imgact_elf.c
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2019-04-08 14:31:07 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2019-04-08 14:31:07 +0000
commit9274fb3599c4504094d9987493d6c3688592f7bd (patch)
tree099e2fdcdbc7cdc9268e49f600f0ea467a693608 /sys/kern/imgact_elf.c
parentde0b14f2db9371dfd7cf537a402e178f183145b6 (diff)
downloadsrc-9274fb3599c4504094d9987493d6c3688592f7bd.tar.gz
src-9274fb3599c4504094d9987493d6c3688592f7bd.zip
Refactor ELF interpreter loading into a separate function.
Reviewed by: kib MFC after: 2 weeks Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D19741
Notes
Notes: svn path=/head/; revision=346030
Diffstat (limited to 'sys/kern/imgact_elf.c')
-rw-r--r--sys/kern/imgact_elf.c75
1 files changed, 41 insertions, 34 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index ddf242512129..41e1cc41316e 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -945,6 +945,41 @@ __elfN(get_interp)(struct image_params *imgp, const Elf_Phdr *phdr,
return (0);
}
+static int
+__elfN(load_interp)(struct image_params *imgp, const Elf_Brandinfo *brand_info,
+ const char *interp, u_long *addr, u_long *entry)
+{
+ char *path;
+ int error;
+
+ 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, entry);
+ free(path, M_TEMP);
+ if (error == 0)
+ return (0);
+ }
+
+ if (brand_info->interp_newpath != NULL &&
+ (brand_info->interp_path == NULL ||
+ strcmp(interp, brand_info->interp_path) == 0)) {
+ error = __elfN(load_file)(imgp->proc,
+ brand_info->interp_newpath, addr, entry);
+ if (error == 0)
+ return (0);
+ }
+
+ error = __elfN(load_file)(imgp->proc, interp, addr, entry);
+ if (error == 0)
+ return (0);
+
+ uprintf("ELF interpreter %s not found, error %d\n", interp, error);
+ return (error);
+}
+
/*
* Impossible et_dyn_addr initial value indicating that the real base
* must be calculated later with some randomization applied.
@@ -960,8 +995,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
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;
@@ -970,7 +1004,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
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 +1040,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
osrel = 0;
fctl0 = 0;
entry = proghdr = 0;
- newinterp = interp = NULL;
+ interp = NULL;
free_interp = false;
td = curthread;
maxalign = PAGE_SIZE;
@@ -1074,8 +1108,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
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
@@ -1200,7 +1232,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
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 */
@@ -1209,35 +1240,11 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
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);
- }
+ error = __elfN(load_interp)(imgp, brand_info, 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);
+ if (error != 0)
goto ret;
- }
} else
addr = et_dyn_addr;