From fa471065c63597963e68a444ff14e35f14adcbaf Mon Sep 17 00:00:00 2001 From: kettenis Date: Mon, 22 Dec 2014 15:05:24 +0000 Subject: [PATCH] Make it possible to execute PIE binaries that don't have an PT_INTERP segment (and therefore no interpreter). Necessary to make self-relocating "static" PIE working. This will also allow execution of shared libraries that have the 'x' bit set. Those shouldn't exist, but unfortunately people outside OpenBSD think differently which means third-party software sometimes installs shared libraries with the 'x' bit set. ok kurt@, deraadt@ --- sys/kern/exec_elf.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c index 4630e52d561..4fcedcf6c1e 100644 --- a/sys/kern/exec_elf.c +++ b/sys/kern/exec_elf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_elf.c,v 1.107 2014/12/16 18:30:03 tedu Exp $ */ +/* $OpenBSD: exec_elf.c,v 1.108 2014/12/22 15:05:24 kettenis Exp $ */ /* * Copyright (c) 1996 Per Fogelstrom @@ -173,7 +173,7 @@ ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo, * Push space for extra arguments on the stack needed by * dynamically linked binaries. */ - if (pack->ep_interp != NULL) { + if (pack->ep_emul_arg != NULL) { pack->ep_emul_argp = stack; stack = (char *)stack + ELF_AUX_ENTRIES * sizeof (AuxInfo); } @@ -567,8 +567,8 @@ ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) } if (eh->e_type == ET_DYN) { - /* need an interpreter and load sections for PIE */ - if (interp == NULL || base_ph == NULL) + /* need load sections for PIE */ + if (base_ph == NULL) goto bad; /* randomize exe_base for PIE */ exe_base = uvm_map_pie(base_ph->p_align); @@ -738,7 +738,7 @@ ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) * Check if we found a dynamically linked binary and arrange to load * its interpreter when the exec file is released. */ - if (interp) { + if (interp || eh->e_type == ET_DYN) { struct elf_args *ap; ap = malloc(sizeof(*ap), M_TEMP, M_WAITOK); @@ -747,6 +747,7 @@ ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) ap->arg_phentsize = eh->e_phentsize; ap->arg_phnum = eh->e_phnum; ap->arg_entry = eh->e_entry + exe_base; + ap->arg_interp = exe_base; epp->ep_emul_arg = ap; epp->ep_interp_pos = pos; @@ -772,19 +773,20 @@ int ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp) { char *interp; - int error; + int error = 0; struct elf_args *ap; AuxInfo ai[ELF_AUX_ENTRIES], *a; Elf_Addr pos = epp->ep_interp_pos; - if (epp->ep_interp == NULL) { + if (epp->ep_emul_arg == NULL) { return (0); } interp = epp->ep_interp; ap = epp->ep_emul_arg; - if ((error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) { + if (interp && + (error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) { free(ap, M_TEMP, 0); pool_put(&namei_pool, interp); kill_vmcmds(&epp->ep_vmcmds); @@ -837,7 +839,8 @@ ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp) error = copyout(ai, epp->ep_emul_argp, sizeof ai); } free(ap, M_TEMP, 0); - pool_put(&namei_pool, interp); + if (interp) + pool_put(&namei_pool, interp); return (error); } -- 2.20.1