On Sat, Nov 7, 2015 at 11:55 PM, Ard Biesheuvel
<ard.biesheu...@linaro.org> wrote:
> On 8 November 2015 at 07:58, Kees Cook <keesc...@chromium.org> wrote:
>> On Fri, Nov 6, 2015 at 11:39 PM, Ard Biesheuvel
>> <ard.biesheu...@linaro.org> wrote:
>>> On 7 November 2015 at 08:09, Ingo Molnar <mi...@kernel.org> wrote:
>>>>
>>>> * Matt Fleming <m...@codeblueprint.co.uk> wrote:
>>>>
>>>>> On Fri, 06 Nov, at 07:55:50AM, Ingo Molnar wrote:
>>>>> >
>>>>> >  3) We should fix the EFI permission problem without relying on the 
>>>>> > firmware: it
>>>>> >     appears we could just mark everything R-X optimistically, and if a 
>>>>> > write fault
>>>>> >     happens (it's pretty rare in fact, only triggers when we write to 
>>>>> > an EFI
>>>>> >     variable and so), we can mark the faulting page RW- on the fly, 
>>>>> > because it
>>>>> >     appears that writable EFI sections, while not enumerated very well 
>>>>> > in 'old'
>>>>> >     firmware, are still supposed to be page granular. (Even 'new' 
>>>>> > firmware I
>>>>> >     wouldn't automatically trust to get the enumeration right...)
>>>>>
>>>>> Sorry, this isn't true. I misled you with one of my earlier posts on
>>>>> this topic. Let me try and clear things up...
>>>>>
>>>>> Writing to EFI regions has to do with every invocation of the EFI
>>>>> runtime services - it's not limited to when you read/write/delete EFI
>>>>> variables. In fact, EFI variables really have nothing to do with this
>>>>> discussion, they're a completely opaque concept to the OS, we have no
>>>>> idea how the firmware implements them. Everything is done via the EFI
>>>>> boot/runtime services.
>>>>>
>>>>> The firmware itself will attempt to write to EFI regions when we
>>>>> invoke the EFI services because that's where the PE/COFF ".data" and
>>>>> ".bss" sections live along with the heap. There's even some relocation
>>>>> fixups that occur as SetVirtualAddressMap() time so it'll write to
>>>>> ".text" too.
>>>>>
>>>>> Now, the above PE/COFF sections are usually (always?) contained within
>>>>> EFI regions of type EfiRuntimeServicesCode. We know this is true
>>>>> because the firmware folks have told us so, and because stopping that
>>>>> is the motivation behind the new EFI_PROPERTIES_TABLE feature in UEFI
>>>>> V2.5.
>>>>>
>>>>> The data sections within the region are also *not* guaranteed to be
>>>>> page granular because work was required in Tianocore for emitting
>>>>> sections with 4k alignment as part of the EFI_PROPERTIES_TABLE
>>>>> support.
>>>>>
>>>>> Ultimately, what this means is that if you were to attempt to
>>>>> dynamically fixup those regions that required write permission, you'd
>>>>> have to modify the mappings for the majority of the EFI regions
>>>>> anyway. And if you're blindly allowing write permission as a fixup,
>>>>> there's not much security to be had.
>>>>
>>>> I think you misunderstood my suggestion: the 'fixup' would be changing it 
>>>> from R-X
>>>> to RW-, i.e. it would add 'write' permission but remove 'execute' 
>>>> permission.
>>>>
>>>> Note that there would be no 'RWX' permission at any given moment - which 
>>>> is the
>>>> dangerous combination.
>>>>
>>>
>>> The problem with that is that /any/ page in the UEFI runtime region
>>> may intersect with both .text and .data of any of the PE/COFF images
>>> that make up the runtime firmware (since the PE/COFF sections are not
>>> necessarily page aligned). Such pages require RWX permissions. The
>>> UEFI memory map does not provide the information to identify those
>>> pages a priori (the entire region containing several PE/COFF images
>>> could be covered by a single entry) so it is hard to guess which pages
>>> should be allowed these RWX permissions.
>>
>> I'm sad that UEFI was designed without even the most basic of memory
>> protections in mind. UEFI _itself_ should be setting up protective
>> page mappings. :(
>>
>
> Well, the 4 KB alignment of sections was considered prohibitive at the
> time from code size pov. But this was a long time ago, obviously.

Heh, yeah, I'd expect max 4K padding to get code/data correctly
aligned on a 2MB binary to not be an issue. :)

>
>> For a boot firmware, it seems to me that safe page table layout would
>> be a top priority bug. The "reporting issues" page for TianoCore
>> doesn't actually seem to link to the "Project Tracker":
>> https://github.com/tianocore/tianocore.github.io/wiki/Reporting-Issues
>>
>> Does anyone know how to get this correctly reported so future UEFI
>> releases don't suffer from this?
>>
>
> Ugh. Don't get me started on that topic. I have been working with the
> UEFI forum since July to get a fundamentally broken implementation of
> memory protections fixed. UEFI v2.5 defines a memory protection scheme
> that is based on splitting PE/COFF images into separate memory regions
> so that R-X and RW- permissions can be applied. Unfortunately, that
> broke every OS in existence (including Windows 8), since the OS is
> allowed to reorder memory regions when it lays out the virtual
> remapping of the UEFI regions, resulting in PE/COFF .data and .text
> potentially appearing out of order.
>
> The good news is that we fixed it for the upcoming release (v2.6). I
> can't disclose any specifics, though :-(

As long as there's motion to getting it fixed, that makes me happy! :)
Does 2.6 get rid of the (AIUI) 2MB limit too?

-Kees

>
> --
> Ard.
>
>
>>>>> >     If that 'supposed to be' turns out to be 'not true' (not unheard of 
>>>>> > in
>>>>> >     firmware land), then plan B would be to mark pages that generate 
>>>>> > write faults
>>>>> >     RWX as well, to not break functionality. (This 'mark it RWX' is not 
>>>>> > something
>>>>> >     that exploits would have easy access to, and we could also generate 
>>>>> > a warning
>>>>> >     [after the EFI call has finished] if it ever triggers.)
>>>>> >
>>>>> >     Admittedly this approach might not be without its own 
>>>>> > complications, but it
>>>>> >     looks reasonably simple (I don't think we need per EFI call page 
>>>>> > tables,
>>>>> >     etc.), and does not assume much about the firmware being able to 
>>>>> > enumerate its
>>>>> >     permissions properly. Were we to merge EFI support today I'd have 
>>>>> > insisted on
>>>>> >     trying such an approach from day 1 on.
>>>>>
>>>>> We already have separate EFI page tables, though with the caveat that
>>>>> we share some of swapper_pg_dir's PGD entries. The best solution would
>>>>> be to stop sharing entries and isolate the EFI mappings from every
>>>>> other page table structure, so that they're only used during the EFI
>>>>> service calls.
>>>>
>>>> Absolutely. Can you try to fix this for v4.3?
>>>>
>>>> Thanks,
>>>>
>>>>         Ingo
>>
>>
>>
>> --
>> Kees Cook
>> Chrome OS Security



-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to