public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Andrew Fish <afish@apple.com>
To: "Zeng, Star" <star.zeng@intel.com>
Cc: Mike Kinney <michael.d.kinney@intel.com>,
	edk2-devel <edk2-devel@lists.01.org>
Subject: Re: [MdeModulePkg] SetVirtualAddressMap() crashed due to DxeReportStatusCodeLib assuming the state of the BootService Memory at runtime.
Date: Wed, 10 Aug 2016 18:59:33 -0700	[thread overview]
Message-ID: <4F6AB174-5C49-4E59-98F9-6E4B57DA31BF@apple.com> (raw)
In-Reply-To: <0C09AFA07DD0434D9E2A0C6AEB048310036A2959@shsmsx102.ccr.corp.intel.com>


> On Aug 10, 2016, at 6:53 PM, Zeng, Star <star.zeng@intel.com> wrote:
> 
> If a DXE_RUNTIME_DRIVER driver just wants to report status code at boot phase and links to DxeReportStatusCodeLib, is it a bug?
> 
> How about just to add notes for DxeReportStatusCodeLib like DxePcdLib.inf?
> 

Star,

This is point about lack of rules around this. I think the difference is the PCD protocol is defined as boot service only. I guess you could argue that depending on how things are constructed you could access some (FixedAtBuild) PCD things at runtime. 

I don't think it is a good idea to produce a runtime service that does not work at runtime. Mike seems to agree. 

But I agree better rules about this would be helpful. 

Thanks,

Andrew Fish

> DxePcdLib.inf:
> "
> # Note: A driver of type DXE_RUNTIME_DRIVER and DXE_SMM_DRIVER can only use this DxePcdLib 
> #  in their initialization without any issues to access Dynamic and DynamicEx PCD. They can't 
> #  access Dynamic and DynamicEx PCD in the implementation of runtime services and SMI handlers.
> #  Because EFI_PCD_PROTOCOL is DXE protocol that is not aviable in OS runtime phase.  
> "
> 
> Thanks,
> Star
> -----Original Message-----
> From: afish@apple.com [mailto:afish@apple.com] 
> Sent: Thursday, August 11, 2016 3:04 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Zeng, Star <star.zeng@intel.com>; edk2-devel <edk2-devel@lists.01.org>
> Subject: Re: [edk2] [MdeModulePkg] SetVirtualAddressMap() crashed due to DxeReportStatusCodeLib assuming the state of the BootService Memory at runtime.
> 
> 
>> On Aug 10, 2016, at 11:02 AM, Kinney, Michael D <michael.d.kinney@intel.com> wrote:
>> 
>> 
>> 
>>> -----Original Message-----
>>> From: afish@apple.com [mailto:afish@apple.com]
>>> Sent: Wednesday, August 10, 2016 10:35 AM
>>> To: Kinney, Michael D <michael.d.kinney@intel.com>
>>> Cc: Zeng, Star <star.zeng@intel.com>; edk2-devel 
>>> <edk2-devel@lists.01.org>
>>> Subject: Re: [edk2] [MdeModulePkg] SetVirtualAddressMap() crashed due 
>>> to DxeReportStatusCodeLib assuming the state of the BootService Memory at runtime.
>>> 
>>> 
>>>> On Aug 10, 2016, at 10:22 AM, Kinney, Michael D <michael.d.kinney@intel.com> wrote:
>>>> 
>>>> Hi Andrew,
>>>> 
>>>> I am staring at the code.  Something is not right here, but I am 
>>>> concerned that there are use cases I am not considering yet.  Here 
>>>> is my analysis so far.
>>>> 
>>>> Here are the lib instances I see:
>>>> (ignoring IntelFramework ones for the purposes of this discussion).
>>>> 
>>>> MdeModulePkg\Library\DxeReportStatusCodeLib\DxeReportStatusCodeLib.inf(25):
>>>> LIBRARY_CLASS = ReportStatusCodeLib|DXE_CORE DXE_DRIVER 
>>>> DXE_RUNTIME_DRIVER
>>> DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
>>>> 
>>>> MdeModulePkg\Library\PeiReportStatusCodeLib\PeiReportStatusCodeLib.inf(27):
>>>> LIBRARY_CLASS = ReportStatusCodeLib|SEC PEIM PEI_CORE
>>>> 
>>>> 
>>> MdeModulePkg\Library\RuntimeDxeReportStatusCodeLib\RuntimeDxeReportSt
>>> atusCodeLib.inf(
>>> 23):
>>>> LIBRARY_CLASS = ReportStatusCodeLib|DXE_RUNTIME_DRIVER 
>>>> DXE_SAL_DRIVER
>>>> 
>>>> MdeModulePkg\Library\SmmReportStatusCodeLib\SmmReportStatusCodeLib.inf(26):
>>>> LIBRARY_CLASS = ReportStatusCodeLib|DXE_SMM_DRIVER SMM_CORE
>>>> 
>>>> MdePkg\Library\BaseReportStatusCodeLibNull\BaseReportStatusCodeLibNull.inf(23):
>>>> LIBRARY_CLASS = ReportStatusCodeLib
>>>> 
>>>> * The BASE one that is a Null instance makes sense when disabling 
>>>> Report Status
>>> Code.
>>>> * The PEI one makes sense for its module compatibility.
>>>> * The SMM one also makes sense its module compatibility.
>>>> * And the RuntimeDxe one also makes sense its module compatibility.
>>>> * The DXE one seems to be over specified and if we reduced its 
>>>> module compatibility, the SMM and RuntimeDxe lib instances can be 
>>>> used to cover those module types.
>>>> 
>>>> When I look at the source code in DxeReportStatusCodeLib, I see 
>>>> comments that describe the use case where a module is dispatched 
>>>> before the Report Status Code Protocol is available.
>>>> 
>>>> The use case you are describing is when the first call to Report 
>>>> Status Code by a module occurs after ExitBootServices().  In that 
>>>> case, we depend on the Boot Services table being zeroed to exit early.
>>>> 
>>>> I agree that no component should depend on Boot Services table being 
>>>> cleared to zeros at ExitBootServices().  It is legal from UEFI/PI 
>>>> spec to not zero at all, or in your example, fill with a pattern 
>>>> other than zeros.
>>>> 
>>>> It appears that the use case of first call to Report Status Code 
>>>> after
>>>> ExitBootServices() is not covered by the DXE lib instance, and we 
>>>> have just been getting lucky due to zeroing behavior of boot services table.
>>>> 
>>>> I can think of a couple options:
>>>> 
>>>> * Update DXE INF to remove the DXE Runtime, DXE SAL, SMM, SMM Core 
>>>> module types.  This may break platform builds if a platform is using 
>>>> this lib mapping for modules of the types being removed.  However, 
>>>> those could be considered platform DSC bugs.
>>>> 
>>>> * Update DXE lib instance to add ExitBootServices() and 
>>>> SetVirtualAddressMap() events.  However, this would basically make 
>>>> the DXE lib instance the same as the DXE Runtime instance and would 
>>>> increase size of non-RT components.
>>>> 
>>>> I would prefer the first option, but we would need to do some 
>>>> testing to see how many platform DSC files break.
>>>> 
>>> 
>>> Mike,
>>> 
>>> That seems to make the most sense, but I too was worried about compatibility.
>>> 
>>> I tried adding the UefiRuntimeLib to just fail calls at Runtime, but 
>>> that breaks the build as DXE_CORE does not support UefiRuntimeLib.
>>> 
>>> I guess one option would be to only add the ExitBootServices event 
>>> and fail calls at runtime?
>> 
>> I agree this would remove the assumption that the boot services table is zeroed.
>> However, the only way this function can be called after 
>> ExitBootServices() is if the module is DXE_RUNTIME_DRIVER, 
>> DXE_SAL_DRIVER, or DXE_SMM_DRIVER.  If a module is one of these types 
>> and they call Report Status Code, then they would want the status code 
>> to go out.  The current behavior of this lib instance silently ignores 
>> all status codes after ExitBootServices().  This silent filtering is 
>> not good, and may be a good reason to move ahead with the first option and fix the platform DSC files.
>> 
> 
> Mike,
> 
> I have to admit the assumption that it works at runtime is how I hit this issue in the first place so I'm fine with restricting the usage. 
> 
> I guess the rule is:
> 1) For BootServices only libraries it is OK to map as Runtime Services as there is an assumption that the calls will only be made at boot services time.
> 2) For RuntimeServices libraries they should always work. 
> 
> I think the issue was a RT library that was coded with 1) assumptions. I have to admit I don't know that we do a good job of documenting this kind of thing. 
> 
> It also brings up the point of maybe it would be better to list fewer things as SMM from a security audit point of view. Maybe it would be worthing it to add runtime checks that fail for things marked SMM that are in bucket 1)? 
> 
> Thanks,
> 
> Andrew Fish
> 
>>> 
>>> Thanks,
>>> 
>>> Andrew Fish
>>> 
>>>> Mike
>>>> 
>>>>> -----Original Message-----
>>>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf 
>>>>> Of Andrew Fish
>>>>> Sent: Tuesday, August 9, 2016 7:50 AM
>>>>> To: Zeng, Star <star.zeng@intel.com>
>>>>> Cc: edk2-devel <edk2-devel@lists.01.org>
>>>>> Subject: Re: [edk2] [MdeModulePkg] SetVirtualAddressMap() crashed 
>>>>> due to DxeReportStatusCodeLib assuming the state of the BootService Memory at runtime.
>>>>> 
>>>>> 
>>>>>> On Aug 8, 2016, at 7:26 PM, Zeng, Star <star.zeng@intel.com> wrote:
>>>>>> 
>>>>>> On 2016/8/9 10:07, Andrew Fish wrote:
>>>>>>> 
>>>>>>>> On Aug 8, 2016, at 6:21 PM, Zeng, Star <star.zeng@intel.com> wrote:
>>>>>>>> 
>>>>>>>> Andrew,
>>>>>>>> 
>>>>>>>> Should MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib be 
>>>>>>>> used for your case
>>>>> if there are really runtime status code reporting needed?
>>>>>>>> 
>>>>>>> 
>>>>>>> Star,
>>>>>>> 
>>>>>>> If the Library instance does not fully support 
>>>>>>> DXE_RUNTIME_DRIVER, why is it
>>>>> listed in the LIBRARY_CLASS as supported?
>>>>>> 
>>>>>> This kind of library can support DXE_RUNTIME_DRIVER at boot time, 
>>>>>> for example
>>>>> UefiHiiLib, UefiHiiServicesLib, UefiBootServicesTableLib, DxePcdLib and etc.
>>>>>> 
>>>>> 
>>>>> Star,
>>>>> 
>>>>> I understand giving access to Boot Services resources to a Runtime 
>>>>> Driver for its constructor. I think the difference here is the 
>>>>> DxeReportStatusCodeLib is
>>> abstracting
>>>>> a runtime service, but not doing it in a way to really works 
>>>>> properly at runtime
>>> in
>>>>> all cases. I would expect that a library abstraction a runtime 
>>>>> feature would work
>>> at
>>>>> runtime. Which is why I ended up with a "bad" mapping in the first place.
>>>>> 
>>>>> Thanks,
>>>>> 
>>>>> Andrew Fish
>>>>> 
>>>>>>> 
>>>>>>> 
>>>>> 
>>> https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/Dx
>>> eReportStatusCod
>>>>> eLib/DxeReportStatusCodeLib.inf#L25
>>>>>>> 
>>>>>>> LIBRARY_CLASS                  = ReportStatusCodeLib|DXE_CORE DXE_DRIVER
>>>>> DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION 
>>>>> UEFI_DRIVER SMM_CORE
>>>>>>> 
>>>>>>> Actually I tried to add the UefiRuntimeDriverLib and the build 
>>>>>>> failed as
>>>>> UefiRuntimeDriverLib was not supported for the DXE_CORE type. Maybe 
>>>>> the bug is
>>> this
>>>>> library instance lists DXE_RUNTIME_DRIVER,  DXE_SAL_DRIVER and 
>>>>> DXE_SMM_DRIVER when
>>> it
>>>>> has special case code to support DXE_CORE? Maybe this library is 
>>>>> trying to do too many things?
>>>>>>> 
>>>>>>> What ReportStatusCodeLib would you recommend to link with RuntimeDxe driver:
>>>>> 
>>> https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Runti
>>> meDxe/RuntimeDxe
>>>>> .inf
>>>>>> 
>>>>>> [LibraryClasses.common.DXE_CORE]
>>>>>> 
>>>>> 
>>> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRe
>>> ReportStatusCodeLib|portStatusCodeLi
>>>>> b.inf
>>>>>> 
>>>>>> [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>>>>>> 
>>>>> 
>>> ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLi
>>> ReportStatusCodeLib|b/RuntimeDxeRepo
>>>>> rtStatusCodeLib.inf
>>>>>> 
>>>>>> [LibraryClasses.common.UEFI_DRIVER]
>>>>>> 
>>>>> 
>>> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRe
>>> ReportStatusCodeLib|portStatusCodeLi
>>>>> b.inf
>>>>>> 
>>>>>> [LibraryClasses.common.DXE_DRIVER]
>>>>>> 
>>>>> 
>>> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRe
>>> ReportStatusCodeLib|portStatusCodeLi
>>>>> b.inf
>>>>>> 
>>>>>> [LibraryClasses.common.UEFI_APPLICATION]
>>>>>> 
>>>>> 
>>> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRe
>>> ReportStatusCodeLib|portStatusCodeLi
>>>>> b.inf
>>>>>> 
>>>>>> Thanks,
>>>>>> Star
>>>>>> 
>>>>>>> 
>>>>>>> Thanks,
>>>>>>> 
>>>>>>> Andrew Fish
>>>>>>> 
>>>>>>>> Thanks,
>>>>>>>> Star
>>>>>>>> -----Original Message-----
>>>>>>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On 
>>>>>>>> Behalf Of Andrew
>>>>> Fish
>>>>>>>> Sent: Tuesday, August 9, 2016 7:08 AM
>>>>>>>> To: edk2-devel <edk2-devel@lists.01.org>
>>>>>>>> Subject: [edk2] [MdeModulePkg] SetVirtualAddressMap() crashed 
>>>>>>>> due to
>>>>> DxeReportStatusCodeLib assuming the state of the BootService Memory at runtime.
>>>>>>>> 
>>>>>>>> I was messing about with an ExitBootServices test that fills 
>>>>>>>> boot services
>>> memory
>>>>> with 0xAFAFAFAFAFAFAFAF (It was Vincent's idea to use my Initials 
>>>>> but it has the handy property of being a non-cononical address and 
>>>>> causes on GP fault on X64) and
>>>>> SetVirtualAddressMap() started crashing.
>>>>>>>> 
>>>>>>>> It looks like this code is assuming the 1st call to ReportStatus 
>>>>>>>> code will not
>>>>> happen at runtime. This is not the case for the RuntimeDxe driver.
>>>>>>>> 
>>>>> 
>>> https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/Dx
>>> eReportStatusCod
>>>>> eLib/ReportStatusCodeLib.c#L43
>>>>>>>> VOID
>>>>>>>> InternalGetReportStatusCode (
>>>>>>>> VOID
>>>>>>>> )
>>>>>>>> {
>>>>>>>> EFI_STATUS  Status;
>>>>>>>> 
>>>>>>>> if (mReportStatusCodeLibStatusCodeProtocol != NULL) { return; }
>>>>>>>> 
>>>>>>>> //
>>>>>>>> // Check gBS just in case ReportStatusCode is called before gBS is initialized.
>>>>>>>> //
>>>>>>>> if (gBS != NULL && gBS->LocateProtocol != NULL) { Status = 
>>>>>>>> gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL,
>>> (VOID**)
>>>>> &mReportStatusCodeLibStatusCodeProtocol);
>>>>>>>> if (EFI_ERROR (Status)) {
>>>>>>>> mReportStatusCodeLibStatusCodeProtocol = NULL; } } }
>>>>>>>> 
>>>>>>>> I'm guessing this seems to work due
>>>>> 
>>> to:https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Dx
>>> e/DxeMain/DxeMai
>>>>> n.c#L803
>>>>>>>> 
>>>>>>>> //
>>>>>>>> // Zero out the Boot Service Table // ZeroMem (gBS, sizeof 
>>>>>>>> (EFI_BOOT_SERVICES));
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Thus if I'm looking at this code correctly it only looks like it 
>>>>>>>> works at
>>> Runtime
>>>>> since it is depending on the value of a boot services memory buffer not changing.
>>>>> This is not a valid assumption as that code is owned by the caller 
>>>>> of ExitBootServices, so it should be legal for my test to change the value.
>>>>>>>> 
>>>>>>>> I wanted to get a few more eyes on this prior to filling a bug?
>>>>>>>> 
>>>>>>>> Thanks,
>>>>>>>> 
>>>>>>>> Andrew Fish
>>>>>>>> 
>>>>>>>> 
>>>>>>>> _______________________________________________
>>>>>>>> edk2-devel mailing list
>>>>>>>> edk2-devel@lists.01.org
>>>>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>>>>> _______________________________________________
>>>>>>>> edk2-devel mailing list
>>>>>>>> edk2-devel@lists.01.org
>>>>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>>> 
>>>>>> _______________________________________________
>>>>>> edk2-devel mailing list
>>>>>> edk2-devel@lists.01.org
>>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>> 
>>>>> _______________________________________________
>>>>> edk2-devel mailing list
>>>>> edk2-devel@lists.01.org
>>>>> https://lists.01.org/mailman/listinfo/edk2-devel



  reply	other threads:[~2016-08-11  1:59 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-08 23:07 [MdeModulePkg] SetVirtualAddressMap() crashed due to DxeReportStatusCodeLib assuming the state of the BootService Memory at runtime Andrew Fish
2016-08-09  1:21 ` Zeng, Star
2016-08-09  2:07   ` Andrew Fish
2016-08-09  2:26     ` Zeng, Star
2016-08-09 14:50       ` Andrew Fish
2016-08-10 17:22         ` Kinney, Michael D
2016-08-10 17:35           ` Andrew Fish
2016-08-10 18:02             ` Kinney, Michael D
2016-08-10 19:04               ` Andrew Fish
2016-08-11  1:53                 ` Zeng, Star
2016-08-11  1:59                   ` Andrew Fish [this message]
2016-08-11  3:06                     ` Zeng, Star

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F6AB174-5C49-4E59-98F9-6E4B57DA31BF@apple.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox