Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78!

From: Linus Torvalds
Date: Fri Mar 31 2017 - 14:26:15 EST


On Fri, Mar 31, 2017 at 10:32 AM, Kees Cook <keescook@xxxxxxxxxxxx> wrote:
>
> How is ffff880000090000 both in the direct mapping and a slab object?

I think this is just very regular /dev/mem behavior, that is hidden by
the fact that the *normal* case for /dev/mem is all to reserved RAM,
which will never be a slab object.

And this is all hidden with STRICT_DEVMEM, which pretty much everybody
has enabled, but Tommi for some reason did not.

> It would need to pass all of these checks, and be marked as PageSlab
> before it could be evaluated by __check_heap_object:

It trivially passes those checks, because it's a normal kernel address
for a page that is just used for kernel stuff.

I think we have two options:

- just get rid of STRICT_DEVMEM and make that unconditional

- make the read_mem/write_mem code use some non-checking copy
routines, since they are obviously designed to access any memory
location (including kernel memory) unless STRICT_DEVMEM is set.

Hmm. Thinking more about this, we do allow access to the first 1MB of
physical memory unconditionally (see devmem_is_allowed() in
arch/x86/mm/init.c). And I think we only _reserve_ the first 64kB or
something. So I guess even STRICT_DEVMEM isn't actually all that
strict.

So this should be visible even *with* STRICT_DEVMEM.

Does a simple

sudo dd if=/dev/mem of=/dev/null bs=4096 count=256

also show the same issue? Maybe regardless of STRICT_DEVMEM?

Maybe we should change devmem_is_allowed() to return a ternary value,
and then have it be "allow access" (for reserved pages), "disallow
access" (for various random stuff), and "just read zero" (for pages in
the low 1M that aren't marked reserved).

That way things like that read the low 1M (like x86info) will
hopefully not be unhappy, but also won't be reading random kernel
data.

Linus