Re: [patch 11/16] x86/ldt: Force access bit for CS/SS

From: Andy Lutomirski
Date: Tue Dec 12 2017 - 13:22:56 EST




> On Dec 12, 2017, at 10:10 AM, Andy Lutomirski <luto@xxxxxxxxxx> wrote:
>
>> On Tue, Dec 12, 2017 at 10:09 AM, Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
>>> On Tue, Dec 12, 2017 at 10:03:02AM -0800, Andy Lutomirski wrote:
>>> On Tue, Dec 12, 2017 at 9:32 AM, Thomas Gleixner <tglx@xxxxxxxxxxxxx> wrote:
>>
>>>> @@ -171,6 +172,9 @@ static void exit_to_usermode_loop(struct
>>>> /* Disable IRQs and retry */
>>>> local_irq_disable();
>>>>
>>>> + if (cached_flags & _TIF_LDT)
>>>> + ldt_exit_user(regs);
>>>
>>> Nope. To the extent that this code actually does anything (which it
>>> shouldn't since you already forced the access bit),
>>
>> Without this; even with the access bit set; IRET will go wobbly and
>> we'll #GP on the user-space side. Try it ;-)
>
> Maybe later.
>
> But that means that we need Intel and AMD to confirm WTF is going on
> before this blows up even with LAR on some other CPU.
>
>>
>>> it's racy against
>>> flush_ldt() from another thread, and that race will be exploitable for
>>> privilege escalation. It needs to be outside the loopy part.
>>
>> The flush_ldt (__ldt_install after these patches) would re-set the TIF
>> flag. But sure, we can move this outside the loop I suppose.

Also, why is LAR deferred to user exit? And I thought that LAR didn't set the accessed bit.

If I had to guess, I'd guess that LAR is actually generating a read fault and forcing the pagetables to get populated. If so, then it means the VMA code isn't quite right, or you're susceptible to failures under memory pressure.

Now maybe LAR will repopulate the PTE every time if you were to never clear it, but ick.