public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "wenyi,xie" <xiewenyi2@huawei.com>
To: "Yao, Jiewen" <jiewen.yao@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>,
	Laszlo Ersek <lersek@redhat.com>,
	"Wang, Jian J" <jian.j.wang@intel.com>
Cc: "songdongkuang@huawei.com" <songdongkuang@huawei.com>,
	"Mathews, John" <john.mathews@intel.com>
Subject: Re: [edk2-devel] [PATCH EDK2 v2 1/1] SecurityPkg/DxeImageVerificationLib:Enhanced verification of Offset
Date: Tue, 1 Sep 2020 15:43:26 +0800	[thread overview]
Message-ID: <7d75c44a-5f52-b51a-57d0-54940731cd34@huawei.com> (raw)
In-Reply-To: <CY4PR11MB128827381EF5BD2F37C170EC8C2E0@CY4PR11MB1288.namprd11.prod.outlook.com>

To Jiewen,

Sorry to make you lost,I mean the patches Laszlo proposed in email,
https://edk2.groups.io/g/devel/message/64243
http://mid.mail-archive.com/eb0c6bcb-77fb-2fb9-783e-aa5025953a80@redhat.com

To Laszlo,

Sure, I will test your patches against my reproducer and add "tested-by:" tag to the patches after you post them.

Regards
Wenyi

On 2020/9/1 15:31, Yao, Jiewen wrote:
> I am sorry, that I am a little lost here.
> 
> We have discussed different patches. I am not 100% sure which one is "Laszlo's patches".
> 
> To make thing easy and record all actions, would you please reply the patch(es) you have verified, with your "tested-by:" tag?
> 
> Thank you
> Yao Jiewen
> 
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of wenyi,xie
>> via groups.io
>> Sent: Tuesday, September 1, 2020 3:11 PM
>> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io; Laszlo Ersek
>> <lersek@redhat.com>; Wang, Jian J <jian.j.wang@intel.com>
>> Cc: songdongkuang@huawei.com; Mathews, John <john.mathews@intel.com>
>> Subject: Re: [edk2-devel] [PATCH EDK2 v2 1/1]
>> SecurityPkg/DxeImageVerificationLib:Enhanced verification of Offset
>>
>> I think Laszlo's patches is OK, I have applied and tested it using my case. It can
>> catch the issue.
>> DEBUG code and log below,
>>
>>   SecDataDirEnd = SecDataDir->VirtualAddress + SecDataDir->Size;
>>   DEBUG((DEBUG_INFO, "SecDataDirEnd=0x%x.\n", SecDataDirEnd));
>>   for (OffSet = SecDataDir->VirtualAddress;
>>        OffSet < SecDataDirEnd;
>>        OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate-
>>> dwLength))) {
>>     SecDataDirLeft = SecDataDirEnd - OffSet;
>>     DEBUG((DEBUG_INFO, "OffSet=0x%x, SecDataDirLeft=0x%x.\n", OffSet,
>> SecDataDirLeft));
>>     if (SecDataDirLeft <= sizeof(WIN_CERTIFICATE)) {
>>       break;
>>     }
>>     WinCertificate = (WIN_CERTIFICATE *)(mImageBase + OffSet);
>>     DEBUG((DEBUG_INFO, "WinCertificate->dwLength=0x%x, ALIGN_SIZE
>> (WinCertificate->dwLength)=0x%x.\n", WinCertificate->dwLength,
>> ALIGN_SIZE(WinCertificate->dwLength)));
>>     if (SecDataDirLeft < WinCertificate->dwLength ||
>> 	(SecDataDirLeft - WinCertificate->dwLength <
>> ALIGN_SIZE(WinCertificate->dwLength))) {
>>       DEBUG((DEBUG_INFO, "Parameter is invalid and break.\n"));
>>       break;
>>     }
>>
>> SecDataDirEnd=0xFFFFFFFC.
>> OffSet=0xE000, SecDataDirLeft=0xFFFF1FFC.
>> WinCertificate->dwLength=0xFFFF1FFB, ALIGN_SIZE (WinCertificate-
>>> dwLength)=0x5.
>> Parameter is invalid and break.
>> The image doesn't pass verification: VenHw(5CF32E0B-8EDF-2E44-9CDA-
>> 93205E99EC1C,00000000)/VenHw(964E5B22-6459-11D2-8E39-
>> 00A0C969723B,00000000)/\signed_1234_4G.efi
>>
>> Regards
>> Wenyi
>>
>> On 2020/9/1 0:06, Yao, Jiewen wrote:
>>> Sounds great. Appreciate your hard work on that.
>>>
>>> Will you post a patch to fix the issue again?
>>>
>>> Thank you
>>> Yao Jiewen
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> wenyi,xie
>>>> via groups.io
>>>> Sent: Monday, August 31, 2020 7:24 PM
>>>> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io; Laszlo
>> Ersek
>>>> <lersek@redhat.com>; Wang, Jian J <jian.j.wang@intel.com>
>>>> Cc: songdongkuang@huawei.com; Mathews, John
>> <john.mathews@intel.com>
>>>> Subject: Re: [edk2-devel] [PATCH EDK2 v2 1/1]
>>>> SecurityPkg/DxeImageVerificationLib:Enhanced verification of Offset
>>>>
>>>> Hi,Jiewen,
>>>>
>>>> I modify the PE file again, this time it can pass the check in PeCoffLib and
>> cause
>>>> offset overflow.
>>>>
>>>> First, create a PE file and sign it(only one signature), then using binary edit
>> tool
>>>> to modify content of PE file like below,
>>>>  1.check the value of SecDataDir->VirtualAddress, in my PE file, it's 0xE000
>>>>  2.changing SecDataDir->Size from 0x5F8 to 0xFFFF1FFC
>>>>  3.changing WinCertificate->dwLength from 0x5F1 to 0xFFFF1FFB
>>>>  4.padding PE file with 0 until the size of the file is 0xFFFFFFFC(it will make the
>> PE
>>>> file so large)
>>>> OffSet + WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength)
>> is
>>>> 0xE000 + 0xFFFF1FFB + 0x5 = 0x100000000
>>>>
>>>> Below is the DEBUG code and log, in second loop the offset overflow and
>>>> become 0
>>>>
>>>> for (OffSet = SecDataDir->VirtualAddress;
>>>>      OffSet < (SecDataDir->VirtualAddress + SecDataDir->Size);
>>>>      OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate-
>>>>> dwLength))) {
>>>>   WinCertificate = (WIN_CERTIFICATE *) (mImageBase + OffSet);
>>>>   DEBUG((DEBUG_INFO, "OffSet=0x%x.\n", OffSet));
>>>>   if ((SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) <= sizeof
>>>> (WIN_CERTIFICATE) ||
>>>>       (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) < WinCertificate-
>>>>> dwLength) {
>>>>     break;
>>>>   }
>>>>   DEBUG((DEBUG_INFO, "WinCertificate->dwLength=0x%x, ALIGN_SIZE
>>>> (WinCertificate->dwLength)=0x%x.\n", WinCertificate->dwLength,
>>>> ALIGN_SIZE(WinCertificate->dwLength)));
>>>>
>>>>
>>>> SecDataDir->VirtualAddress=0xE000, SecDataDir->Size=0xFFFF1FFC.
>>>> OffSet=0xE000.
>>>> WinCertificate->dwLength=0xFFFF1FFB, ALIGN_SIZE (WinCertificate-
>>>>> dwLength)=0x5.
>>>> DxeImageVerificationLib: Image is signed but signature is not allowed by DB
>> and
>>>> SHA256 hash of image is notOffSet=0x0.
>>>> WinCertificate->dwLength=0x5A4D, ALIGN_SIZE (WinCertificate-
>>>>> dwLength)=0x3.
>>>> OffSet=0x5A50.
>>>> WinCertificate->dwLength=0x9024, ALIGN_SIZE (WinCertificate-
>>>>> dwLength)=0x4.
>>>> OffSet=0xEA78.
>>>> WinCertificate->dwLength=0x0, ALIGN_SIZE (WinCertificate->dwLength)=0x0.
>>>> The image doesn't pass verification: VenHw(5CF32E0B-8EDF-2E44-9CDA-
>>>> 93205E99EC1C,00000000)/VenHw(964E5B22-6459-11D2-8E39-
>>>> 00A0C969723B,00000000)/\signed_1234_4G.efi
>>>>
>>>>
>>>> Regards
>>>> Wenyi
>>>>
>>>>
>>>> On 2020/8/28 14:43, Yao, Jiewen wrote:
>>>>> Apology that I did not say clearly.
>>>>> I mean you should not modify any code to perform an attack.
>>>>>
>>>>> I am not asking you to exploit the system. Attack here just means: to cause
>>>> system hang or buffer overflow. That is enough.
>>>>> But you cannot modify code to remove any existing checker.
>>>>>
>>>>> Thank you
>>>>> Yao Jiewen
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>>>> wenyi,xie
>>>>>> via groups.io
>>>>>> Sent: Friday, August 28, 2020 2:18 PM
>>>>>> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io; Laszlo
>>>> Ersek
>>>>>> <lersek@redhat.com>; Wang, Jian J <jian.j.wang@intel.com>
>>>>>> Cc: songdongkuang@huawei.com; Mathews, John
>>>> <john.mathews@intel.com>
>>>>>> Subject: Re: [edk2-devel] [PATCH EDK2 v2 1/1]
>>>>>> SecurityPkg/DxeImageVerificationLib:Enhanced verification of Offset
>>>>>>
>>>>>> Hi,Jiewen,
>>>>>>
>>>>>> I don't really get the meaning "create a case that bypass all checks in
>>>> PeCoffLib",
>>>>>> do you mean I need to create a PE file that can bypass all check in
>> PeCoffLib
>>>>>> without modify any
>>>>>> code and then cause the problem in DxeImageVerificationLib, or just
>> modify
>>>>>> some code in PeCoffLib to bypass check instead of removing the calling of
>>>>>> PeCoffLoaderGetImageInfo. Would
>>>>>> you mind explaining a little more specifically? As far as I tried, it's really
>> hard
>>>> to
>>>>>> reproduce the issue without touching any code.
>>>>>>
>>>>>> Thanks
>>>>>> Wenyi
>>>>>>
>>>>>> On 2020/8/28 11:50, Yao, Jiewen wrote:
>>>>>>> HI Wenyi
>>>>>>> Thank you very much to take time to reproduce.
>>>>>>>
>>>>>>> I am particular interested in below:
>>>>>>> 	"As PE file is modified, function PeCoffLoaderGetImageInfo will return
>>>>>> error, so I have to remove it so that for loop can be tested in
>>>>>> DxeImageVerificationHandler."
>>>>>>>
>>>>>>> By design, the PeCoffLib should catch illegal PE/COFF image and return
>> error.
>>>>>> (even it cannot catch all, it should catch most ones).
>>>>>>> Other PE/COFF parser may rely on the checker in PeCoffLib and *no
>> need*
>>>> to
>>>>>> duplicate all checkers.
>>>>>>> As such, DxeImageVerificationLib (and other PeCoff consumer) just need
>>>>>> checks what has passed the check in PeCoffLib.
>>>>>>>
>>>>>>> I don’t think you should remove the checker. If people can remove the
>>>> checker,
>>>>>> I am sure the rest code will be vulnerable, according to the current design.
>>>>>>> Could you please to create a case that bypass all checks in PeCoffLib,
>> then
>>>> run
>>>>>> into DxeImageVerificationLib and cause the problem? That would be more
>>>>>> valuable for us.
>>>>>>>
>>>>>>> Thank you
>>>>>>> Yao Jiewen
>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>>>>>> wenyi,xie
>>>>>>>> via groups.io
>>>>>>>> Sent: Friday, August 28, 2020 11:18 AM
>>>>>>>> To: Laszlo Ersek <lersek@redhat.com>; Wang, Jian J
>>>>>> <jian.j.wang@intel.com>;
>>>>>>>> devel@edk2.groups.io; Yao, Jiewen <jiewen.yao@intel.com>
>>>>>>>> Cc: songdongkuang@huawei.com; Mathews, John
>>>>>> <john.mathews@intel.com>
>>>>>>>> Subject: Re: [edk2-devel] [PATCH EDK2 v2 1/1]
>>>>>>>> SecurityPkg/DxeImageVerificationLib:Enhanced verification of Offset
>>>>>>>>
>>>>>>>> Hi,Laszlo and everyone,
>>>>>>>>
>>>>>>>> These days I tried to reproduce the issue,and made some progress. I
>>>> think
>>>>>>>> there are two way to cause overflow from a mathematical point of view,
>>>>>>>> 1.As Laszlo analysed before, if WinCertificate->dwLength is large
>> enough,
>>>>>> close
>>>>>>>> to MAX_UINT32, then (WinCertificate->dwLength + ALIGN_SIZE
>>>>>> (WinCertificate-
>>>>>>>>> dwLength)) will cause overflow.
>>>>>>>> 2.(WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength))
>> is
>>>>>> good,
>>>>>>>> OffSet is good, but OffSet += (WinCertificate->dwLength + ALIGN_SIZE
>>>>>>>> (WinCertificate->dwLength)) cause overflow.
>>>>>>>>
>>>>>>>> Here I choose the second way to reproduce the issue, I choose a PE file
>>>> and
>>>>>> sign
>>>>>>>> it with my own db certificate. Then I use binary edit tool to modify the
>> PE
>>>> file
>>>>>> like
>>>>>>>> below,
>>>>>>>>
>>>>>>>> 1.change SecDataDir->Size from 0x5F8 to 0xFFFF1FFF
>>>>>>>> 2.change WinCertificate->dwLength from 0x5F1 to 0xFFFF1FFE
>>>>>>>> SecDataDir->VirtualAddress in my PE is 0xe000 and no need to change.
>>>>>>>>
>>>>>>>> As PE file is modified, function PeCoffLoaderGetImageInfo will return
>> error,
>>>>>> so I
>>>>>>>> have to remove it so that for loop can be tested in
>>>>>> DxeImageVerificationHandler.
>>>>>>>> The log is as below,
>>>>>>>>
>>>>>>>> SecDataDir->VirtualAddress=0xE000, SecDataDir->Size=0xFFFF1FFF.
>>>>>>>> (First Loop)
>>>>>>>> OffSet=0xE000.
>>>>>>>> WinCertificate->dwLength=0xFFFF1FFE, ALIGN_SIZE (WinCertificate-
>>>>>>>>> dwLength)=0x2.
>>>>>>>> (Second Loop)
>>>>>>>> OffSet=0x0.
>>>>>>>> WinCertificate->dwLength=0x5A4D, ALIGN_SIZE (WinCertificate-
>>>>>>>>> dwLength)=0x3.
>>>>>>>> (Third Loop)
>>>>>>>> OffSet=0x5A50.
>>>>>>>> WinCertificate->dwLength=0x9024, ALIGN_SIZE (WinCertificate-
>>>>>>>>> dwLength)=0x4.
>>>>>>>> (Forth Loop)
>>>>>>>> OffSet=0xEA78.
>>>>>>>> WinCertificate->dwLength=0xAFAFAFAF, ALIGN_SIZE (WinCertificate-
>>>>>>>>> dwLength)=0x1.
>>>>>>>> (Fifth Loop)
>>>>>>>> OffSet=0xAFB09A28.
>>>>>>>>
>>>>>>>> As I modify SecDataDir->Size and WinCertificate->dwLength, so in first
>>>> loop
>>>>>> the
>>>>>>>> condition check whether the Security Data Directory has enough room
>> left
>>>>>> for
>>>>>>>> "WinCertificate->dwLength" is ok.
>>>>>>>>
>>>>>>>> if ((SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) <= sizeof
>>>>>>>> (WIN_CERTIFICATE) ||
>>>>>>>>     (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) <
>>>> WinCertificate-
>>>>>>>>> dwLength) {
>>>>>>>>   break;
>>>>>>>> }
>>>>>>>>
>>>>>>>> In the beginning of second loop, WinCertificate->dwLength +
>> ALIGN_SIZE
>>>>>>>> (WinCertificate->dwLength) is 0xFFFF2000, offset is 0xE000
>>>>>>>>
>>>>>>>> OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate-
>>>>>>> dwLength))
>>>>>>>>
>>>>>>>> Offset now is 0 and overflow happens. So even if my PE only have one
>>>>>> signature,
>>>>>>>> the for loop is still going untill exception happens.
>>>>>>>>
>>>>>>>>
>>>>>>>> I can't reproduce the issue using the first way, because if WinCertificate-
>>>>>>>>> dwLength is close to MAX_UINT32, it means SecDataDir->Size should
>> also
>>>>>> close
>>>>>>>> to MAX_UINT32, or the condition check
>>>>>>>> "(SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) <
>>>> WinCertificate-
>>>>>>>>> dwLength" will break. But if SecDataDir->Size is very large, SecDataDir-
>>>>>>>>> VirtualAddress have to be smaller than 8 bytes,
>>>>>>>> because SecDataDir->VirtualAddress + SecDataDir->Size < MAX_UINT32.
>>>>>>>> SecDataDir->VirtualAddress is the beginning address of the signature,
>> and
>>>>>> before
>>>>>>>> SecDataDir->VirtualAddress is the content of origin PE file, I think it's
>>>>>> impossible
>>>>>>>> that the size of PE file is only 8 bytes.
>>>>>>>>
>>>>>>>> As I changed the one line code in DxeImageVerificationHandler to
>>>> reproduce
>>>>>> the
>>>>>>>> issue, I'm not sure whether it's ok.
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>> Wenyi
>>>>>>>>
>>>>>>>> On 2020/8/19 17:26, Laszlo Ersek wrote:
>>>>>>>>> On 08/18/20 17:18, Mathews, John wrote:
>>>>>>>>>> I dug up the original report details.  This was noted as a concern
>> during a
>>>>>>>> source code inspection.  There was no demonstration of how it might be
>>>>>>>> triggered.
>>>>>>>>>>
>>>>>>>>>> " There is an integer overflow vulnerability in the
>>>>>>>> DxeImageVerificationHandler function when
>>>>>>>>>> parsing the PE files attribute certificate table. In cases where
>>>>>> WinCertificate-
>>>>>>>>> dwLength is
>>>>>>>>>> sufficiently large, it's possible to overflow Offset back to 0 causing an
>>>>>> endless
>>>>>>>> loop."
>>>>>>>>>>
>>>>>>>>>> The recommendation was to add stricter checking of "Offset" and the
>>>>>>>> embedded length fields of certificate data
>>>>>>>>>> before using them.
>>>>>>>>>
>>>>>>>>> Thanks for checking!
>>>>>>>>>
>>>>>>>>> Laszlo
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> -----Original Message-----
>>>>>>>>>> From: Laszlo Ersek <lersek@redhat.com>
>>>>>>>>>> Sent: Tuesday, August 18, 2020 1:59 AM
>>>>>>>>>> To: Wang, Jian J <jian.j.wang@intel.com>; devel@edk2.groups.io;
>> Yao,
>>>>>>>> Jiewen <jiewen.yao@intel.com>; xiewenyi2@huawei.com
>>>>>>>>>> Cc: huangming23@huawei.com; songdongkuang@huawei.com;
>>>> Mathews,
>>>>>>>> John <john.mathews@intel.com>
>>>>>>>>>> Subject: Re: [edk2-devel] [PATCH EDK2 v2 1/1]
>>>>>>>> SecurityPkg/DxeImageVerificationLib:Enhanced verification of Offset
>>>>>>>>>>
>>>>>>>>>> On 08/18/20 04:10, Wang, Jian J wrote:
>>>>>>>>>>> Laszlo,
>>>>>>>>>>>
>>>>>>>>>>> My apologies for the slow response. I'm not the original reporter but
>>>>>>>>>>> just the BZ submitter. And I didn't do deep analysis to this issue.
>>>>>>>>>>> The issues was reported from one internal team. Add John in loop to
>>>> see
>>>>>> if
>>>>>>>> he knows more about it or not.
>>>>>>>>>>>
>>>>>>>>>>> My superficial understanding on such issue is that, if there's
>>>>>>>>>>> "potential" issue in theory and hard to reproduce, it's still worthy
>>>>>>>>>>> of using an alternative way to replace the original implementation
>>>>>>>>>>> with no "potential" issue at all. Maybe we don't have to prove old
>> way
>>>> is
>>>>>>>> something wrong but must prove that the new way is really safe.
>>>>>>>>>>
>>>>>>>>>> I agree, thanks.
>>>>>>>>>>
>>>>>>>>>> It would be nice to hear more from the internal team about the
>>>> originally
>>>>>>>> reported (even if hard-to-trigger) issue.
>>>>>>>>>>
>>>>>>>>>> Thanks!
>>>>>>>>>> Laszlo
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Regards,
>>>>>>>>>>> Jian
>>>>>>>>>>>
>>>>>>>>>>>> -----Original Message-----
>>>>>>>>>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf
>> Of
>>>>>> Laszlo
>>>>>>>>>>>> Ersek
>>>>>>>>>>>> Sent: Tuesday, August 18, 2020 12:53 AM
>>>>>>>>>>>> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io;
>>>>>>>>>>>> xiewenyi2@huawei.com; Wang, Jian J <jian.j.wang@intel.com>
>>>>>>>>>>>> Cc: huangming23@huawei.com; songdongkuang@huawei.com
>>>>>>>>>>>> Subject: Re: [edk2-devel] [PATCH EDK2 v2 1/1]
>>>>>>>>>>>> SecurityPkg/DxeImageVerificationLib:Enhanced verification of
>> Offset
>>>>>>>>>>>>
>>>>>>>>>>>> Hi Jiewen,
>>>>>>>>>>>>
>>>>>>>>>>>> On 08/14/20 10:53, Yao, Jiewen wrote:
>>>>>>>>>>>>>> To Jiewen,
>>>>>>>>>>>>>> Sorry, I don't have environment to reproduce the issue.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Please help me understand, if you don’t have environment to
>>>>>>>>>>>>> reproduce the
>>>>>>>>>>>> issue, how do you guarantee that your patch does fix the problem
>> and
>>>>>>>>>>>> we don’t have any other vulnerabilities?
>>>>>>>>>>>>
>>>>>>>>>>>> The original bug report in
>>>>>>>>>>>> <https://bugzilla.tianocore.org/show_bug.cgi?id=2215#c0> is
>>>> seriously
>>>>>>>>>>>> lacking. It does not go into detail about the alleged integer
>> overflow.
>>>>>>>>>>>> It does not quote the code, does not explain the control flow, does
>>>>>>>>>>>> not identify the exact edk2 commit at which the vulnerability exists.
>>>>>>>>>>>>
>>>>>>>>>>>> The bug report also does not offer a reproducer.
>>>>>>>>>>>>
>>>>>>>>>>>> Additionally, the exact statement that the bug report does make,
>>>>>>>>>>>> namely
>>>>>>>>>>>>
>>>>>>>>>>>>   it's possible to overflow Offset back to 0 causing an endless loop
>>>>>>>>>>>>
>>>>>>>>>>>> is wrong (as far as I can tell anyway). It is not "OffSet" that can
>>>>>>>>>>>> be overflowed to zero, but the *addend* that is added to OffSet
>> can
>>>>>>>>>>>> be overflowed to zero. Therefore the infinite loop will arise
>> because
>>>>>>>>>>>> OffSet remains stuck at its present value, and not because OffSet
>>>>>>>>>>>> will be re-set to zero.
>>>>>>>>>>>>
>>>>>>>>>>>> For the reasons, we can only speculate as to what the actual
>> problem
>>>>>>>>>>>> is, unless Jian decides to join the discussion and clarifies what he
>>>>>>>>>>>> had in mind originally.
>>>>>>>>>>>>
>>>>>>>>>>>> My understanding (or even "reconstruction") of the vulnerability is
>>>>>>>>>>>> described above, and in the patches that I proposed.
>>>>>>>>>>>>
>>>>>>>>>>>> We can write a patch based on code analysis. It's possible to
>>>>>>>>>>>> identify integer overflows based on code analysis, and it's possible
>>>>>>>>>>>> to verify the correctness of fixes by code review. Obviously testing
>>>>>>>>>>>> is always good, but many times, constructing reproducers for such
>>>>>>>>>>>> issues that were found by code review, is difficult and time
>>>>>>>>>>>> consuming. We can say that we don't fix vulnerabilities without
>>>>>>>>>>>> reproducers, or we can say that we make an effort to fix them even
>> if
>>>>>>>>>>>> all we have is code analysis (and not a reproducer).
>>>>>>>>>>>>
>>>>>>>>>>>> So the above paragraph concerns "correctness". Regarding
>>>>>>>>>>>> "completeness", I guarantee you that this patch does not fix *all*
>>>>>>>>>>>> problems related to PE parsing. (See the other BZ tickets.) It does
>>>>>>>>>>>> fix *one* issue with PE parsing. We can say that we try to fix such
>>>>>>>>>>>> issues gradually (give different CVE numbers to different issues, and
>>>>>>>>>>>> address them one at a time), or we can say that we rewrite PE
>> parsing
>>>>>>>> from the ground up.
>>>>>>>>>>>> (BTW: I have seriously attempted that in the past, and I gave up,
>>>>>>>>>>>> because the PE format is FUBAR.)
>>>>>>>>>>>>
>>>>>>>>>>>> In summary:
>>>>>>>>>>>>
>>>>>>>>>>>> - the problem statement is unclear,
>>>>>>>>>>>>
>>>>>>>>>>>> - it seems like there is indeed an integer overflow problem in the
>>>>>>>>>>>> SecDataDir parsing loop, but it's uncertain whether the bug
>> reporter
>>>>>>>>>>>> had exactly that in mind
>>>>>>>>>>>>
>>>>>>>>>>>> - PE parsing is guaranteed to have other vulnerabilities elsewhere in
>>>>>>>>>>>> edk2, but I'm currently unaware of other such issues in
>>>>>>>>>>>> DxeImageVerificationLib specifically
>>>>>>>>>>>>
>>>>>>>>>>>> - even if there are other such problems (in DxeImageVerificationLib
>>>>>>>>>>>> or elswehere), fixing this bug that we know about is likely
>>>>>>>>>>>> worthwhile
>>>>>>>>>>>>
>>>>>>>>>>>> - for many such bugs, constructing a reproducer is difficult and time
>>>>>>>>>>>> consuming; code analysis, and *regression-testing* are frequently
>> the
>>>>>>>>>>>> only tools we have. That doesn't mean we should ignore this class
>> of
>>>>>> bugs.
>>>>>>>>>>>>
>>>>>>>>>>>> (Fixing integer overflows retro-actively is more difficult than
>>>>>>>>>>>> writing overflow-free code in the first place, but that ship has
>>>>>>>>>>>> sailed; so we can only fight these bugs incrementally now, unless
>> we
>>>>>>>>>>>> can rewrite PE parsing with a new data structure from the ground
>> up.
>>>>>>>>>>>> Again I tried that and gave up, because the spec is not public, and
>>>>>>>>>>>> what I did manage to learn about PE, showed that it was insanely
>>>>>>>>>>>> over-engineered. I'm not saying that other binary / executable
>>>>>>>>>>>> formats are better, of course.)
>>>>>>>>>>>>
>>>>>>>>>>>> Please check out my patches (inlined elsewhere in this thread), and
>>>>>>>>>>>> comment whether you'd like me to post them to the list as a
>>>>>>>>>>>> standalone series.
>>>>>>>>>>>>
>>>>>>>>>>>> Jian: it wouldn't hurt if you commented as well.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks
>>>>>>>>>>>> Laszlo
>>>>>>>>>>>>
>>>>>>>>>>>>>> -----Original Message-----
>>>>>>>>>>>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf
>>>> Of
>>>>>>>>>>>> wenyi,xie
>>>>>>>>>>>>>> via groups.io
>>>>>>>>>>>>>> Sent: Friday, August 14, 2020 3:54 PM
>>>>>>>>>>>>>> To: Laszlo Ersek <lersek@redhat.com>; devel@edk2.groups.io;
>> Yao,
>>>>>>>>>>>>>> Jiewen <jiewen.yao@intel.com>; Wang, Jian J
>>>>>> <jian.j.wang@intel.com>
>>>>>>>>>>>>>> Cc: huangming23@huawei.com; songdongkuang@huawei.com
>>>>>>>>>>>>>> Subject: Re: [edk2-devel] [PATCH EDK2 v2 1/1]
>>>>>>>>>>>>>> SecurityPkg/DxeImageVerificationLib:Enhanced verification of
>>>> Offset
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> To Laszlo,
>>>>>>>>>>>>>> Thank you for your detailed description, I agree with what you
>>>>>>>>>>>>>> analyzed and
>>>>>>>>>>>> I'm
>>>>>>>>>>>>>> OK with your patches, it's
>>>>>>>>>>>>>> correct and much simpler.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> To Jiewen,
>>>>>>>>>>>>>> Sorry, I don't have environment to reproduce the issue.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>> Wenyi
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 2020/8/14 2:50, Laszlo Ersek wrote:
>>>>>>>>>>>>>>> On 08/13/20 13:55, Wenyi Xie wrote:
>>>>>>>>>>>>>>>> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2215
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> There is an integer overflow vulnerability in
>>>>>>>>>>>>>>>> DxeImageVerificationHandler function when parsing the PE
>> files
>>>>>>>>>>>>>>>> attribute certificate table. In cases where
>>>>>>>>>>>>>>>> WinCertificate->dwLength is sufficiently large, it's possible to
>>>>>>>> overflow Offset back to 0 causing an endless loop.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Check offset inbetween VirtualAddress and VirtualAddress +
>> Size.
>>>>>>>>>>>>>>>> Using SafeintLib to do offset addition with result check.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Cc: Jiewen Yao <jiewen.yao@intel.com>
>>>>>>>>>>>>>>>> Cc: Jian J Wang <jian.j.wang@intel.com>
>>>>>>>>>>>>>>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>>>>>>>>>>>>>>> Signed-off-by: Wenyi Xie <xiewenyi2@huawei.com>
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>> SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>>>> ib.inf
>>>>>>>>>>>> |
>>>>>>>>>>>>>> 1 +
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>> SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>>>> ib.h
>>>>>>>>>>>> |
>>>>>>>>>>>>>> 1 +
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>> SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>> |
>>>>>>>>>>>>>> 111 +++++++++++---------
>>>>>>>>>>>>>>>>  3 files changed, 63 insertions(+), 50 deletions(-)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.inf
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.inf
>>>>>>>>>>>>>>>> index 1e1a639857e0..a7ac4830b3d4 100644
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.inf
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.inf
>>>>>>>>>>>>>>>> @@ -53,6 +53,7 @@ [LibraryClasses]
>>>>>>>>>>>>>>>>    SecurityManagementLib
>>>>>>>>>>>>>>>>    PeCoffLib
>>>>>>>>>>>>>>>>    TpmMeasurementLib
>>>>>>>>>>>>>>>> +  SafeIntLib
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>  [Protocols]
>>>>>>>>>>>>>>>>    gEfiFirmwareVolume2ProtocolGuid       ##
>>>>>> SOMETIMES_CONSUMES
>>>>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.h
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.h
>>>>>>>>>>>>>>>> index 17955ff9774c..060273917d5d 100644
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.h
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.h
>>>>>>>>>>>>>>>> @@ -23,6 +23,7 @@ SPDX-License-Identifier: BSD-2-Clause-
>>>> Patent
>>>>>>>>>>>>>>>> #include <Library/DevicePathLib.h>  #include
>>>>>>>>>>>>>>>> <Library/SecurityManagementLib.h>  #include
>>>> <Library/PeCoffLib.h>
>>>>>>>>>>>>>>>> +#include <Library/SafeIntLib.h>
>>>>>>>>>>>>>>>>  #include <Protocol/FirmwareVolume2.h>  #include
>>>>>>>>>>>>>>>> <Protocol/DevicePath.h>  #include <Protocol/BlockIo.h> diff -
>> -
>>>> git
>>>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>>> index 36b87e16d53d..dbc03e28c05b 100644
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib
>>>>>>>>>>>> .c
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>>> @@ -1658,6 +1658,10 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>    EFI_STATUS                           HashStatus;
>>>>>>>>>>>>>>>>    EFI_STATUS                           DbStatus;
>>>>>>>>>>>>>>>>    BOOLEAN                              IsFound;
>>>>>>>>>>>>>>>> +  UINT32                               AlignedLength;
>>>>>>>>>>>>>>>> +  UINT32                               Result;
>>>>>>>>>>>>>>>> +  EFI_STATUS                           AddStatus;
>>>>>>>>>>>>>>>> +  BOOLEAN                              IsAuthDataAssigned;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>    SignatureList     = NULL;
>>>>>>>>>>>>>>>>    SignatureListSize = 0;
>>>>>>>>>>>>>>>> @@ -1667,6 +1671,7 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>    Action            = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;
>>>>>>>>>>>>>>>>    IsVerified        = FALSE;
>>>>>>>>>>>>>>>>    IsFound           = FALSE;
>>>>>>>>>>>>>>>> +  Result            = 0;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>    //
>>>>>>>>>>>>>>>>    // Check the image type and get policy setting.
>>>>>>>>>>>>>>>> @@ -1850,9 +1855,10 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>    // The first certificate starts at offset
>>>>>>>>>>>>>>>> (SecDataDir->VirtualAddress) from
>>>>>>>>>>>> the
>>>>>>>>>>>>>> start of the file.
>>>>>>>>>>>>>>>>    //
>>>>>>>>>>>>>>>>    for (OffSet = SecDataDir->VirtualAddress;
>>>>>>>>>>>>>>>> -       OffSet < (SecDataDir->VirtualAddress + SecDataDir->Size);
>>>>>>>>>>>>>>>> -       OffSet += (WinCertificate->dwLength + ALIGN_SIZE
>>>>>>>> (WinCertificate-
>>>>>>>>>>>>>>> dwLength))) {
>>>>>>>>>>>>>>>> +       (OffSet >= SecDataDir->VirtualAddress) && (OffSet <
>>>>>>>>>>>>>>>> + (SecDataDir-
>>>>>>>>>>>>>>> VirtualAddress + SecDataDir->Size));) {
>>>>>>>>>>>>>>>> +    IsAuthDataAssigned = FALSE;
>>>>>>>>>>>>>>>>      WinCertificate = (WIN_CERTIFICATE *) (mImageBase +
>> OffSet);
>>>>>>>>>>>>>>>> +    AlignedLength = WinCertificate->dwLength + ALIGN_SIZE
>>>>>>>>>>>> (WinCertificate-
>>>>>>>>>>>>>>> dwLength);
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I disagree with this patch.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The primary reason for my disagreement is that the bug report
>>>>>>>>>>>>>>> <https://bugzilla.tianocore.org/show_bug.cgi?id=2215#c0> is
>>>>>>>>>>>>>>> inexact, and so this patch tries to fix the wrong thing.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> With edk2 master at commit 65904cdbb33c, it is *not* possible
>> to
>>>>>>>>>>>>>>> overflow the OffSet variable to zero with "WinCertificate-
>>>>>>> dwLength"
>>>>>>>>>>>>>>> *purely*, and cause an endless loop. Note that we have (at
>>>> commit
>>>>>>>>>>>>>>> 65904cdbb33c):
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   for (OffSet = SecDataDir->VirtualAddress;
>>>>>>>>>>>>>>>        OffSet < (SecDataDir->VirtualAddress + SecDataDir->Size);
>>>>>>>>>>>>>>>        OffSet += (WinCertificate->dwLength + ALIGN_SIZE
>>>>>>>>>>>>>>> (WinCertificate-
>>>>>>>>>>>>>>> dwLength))) {
>>>>>>>>>>>>>>>     WinCertificate = (WIN_CERTIFICATE *) (mImageBase +
>> OffSet);
>>>>>>>>>>>>>>>     if ((SecDataDir->VirtualAddress + SecDataDir->Size - OffSet)
>>>>>>>>>>>>>>> <= sizeof
>>>>>>>>>>>>>> (WIN_CERTIFICATE) ||
>>>>>>>>>>>>>>>         (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) <
>>>>>>>>>>>> WinCertificate-
>>>>>>>>>>>>>>> dwLength) {
>>>>>>>>>>>>>>>       break;
>>>>>>>>>>>>>>>     }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The last sub-condition checks whether the Security Data
>> Directory
>>>>>>>>>>>>>>> has enough room left for "WinCertificate->dwLength". If not,
>> then
>>>>>>>>>>>>>>> we break out of the loop.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> If we *do* have enough room, that is:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) >=
>>>>>>>>>>>> WinCertificate-
>>>>>>>>>>>>>>> dwLength
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> then we have (by adding OffSet to both sides):
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   SecDataDir->VirtualAddress + SecDataDir->Size >= OffSet +
>>>>>>>>>>>>>>> WinCertificate- dwLength
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The left hand side is a known-good UINT32, and so
>> incrementing
>>>>>>>>>>>>>>> OffSet (a
>>>>>>>>>>>>>>> UINT32) *solely* by "WinCertificate->dwLength" (also a
>> UINT32)
>>>>>>>>>>>>>>> does not cause an overflow.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Instead, the problem is with the alignment. The "if" statement
>>>>>>>>>>>>>>> checks whether we have enough room for "dwLength", but
>> then
>>>>>>>>>>>>>>> "OffSet" is advanced by "dwLength" *aligned up* to the next
>>>>>>>>>>>>>>> multiple of 8. And that may indeed cause various overflows.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Now, the main problem with the present patch is that it does
>> not
>>>>>>>>>>>>>>> fix one of those overflows. Namely, consider that "dwLength" is
>>>>>>>>>>>>>>> very close to
>>>>>>>>>>>>>>> MAX_UINT32 (or even think it's exactly MAX_UINT32). Then
>>>> aligning
>>>>>>>>>>>>>>> it up to the next multiple of 8 will yield 0. In other words,
>>>>>>>> "AlignedLength"
>>>>>>>>>>>>>>> will be zero.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> And when that happens, there's going to be an infinite loop just
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> same: "OffSet" will not be zero, but it will be *stuck*. The
>>>>>>>>>>>>>>> SafeUint32Add() call at the bottom will succeed, but it will not
>>>>>>>>>>>>>>> change the value of "OffSet".
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> More at the bottom.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>      if ((SecDataDir->VirtualAddress + SecDataDir->Size - OffSet)
>>>>>>>>>>>>>>>> <= sizeof
>>>>>>>>>>>>>> (WIN_CERTIFICATE) ||
>>>>>>>>>>>>>>>>          (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet)
>>>>>>>>>>>>>>>> <
>>>>>>>>>>>>>> WinCertificate->dwLength) {
>>>>>>>>>>>>>>>>        break;
>>>>>>>>>>>>>>>> @@ -1872,6 +1878,8 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>        }
>>>>>>>>>>>>>>>>        AuthData   = PkcsCertData->CertData;
>>>>>>>>>>>>>>>>        AuthDataSize = PkcsCertData->Hdr.dwLength -
>>>>>>>>>>>>>>>> sizeof(PkcsCertData-
>>>>>>>>>>>>> Hdr);
>>>>>>>>>>>>>>>> +      IsAuthDataAssigned = TRUE;
>>>>>>>>>>>>>>>> +      HashStatus = HashPeImageByType (AuthData,
>> AuthDataSize);
>>>>>>>>>>>>>>>>      } else if (WinCertificate->wCertificateType ==
>>>>>>>>>>>> WIN_CERT_TYPE_EFI_GUID)
>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>        //
>>>>>>>>>>>>>>>>        // The certificate is formatted as
>>>>>>>>>>>>>>>> WIN_CERTIFICATE_UEFI_GUID which
>>>>>>>>>>>> is
>>>>>>>>>>>>>> described in UEFI Spec.
>>>>>>>>>>>>>>>> @@ -1880,72 +1888,75 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>        if (WinCertUefiGuid->Hdr.dwLength <=
>>>>>>>>>>>>>> OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData)) {
>>>>>>>>>>>>>>>>          break;
>>>>>>>>>>>>>>>>        }
>>>>>>>>>>>>>>>> -      if (!CompareGuid (&WinCertUefiGuid->CertType,
>>>>>>>> &gEfiCertPkcs7Guid))
>>>>>>>>>>>> {
>>>>>>>>>>>>>>>> -        continue;
>>>>>>>>>>>>>>>> +      if (CompareGuid (&WinCertUefiGuid->CertType,
>>>>>>>>>>>>>>>> + &gEfiCertPkcs7Guid))
>>>>>>>>>>>> {
>>>>>>>>>>>>>>>> +        AuthData = WinCertUefiGuid->CertData;
>>>>>>>>>>>>>>>> +        AuthDataSize = WinCertUefiGuid->Hdr.dwLength -
>>>>>>>>>>>>>> OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData);
>>>>>>>>>>>>>>>> +        IsAuthDataAssigned = TRUE;
>>>>>>>>>>>>>>>> +        HashStatus = HashPeImageByType (AuthData,
>>>> AuthDataSize);
>>>>>>>>>>>>>>>>        }
>>>>>>>>>>>>>>>> -      AuthData = WinCertUefiGuid->CertData;
>>>>>>>>>>>>>>>> -      AuthDataSize = WinCertUefiGuid->Hdr.dwLength -
>>>>>>>>>>>>>> OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData);
>>>>>>>>>>>>>>>>      } else {
>>>>>>>>>>>>>>>>        if (WinCertificate->dwLength < sizeof (WIN_CERTIFICATE))
>> {
>>>>>>>>>>>>>>>>          break;
>>>>>>>>>>>>>>>>        }
>>>>>>>>>>>>>>>> -      continue;
>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> -    HashStatus = HashPeImageByType (AuthData,
>> AuthDataSize);
>>>>>>>>>>>>>>>> -    if (EFI_ERROR (HashStatus)) {
>>>>>>>>>>>>>>>> -      continue;
>>>>>>>>>>>>>>>> -    }
>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>> -    //
>>>>>>>>>>>>>>>> -    // Check the digital signature against the revoked
>> certificate
>>>> in
>>>>>>>>>>>> forbidden
>>>>>>>>>>>>>> database (dbx).
>>>>>>>>>>>>>>>> -    //
>>>>>>>>>>>>>>>> -    if (IsForbiddenByDbx (AuthData, AuthDataSize)) {
>>>>>>>>>>>>>>>> -      Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;
>>>>>>>>>>>>>>>> -      IsVerified = FALSE;
>>>>>>>>>>>>>>>> -      break;
>>>>>>>>>>>>>>>> -    }
>>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>>> -    //
>>>>>>>>>>>>>>>> -    // Check the digital signature against the valid certificate in
>>>>>>>> allowed
>>>>>>>>>>>>>> database (db).
>>>>>>>>>>>>>>>> -    //
>>>>>>>>>>>>>>>> -    if (!IsVerified) {
>>>>>>>>>>>>>>>> -      if (IsAllowedByDb (AuthData, AuthDataSize)) {
>>>>>>>>>>>>>>>> -        IsVerified = TRUE;
>>>>>>>>>>>>>>>> +    if (IsAuthDataAssigned && !EFI_ERROR (HashStatus)) {
>>>>>>>>>>>>>>>> +      //
>>>>>>>>>>>>>>>> +      // Check the digital signature against the revoked
>>>>>>>>>>>>>>>> + certificate in
>>>>>>>>>>>> forbidden
>>>>>>>>>>>>>> database (dbx).
>>>>>>>>>>>>>>>> +      //
>>>>>>>>>>>>>>>> +      if (IsForbiddenByDbx (AuthData, AuthDataSize)) {
>>>>>>>>>>>>>>>> +        Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;
>>>>>>>>>>>>>>>> +        IsVerified = FALSE;
>>>>>>>>>>>>>>>> +        break;
>>>>>>>>>>>>>>>>        }
>>>>>>>>>>>>>>>> -    }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> -    //
>>>>>>>>>>>>>>>> -    // Check the image's hash value.
>>>>>>>>>>>>>>>> -    //
>>>>>>>>>>>>>>>> -    DbStatus = IsSignatureFoundInDatabase (
>>>>>>>>>>>>>>>> -                 EFI_IMAGE_SECURITY_DATABASE1,
>>>>>>>>>>>>>>>> -                 mImageDigest,
>>>>>>>>>>>>>>>> -                 &mCertType,
>>>>>>>>>>>>>>>> -                 mImageDigestSize,
>>>>>>>>>>>>>>>> -                 &IsFound
>>>>>>>>>>>>>>>> -                 );
>>>>>>>>>>>>>>>> -    if (EFI_ERROR (DbStatus) || IsFound) {
>>>>>>>>>>>>>>>> -      Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;
>>>>>>>>>>>>>>>> -      DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image
>> is
>>>>>>>> signed
>>>>>>>>>>>> but %s
>>>>>>>>>>>>>> hash of image is found in DBX.\n", mHashTypeStr));
>>>>>>>>>>>>>>>> -      IsVerified = FALSE;
>>>>>>>>>>>>>>>> -      break;
>>>>>>>>>>>>>>>> -    }
>>>>>>>>>>>>>>>> +      //
>>>>>>>>>>>>>>>> +      // Check the digital signature against the valid
>>>>>>>>>>>>>>>> + certificate in allowed
>>>>>>>>>>>>>> database (db).
>>>>>>>>>>>>>>>> +      //
>>>>>>>>>>>>>>>> +      if (!IsVerified) {
>>>>>>>>>>>>>>>> +        if (IsAllowedByDb (AuthData, AuthDataSize)) {
>>>>>>>>>>>>>>>> +          IsVerified = TRUE;
>>>>>>>>>>>>>>>> +        }
>>>>>>>>>>>>>>>> +      }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> -    if (!IsVerified) {
>>>>>>>>>>>>>>>> +      //
>>>>>>>>>>>>>>>> +      // Check the image's hash value.
>>>>>>>>>>>>>>>> +      //
>>>>>>>>>>>>>>>>        DbStatus = IsSignatureFoundInDatabase (
>>>>>>>>>>>>>>>> -                   EFI_IMAGE_SECURITY_DATABASE,
>>>>>>>>>>>>>>>> +                   EFI_IMAGE_SECURITY_DATABASE1,
>>>>>>>>>>>>>>>>                     mImageDigest,
>>>>>>>>>>>>>>>>                     &mCertType,
>>>>>>>>>>>>>>>>                     mImageDigestSize,
>>>>>>>>>>>>>>>>                     &IsFound
>>>>>>>>>>>>>>>>                     );
>>>>>>>>>>>>>>>> -      if (!EFI_ERROR (DbStatus) && IsFound) {
>>>>>>>>>>>>>>>> -        IsVerified = TRUE;
>>>>>>>>>>>>>>>> -      } else {
>>>>>>>>>>>>>>>> -        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image
>> is
>>>>>>>> signed
>>>>>>>>>>>> but
>>>>>>>>>>>>>> signature is not allowed by DB and %s hash of image is not found
>> in
>>>>>>>>>>>> DB/DBX.\n",
>>>>>>>>>>>>>> mHashTypeStr));
>>>>>>>>>>>>>>>> +      if (EFI_ERROR (DbStatus) || IsFound) {
>>>>>>>>>>>>>>>> +        Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;
>>>>>>>>>>>>>>>> +        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image
>> is
>>>>>>>>>>>>>>>> + signed
>>>>>>>>>>>>>> but %s hash of image is found in DBX.\n", mHashTypeStr));
>>>>>>>>>>>>>>>> +        IsVerified = FALSE;
>>>>>>>>>>>>>>>> +        break;
>>>>>>>>>>>>>>>>        }
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +      if (!IsVerified) {
>>>>>>>>>>>>>>>> +        DbStatus = IsSignatureFoundInDatabase (
>>>>>>>>>>>>>>>> +                     EFI_IMAGE_SECURITY_DATABASE,
>>>>>>>>>>>>>>>> +                     mImageDigest,
>>>>>>>>>>>>>>>> +                     &mCertType,
>>>>>>>>>>>>>>>> +                     mImageDigestSize,
>>>>>>>>>>>>>>>> +                     &IsFound
>>>>>>>>>>>>>>>> +                     );
>>>>>>>>>>>>>>>> +        if (!EFI_ERROR (DbStatus) && IsFound) {
>>>>>>>>>>>>>>>> +          IsVerified = TRUE;
>>>>>>>>>>>>>>>> +        } else {
>>>>>>>>>>>>>>>> +          DEBUG ((DEBUG_INFO, "DxeImageVerificationLib:
>> Image
>>>> is
>>>>>>>>>>>>>>>> + signed
>>>>>>>>>>>> but
>>>>>>>>>>>>>> signature is not allowed by DB and %s hash of image is not found
>> in
>>>>>>>>>>>> DB/DBX.\n",
>>>>>>>>>>>>>> mHashTypeStr));
>>>>>>>>>>>>>>>> +        }
>>>>>>>>>>>>>>>> +      }
>>>>>>>>>>>>>>>> +    }
>>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>> +    AddStatus = SafeUint32Add (OffSet, AlignedLength,
>> &Result);
>>>>>>>>>>>>>>>> +    if (EFI_ERROR (AddStatus)) {
>>>>>>>>>>>>>>>> +      break;
>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>> +    OffSet = Result;
>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>    if (OffSet != (SecDataDir->VirtualAddress + SecDataDir->Size))
>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> There are other (smaller) reasons why I dislike this patch:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> - The "IsAuthDataAssigned" variable is superfluous; we could
>> use
>>>>>>>>>>>>>>> the existent "AuthData" variable (with a NULL-check and a
>>>>>>>>>>>>>>> NULL-assignment) similarly.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> - The patch complicates / reorganizes the control flow
>> needlessly.
>>>>>>>>>>>>>>> This complication originates from placing the checked "OffSet"
>>>>>>>>>>>>>>> increment at the bottom of the loop, which then requires the
>>>>>>>>>>>>>>> removal of all the "continue" statements. But we don't need to
>>>>>>>>>>>>>>> check-and-increment at the bottom. We can keep the
>> increment
>>>>>>>>>>>>>>> inside the "for" statement, only extend the *existent* room
>> check
>>>>>>>>>>>>>>> (which I've quoted) to take the alignment into account as well.
>> If
>>>>>>>>>>>>>>> there is enough room for the alignment in the security data
>>>>>>>>>>>>>>> directory, then that guarantees there won't be a UINT32
>> overflow
>>>>>>>> either.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> All in all, I'm proposing the following three patches instead. The
>>>>>>>>>>>>>>> first two patches are preparation, the last patch is the fix.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Patch#1:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> From 11af0a104d34d39bf1b1aab256428ae4edbddd77 Mon
>> Sep
>>>> 17
>>>>>>>>>>>> 00:00:00
>>>>>>>>>>>>>> 2001
>>>>>>>>>>>>>>>> From: Laszlo Ersek <lersek@redhat.com>
>>>>>>>>>>>>>>>> Date: Thu, 13 Aug 2020 19:11:39 +0200
>>>>>>>>>>>>>>>> Subject: [PATCH 1/3] SecurityPkg/DxeImageVerificationLib:
>>>> extract
>>>>>>>>>>>>>>>> SecDataDirEnd, SecDataDirLeft
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The following two quantities:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   SecDataDir->VirtualAddress + SecDataDir->Size
>>>>>>>>>>>>>>>>   SecDataDir->VirtualAddress + SecDataDir->Size - OffSet
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> are used multiple times in DxeImageVerificationHandler().
>>>>>>>>>>>>>>>> Introduce helper variables for them: "SecDataDirEnd" and
>>>>>>>> "SecDataDirLeft", respectively.
>>>>>>>>>>>>>>>> This saves us multiple calculations and significantly simplifies
>> the
>>>>>> code.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Note that all three summands above have type UINT32,
>>>> therefore
>>>>>>>>>>>>>>>> the new variables are also of type UINT32.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> This patch does not change behavior.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> (Note that the code already handles the case when the
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   SecDataDir->VirtualAddress + SecDataDir->Size
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> UINT32 addition overflows -- namely, in that case, the
>>>>>>>>>>>>>>>> certificate loop is never entered, and the corruption check
>> right
>>>>>>>>>>>>>>>> after the loop fires.)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>> SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>>>> ib.c |
>>>>>>>>>>>> 12
>>>>>>>>>>>>>> ++++++++----
>>>>>>>>>>>>>>>>  1 file changed, 8 insertions(+), 4 deletions(-)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>>> index 36b87e16d53d..8761980c88aa 100644
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib
>>>>>>>>>>>> .c
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>>> @@ -1652,6 +1652,8 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>    UINT8                                *AuthData;
>>>>>>>>>>>>>>>>    UINTN                                AuthDataSize;
>>>>>>>>>>>>>>>>    EFI_IMAGE_DATA_DIRECTORY             *SecDataDir;
>>>>>>>>>>>>>>>> +  UINT32                               SecDataDirEnd;
>>>>>>>>>>>>>>>> +  UINT32                               SecDataDirLeft;
>>>>>>>>>>>>>>>>    UINT32                               OffSet;
>>>>>>>>>>>>>>>>    CHAR16                               *NameStr;
>>>>>>>>>>>>>>>>    RETURN_STATUS                        PeCoffStatus;
>>>>>>>>>>>>>>>> @@ -1849,12 +1851,14 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>    // "Attribute Certificate Table".
>>>>>>>>>>>>>>>>    // The first certificate starts at offset
>>>>>>>>>>>>>>>> (SecDataDir->VirtualAddress) from
>>>>>>>>>>>> the
>>>>>>>>>>>>>> start of the file.
>>>>>>>>>>>>>>>>    //
>>>>>>>>>>>>>>>> +  SecDataDirEnd = SecDataDir->VirtualAddress + SecDataDir-
>>>>> Size;
>>>>>>>>>>>>>>>>    for (OffSet = SecDataDir->VirtualAddress;
>>>>>>>>>>>>>>>> -       OffSet < (SecDataDir->VirtualAddress + SecDataDir->Size);
>>>>>>>>>>>>>>>> +       OffSet < SecDataDirEnd;
>>>>>>>>>>>>>>>>         OffSet += (WinCertificate->dwLength + ALIGN_SIZE
>>>>>>>>>>>>>>>> (WinCertificate-
>>>>>>>>>>>>>>> dwLength))) {
>>>>>>>>>>>>>>>>      WinCertificate = (WIN_CERTIFICATE *) (mImageBase +
>> OffSet);
>>>>>>>>>>>>>>>> -    if ((SecDataDir->VirtualAddress + SecDataDir->Size - OffSet)
>> <=
>>>>>>>> sizeof
>>>>>>>>>>>>>> (WIN_CERTIFICATE) ||
>>>>>>>>>>>>>>>> -        (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet)
>> <
>>>>>>>>>>>>>> WinCertificate->dwLength) {
>>>>>>>>>>>>>>>> +    SecDataDirLeft = SecDataDirEnd - OffSet;
>>>>>>>>>>>>>>>> +    if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE) ||
>>>>>>>>>>>>>>>> +        SecDataDirLeft < WinCertificate->dwLength) {
>>>>>>>>>>>>>>>>        break;
>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> @@ -1948,7 +1952,7 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>>    }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> -  if (OffSet != (SecDataDir->VirtualAddress + SecDataDir->Size))
>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>> +  if (OffSet != SecDataDirEnd) {
>>>>>>>>>>>>>>>>      //
>>>>>>>>>>>>>>>>      // The Size in Certificate Table or the attribute
>>>>>>>>>>>>>>>> certificate table is
>>>>>>>>>>>> corrupted.
>>>>>>>>>>>>>>>>      //
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> 2.19.1.3.g30247aa5d201
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Patch#2:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> From 72012c065a53582f7df695e7b9730c45f49226c6 Mon Sep
>>>> 17
>>>>>>>> 00:00:00
>>>>>>>>>>>>>> 2001
>>>>>>>>>>>>>>>> From: Laszlo Ersek <lersek@redhat.com>
>>>>>>>>>>>>>>>> Date: Thu, 13 Aug 2020 19:19:06 +0200
>>>>>>>>>>>>>>>> Subject: [PATCH 2/3] SecurityPkg/DxeImageVerificationLib:
>>>> assign
>>>>>>>>>>>>>>>> WinCertificate after size check
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Currently the (SecDataDirLeft <= sizeof (WIN_CERTIFICATE))
>>>> check
>>>>>>>>>>>>>>>> only guards the de-referencing of the "WinCertificate" pointer.
>>>>>>>>>>>>>>>> It does not guard the calculation of hte pointer itself:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   WinCertificate = (WIN_CERTIFICATE *) (mImageBase +
>> OffSet);
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> This is wrong; if we don't know for sure that we have enough
>>>> room
>>>>>>>>>>>>>>>> for a WIN_CERTIFICATE, then even creating such a pointer,
>> not
>>>>>>>>>>>>>>>> just de-referencing it, may invoke undefined behavior.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Move the pointer calculation after the size check.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>> SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>>>> ib.c |
>>>>>>>>>>>> 8
>>>>>>>>>>>>>> +++++---
>>>>>>>>>>>>>>>>  1 file changed, 5 insertions(+), 3 deletions(-)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>>> index 8761980c88aa..461ed7cfb5ac 100644
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib
>>>>>>>>>>>> .c
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>>> @@ -1855,10 +1855,12 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>    for (OffSet = SecDataDir->VirtualAddress;
>>>>>>>>>>>>>>>>         OffSet < SecDataDirEnd;
>>>>>>>>>>>>>>>>         OffSet += (WinCertificate->dwLength + ALIGN_SIZE
>>>>>>>>>>>>>>>> (WinCertificate-
>>>>>>>>>>>>>>> dwLength))) {
>>>>>>>>>>>>>>>> -    WinCertificate = (WIN_CERTIFICATE *) (mImageBase +
>>>> OffSet);
>>>>>>>>>>>>>>>>      SecDataDirLeft = SecDataDirEnd - OffSet;
>>>>>>>>>>>>>>>> -    if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE) ||
>>>>>>>>>>>>>>>> -        SecDataDirLeft < WinCertificate->dwLength) {
>>>>>>>>>>>>>>>> +    if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE)) {
>>>>>>>>>>>>>>>> +      break;
>>>>>>>>>>>>>>>> +    }
>>>>>>>>>>>>>>>> +    WinCertificate = (WIN_CERTIFICATE *) (mImageBase +
>>>> OffSet);
>>>>>>>>>>>>>>>> +    if (SecDataDirLeft < WinCertificate->dwLength) {
>>>>>>>>>>>>>>>>        break;
>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> 2.19.1.3.g30247aa5d201
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Patch#3:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> From 0bbba15b84f8f9f2cdc770a89f418aaec6cfb31e Mon Sep
>> 17
>>>>>>>> 00:00:00
>>>>>>>>>>>>>> 2001
>>>>>>>>>>>>>>>> From: Laszlo Ersek <lersek@redhat.com>
>>>>>>>>>>>>>>>> Date: Thu, 13 Aug 2020 19:34:33 +0200
>>>>>>>>>>>>>>>> Subject: [PATCH 3/3] SecurityPkg/DxeImageVerificationLib:
>> catch
>>>>>>>>>>>> alignment
>>>>>>>>>>>>>>>>  overflow (CVE-2019-14562)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The DxeImageVerificationHandler() function currently checks
>>>>>>>>>>>>>>>> whether "SecDataDir" has enough room for
>>>>>>>>>>>>>>>> "WinCertificate->dwLength". However,
>>>>>>>>>>>>>> for
>>>>>>>>>>>>>>>> advancing "OffSet", "WinCertificate->dwLength" is aligned to
>> the
>>>>>>>>>>>>>>>> next multiple of 8. If "WinCertificate->dwLength" is large
>>>>>>>>>>>>>>>> enough, the alignment will return 0, and "OffSet" will be stuck
>> at
>>>>>> the
>>>>>>>> same value.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Check whether "SecDataDir" has room left for both
>>>>>>>>>>>>>>>> "WinCertificate->dwLength" and the alignment.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>> SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>>>> ib.c |
>>>>>>>>>>>> 4
>>>>>>>>>>>>>> +++-
>>>>>>>>>>>>>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>>> index 461ed7cfb5ac..e38eb981b7a0 100644
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>
>>>>>> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib
>>>>>>>>>>>> .c
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>
>>>>>> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL
>>>>>>>>>>>>>> ib.c
>>>>>>>>>>>>>>>> @@ -1860,7 +1860,9 @@ DxeImageVerificationHandler (
>>>>>>>>>>>>>>>>        break;
>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>>      WinCertificate = (WIN_CERTIFICATE *) (mImageBase +
>> OffSet);
>>>>>>>>>>>>>>>> -    if (SecDataDirLeft < WinCertificate->dwLength) {
>>>>>>>>>>>>>>>> +    if (SecDataDirLeft < WinCertificate->dwLength ||
>>>>>>>>>>>>>>>> +        (SecDataDirLeft - WinCertificate->dwLength <
>>>>>>>>>>>>>>>> +         ALIGN_SIZE (WinCertificate->dwLength))) {
>>>>>>>>>>>>>>>>        break;
>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> 2.19.1.3.g30247aa5d201
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> If Wenyi and the reviewers are OK with these patches, I can
>>>> submit
>>>>>>>>>>>>>>> them as a standalone patch series.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Note that I do not have any reproducer for the issue; the best
>>>>>>>>>>>>>>> testing that I could offer would be some light-weight Secure
>> Boot
>>>>>>>>>>>>>>> regression tests.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>> Laszlo
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> .
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> .
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>
>>
>> 
> 


  reply	other threads:[~2020-09-01  7:43 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-13 11:55 [PATCH EDK2 v2 0/1] SecurityPkg/DxeImageVerificationLib:Enhanced verification of Offset wenyi,xie
2020-08-13 11:55 ` [PATCH EDK2 v2 1/1] " wenyi,xie
2020-08-13 14:32   ` Yao, Jiewen
2020-08-13 18:50   ` Laszlo Ersek
2020-08-14  7:53     ` wenyi,xie
2020-08-14  8:53       ` [edk2-devel] " Yao, Jiewen
2020-08-14 11:29         ` wenyi,xie
2020-08-17 16:52         ` Laszlo Ersek
2020-08-17 23:23           ` Yao, Jiewen
2020-08-18 10:17             ` Laszlo Ersek
     [not found]               ` <a7elBrHZ3zD0Stt3MiPOUU_6uOnp-LlR4c9weDhWm4xYH388XWK0M80fLZe_AqbzF68IFK_IdkWQtKN8HKyRnQ==@protonmail.internalid>
2020-08-18 10:24               ` Marvin Häuser
2020-08-18 11:01                 ` Laszlo Ersek
2020-08-18 12:21                 ` Vitaly Cheptsov
2020-08-18 13:12               ` Yao, Jiewen
2020-08-18 17:29                 ` Bret Barkelew
2020-08-18 23:00                   ` Yao, Jiewen
2020-08-19  9:33                   ` Laszlo Ersek
2020-08-18  2:10           ` Wang, Jian J
2020-08-18  8:58             ` Laszlo Ersek
2020-08-18 15:18               ` john.mathews
2020-08-19  9:26                 ` Laszlo Ersek
2020-08-28  3:17                   ` wenyi,xie
2020-08-28  3:50                     ` Yao, Jiewen
2020-08-28  6:18                       ` wenyi,xie
2020-08-28  6:43                         ` Yao, Jiewen
2020-08-31 11:23                           ` wenyi,xie
2020-08-31 16:06                             ` Yao, Jiewen
2020-09-01  7:10                               ` wenyi,xie
2020-09-01  7:31                                 ` Yao, Jiewen
2020-09-01  7:43                                   ` wenyi,xie [this message]
2020-09-01  7:56                                     ` Laszlo Ersek
2020-09-01  7:29                               ` Laszlo Ersek

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=7d75c44a-5f52-b51a-57d0-54940731cd34@huawei.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