diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-12-22 15:05:25 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-12-22 15:05:25 +0000 |
commit | ec22bee7bfcc69eb9d1dcec5896255dd7ea28bd2 (patch) | |
tree | e54640a99ac55b09c1eec6df3172ee0c6884b739 /sys/kern | |
parent | 3adb66e4c6c8acf7457fd3c8d5e34c622a430300 (diff) |
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@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/exec_elf.c | 21 |
1 files 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); } |