kernel patch available
30 April, 2015 by guenther@openbsd.org | openbsd
Patches are now available for 5.6 and 5.7 which fix local security issues in the kernel's handling of malformed ELF executables, which could be used to panic the kernel or view some kernel memory. Our thanks to Alejandro Hernandez for test cases and Maxime Villard for providing the basis for one of the changes. Links: http://www.openbsd.org/errata56.html http://ftp.openbsd.org/pub/OpenBSD/patches/5.6/common/023_elf.patch.sig and http://www.openbsd.org/errata57.html http://ftp.openbsd.org/pub/OpenBSD/patches/5.7/common/006_elf.patch.sig untrusted comment: signature from openbsd 5.7 base secret key RWSvUZXnw9gUby4OBLM0n2MCFo9TM/FWZlryKfa4mLnPMEgi87dSLa8HTEXN15Z0YumeDyfsnFVHyQHjtL6106R1LxIOtJ/6pww OpenBSD 5.7 errata 6, Apr 30, 2015: Missing validity checks in the kernel ELF loader meant malformed binaries could trigger kernel panics or view kernel memory. Apply by doing: cd /usr/src signify -Vep /etc/signify/openbsd-57-base.pub -x 006_elf.patch.sig -m - | \ patch -p0 Then build and install a new kernel: cd /usr/src/sys/arch/`machine`/conf KK=`sysctl -n kern.osversion | cut -d# -f1` config $KK cd ../compile/$KK make make install Index: sys/kern/exec_elf.c =================================================================== RCS file: /cvs/src/sys/kern/exec_elf.c,v retrieving revision 1.112 diff -u -p -r1.112 exec_elf.c --- sys/kern/exec_elf.c 10 Feb 2015 23:39:57 -0000 1.112 +++ sys/kern/exec_elf.c 30 Apr 2015 18:41:25 -0000 @@ -362,6 +362,8 @@ ELFNAME(load_file)(struct proc *p, char for (i = 0; i < eh.e_phnum; i++) { if (ph[i].p_type == PT_LOAD) { + if (ph[i].p_filesz > ph[i].p_memsz) + goto bad1; loadmap[idx].vaddr = trunc_page(ph[i].p_vaddr); loadmap[idx].memsz = round_page (ph[i].p_vaddr + ph[i].p_memsz - loadmap[idx].vaddr); @@ -549,14 +551,20 @@ ELFNAME2(exec,makecmds)(struct proc *p, for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) { if (pp->p_type == PT_INTERP && !interp) { - if (pp->p_filesz >= MAXPATHLEN) + if (pp->p_filesz < 2 || pp->p_filesz > MAXPATHLEN) goto bad; interp = pool_get(&namei_pool, PR_WAITOK); if ((error = ELFNAME(read_from)(p, epp->ep_vp, pp->p_offset, interp, pp->p_filesz)) != 0) { goto bad; } + if (interp[pp->p_filesz - 1] != '\0') + goto bad; } else if (pp->p_type == PT_LOAD) { + if (pp->p_filesz > pp->p_memsz) { + error = EINVAL; + goto bad; + } if (base_ph == NULL) base_ph = pp; } else if (pp->p_type == PT_PHDR) {