diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2015-02-10 23:39:58 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2015-02-10 23:39:58 +0000 |
commit | eaf0710f98e22180957b33b8a2a9370b8d62987a (patch) | |
tree | 8c2cb21b05ad64ad42ab485b29741cfc702da820 | |
parent | dae1601205871e533cdf3f8402c70bbf3a7f9819 (diff) |
Don't use an uninitialized variable when a PT_LOAD segment with
alignment 0 or 1 is encountered. The result before was just a
spurious failure by execve(), though I had to manually mangle a
binary to hit this case: segments are all long-aligned or better
in practice.
uninitialized variable noted by Maxime Villard (rustyBSD (at) gmx.fr)
ok and prod jsg@
-rw-r--r-- | sys/kern/exec_elf.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c index 1f2fbc84360..50a52badb42 100644 --- a/sys/kern/exec_elf.c +++ b/sys/kern/exec_elf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_elf.c,v 1.111 2015/02/06 23:58:12 deraadt Exp $ */ +/* $OpenBSD: exec_elf.c,v 1.112 2015/02/10 23:39:57 guenther Exp $ */ /* * Copyright (c) 1996 Per Fogelstrom @@ -213,7 +213,7 @@ void ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp, Elf_Phdr *ph, Elf_Addr *addr, Elf_Addr *size, int *prot, int flags) { - u_long uaddr, msize, lsize, psize, rm, rf; + u_long msize, lsize, psize, rm, rf; long diff, offset, bdiff; Elf_Addr base; @@ -227,19 +227,18 @@ ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp, /* page align vaddr */ base = *addr + trunc_page(ph->p_vaddr) - ELF_TRUNC(ph->p_vaddr, ph->p_align); - - bdiff = ph->p_vaddr - trunc_page(ph->p_vaddr); - - } else + } else { diff = 0; + base = *addr + trunc_page(ph->p_vaddr) - ph->p_vaddr; + } } else { - *addr = uaddr = ph->p_vaddr; + *addr = ph->p_vaddr; if (ph->p_align > 1) - *addr = ELF_TRUNC(uaddr, ph->p_align); - base = trunc_page(uaddr); - bdiff = uaddr - base; - diff = uaddr - *addr; + *addr = ELF_TRUNC(*addr, ph->p_align); + base = trunc_page(ph->p_vaddr); + diff = ph->p_vaddr - *addr; } + bdiff = ph->p_vaddr - trunc_page(ph->p_vaddr); *prot |= (ph->p_flags & PF_R) ? PROT_READ : 0; *prot |= (ph->p_flags & PF_W) ? PROT_WRITE : 0; |