kernel patch available

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

kernel patch available

Philip Guenther-3
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) {

Reply | Threaded
Open this post in threaded view
|

Re: kernel patch available

Maxime Villard-2
Le 30/04/2015 22:42, Philip Guenther a écrit :
> 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.

Hum. It curiously looks like the patch I sent here about two years
ago that nobody gave a shit about:

        http://marc.info/?l=openbsd-tech&m=138703150604223&w=2

- - - -

And don't you feel like there's an obvious bug in these patches?

                if (ph[i].p_filesz > ph[i].p_memsz)
                        goto bad1;

[...]

        bad1:
                VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p);
        bad:
                free(ph, M_TEMP, 0);

                *last = addr;
                vput(nd.ni_vp);
                return (error);


Where is 'error' initialized?




Le 30/04/2015 22:42, Philip Guenther a écrit :

> 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) {
>