Date: Tue, 14 May 2019 20:27:46 +0000 (UTC) From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r347575 - stable/12/sys/kern Message-ID: <201905142027.x4EKRkY1069144@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: trasz Date: Tue May 14 20:27:45 2019 New Revision: 347575 URL: https://svnweb.freebsd.org/changeset/base/347575 Log: MFC r346030: Refactor ELF interpreter loading into a separate function. Sponsored by: DARPA, AFRL Modified: stable/12/sys/kern/imgact_elf.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/kern/imgact_elf.c ============================================================================== --- stable/12/sys/kern/imgact_elf.c Tue May 14 20:26:05 2019 (r347574) +++ stable/12/sys/kern/imgact_elf.c Tue May 14 20:27:45 2019 (r347575) @@ -946,6 +946,41 @@ __elfN(get_interp)(struct image_params *imgp, const El 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. @@ -961,8 +996,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i 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; @@ -971,7 +1005,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i 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; @@ -1007,7 +1041,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i osrel = 0; fctl0 = 0; entry = proghdr = 0; - newinterp = interp = NULL; + interp = NULL; free_interp = false; td = curthread; maxalign = PAGE_SIZE; @@ -1075,8 +1109,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i 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 @@ -1201,7 +1233,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i 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 */ @@ -1210,35 +1241,11 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i 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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905142027.x4EKRkY1069144>