[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] OVMF/Xen, Debian wheezy can't boot with NX on stack (Was: Re: [edk2] [PATCH] OvmfPkg: prevent code execution from DXE stack)



On 09/09/15 12:48, Laszlo Ersek wrote:
> On 09/09/15 11:37, Ian Campbell wrote:
>> On Wed, 2015-09-09 at 01:06 -0600, Jan Beulich wrote:
>>>>>> On 09.09.15 at 00:23, <lersek@xxxxxxxxxx> wrote:
>>>> On 09/08/15 19:26, Anthony PERARD wrote:
>>>>> And I get this on the console:
>>>>> Welcome to GRUB!
>>>>>
>>>>> !!!! X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID -
>>>>> 00000000 !!!!
>>>>> RIP  - 000000000F5F8918, CS  - 0000000000000028, RFLAGS -
>>>>> 0000000000210206
>>>>> ExceptionData - 0000000000000011
>>>>> RAX  - 0000000000000000, RCX - 0000000007FCE000, RDX -
>>>>> 0000000000000000
>>>>> RBX  - 000000000B6092C0, RSP - 000000000F5F8590, RBP -
>>>>> 000000000B608EA0
>>>>> RSI  - 000000000F5F8838, RDI - 000000000B608EA0
>>>>> R8   - 0000000000000000, R9  - 000000000B609200, R10 -
>>>>> 0000000000000000
>>>>> R11  - 000000000000000A, R12 - 0000000000000000, R13 -
>>>>> 000000000000001B
>>>>> R14  - 000000000B609360, R15 - 0000000000000000
>>>>> DS   - 0000000000000008, ES  - 0000000000000008, FS  -
>>>>> 0000000000000008
>>>>> GS   - 0000000000000008, SS  - 0000000000000008
>>>>> CR0  - 0000000080000033, CR2 - 000000000F5F8918, CR3 -
>>>>> 000000000F597000
>>>>> CR4  - 0000000000000668, CR8 - 0000000000000000
>>>>> DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 -
>>>>> 0000000000000000
>>>>> DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 -
>>>>> 0000000000000400
>>>>> GDTR - 000000000F57BF18 000000000000003F, LDTR - 0000000000000000
>>>>> IDTR - 000000000EEA5018 0000000000000FFF,   TR - 0000000000000000
>>>>> FXSAVE_STATE - 000000000F5F81F0
>>>>> !!!! Find PE image 
>>>> /build/xen-unstable/src/xen-unstable/tools/firmware/ovmf-dir
>>>> -remote/Build
>>>> /OvmfX64/DEBUG_GCC49/X64/IntelFrameworkModulePkg/Universal/StatusCode/R
>>>> untime
>>>> Dxe/StatusCodeRuntimeDxe/DEBUG/StatusCodeRuntimeDxe.dll 
>>>> (ImageBase=000000000F556000, EntryPoint=000000000F55628F) !!!!
>>>>>
>>>>> I did check with other guest (Windows, Ubuntu, Debian Jessie), and
>>>>> they are
>>>>> working correctly. Debian Wheezy is the only one that fail.
>>>>
>>>> I don't have an environment to reproduce this in. I think we should try
>>>> to understand this problem better, before deciding how to make it go
>>>> away.
>>>>
>>>> Please locate the "StatusCodeRuntimeDxe.debug" file in your Build
>>>> directory (ie. under the location listed in the error report). Then,
>>>> please disassemble it with "objdump -S". The fault location in the
>>>> disassembly can be found based on RIP, ImageBase and EntryPoint;
>>>
>>> I don't think the exact instruction at that address really matters. The
>>> main question appears to be why RIP and RSP both point into the
>>> same page (see also the subject of Anthony's mail).
>>
>> I'm not 100% what is going on,
> 
> me neither :)
> 
>> but if this (executable code on stack) is
>> happening in grub is there something which is explicitly forbidden to UEFI
>> apps by the UEFI spec?
> 
> Yes, there is. This small OvmfPkg patch only enables the edk2 feature
> added by Star Zeng in
> <https://github.com/tianocore/edk2/commit/5630cdfe> for OVMF. That patch
> (also referenced in my commit message by SVN rev) says,
> 
>     This feature is added for UEFI spec that says
>     "Stack may be marked as non-executable in identity mapped page
>     tables".
>     A PCD PcdSetNxForStack is added to turn on/off this feature, and it
>     is FALSE by default.
> 
> A UEFI app runs (well, *starts*, anyway) before ExitBootServices() /
> SetVirtualAddressMap(), so it's bound by the above.
> 
> The spec passage above is quoted from "2.3.2 IA-32 Platforms", and
> "2.3.4 x64 Platforms", in chapter "2.3 Calling Conventions", where the
> boot services time environment is specified.
> 
> This is new in UEFI-2.5, and it comes from Mantis ticket 1224: "Adding
> support for No executable data areas".
> 
> ... The question could be then if grub (in Wheezy) should be adapted to
> UEFI-2.5 (if that's possible) or if OVMF should be built without this
> feature.
> 
> Hmmm. Actually, I'm torn about the default for PcdSetNxForStack.
> 
> Namely, Mantis ticket 1224 has come up before. There's another edk2
> sub-feature related to this UEFI spec feature / Mantis ticket; the
> properties table (controlled by "PcdPropertiesTableEnable"), and the
> effects it has on the UEFI memory map, and the requirements it presents
> for UEFI OSes.
> 
> *That* sub-feature is extremely intrusive.
> "MdeModulePkg/MdeModulePkg.dec" sets "PcdPropertiesTableEnable" TRUE by
> default, and OvmfPkg inherits it. I have not overridden that default
> just yet in OvmfPkg because the properties table feature depends on
> something *else* too: sections in runtime DXE driver binaries must be
> aligned at 4KB, and that is not ensured for OvmfPkg (yet?). Therefore,
> the properties table feature is not active in OVMF at the moment due to
> a "random build tools circumstance" -- and not because the feature flag
> is actually disabled.
> 
> Now, the properties table feature absolutely cannot be (effectively)
> enabled in OVMF as a default. It would break Windows 7 / Windows Server
> 2008 R2. A huge number of users run such guests for GPU passthrough.
> 
> The idea that just crossed my mind was to introduce a new build flag for
> OVMF, like -D NOEXEC_DATA_ENABLE. And this would then control
> PcdSetNxForStack *and* PcdPropertiesTableEnable *together*:
> 
> if NOEXEC_DATA_ENABLE:
>   PcdSetNxForStack := TRUE
>   PcdPropertiesTableEnable := TRUE
> else
>   PcdSetNxForStack := FALSE
>   PcdPropertiesTableEnable := FALSE
> 
> However, I think that's a bad idea.
> 
> "PcdPropertiesTableEnable" breaks a very widely used guest OS for which
> there is no update in sight (ie. no Service Pack 2 for Windows 7 /
> Windows Server 2008 R2), but is otherwise supposed to be supported for
> years to come.
> 
> Whereas Debian Wheezy is not as widely used as a guest (for one: it
> "competes" with all the other Linux distros from the same timeframe).
> Debian Wheezy also provides a quite non-intrusive upgrade path (to
> Jessie), which is not the case for Windows 7. So the breakage casued by
> setting PcdSetNxForStack has much smaller impact, I think, and the
> benefits might outweigh the breakage.
> 
> Which just means that a heavy-handed -D NOEXEC_DATA_ENABLE, like above,
> would not be appropriate. PcdSetNxForStack set, and
> PcdPropertiesTableEnable clear, is a valid configuration.
> 
> In any case, I sort of convinced myself that Wheezy's grub is not at
> fault; it was simply written against an earlier release of the UEFI spec.
> 
> How about this:
> 
> - (somewhat unrelatedly, but for completeness):
>   I post a patch that exposes PcdPropertiesTableEnable with a build
>   time flag (NX_PROP_TABLE_ENABLE) with an OVMF-default of FALSE,
> 
> - I post another patch that exposes PcdSetNxForStack with a build time
>   flag (NX_STACK_ENABLE) with an OVMF-default of *TRUE*. You could then
>   pass -D NX_STACK_ENABLE=FALSE when you build OVMF for any environment
>   where Wheezy guests are expected.
> 
> Jordan?
> 
> Yet another (quite complex) possibility:
> 
> - According to "MdeModulePkg/MdeModulePkg.dec",
>   a platform DSC can already type PcdPropertiesTableEnable as a dynamic
>   PCD. We could allow the same for PcdSetNxForStack. Star?
> 
>   Both PCDs are consumed "acceptably late" (the first in the DXE core,
>   the second in the DXE IPL PEIM). This would allow
>   OvmfPkg/PlatformPei to set the PCDs dynamically.
> 
> - Then the question is how we pass in the PCD values from the outside.
>   For QEMU/KVM virtual machines, we could use Gabriel's QEMU feature
> 
>   -fw_cfg name=opt/my_item_name,file=./my_blob.bin
> 
>   ie. no changes for QEMU would be necessary. Xen virtual machines
>   don't have fw_cfg however, therefore "some other" info passing should
>   be implemented in "OvmfPkg/PlatformPei/Xen.c", and (I assume!) in the
>   host-side Xen tools as well.
> 
> Personally I think that this dynamic approach is overkill (mainly
> because I'm fine with being unable to install Debian Wheezy guests, both
> wearing and not wearing my red fedora; and because the properties table
> feature is not active for *any* OVMF guests anyway, in practice).
> 
> So I'd like to ask you guys to decide which one you prefer: a simple
> build time flag called NX_STACK_ENABLE (which will allow you to install
> Wheezy guests, but deprive all other guests from a non-exec stack), or
> the dynamic switches (which will take host-side work in Xen, plus a
> matching OvmfPkg patch).

I might go ahead and implement the -fw_cfg solution (for when OVMF runs
on QEMU), leaving any parallel Xen functionality to Xen developers, for
later.

Because, I just found out that the GRUB binary built into the bits-2005
release ISO <http://biosbits.org/download/> blows up the exact same way,
and *that* is very annoying to me personally.

Maybe we should invert the default. I'm not so convinced any longer that
the current default is right. I didn't know that the GRUB version with
code on the stack was this wide-spread.

Thanks
Laszlo

> 
>>
>> Or is it happening within UEFI itself based on a call from grub.efi?
> 
> (
> I wrote this before the above paragraphs, but it's moot now:
> 
> It's unclear. As far as I can see from the error report, things blow up
> after grub starts, but before it calls ExitBootServices(). The fault RIP
> points into a runtime DXE driver. Which is both a consistent and an
> inconsistent symptom.
> 
> It is "consistent" because a runtime DXE driver is certainly in memory;
> it even survives ExitBootServices(), so its blowing up cannot be
> immediately excluded on the grounds that "it's not there". It *is* there.
> 
> However, the symptom is also inconsistent / inexplicable because this
> runtime DXE driver doesn't really have anything to do with grub. And
> it's unclear why some of its machine could would exist in stack / NX
> pages. Some memory may possibly be corrupt by the time the edk2 fault
> handler associates the RIP with the driver load addresses. Not sure.
> )
> 
> Thanks
> Laszlo
> 
>>
>>
>>>  I.e. we need to
>>> spot the entity setting the stack to a page that also contains code,
>>> or placing code on the stack. That's unlikely to be found by identifying
>>> the instruction RIP points to, but rather (sadly not part of the state
>>> dump) something higher up the call chain.
>>>
>>> Jan
>>>
>>>
>>> _______________________________________________
>>> Xen-devel mailing list
>>> Xen-devel@xxxxxxxxxxxxx
>>> http://lists.xen.org/xen-devel
> 


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.