public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Oliver Smith-Denny" <osde@linux.microsoft.com>
To: devel@edk2.groups.io, ardb@kernel.org
Cc: Liming Gao <gaoliming@byosoft.com.cn>,
	Leif Lindholm <quic_llindhol@quicinc.com>,
	Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Sami Mujawar <sami.mujawar@arm.com>,
	Taylor Beebe <taylor.d.beebe@gmail.com>
Subject: Re: [edk2-devel][PATCH v1 1/3] MdeModulePkg: ImagePropertiesRecordLib: Use SectionAlignment for CodeSize
Date: Mon, 4 Mar 2024 11:24:31 -0800	[thread overview]
Message-ID: <531b3cfe-b57c-4b5a-97fd-45e428f97853@linux.microsoft.com> (raw)
In-Reply-To: <CAMj1kXGsso6BjOajEgqE3AOC1ZSdStQmeYmCoJMQo_tK1QHTWw@mail.gmail.com>

On 3/4/2024 10:54 AM, Ard Biesheuvel wrote:
> On Mon, 4 Mar 2024 at 18:49, Oliver Smith-Denny
> <osde@linux.microsoft.com> wrote:
>>
>> Hi Ard,
>>
>> On 3/1/2024 3:58 AM, Ard Biesheuvel wrote:
>>> Hi Oliver,
>>>
>>> On Tue, 27 Feb 2024 at 21:27, Oliver Smith-Denny
>>> <osde@linux.microsoft.com> wrote:
>>>>
>>>> When an ImageRecord is stored by ImagePropertiesRecordLib, it reports the
>>>> CodeSegmentSize as the SizeOfRawData from the image. However, the image
>>>> as loaded into memory is aligned to the SectionAlignment, so
>>>> SizeOfRawData is under the actual size in memory. This is important,
>>>> because the memory attributes table uses these image records to create
>>>> its entries and it will report that the alignment of an image is
>>>> incorrect, even though the actual image is correct.
>>>>
>>>> This was discovered on ARM64, which has a 64k runtime page granularity
>>>> alignment, which is backed by a 64k section alignment for
>>>> DXE_RUNTIME_DRIVERs. The runtime code and data was correctly being
>>>> loaded into memory, however the memory attribute table was incorrectly
>>>> reporting misaligned ranges to the OS, causing attributes to be
>>>> ignored for these sections for OSes using greater than 4k pages.
>>>>
>>>> This patch correctly aligns the CodeSegmentSize to the SectionAlignment
>>>> and the corresponding memory attribute table entries are now correctly
>>>> aligned and pointing to the right places in memory.
>>>>
>>>
>>> Can you explain how these can differ in the first place? Our flaky
>>> ELF-to-PE/COFF converter should never generate such images to begin
>>> with (which is probably how we ended up with this problem in the first
>>> place), so I  suppose this is native PE/COFF tooling emitting sections
>>> either using a non-1:1 file:memory mapping, or with unallocated holes
>>> in the file representation?
>>>
>>
>> This is an artifact of PE/COFF itself and is useful for having smaller
>> FW images. In PE/COFF we have the section alignment (which is how we get
>> loaded into memory) and the file alignment (how the actual file is
>> aligned). It is valid for these two to be different. For example, these
>> runtime DXE drivers, which are not XIP (which the case we do need the
>> section and file alignment to be the same, as we are executing from
>> the file image) can be a smaller size in the file, but when loaded into
>> memory we will relocate them and do the proper rebasing to set these on
>> 64k boundaries. Different toolchains have different ways of specifying
>> the two things, on gcc I have seen common-page-size affect the section
>> alignment and max-page-size affect both section and file alignment. For
>> msvc there are /ALIGN and /FILEALIGN commands which directly manipulate
>> these values.
>>
>> The issue here was not that we have different section and file
>> alignment, in fact, the issue still exists if section alignement ==
>> file alignment. This is because SizeOfRawData in the PE/COFF header is
>> the raw size of bytes used, not even page aligned. So no matter what,
>> the image records we were creating here had bad sizes being set which
>> do not match what the image loader was actually doing.
>>
> 
> IIUC the SizeOfRawData is the file view not the memory view, and must
> always be aligned to the FileAlignment.

I relooked at the spec, you are correct, SizeOfRawData is aligned to
the FileAlignment. So this is only a bug for a file with
SectionAlignment != FileAlignment.

> 
>> I do think there is a fair argument that would say the image loader
>> should create the image records when it loads images, since in the
>> end we want the record to match exactly what the image in memory is,
>> creating after the fact is a poor pattern.
>>
> 
> Yeah, no disagreement there.
> 
>>>> Cc: Liming Gao <gaoliming@byosoft.com.cn>
>>>> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
>>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>>> Cc: Sami Mujawar <sami.mujawar@arm.com>
>>>> Cc: Taylor Beebe <taylor.d.beebe@gmail.com>
>>>>
>>>> Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>
>>>> ---
>>>>    MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 2 +-
>>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
>>>> index e53ce086c54c..07ced0e54e38 100644
>>>> --- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
>>>> +++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
>>>> @@ -1090,7 +1090,7 @@ CreateImagePropertiesRecord (
>>>>          ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
>>>>
>>>>          ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageBase + Section[Index].VirtualAddress;
>>>> -      ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData;
>>>> +      ImageRecordCodeSection->CodeSegmentSize = ALIGN_VALUE (Section[Index].SizeOfRawData, SectionAlignment);
>>>>
>>>
>>> This should be the virtual size, not the file size, right?
>>
>> Correct, SectionAlignment is the alignment of the image as loaded in
>> memory, so in the case of a DXE runtime driver on ARM64, it will be
>> 64k.
>>
> 
> No, I mean we should not be using SizeOfRawData here but VirtualSize.
> 
> I understand this is unlikely to make a difference in practice, but
> VirtualSize may exceed SizeOfRawData by a wide margin, and we need the
> whole region to be covered.
> 

I see, yes I do believe VirtualSize could be used here instead. Two
things give me pause. One is that the PE spec states that SizeOfRawData
is rounded and VirtualSize is not, so that SizeOfRawData may be greater
than the VirtualSize in some cases (which seems incorrect).

The other is that the image loader partially uses VirtualSize when
loading:

https://github.com/tianocore/edk2/blob/918288ab5a7c3abe9c58d576ccc0ae32e2c7dea0/MdePkg/Library/BasePeCoffLib/BasePeCoff.c#L1399-L1400

However, when determining the size of a loaded image (and therefore the
number of pages to allocate) it will allocate an extra page:

https://github.com/tianocore/edk2/blob/918288ab5a7c3abe9c58d576ccc0ae32e2c7dea0/MdeModulePkg/Core/Dxe/Image/Image.c#L646-L652

as ImageSize here is:

https://github.com/tianocore/edk2/blob/918288ab5a7c3abe9c58d576ccc0ae32e2c7dea0/MdePkg/Library/BasePeCoffLib/BasePeCoff.c#L312

Which according to the spec, SizeOfImage is the size of the image as
loaded into memory and must be a multiple of section alignment.

So, reflecting on this, let me test with VirtualSize here, I think
that is the right value to use, the only time we would have a
SizeOfRawData that is greater than the VirtualSize would be if our
FileAlignment is greater than our SectionAlignment, which would be
a misconfiguration.

I do think the ImageLoader should also be fixed to only allocate
ImageSize number of pages (which should be the sum of the section
VirtualSizes + any headers that aren't included). Might as well not
waste an extra page for each image and then our image record code is
simpler as well (ensuring we are protecting the right pages).

I think this patch series should go in, as it is fixing an active bug,
but I will also take a look at the image loader creating the image
records and having a protocol it produces to retrieve the list, to
attempt to avoid issues like this in the future.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116340): https://edk2.groups.io/g/devel/message/116340
Mute This Topic: https://groups.io/mt/104610770/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  reply	other threads:[~2024-03-04 19:24 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-27 20:27 [edk2-devel][PATCH v1 0/3] MdeModulePkg: ImagePropertiesRecordLib Fixes Oliver Smith-Denny
2024-02-27 20:27 ` [edk2-devel][PATCH v1 1/3] MdeModulePkg: ImagePropertiesRecordLib: Use SectionAlignment for CodeSize Oliver Smith-Denny
2024-03-01 11:58   ` Ard Biesheuvel
2024-03-04 17:49     ` Oliver Smith-Denny
2024-03-04 18:54       ` Ard Biesheuvel
2024-03-04 19:24         ` Oliver Smith-Denny [this message]
     [not found]         ` <17B9A63355E03AE5.30946@groups.io>
2024-03-04 22:38           ` Oliver Smith-Denny
     [not found]           ` <17B9B0CE1BDDC06B.30946@groups.io>
2024-03-11 19:34             ` Oliver Smith-Denny
2024-03-12  8:32               ` Ard Biesheuvel
2024-03-12 14:38                 ` Oliver Smith-Denny
2024-02-27 20:27 ` [edk2-devel][PATCH v1 2/3] MdeModulePkg: ImagePropertiesRecordLib: Consolidate Usage Oliver Smith-Denny
2024-02-27 20:27 ` [edk2-devel][PATCH v1 3/3] MdeModulePkg: MemoryProtection: Use ImageRecordPropertiesLib Oliver Smith-Denny
     [not found] <20240227202721.30070-1-osde@...>
     [not found] ` <20240227202721.30070-2-osde@...>
     [not found]   ` <CAMj1kXGDCsFZmPsKe4GD1XdT+t9SKHVStNSx-FsA_YwBiVh6ng@...>
     [not found]     ` <5d95548d-d25f-4306-a271-a2960cc81ccf@...>
     [not found]       ` <CAMj1kXGsso6BjOajEgqE3AOC1ZSdStQmeYmCoJMQo_tK1QHTWw@...>
     [not found]         ` <531b3cfe-b57c-4b5a-97fd-45e428f97853@...>
2024-03-14  9:57           ` [edk2-devel][PATCH v1 1/3] MdeModulePkg: ImagePropertiesRecordLib: Use SectionAlignment for CodeSize Marvin Häuser
2024-03-14 14:45             ` Oliver Smith-Denny
2024-03-14 21:57               ` Marvin Häuser
2024-03-15 22:56                 ` Oliver Smith-Denny
2024-03-15 23:45                   ` Marvin Häuser
2024-03-16 15:47                     ` Oliver Smith-Denny

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=531b3cfe-b57c-4b5a-97fd-45e428f97853@linux.microsoft.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