Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1603515 > unrolled thread
| Started by | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| First post | 2017-03-17 19:00 +0100 |
| Last post | 2017-03-17 22:50 +0100 |
| Articles | 7 — 3 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.
Re: [x86] 45fc8757d1: BUG:unable_to_handle_kernel Linus Torvalds <torvalds@linux-foundation.org> - 2017-03-17 19:00 +0100
Re: [x86] 45fc8757d1: BUG:unable_to_handle_kernel Linus Torvalds <torvalds@linux-foundation.org> - 2017-03-17 19:10 +0100
Re: [x86] 45fc8757d1: BUG:unable_to_handle_kernel Linus Torvalds <torvalds@linux-foundation.org> - 2017-03-17 19:10 +0100
Re: [x86] 45fc8757d1: BUG:unable_to_handle_kernel Andy Lutomirski <luto@kernel.org> - 2017-03-17 19:30 +0100
Re: [x86] 45fc8757d1: BUG:unable_to_handle_kernel Andy Lutomirski <luto@amacapital.net> - 2017-03-17 21:20 +0100
Re: [x86] 45fc8757d1: BUG:unable_to_handle_kernel Linus Torvalds <torvalds@linux-foundation.org> - 2017-03-17 22:20 +0100
Re: [x86] 45fc8757d1: BUG:unable_to_handle_kernel Linus Torvalds <torvalds@linux-foundation.org> - 2017-03-17 22:50 +0100
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2017-03-17 19:00 +0100 |
| Subject | Re: [x86] 45fc8757d1: BUG:unable_to_handle_kernel |
| Message-ID | <tm4kr-1GF-49@gated-at.bofh.it> |
On Fri, Mar 17, 2017 at 4:59 AM, kernel test robot
<xiaolong.ye@intel.com> wrote:
>
> FYI, we noticed the following commit:
>
> commit: 45fc8757d1d2128e342b4e7ef39adedf7752faac ("x86: Make the GDT remapping read-only on 64-bit")
> https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git x86/mm
>
> in testcase: boot
>
> [ 4.347219] BUG: unable to handle kernel paging request at ffffffffff577060
> [ 4.360480] Oops: 0003 [#1] SMP
> [ 4.373550] RIP: 0023:0xf77e91ed
> [ 4.375284] RSP: 002b:00000000ffed034c EFLAGS: 00010246
Heh. That's actually in user space, but the error code (0003) means
"protection fault on a write, not a user access".
So it's almost certainly something that tries to access a segment
descriptor in the GDT, but that segment was marked as "not accessed",
and the CPU was trying to set the accessed bit.
I *thought* we always maked everything accessed when we initialize it,
but something clearly is not.
That's why there's no kernel call trace or anything like that: it is a
system page fault, but it's triggered directly from user mode.
The linear address can be used to look up which entry it is. I assume
the GDT starts at ffffffffff577000, and that this is at offset 0x60
from that. Whatever descriptor that would be..
Linus
[toc] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2017-03-17 19:10 +0100 |
| Message-ID | <tm4u5-21N-5@gated-at.bofh.it> |
| In reply to | #1603515 |
On Fri, Mar 17, 2017 at 10:49 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> The linear address can be used to look up which entry it is. I assume
> the GDT starts at ffffffffff577000, and that this is at offset 0x60
> from that. Whatever descriptor that would be..
Hmm. That should be gdt index 12, aka GDT_ENTRY_TLS_MIN.
I guess user space can set almost anything there. Including setting a
segment type that isn't accessed, and that the CPU will change on the
first actual access.
We do have code to verify the limits and types etc iirc, I guess we
can make sure to set the accessed bit too.
Linus
[toc] | [prev] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2017-03-17 19:10 +0100 |
| Message-ID | <tm4u6-21N-25@gated-at.bofh.it> |
| In reply to | #1603518 |
On Fri, Mar 17, 2017 at 11:00 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Fri, Mar 17, 2017 at 10:49 AM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
>>
>> The linear address can be used to look up which entry it is. I assume
>> the GDT starts at ffffffffff577000, and that this is at offset 0x60
>> from that. Whatever descriptor that would be..
>
> Hmm. That should be gdt index 12, aka GDT_ENTRY_TLS_MIN.
>
> I guess user space can set almost anything there. Including setting a
> segment type that isn't accessed, and that the CPU will change on the
> first actual access.
>
> We do have code to verify the limits and types etc iirc, I guess we
> can make sure to set the accessed bit too.
Hmm. "fill_ldt()" does this:
desc->type = (info->read_exec_only ^ 1) << 1;
desc->type |= info->contents << 2;
which always leaves bit #0 of ->type clear. That's the A bit.
Does the problem go away if we just add a
desc->type |= 1;
to the end there?
But it is entirely possible that I'm missing something here. It's been
_years_ since I looked at descriptor table entries.
Linus
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2017-03-17 19:30 +0100 |
| Message-ID | <tm4Ns-29P-21@gated-at.bofh.it> |
| In reply to | #1603522 |
On Fri, Mar 17, 2017 at 11:07 AM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > On Fri, Mar 17, 2017 at 11:00 AM, Linus Torvalds > <torvalds@linux-foundation.org> wrote: >> On Fri, Mar 17, 2017 at 10:49 AM, Linus Torvalds >> <torvalds@linux-foundation.org> wrote: >>> >>> The linear address can be used to look up which entry it is. I assume >>> the GDT starts at ffffffffff577000, and that this is at offset 0x60 >>> from that. Whatever descriptor that would be.. >> >> Hmm. That should be gdt index 12, aka GDT_ENTRY_TLS_MIN. >> >> I guess user space can set almost anything there. Including setting a >> segment type that isn't accessed, and that the CPU will change on the >> first actual access. >> >> We do have code to verify the limits and types etc iirc, I guess we >> can make sure to set the accessed bit too. > > Hmm. "fill_ldt()" does this: > > desc->type = (info->read_exec_only ^ 1) << 1; > desc->type |= info->contents << 2; > > which always leaves bit #0 of ->type clear. That's the A bit. > > Does the problem go away if we just add a > > desc->type |= 1; > > to the end there? I can easily imagine that breaking WINE or DOSEMU because it'll affect the LDT, too. How about this: https://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git/commit/?h=x86/fixes&id=df8110544c6e899897e1b2ec3ab53d9e4ee40f65 I'll see why selftests didn't catch this, too.
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2017-03-17 21:20 +0100 |
| Message-ID | <tm6vT-3sM-5@gated-at.bofh.it> |
| In reply to | #1603531 |
On Fri, Mar 17, 2017 at 12:36 PM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > On Fri, Mar 17, 2017 at 11:20 AM, Andy Lutomirski <luto@kernel.org> wrote: >> >> I can easily imagine that breaking WINE or DOSEMU because it'll affect >> the LDT, too. > > Can they even *read* the LDT contents, though? The whole accessed bit > doesn't show up in 'struct user_desc', so you can neither set it nor > read it. LAR. I've learned to never underestimate the absurdity of the games played by 16-bit apps. (See, for example, the fact that some of them apparently use SGDT just to find a page that's guaranteed not to be accessible.) > >> How about this: > > I don't think that's _wrong_, but.. > > I'd really rather just do it in fill_ldt() itself, unless you can > explain how it would be visible to anybody.. See above :( (Also, your approach would probably break some selftests.) --Andy
[toc] | [prev] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2017-03-17 22:20 +0100 |
| Message-ID | <tm7rY-495-1@gated-at.bofh.it> |
| In reply to | #1603604 |
On Fri, Mar 17, 2017 at 1:18 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Fri, Mar 17, 2017 at 12:36 PM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
>>
>> Can they even *read* the LDT contents, though? The whole accessed bit
>> doesn't show up in 'struct user_desc', so you can neither set it nor
>> read it.
>
> LAR. I've learned to never underestimate the absurdity of the games
> played by 16-bit apps. (See, for example, the fact that some of them
> apparently use SGDT just to find a page that's guaranteed not to be
> accessible.)
Ugh. Right you are, LAR will return those type bits.
Of course, maybe somebody cares about them in the GDT already? So
it's visible even with your patch, isn't it. We give users four
entries to play with...
Linus
[toc] | [prev] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2017-03-17 22:50 +0100 |
| Message-ID | <tm6vT-3sM-7@gated-at.bofh.it> |
| In reply to | #1603531 |
On Fri, Mar 17, 2017 at 11:20 AM, Andy Lutomirski <luto@kernel.org> wrote:
>
> I can easily imagine that breaking WINE or DOSEMU because it'll affect
> the LDT, too.
Can they even *read* the LDT contents, though? The whole accessed bit
doesn't show up in 'struct user_desc', so you can neither set it nor
read it.
> How about this:
I don't think that's _wrong_, but..
I'd really rather just do it in fill_ldt() itself, unless you can
explain how it would be visible to anybody..
Linus
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web