[edk2-devel] ArmVirt and Self-Updating Code

Ard Biesheuvel ardb at kernel.org
Fri Jul 23 14:34:22 UTC 2021


On Fri, 23 Jul 2021 at 16:27, Marvin Häuser <mhaeuser at posteo.de> wrote:
>
>
>
> On 23.07.21 16:09, Ard Biesheuvel wrote:
> > On Fri, 23 Jul 2021 at 12:47, Marvin Häuser <mhaeuser at posteo.de> wrote:
> >> On 23.07.21 12:13, Ard Biesheuvel wrote:
> >>> On Fri, 23 Jul 2021 at 11:55, Marvin Häuser <mhaeuser at posteo.de> wrote:
...
> >>>> 2) emit a GOT, which ends up being converted to PE/COFF Relocations (->
> >>>> self-relocation), for global data that cannot be referenced relatively?
> >>>> Is there any way to know/force that no symbol in GOT is accessed up
> >>>> until the end of the self-relocation process?
>
> Do you maybe have one final comment regarding that second question,
> please? :)

The RELA section is not converted into PE/COFF relocations. This would
not achieve a lot, given that no prior PE/COFF loader exists to
process them. There is a snippet of asm code in the startup code that
processes the R_AARCH64_RELATIVE relocation entries before calling
into C code.

This also gives us the guarantee that no GOT indirections are
dereferenced, given that our asm code simply does not do that.

> Let's drop "GOT" and make it "any instruction that requires prior
> relocation to function correctly".
>

The thing to keep in mind here is that R_AARCH64_RELATIVE relocations
never target instructions, but only memory locations that carry
absolute addresses. This could be locations in .rodata or .data
(global vars carrying pointer values), or GOT entries.

> >>> It is not really a GOT. Actually, a GOT is undesirable, as it forces
> >>> global variables to be referenced via an absolute address, even when a
> >>> relative reference could be used.
> >> Hmm, the GCC docs say a GOT is used for "all constant addresses" (I took
> >> it as "absolute"?), it is kind of vague. I understood it this way:
> >> 1) no-pie emits relocations that can target the .text and .data sections
> >> for instructions that embed and variables that hold an absolute address
> >> (I thought this was RELA?)
> >> 2) pie emits a GOT such that there are no relocations as described in
> >> 1), because all absolute addresses are indirected by GOT (just GOT
> >> references are relocated)
> >>
> > Correct. And this works really well for shared libraries, where all
> > text and data sections can be shared between processes, as they will
> > not be modified by the loader. All locations targeted by relocations
> > will be nicely lumped together in the GOT.
> >
> > However, for bare metal style programs, there is no sharing, and there
> > is no advantage to lumping anything together. It is much better to use
> > relative references where possible, and simply apply relocations
> > wherever needed across the text and data sections,
> >
> >> If I understood the process right, but the term (GOT) is wrong, sorry,
> >> that is what I gathered from the docs. :)
> >> I have a x86 + PE background, so ARM + ELF is a bit of a learning curve...
> >>
> > The GOT is a special data structure used for implicit variable
> > accesses, i.e., global vars used in the code. Statically initialized
> > pointer variables are the other category, which are not code, and for
> > which the same considerations do not apply, given that the right value
> > simply needs to be stored in the variable before the program starts.
> >
> >>> For instance, a statically initialized pointer always carries an
> >>> absolute address, and so it always needs an entry in the RELA table
> >>>
> >>> E.g.,
> >>>
> >>> int foo = 10; // external linkage
> >>> static int *bar = &foo;
> >>>
> >>> In this case, there is no way to use relative addressing because the
> >>> address of foo is taken at build time.
> >>>
> >>> However, if bar would be something like
> >>>
> >>> static int *bar() { return &foo; }
> >>>
> >>> the address is only taken at runtime, and the compiler can use a
> >>> relative reference instead, and no RELA entry is needed. With a GOT,
> >>> we force the compiler to allocate a variable that holds the absolute
> >>> address, which we would prefer to avoid.
> >> And this is not forced by whatever table -fpie uses, as per my
> >> understanding above?
> >>
> > The selection of 'code model' as it is called is controlled by GCC's
> > -mcmodel= argument, which defaults to 'small' on AArch64, regardless
> > of whether you use PIC/PIE or not.
>
> Aha, makes sense, thanks!
>
> Best regards,
> Marvin
>
> >>>>>> “Now, StandaloneMmPkg has similar (self-)relocation code too:https://github.com/tianocore/edk2/blob/17143c4837393d42c484b42d1789b85b2cff1aaf/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c#L379-L386
> >>>>>>
> >>>>>> Because I cannot find such elsewhere, I assume it must be for the same ARM virtualised environment as above.
> >>>>> No.
> >>>>>
> >>>>>> The binary it applies the Relocations to is documented to be the Standalone MM core, but in fact SecCore is located:
> >>>>>>
> >>>>>> https://github.com/tianocore/edk2/blob/17143c4837393d42c484b42d1789b85b2cff1aaf/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/SetPermissions.c#L131-L158
> >>>> As per your comments below, I think SecCore should not be located here.
> >>>> Is the Standalone MM core of *type* SecCore in the FFS (without *being*
> >>>> SecCore)? This confused me the most.
> >>>>
> >>> If the FFS SecCore section type is used here, it does not mean that
> >>> the image is a SEC image in the strict PI sense.
> >>>
> >>> Perhaps we were just too lazy to add a new type to the FFS spec?
> >> That is what I meant to imply with the middle question (well, not
> >> necessarily "lazy", for ARM there simply seems to not be any reason to
> >> distinguish if the environments are fully separate), just wanted to make
> >> sure I understand what the code does before modifying it.
> >>
> >> Thank you again!
> >>
> >> Best regards,
> >> Marvin
> >>
> >>>>>> “This yields the following questions to me:
> >>>>>>
> >>>>>> 1) What even invokes Standalone MM on ARM? It is documented it is spawned during SEC, but I could not find any actual invocation.
> >>>>>>
> >>>>> It is not spawned by the normal world code that runs UEFI. It is a
> >>>>> secure world component that runs in a completely different execution
> >>>>> context (TrustZone). The code does run with the MMU enabled from the
> >>>>> start, but running from an a priori fixed offset was considered to be
> >>>>> a security hazard, so we added self relocation support.
> >>>>>
> >>>>> The alternative would have been to add metadata to the StMmCore
> >>>>> component that can be interpreted by the secure world component that
> >>>>> loads it, but this would go beyond any existing specs, and make
> >>>>> portability more problematic.
> >>>>>
> >>>>>> 2) Why does Standalone MM (self-)relocation locate SecCore? Should it not already have been relocated with the code from ArmPlatformPkg? Is Standalone MM embedded into ARM SecCore?
> >>>>>>
> >>>>> No and no. Standalone MM has nothing to do with the code that runs as
> >>>>> part of UEFI itself. ArmPlatformPkg is completely separate from
> >>>>> StandaloneMmPkg.
> >>>>>
> >>>>>> 3) Why is SecCore the only module relocated? Are all others guaranteed to be "properly" loaded?
> >>>>>>
> >>>>> SecCore contains a PE/COFF loader, so all subsequent modules are
> >>>>> loaded normally. This is similar to the ArmVirtQemuKernel
> >>>>> self-relocating SEC module, which only relocates itself in this
> >>>>> manner, and relies on standard PE/COFF metadata for loading other
> >>>>> modules.
> >>>> Interesting... this definitely is vastly different from the x86 side of
> >>>> things. I think most things became very clear. Thanks a lot!
> >>>>
> >>>>>> 4) Is there maybe some high-level documented about the ARM boot flow? It seems to be significantly different from the x86 routes quite vastly.”
> >>>>>>
> >>>>> trustedfirmware.org may have some useful documentation.
> >>>> I'll check it some time, hopefully this weekend. Thanks!
> >>>>
> >>> My pleasure.
>


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#78137): https://edk2.groups.io/g/devel/message/78137
Mute This Topic: https://groups.io/mt/84380729/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list