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....@intel.com>; devel@edk2.groups.io; Laszlo Ersek
> <ler...@redhat.com>; Wang, Jian J <jian.j.w...@intel.com>
> Cc: songdongku...@huawei.com; Mathews, John <john.math...@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 <ler...@redhat.com>; Wang, Jian J
> <jian.j.w...@intel.com>;
> >> devel@edk2.groups.io; Yao, Jiewen <jiewen....@intel.com>
> >> Cc: songdongku...@huawei.com; Mathews, John
> <john.math...@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 <ler...@redhat.com>
> >>>> Sent: Tuesday, August 18, 2020 1:59 AM
> >>>> To: Wang, Jian J <jian.j.w...@intel.com>; devel@edk2.groups.io; Yao,
> >> Jiewen <jiewen....@intel.com>; xiewen...@huawei.com
> >>>> Cc: huangmin...@huawei.com; songdongku...@huawei.com; Mathews,
> >> John <john.math...@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....@intel.com>; devel@edk2.groups.io;
> >>>>>> xiewen...@huawei.com; Wang, Jian J <jian.j.w...@intel.com>
> >>>>>> Cc: huangmin...@huawei.com; songdongku...@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 <ler...@redhat.com>; devel@edk2.groups.io; Yao,
> >>>>>>>> Jiewen <jiewen....@intel.com>; Wang, Jian J
> <jian.j.w...@intel.com>
> >>>>>>>> Cc: huangmin...@huawei.com; songdongku...@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....@intel.com>
> >>>>>>>>>> Cc: Jian J Wang <jian.j.w...@intel.com>
> >>>>>>>>>> Cc: Laszlo Ersek <ler...@redhat.com>
> >>>>>>>>>> Signed-off-by: Wenyi Xie <xiewen...@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 <ler...@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 <ler...@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 <ler...@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 <ler...@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 <ler...@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 <ler...@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
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> .
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>>
> >>>
> >>> .
> >>>
> >>
> >>
> >>
> >
> 
> 
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#64742): https://edk2.groups.io/g/devel/message/64742
Mute This Topic: https://groups.io/mt/76165658/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to