Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1613286 > unrolled thread

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

Started byKees Cook <keescook@chromium.org>
First post2017-03-30 18:50 +0200
Last post2017-04-05 21:40 +0200
Articles 19 — 6 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Kees Cook <keescook@chromium.org> - 2017-03-30 18:50 +0200
    Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Laura Abbott <labbott@redhat.com> - 2017-03-30 19:30 +0200
      Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Kees Cook <keescook@chromium.org> - 2017-03-30 19:40 +0200
        Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Laura Abbott <labbott@redhat.com> - 2017-03-30 19:50 +0200
    Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Mark Rutland <mark.rutland@arm.com> - 2017-03-30 19:30 +0200
    Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Dave Jones <davej@codemonkey.org.uk> - 2017-03-30 21:50 +0200
      Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Kees Cook <keescook@chromium.org> - 2017-03-30 22:00 +0200
        Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Dave Jones <davej@codemonkey.org.uk> - 2017-03-30 22:10 +0200
        Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Dave Jones <davej@codemonkey.org.uk> - 2017-03-31 19:20 +0200
          Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Kees Cook <keescook@chromium.org> - 2017-03-31 19:40 +0200
            Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Dave Jones <davej@codemonkey.org.uk> - 2017-03-31 20:10 +0200
              Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Andy Lutomirski <luto@amacapital.net> - 2017-03-31 21:00 +0200
            Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Linus Torvalds <torvalds@linux-foundation.org> - 2017-03-31 20:30 +0200
              Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Kees Cook <keescook@chromium.org> - 2017-04-01 02:00 +0200
              Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Kees Cook <keescook@chromium.org> - 2017-04-05 00:40 +0200
                Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Linus Torvalds <torvalds@linux-foundation.org> - 2017-04-05 01:00 +0200
                  Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Kees Cook <keescook@chromium.org> - 2017-04-05 01:10 +0200
                  Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Linus Torvalds <torvalds@linux-foundation.org> - 2017-04-05 02:30 +0200
                    Re: sudo x86info -a => kernel BUG at mm/usercopy.c:78! Kees Cook <keescook@chromium.org> - 2017-04-05 21:40 +0200

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

FromKees Cook <keescook@chromium.org>
Date2017-03-30 18:50 +0200
SubjectRe: sudo x86info -a => kernel BUG at mm/usercopy.c:78!
Message-ID<tqLqO-KI-13@gated-at.bofh.it>
On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
<tommi.t.rantala@nokia.com> wrote:
> Hi,
>
> Running:
>
>   $ sudo x86info -a
>
> On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
> produces the following kernel BUG.
>
>   $ git describe
>   v4.11-rc4-40-gfe82203
>
> It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
>
> Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
>
> [   51.418954] usercopy: kernel memory exposure attempt detected from
> ffff880000090000 (dma-kmalloc-256) (4096 bytes)

This seems like a real exposure: the copy is attempting to read 4096
bytes from a 256 byte object.

> [...]
> [   51.419063] Call Trace:
> [   51.419066]  read_mem+0x70/0x120
> [   51.419069]  __vfs_read+0x28/0x130
> [   51.419072]  ? security_file_permission+0x9b/0xb0
> [   51.419075]  ? rw_verify_area+0x4e/0xb0
> [   51.419077]  vfs_read+0x96/0x130
> [   51.419079]  SyS_read+0x46/0xb0
> [   51.419082]  ? SyS_lseek+0x87/0xb0
> [   51.419085]  entry_SYSCALL_64_fastpath+0x1a/0xa9

I can't reproduce this myself, so I assume it's some specific /proc or
/sys file that I don't have. Are you able to get a strace of x86info
as it runs to see which file it is attempting to read here?

Thanks!

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [next] | [standalone]


#1613313

FromLaura Abbott <labbott@redhat.com>
Date2017-03-30 19:30 +0200
Message-ID<tqM3w-1dT-9@gated-at.bofh.it>
In reply to#1613286
On 03/30/2017 09:45 AM, Kees Cook wrote:
> On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
> <tommi.t.rantala@nokia.com> wrote:
>> Hi,
>>
>> Running:
>>
>>   $ sudo x86info -a
>>
>> On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
>> produces the following kernel BUG.
>>
>>   $ git describe
>>   v4.11-rc4-40-gfe82203
>>
>> It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
>>
>> Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
>>
>> [   51.418954] usercopy: kernel memory exposure attempt detected from
>> ffff880000090000 (dma-kmalloc-256) (4096 bytes)
> 
> This seems like a real exposure: the copy is attempting to read 4096
> bytes from a 256 byte object.
> 
>> [...]
>> [   51.419063] Call Trace:
>> [   51.419066]  read_mem+0x70/0x120
>> [   51.419069]  __vfs_read+0x28/0x130
>> [   51.419072]  ? security_file_permission+0x9b/0xb0
>> [   51.419075]  ? rw_verify_area+0x4e/0xb0
>> [   51.419077]  vfs_read+0x96/0x130
>> [   51.419079]  SyS_read+0x46/0xb0
>> [   51.419082]  ? SyS_lseek+0x87/0xb0
>> [   51.419085]  entry_SYSCALL_64_fastpath+0x1a/0xa9
> 
> I can't reproduce this myself, so I assume it's some specific /proc or
> /sys file that I don't have. Are you able to get a strace of x86info
> as it runs to see which file it is attempting to read here?
> 
> Thanks!
> 
> -Kees
> 

I can't see this on any of my Fedora systems. It looks like this
is trying to read /dev/mem so I suspect your BIOS is putting out
unexpected values. If you turn off hardened usercopy does x86info
give you reasonable values? I'd also echo getting an strace.

Thanks,
Laura

[toc] | [prev] | [next] | [standalone]


#1613320

FromKees Cook <keescook@chromium.org>
Date2017-03-30 19:40 +0200
Message-ID<tqMdc-1mD-15@gated-at.bofh.it>
In reply to#1613313
On Thu, Mar 30, 2017 at 10:27 AM, Laura Abbott <labbott@redhat.com> wrote:
> On 03/30/2017 09:45 AM, Kees Cook wrote:
>> On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
>> <tommi.t.rantala@nokia.com> wrote:
>>> Hi,
>>>
>>> Running:
>>>
>>>   $ sudo x86info -a
>>>
>>> On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
>>> produces the following kernel BUG.
>>>
>>>   $ git describe
>>>   v4.11-rc4-40-gfe82203
>>>
>>> It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
>>>
>>> Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
>>>
>>> [   51.418954] usercopy: kernel memory exposure attempt detected from
>>> ffff880000090000 (dma-kmalloc-256) (4096 bytes)
>>
>> This seems like a real exposure: the copy is attempting to read 4096
>> bytes from a 256 byte object.
>>
>>> [...]
>>> [   51.419063] Call Trace:
>>> [   51.419066]  read_mem+0x70/0x120
>>> [   51.419069]  __vfs_read+0x28/0x130
>>> [   51.419072]  ? security_file_permission+0x9b/0xb0
>>> [   51.419075]  ? rw_verify_area+0x4e/0xb0
>>> [   51.419077]  vfs_read+0x96/0x130
>>> [   51.419079]  SyS_read+0x46/0xb0
>>> [   51.419082]  ? SyS_lseek+0x87/0xb0
>>> [   51.419085]  entry_SYSCALL_64_fastpath+0x1a/0xa9
>>
>> I can't reproduce this myself, so I assume it's some specific /proc or
>> /sys file that I don't have. Are you able to get a strace of x86info
>> as it runs to see which file it is attempting to read here?
>
> I can't see this on any of my Fedora systems. It looks like this
> is trying to read /dev/mem so I suspect your BIOS is putting out
> unexpected values. If you turn off hardened usercopy does x86info
> give you reasonable values? I'd also echo getting an strace.

Reads out of /dev/mem should be restricted to non-RAM on Fedora, yes?

Tommi, do your kernels have CONFIG_STRICT_DEVMEM=y ?

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [prev] | [next] | [standalone]


#1613325

FromLaura Abbott <labbott@redhat.com>
Date2017-03-30 19:50 +0200
Message-ID<tqMmR-1rG-5@gated-at.bofh.it>
In reply to#1613320
On 03/30/2017 10:37 AM, Kees Cook wrote:
> On Thu, Mar 30, 2017 at 10:27 AM, Laura Abbott <labbott@redhat.com> wrote:
>> On 03/30/2017 09:45 AM, Kees Cook wrote:
>>> On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
>>> <tommi.t.rantala@nokia.com> wrote:
>>>> Hi,
>>>>
>>>> Running:
>>>>
>>>>   $ sudo x86info -a
>>>>
>>>> On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
>>>> produces the following kernel BUG.
>>>>
>>>>   $ git describe
>>>>   v4.11-rc4-40-gfe82203
>>>>
>>>> It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
>>>>
>>>> Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
>>>>
>>>> [   51.418954] usercopy: kernel memory exposure attempt detected from
>>>> ffff880000090000 (dma-kmalloc-256) (4096 bytes)
>>>
>>> This seems like a real exposure: the copy is attempting to read 4096
>>> bytes from a 256 byte object.
>>>
>>>> [...]
>>>> [   51.419063] Call Trace:
>>>> [   51.419066]  read_mem+0x70/0x120
>>>> [   51.419069]  __vfs_read+0x28/0x130
>>>> [   51.419072]  ? security_file_permission+0x9b/0xb0
>>>> [   51.419075]  ? rw_verify_area+0x4e/0xb0
>>>> [   51.419077]  vfs_read+0x96/0x130
>>>> [   51.419079]  SyS_read+0x46/0xb0
>>>> [   51.419082]  ? SyS_lseek+0x87/0xb0
>>>> [   51.419085]  entry_SYSCALL_64_fastpath+0x1a/0xa9
>>>
>>> I can't reproduce this myself, so I assume it's some specific /proc or
>>> /sys file that I don't have. Are you able to get a strace of x86info
>>> as it runs to see which file it is attempting to read here?
>>
>> I can't see this on any of my Fedora systems. It looks like this
>> is trying to read /dev/mem so I suspect your BIOS is putting out
>> unexpected values. If you turn off hardened usercopy does x86info
>> give you reasonable values? I'd also echo getting an strace.
> 
> Reads out of /dev/mem should be restricted to non-RAM on Fedora, yes?
> 
> Tommi, do your kernels have CONFIG_STRICT_DEVMEM=y ?
> 
> -Kees
> 

CONFIG_STRICT_DEVMEM should be on in all Fedora kernels.

Thanks,
Laura

[toc] | [prev] | [next] | [standalone]


#1613316

FromMark Rutland <mark.rutland@arm.com>
Date2017-03-30 19:30 +0200
Message-ID<tqM3w-1dT-25@gated-at.bofh.it>
In reply to#1613286
On Thu, Mar 30, 2017 at 09:45:26AM -0700, Kees Cook wrote:
> On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
> <tommi.t.rantala@nokia.com> wrote:
> > Hi,
> >
> > Running:
> >
> >   $ sudo x86info -a
> >
> > On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
> > produces the following kernel BUG.
> >
> >   $ git describe
> >   v4.11-rc4-40-gfe82203
> >
> > It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
> >
> > Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
> >
> > [   51.418954] usercopy: kernel memory exposure attempt detected from
> > ffff880000090000 (dma-kmalloc-256) (4096 bytes)
> 
> This seems like a real exposure: the copy is attempting to read 4096
> bytes from a 256 byte object.
> 
> > [...]
> > [   51.419063] Call Trace:
> > [   51.419066]  read_mem+0x70/0x120
> > [   51.419069]  __vfs_read+0x28/0x130
> > [   51.419072]  ? security_file_permission+0x9b/0xb0
> > [   51.419075]  ? rw_verify_area+0x4e/0xb0
> > [   51.419077]  vfs_read+0x96/0x130
> > [   51.419079]  SyS_read+0x46/0xb0
> > [   51.419082]  ? SyS_lseek+0x87/0xb0
> > [   51.419085]  entry_SYSCALL_64_fastpath+0x1a/0xa9
> 
> I can't reproduce this myself, so I assume it's some specific /proc or
> /sys file that I don't have. Are you able to get a strace of x86info
> as it runs to see which file it is attempting to read here?

Presumably this is /dev/mem, with read_mem in drivers/char/mem.c.

I guess you may have locked that down on your system anyhow. ;)

Thanks,
Mark.

[toc] | [prev] | [next] | [standalone]


#1613408

FromDave Jones <davej@codemonkey.org.uk>
Date2017-03-30 21:50 +0200
Message-ID<tqOf0-2K2-11@gated-at.bofh.it>
In reply to#1613286
On Thu, Mar 30, 2017 at 09:45:26AM -0700, Kees Cook wrote:
 > On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
 > <tommi.t.rantala@nokia.com> wrote:
 > > Hi,
 > >
 > > Running:
 > >
 > >   $ sudo x86info -a
 > >
 > > On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
 > > produces the following kernel BUG.
 > >
 > >   $ git describe
 > >   v4.11-rc4-40-gfe82203
 > >
 > > It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
 > >
 > > Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
 > >
 > > [   51.418954] usercopy: kernel memory exposure attempt detected from
 > > ffff880000090000 (dma-kmalloc-256) (4096 bytes)
 > 
 > This seems like a real exposure: the copy is attempting to read 4096
 > bytes from a 256 byte object.

The code[1] is doing a 4k read from /dev/mem in the range 0x90000 -> 0xa0000
According to arch/x86/mm/init.c:devmem_is_allowed, that's still valid..

Note that the printk is using the direct mapping address. Is that what's
being passed down to devmem_is_allowed now ? If so, that's probably what broke.

	Dave

[1] https://github.com/kernelslacker/x86info/blob/master/mptable.c

[toc] | [prev] | [next] | [standalone]


#1613426

FromKees Cook <keescook@chromium.org>
Date2017-03-30 22:00 +0200
Message-ID<tqOoG-2NT-33@gated-at.bofh.it>
In reply to#1613408
On Thu, Mar 30, 2017 at 12:41 PM, Dave Jones <davej@codemonkey.org.uk> wrote:
> On Thu, Mar 30, 2017 at 09:45:26AM -0700, Kees Cook wrote:
>  > On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
>  > <tommi.t.rantala@nokia.com> wrote:
>  > > Hi,
>  > >
>  > > Running:
>  > >
>  > >   $ sudo x86info -a
>  > >
>  > > On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
>  > > produces the following kernel BUG.
>  > >
>  > >   $ git describe
>  > >   v4.11-rc4-40-gfe82203
>  > >
>  > > It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
>  > >
>  > > Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
>  > >
>  > > [   51.418954] usercopy: kernel memory exposure attempt detected from
>  > > ffff880000090000 (dma-kmalloc-256) (4096 bytes)
>  >
>  > This seems like a real exposure: the copy is attempting to read 4096
>  > bytes from a 256 byte object.
>
> The code[1] is doing a 4k read from /dev/mem in the range 0x90000 -> 0xa0000
> According to arch/x86/mm/init.c:devmem_is_allowed, that's still valid..
>
> Note that the printk is using the direct mapping address. Is that what's
> being passed down to devmem_is_allowed now ? If so, that's probably what broke.

So this is attempting to read physical memory 0x90000 -> 0xa0000, but
that's somehow resolving to a virtual address that is claimed by
dma-kmalloc?? I'm confused how that's happening...

-Kees

>
>         Dave
>
> [1] https://github.com/kernelslacker/x86info/blob/master/mptable.c



-- 
Kees Cook
Pixel Security

[toc] | [prev] | [next] | [standalone]


#1613433

FromDave Jones <davej@codemonkey.org.uk>
Date2017-03-30 22:10 +0200
Message-ID<tqOym-36A-17@gated-at.bofh.it>
In reply to#1613426
On Thu, Mar 30, 2017 at 12:52:31PM -0700, Kees Cook wrote:
 > On Thu, Mar 30, 2017 at 12:41 PM, Dave Jones <davej@codemonkey.org.uk> wrote:
 > > On Thu, Mar 30, 2017 at 09:45:26AM -0700, Kees Cook wrote:
 > >  > On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
 > >  > <tommi.t.rantala@nokia.com> wrote:
 > >  > > Hi,
 > >  > >
 > >  > > Running:
 > >  > >
 > >  > >   $ sudo x86info -a
 > >  > >
 > >  > > On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
 > >  > > produces the following kernel BUG.
 > >  > >
 > >  > >   $ git describe
 > >  > >   v4.11-rc4-40-gfe82203
 > >  > >
 > >  > > It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
 > >  > >
 > >  > > Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
 > >  > >
 > >  > > [   51.418954] usercopy: kernel memory exposure attempt detected from
 > >  > > ffff880000090000 (dma-kmalloc-256) (4096 bytes)
 > >  >
 > >  > This seems like a real exposure: the copy is attempting to read 4096
 > >  > bytes from a 256 byte object.
 > >
 > > The code[1] is doing a 4k read from /dev/mem in the range 0x90000 -> 0xa0000
 > > According to arch/x86/mm/init.c:devmem_is_allowed, that's still valid..
 > >
 > > Note that the printk is using the direct mapping address. Is that what's
 > > being passed down to devmem_is_allowed now ? If so, that's probably what broke.
 > 
 > So this is attempting to read physical memory 0x90000 -> 0xa0000, but
 > that's somehow resolving to a virtual address that is claimed by
 > dma-kmalloc?? I'm confused how that's happening...

The only thing that I can think of would be a rogue ptr in the bios
table, but that seems unlikely.  Tommi, can you put strace of x86info -mp somewhere?
That will confirm/deny whether we're at least asking the kernel to do sane things.

	Dave

[toc] | [prev] | [next] | [standalone]


#1614175

FromDave Jones <davej@codemonkey.org.uk>
Date2017-03-31 19:20 +0200
Message-ID<tr8nn-7xP-7@gated-at.bofh.it>
In reply to#1613426
On Thu, Mar 30, 2017 at 12:52:31PM -0700, Kees Cook wrote:
 > On Thu, Mar 30, 2017 at 12:41 PM, Dave Jones <davej@codemonkey.org.uk> wrote:
 > > On Thu, Mar 30, 2017 at 09:45:26AM -0700, Kees Cook wrote:
 > >  > On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
 > >  > <tommi.t.rantala@nokia.com> wrote:
 > >  > > Hi,
 > >  > >
 > >  > > Running:
 > >  > >
 > >  > >   $ sudo x86info -a
 > >  > >
 > >  > > On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
 > >  > > produces the following kernel BUG.
 > >  > >
 > >  > >   $ git describe
 > >  > >   v4.11-rc4-40-gfe82203
 > >  > >
 > >  > > It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
 > >  > >
 > >  > > Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
 > >  > >
 > >  > > [   51.418954] usercopy: kernel memory exposure attempt detected from
 > >  > > ffff880000090000 (dma-kmalloc-256) (4096 bytes)
 > >  >
 > >  > This seems like a real exposure: the copy is attempting to read 4096
 > >  > bytes from a 256 byte object.
 > >
 > > The code[1] is doing a 4k read from /dev/mem in the range 0x90000 -> 0xa0000
 > > According to arch/x86/mm/init.c:devmem_is_allowed, that's still valid..
 > >
 > > Note that the printk is using the direct mapping address. Is that what's
 > > being passed down to devmem_is_allowed now ? If so, that's probably what broke.
 > 
 > So this is attempting to read physical memory 0x90000 -> 0xa0000, but
 > that's somehow resolving to a virtual address that is claimed by
 > dma-kmalloc?? I'm confused how that's happening...

/dev/mem is using physical addresses that the kernel translates through the
direct mapping.  __check_object_size seems to think that anything passed
into it is always allocated by the kernel, but in this case, I think read_mem()
is just passing through the direct mapping to copy_to_user.

	Dave

[toc] | [prev] | [next] | [standalone]


#1614183

FromKees Cook <keescook@chromium.org>
Date2017-03-31 19:40 +0200
Message-ID<tr8GJ-7Fk-9@gated-at.bofh.it>
In reply to#1614175
On Fri, Mar 31, 2017 at 10:17 AM, Dave Jones <davej@codemonkey.org.uk> wrote:
> On Thu, Mar 30, 2017 at 12:52:31PM -0700, Kees Cook wrote:
>  > On Thu, Mar 30, 2017 at 12:41 PM, Dave Jones <davej@codemonkey.org.uk> wrote:
>  > > On Thu, Mar 30, 2017 at 09:45:26AM -0700, Kees Cook wrote:
>  > >  > On Wed, Mar 29, 2017 at 11:44 PM, Tommi Rantala
>  > >  > <tommi.t.rantala@nokia.com> wrote:
>  > >  > > Hi,
>  > >  > >
>  > >  > > Running:
>  > >  > >
>  > >  > >   $ sudo x86info -a
>  > >  > >
>  > >  > > On this HP ZBook 15 G3 laptop kills the x86info process with segfault and
>  > >  > > produces the following kernel BUG.
>  > >  > >
>  > >  > >   $ git describe
>  > >  > >   v4.11-rc4-40-gfe82203
>  > >  > >
>  > >  > > It is also reproducible with the fedora kernel: 4.9.14-200.fc25.x86_64
>  > >  > >
>  > >  > > Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
>  > >  > >
>  > >  > > [   51.418954] usercopy: kernel memory exposure attempt detected from
>  > >  > > ffff880000090000 (dma-kmalloc-256) (4096 bytes)
>  > >  >
>  > >  > This seems like a real exposure: the copy is attempting to read 4096
>  > >  > bytes from a 256 byte object.
>  > >
>  > > The code[1] is doing a 4k read from /dev/mem in the range 0x90000 -> 0xa0000
>  > > According to arch/x86/mm/init.c:devmem_is_allowed, that's still valid..
>  > >
>  > > Note that the printk is using the direct mapping address. Is that what's
>  > > being passed down to devmem_is_allowed now ? If so, that's probably what broke.
>  >
>  > So this is attempting to read physical memory 0x90000 -> 0xa0000, but
>  > that's somehow resolving to a virtual address that is claimed by
>  > dma-kmalloc?? I'm confused how that's happening...
>
> /dev/mem is using physical addresses that the kernel translates through the
> direct mapping.  __check_object_size seems to think that anything passed
> into it is always allocated by the kernel, but in this case, I think read_mem()
> is just passing through the direct mapping to copy_to_user.

How is ffff880000090000 both in the direct mapping and a slab object?

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

        if (is_vmalloc_or_module_addr(ptr))
                return NULL;

        if (!virt_addr_valid(ptr))
                return NULL;

        page = virt_to_head_page(ptr);

        /* Check slab allocator for flags and size. */
        if (PageSlab(page))
                return __check_heap_object(ptr, n, page);


-Kees

-- 
Kees Cook
Pixel Security

[toc] | [prev] | [next] | [standalone]


#1614233

FromDave Jones <davej@codemonkey.org.uk>
Date2017-03-31 20:10 +0200
Message-ID<tr99L-86R-1@gated-at.bofh.it>
In reply to#1614183
On Fri, Mar 31, 2017 at 10:32:04AM -0700, Kees Cook wrote:
 
 > >  > >  > > Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
 > >  > >  > >
 > >  > >  > > [   51.418954] usercopy: kernel memory exposure attempt detected from
 > >  > >  > > ffff880000090000 (dma-kmalloc-256) (4096 bytes)
 > >  > >  >
 > >  > >  > This seems like a real exposure: the copy is attempting to read 4096
 > >  > >  > bytes from a 256 byte object.
 > >  > >
 > >  > > The code[1] is doing a 4k read from /dev/mem in the range 0x90000 -> 0xa0000
 > >  > > According to arch/x86/mm/init.c:devmem_is_allowed, that's still valid..
 > >  > >
 > >  > > Note that the printk is using the direct mapping address. Is that what's
 > >  > > being passed down to devmem_is_allowed now ? If so, that's probably what broke.
 > >  >
 > >  > So this is attempting to read physical memory 0x90000 -> 0xa0000, but
 > >  > that's somehow resolving to a virtual address that is claimed by
 > >  > dma-kmalloc?? I'm confused how that's happening...
 > >
 > > /dev/mem is using physical addresses that the kernel translates through the
 > > direct mapping.  __check_object_size seems to think that anything passed
 > > into it is always allocated by the kernel, but in this case, I think read_mem()
 > > is just passing through the direct mapping to copy_to_user.
 > 
 > How is ffff880000090000 both in the direct mapping and a slab object?
 > 
 > It would need to pass all of these checks, and be marked as PageSlab
 > before it could be evaluated by __check_heap_object:
 > 
 >         if (is_vmalloc_or_module_addr(ptr))
 >                 return NULL;
 > 
 >         if (!virt_addr_valid(ptr))
 >                 return NULL;
 > 
 >         page = virt_to_head_page(ptr);
 > 
 >         /* Check slab allocator for flags and size. */
 >         if (PageSlab(page))
 >                 return __check_heap_object(ptr, n, page);

Looking at Tommi's dmesg output closer, it appears that he's booting in
EFI mode (which isn't unusual these days).  I'm not sure that the EBDA
(that x86info is trying to read) even exists under EFI, which is
probably why the memory range is showing up as usable, and then ending
up as a slab page, rather than being reserved by the BIOS.

...
reserve setup_data: [mem 0x0000000000059000-0x000000000009dfff] usable
...

If EBDA under EFI isn't a valid thing, the puzzling part is why there's
still an EBDA pointer in lowmem. x86 people ?

Longterm, I think I'm just going to gut all the ebda code from x86info,
as it isn't really necessary.  Whether we still need to change /dev/mem
to cope with this situation depends on whether there are other valid
usecases.

	Dave

[toc] | [prev] | [next] | [standalone]


#1614252

FromAndy Lutomirski <luto@amacapital.net>
Date2017-03-31 21:00 +0200
Message-ID<tr9Wa-8nY-11@gated-at.bofh.it>
In reply to#1614233
On Fri, Mar 31, 2017 at 11:03 AM, Dave Jones <davej@codemonkey.org.uk> wrote:
> On Fri, Mar 31, 2017 at 10:32:04AM -0700, Kees Cook wrote:
>
>  > >  > >  > > Full dmesg output here: https://pastebin.com/raw/Kur2mpZq
>  > >  > >  > >
>  > >  > >  > > [   51.418954] usercopy: kernel memory exposure attempt detected from
>  > >  > >  > > ffff880000090000 (dma-kmalloc-256) (4096 bytes)
>  > >  > >  >
>  > >  > >  > This seems like a real exposure: the copy is attempting to read 4096
>  > >  > >  > bytes from a 256 byte object.
>  > >  > >
>  > >  > > The code[1] is doing a 4k read from /dev/mem in the range 0x90000 -> 0xa0000
>  > >  > > According to arch/x86/mm/init.c:devmem_is_allowed, that's still valid..
>  > >  > >
>  > >  > > Note that the printk is using the direct mapping address. Is that what's
>  > >  > > being passed down to devmem_is_allowed now ? If so, that's probably what broke.
>  > >  >
>  > >  > So this is attempting to read physical memory 0x90000 -> 0xa0000, but
>  > >  > that's somehow resolving to a virtual address that is claimed by
>  > >  > dma-kmalloc?? I'm confused how that's happening...
>  > >
>  > > /dev/mem is using physical addresses that the kernel translates through the
>  > > direct mapping.  __check_object_size seems to think that anything passed
>  > > into it is always allocated by the kernel, but in this case, I think read_mem()
>  > > is just passing through the direct mapping to copy_to_user.
>  >
>  > How is ffff880000090000 both in the direct mapping and a slab object?
>  >
>  > It would need to pass all of these checks, and be marked as PageSlab
>  > before it could be evaluated by __check_heap_object:
>  >
>  >         if (is_vmalloc_or_module_addr(ptr))
>  >                 return NULL;
>  >
>  >         if (!virt_addr_valid(ptr))
>  >                 return NULL;
>  >
>  >         page = virt_to_head_page(ptr);
>  >
>  >         /* Check slab allocator for flags and size. */
>  >         if (PageSlab(page))
>  >                 return __check_heap_object(ptr, n, page);
>
> Looking at Tommi's dmesg output closer, it appears that he's booting in
> EFI mode (which isn't unusual these days).  I'm not sure that the EBDA
> (that x86info is trying to read) even exists under EFI, which is
> probably why the memory range is showing up as usable, and then ending
> up as a slab page, rather than being reserved by the BIOS.
>

This stuff all sucks.  Presumably the only reason that we pay
attention to the EBDA at all in EFI mode is that no one has the guts
to change it: maybe there's a firmware out there that puts something
important in the EBDA and fails to properly reserve it in the EFI
memory map.

> ...
> reserve setup_data: [mem 0x0000000000059000-0x000000000009dfff] usable
> ...
>
> If EBDA under EFI isn't a valid thing, the puzzling part is why there's
> still an EBDA pointer in lowmem. x86 people ?
>
> Longterm, I think I'm just going to gut all the ebda code from x86info,
> as it isn't really necessary.  Whether we still need to change /dev/mem
> to cope with this situation depends on whether there are other valid
> usecases.

I would like to at least consider a stricter alternative: make
/dev/mem a real whitelist.  The rules would be that, by default,
/dev/mem access is always rejected.  Kernel code could explicitly
register resources that would be permitted via /dev/mem -- each
resource would be tagged with a bit saying "devmem okay" along with
some indication of caching mode.  For example, on very recent kernels,
some crappy HP tools are busted because they try to access SMBIOS
using explicit uncached devmem accesses, but that's verboten because
the kernel accesses it with ioremap_cache().

There are really very few cases where /dev/mem is okay at all, I
think.  Maybe the EBDA is one of them.  And we could make up some hack
where devmem access to certain ranges just gets all zeros regardless
of what's actually there.

--Andy

[toc] | [prev] | [next] | [standalone]


#1614240

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-03-31 20:30 +0200
Message-ID<tr9t8-8dB-9@gated-at.bofh.it>
In reply to#1614183
On Fri, Mar 31, 2017 at 10:32 AM, Kees Cook <keescook@chromium.org> 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

[toc] | [prev] | [next] | [standalone]


#1614335

FromKees Cook <keescook@chromium.org>
Date2017-04-01 02:00 +0200
Message-ID<treCu-2V3-15@gated-at.bofh.it>
In reply to#1614240
On Fri, Mar 31, 2017 at 11:26 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Fri, Mar 31, 2017 at 10:32 AM, Kees Cook <keescook@chromium.org> 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 tripped under Fedora (with STRICT_DEVMEM) too, but I see below you
isolated it...)

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

I'm a fan of this whatever the case; have all the video drivers moved
away from crazy userspace direct memory access? (Or am I
misremembering the reason for allowing /dev/mem to read RAM?)

>  - 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.

I don't think this is a probably with the usercopy code: it is
attempting to read RAM which should be blocked. It just _happens_ that
this RAM got used for slab cache.

> Hmm. Thinking more about this, we do allow access to the first 1MB of
> physical memory unconditionally (see devmem_is_allowed() in

Oooh, yes, that's the issue here. If the location is bypassing
devmem_is_allowed(), oops.

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

If that doesn't break x86info, that would be nice too.

> 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.

So, this seems like an uncommon situation where <1M memory ended up in
as regular RAM. It seems like this exception is the problem?

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [prev] | [next] | [standalone]


#1616430

FromKees Cook <keescook@chromium.org>
Date2017-04-05 00:40 +0200
Message-ID<tsFhf-2yy-7@gated-at.bofh.it>
In reply to#1614240
On Fri, Mar 31, 2017 at 12:32 PM, Tommi Rantala
<tommi.t.rantala@nokia.com> wrote:
> On 31.03.2017 21:26, Linus Torvalds wrote:
>>
>> 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?
>
>
> Yep, it is enough to trigger the bug.
>
> Also crashes with the fedora kernel that has STRICT_DEVMEM:
>
> $ sudo dd if=/dev/mem of=/dev/null bs=4096 count=256
> Segmentation fault
>
> [   73.224025] usercopy: kernel memory exposure attempt detected from
> ffff893a80059000 (dma-kmalloc-16) (4096 bytes)
> [   73.224049] ------------[ cut here ]------------
> [   73.224056] kernel BUG at mm/usercopy.c:75!
> [   73.224060] invalid opcode: 0000 [#1] SMP
> [   73.224237] CPU: 5 PID: 2860 Comm: dd Not tainted 4.9.14-200.fc25.x86_64
> #1

As root, what does dumping /proc/iomem show you?

For one of my systems, I see something like this:

00000000-00000fff : reserved
00001000-0008efff : System RAM
0008f000-0008ffff : reserved
00090000-0009f7ff : System RAM
0009f800-0009ffff : reserved
000a0000-000bffff : PCI Bus 0000:00
000c0000-000c7fff : Video ROM
000e0000-000fffff : reserved
  000e0000-000effff : PCI Bus 0000:00
  000f0000-000fffff : System ROM
00100000-cdee6fff : System RAM
  cbc00000-cc49a653 : Kernel code
  cc49a654-ccb661bf : Kernel data
  cccf3000-cce30fff : Kernel bss
...

I note that there are two "System RAM" areas below 0x100000. In
arch/x86/mm/init.c, devmem_is_allowed() says:

/*
 * devmem_is_allowed() checks to see if /dev/mem access to a certain address
 * is valid. The argument is a physical page number.
 *
 *
 * On x86, access has to be given to the first megabyte of ram because that area
 * contains BIOS code and data regions used by X and dosemu and similar apps.
 * Access has to be given to non-kernel-ram areas as well, these contain the PCI
 * mmio resources as well as potential bios/acpi data regions.
 */
int devmem_is_allowed(unsigned long pagenr)
{
        if (pagenr < 256)
                return 1;
        if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
                return 0;
        if (!page_is_ram(pagenr))
                return 1;
        return 0;
}

This means that it allows reads into even System RAM below 0x100000,
but I think that's a mistake. Shouldn't BIOS code and data regions
already be marked as "reserved", as seen in my /proc/iomem output? I
feel like the "pagenr < 256" exception should be dropped, but I don't
know all the minor details on the history here.

When I remove this exception, x86info blows up for me ("error reading
EBDA pointer").

So, my question is: are there actually BIOS code/data in memory areas
marked as System RAM? If so, what normally keeps them from being used
for kernel memory? If not, then I assume x86info is wrong?

Dave, you implied the latter, but I wanted to make sure this is
actually true? (And if so, we need to do something like what Linus
suggested to return zeros to keep old x86info "happy" -- would that
keep it happy?)

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [prev] | [next] | [standalone]


#1616435

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-04-05 01:00 +0200
Message-ID<tsFAB-2Hi-1@gated-at.bofh.it>
In reply to#1616430
On Tue, Apr 4, 2017 at 3:37 PM, Kees Cook <keescook@chromium.org> wrote:
>
> For one of my systems, I see something like this:
>
> 00000000-00000fff : reserved
> 00001000-0008efff : System RAM
> 0008f000-0008ffff : reserved
> 00090000-0009f7ff : System RAM
> 0009f800-0009ffff : reserved

That's fairly normal.

> I note that there are two "System RAM" areas below 0x100000.

Yes. Traditionally the area from about 4k to 640kB is RAM. With a
random smattering of BIOS areas.

>  * On x86, access has to be given to the first megabyte of ram because that area
>  * contains BIOS code and data regions used by X and dosemu and similar apps.

Rigth. Traditionally, dosemu did one big mmap of the 1MB area to just
get all the BIOS data in one go.

> This means that it allows reads into even System RAM below 0x100000,
> but I think that's a mistake.

What you think is a "mistake" is how /dev/mem has always worked.

/dev/mem gave access to all the memory of the system. That's LITERALLY
the whole point of it. There was no "BIOS area" or anything else. It
was access to physical memory.

We've added limits to it, but those limits came later, and they came
with the caveat that lots of programs used /dev/mem in various ways.

Nobody was crazy enough to read /dev/mem one byte at a time trying to
follow BIOS tables. No, the traditional way was to just map (or read)
large chunks of it, and then follow the tables in the result. The
easiest way was to just do the whole low 1MB.

There's no "mistake" here. The only thing that is mistaken is you
thinking that we can redefine reality and change history.

I already explained what the likely fix is: make devmem_is_allowed()
return a ternary value, so that those things that *do* read the BIOS
area can just continue to do so, but they see zeroes for the parts
that the kernel has taken over.

                 Linus

[toc] | [prev] | [next] | [standalone]


#1616441

FromKees Cook <keescook@chromium.org>
Date2017-04-05 01:10 +0200
Message-ID<tsFKi-2Zv-25@gated-at.bofh.it>
In reply to#1616435
On Tue, Apr 4, 2017 at 3:55 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Tue, Apr 4, 2017 at 3:37 PM, Kees Cook <keescook@chromium.org> wrote:
>>
>> For one of my systems, I see something like this:
>>
>> 00000000-00000fff : reserved
>> 00001000-0008efff : System RAM
>> 0008f000-0008ffff : reserved
>> 00090000-0009f7ff : System RAM
>> 0009f800-0009ffff : reserved
>
> That's fairly normal.
>
>> I note that there are two "System RAM" areas below 0x100000.
>
> Yes. Traditionally the area from about 4k to 640kB is RAM. With a
> random smattering of BIOS areas.
>
>>  * On x86, access has to be given to the first megabyte of ram because that area
>>  * contains BIOS code and data regions used by X and dosemu and similar apps.
>
> Rigth. Traditionally, dosemu did one big mmap of the 1MB area to just
> get all the BIOS data in one go.
>
>> This means that it allows reads into even System RAM below 0x100000,
>> but I think that's a mistake.
>
> What you think is a "mistake" is how /dev/mem has always worked.
>
> /dev/mem gave access to all the memory of the system. That's LITERALLY
> the whole point of it. There was no "BIOS area" or anything else. It
> was access to physical memory.
>
> We've added limits to it, but those limits came later, and they came
> with the caveat that lots of programs used /dev/mem in various ways.
>
> Nobody was crazy enough to read /dev/mem one byte at a time trying to
> follow BIOS tables. No, the traditional way was to just map (or read)
> large chunks of it, and then follow the tables in the result. The
> easiest way was to just do the whole low 1MB.
>
> There's no "mistake" here. The only thing that is mistaken is you
> thinking that we can redefine reality and change history.

I'm not trying to rewrite history. :) I'm try to understand the
requirements for how the 1MB area was used, which you've explained the
history of now. (Thank you!)

> I already explained what the likely fix is: make devmem_is_allowed()
> return a ternary value, so that those things that *do* read the BIOS
> area can just continue to do so, but they see zeroes for the parts
> that the kernel has taken over.

Sounds good to me. I'll go work on that.

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [prev] | [next] | [standalone]


#1616466

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-04-05 02:30 +0200
Message-ID<tsGZH-3Ia-3@gated-at.bofh.it>
In reply to#1616435
On Tue, Apr 4, 2017 at 3:55 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> I already explained what the likely fix is: make devmem_is_allowed()
> return a ternary value, so that those things that *do* read the BIOS
> area can just continue to do so, but they see zeroes for the parts
> that the kernel has taken over.

Actually, a simpler solution might be to

 (a) keep the binary value

 (b) remove the test for the low 1M

 (c) to avoid breakage, don't return _error_, but just always read zero

that also removes (or at least makes it much more expensive) a signal
of which pages are kernel allocated vs BIOS allocated.

               Linus

[toc] | [prev] | [next] | [standalone]


#1617314

FromKees Cook <keescook@chromium.org>
Date2017-04-05 21:40 +0200
Message-ID<tsYWB-6NO-17@gated-at.bofh.it>
In reply to#1616466
On Tue, Apr 4, 2017 at 5:22 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Tue, Apr 4, 2017 at 3:55 PM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
>>
>> I already explained what the likely fix is: make devmem_is_allowed()
>> return a ternary value, so that those things that *do* read the BIOS
>> area can just continue to do so, but they see zeroes for the parts
>> that the kernel has taken over.
>
> Actually, a simpler solution might be to
>
>  (a) keep the binary value
>
>  (b) remove the test for the low 1M
>
>  (c) to avoid breakage, don't return _error_, but just always read zero
>
> that also removes (or at least makes it much more expensive) a signal
> of which pages are kernel allocated vs BIOS allocated.

This last part (reading zero) is what I'm poking at now. It's not
obvious to me yet how to make the mmap interface hand back zero-mapped
pages. I'll keep digging...

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web