From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by mx.groups.io with SMTP id smtpd.web08.8983.1627835623891013263 for ; Sun, 01 Aug 2021 09:33:44 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=iJcrqX5U; spf=pass (domain: kernel.org, ip: 198.145.29.99, mailfrom: ardb@kernel.org) Received: by mail.kernel.org (Postfix) with ESMTPSA id 33574610D0 for ; Sun, 1 Aug 2021 16:33:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1627835623; bh=8Z6VfZtVZ47FacGzpXdUhxw8gDBYPGXy7on4r/cyfpc=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=iJcrqX5Uy3f5rRgtaEhSGTTeZPtINiDAG87p5Ke7o51CUT/r0u8BFktlu7W6rZwQD CsRj4Xg+b5WGZlsEGYM+B60nAfBsxFX9zOk55VlLhijkbC0OGlh9mBk4/DIm+fbICv u7Wmjl7F3UHAAnEA83IHdvBdUaPZ5WkKR/0aXhDOH9fSq6fTsHWyiWqmEWoLOtjdp1 +SUNxjetPWpEveYEzejgzhlNEKtOo0ikT0pC2nUMqtYnPvm/JIBS7wFW1tJ0PQIuRF G8Vff18rO9l9BdZOzK+XnceqdyFunTn35Wctw0cjRnN5WopOoB7BiSkReWGCbw48z7 hQUKRkiGDwsYw== Received: by mail-oi1-f182.google.com with SMTP id q6so21210447oiw.7 for ; Sun, 01 Aug 2021 09:33:43 -0700 (PDT) X-Gm-Message-State: AOAM532umsHFJr2+u3c5VVzfJmlQcFQR/8Nsk+r9+D5LcKznnAKVAf+3 Hw2OCkFIyPk/JOOK9UF3rQXFzA7n1MHL9sPgVUs= X-Google-Smtp-Source: ABdhPJzfW8qCmrSnXtfXXaN+jyWgR0bNGGDW8KC8YrKyrUsJXlL3tTSqFoeDBveGHmCrPrWqfCsbDf0JUDfRYEFtuZk= X-Received: by 2002:a05:6808:2219:: with SMTP id bd25mr3983062oib.33.1627835622411; Sun, 01 Aug 2021 09:33:42 -0700 (PDT) MIME-Version: 1.0 References: <36b32106-da0e-bfd5-10cf-6c9bb86173d1@posteo.de> <39afb072-3e01-6946-9387-e414a8f62f8d@posteo.de> In-Reply-To: From: "Ard Biesheuvel" Date: Sun, 1 Aug 2021 18:33:31 +0200 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: ArmVirt and Self-Updating Code To: =?UTF-8?Q?Marvin_H=C3=A4user?= Cc: Bret Barkelew , Thomas Abraham , "Ard Biesheuvel (TianoCore)" , "Lindholm, Leif" , Laszlo Ersek , Sami Mujawar , "devel@edk2.groups.io" , nd Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, 31 Jul 2021 at 21:08, Marvin H=C3=A4user wrote= : > > On 23.07.21 16:34, Ard Biesheuvel wrote: > > On Fri, 23 Jul 2021 at 16:27, Marvin H=C3=A4user w= rote: > >> > >> > >> On 23.07.21 16:09, Ard Biesheuvel wrote: > >>> On Fri, 23 Jul 2021 at 12:47, Marvin H=C3=A4user = wrote: > >>>> On 23.07.21 12:13, Ard Biesheuvel wrote: > >>>>> On Fri, 23 Jul 2021 at 11:55, Marvin H=C3=A4user wrote: > > ... > >>>>>> 2) emit a GOT, which ends up being converted to PE/COFF Relocation= s (-> > >>>>>> self-relocation), for global data that cannot be referenced relati= vely? > >>>>>> Is there any way to know/force that no symbol in GOT is accessed u= p > >>>>>> 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. > > I searched for said ASM code till my fingers fell asleep and at last > found this: > https://github.com/tianocore/edk2/commit/b16fd231f6d8124fa05a0f086840934b= 8709faf9#diff-3d563cc4775c7720900f4895bf619eed06291044aaa277fcc57eddc761835= 1a1L12-R148 > > If I understand the commit message correctly, it is basically "pray the > C code does not use globals at all", which is fair enough, so maybe I > should document this in my proposed new library? I trust that this is > enough of a constraint for both ARM and AArch64, because I do not know > them at all. > The C code can use globals, but not global pointer variables. But you are right, this is not very robust at all. > What worries me is that StandaloneMmCore has no such ASM entry point at > all and instead it's just executing C directly. Also, it is not passed > the "-fno-jump-tables" flag that is commented to be important in the > commit linked above. > This is because the StandaloneMmCore is built with -fpie, which already implies -fno-jump-tables, although I suppose this may not offer complete coverage for BASE libraries that are pulled into the link. > Best regards, > Marvin > > > 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 force= s > >>>>> global variables to be referenced via an absolute address, even whe= n 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 sect= ions > >>>> for instructions that embed and variables that hold an absolute addr= ess > >>>> (I thought this was RELA?) > >>>> 2) pie emits a GOT such that there are no relocations as described i= n > >>>> 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 ther= e > >>> is no advantage to lumping anything together. It is much better to us= e > >>> 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, sorr= y, > >>>> that is what I gathered from the docs. :) > >>>> I have a x86 + PE background, so ARM + ELF is a bit of a learning cu= rve... > >>>> > >>> 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 valu= e > >>> 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 =3D 10; // external linkage > >>>>> static int *bar =3D &foo; > >>>>> > >>>>> In this case, there is no way to use relative addressing because th= e > >>>>> 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 absolut= e > >>>>> 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=3D argument, which defaults to 'small' on AArch64, regardles= s > >>> of whether you use PIC/PIE or not. > >> Aha, makes sense, thanks! > >> > >> Best regards, > >> Marvin > >> > >>>>>>>> =E2=80=9CNow, StandaloneMmPkg has similar (self-)relocation code= too:https://github.com/tianocore/edk2/blob/17143c4837393d42c484b42d1789b85= b2cff1aaf/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/Standa= loneMmCoreEntryPoint.c#L379-L386 > >>>>>>>> > >>>>>>>> Because I cannot find such elsewhere, I assume it must be for th= e 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/17143c4837393d42c484b42d1= 789b85b2cff1aaf/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 *b= eing* > >>>>>> 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 > >>>> > >>>>>>>> =E2=80=9CThis yields the following questions to me: > >>>>>>>> > >>>>>>>> 1) What even invokes Standalone MM on ARM? It is documented it i= s 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 execut= ion > >>>>>>> context (TrustZone). The code does run with the MMU enabled from = the > >>>>>>> start, but running from an a priori fixed offset was considered t= o 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 t= hat > >>>>>>> loads it, but this would go beyond any existing specs, and make > >>>>>>> portability more problematic. > >>>>>>> > >>>>>>>> 2) Why does Standalone MM (self-)relocation locate SecCore? Shou= ld 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 run= s as > >>>>>>> part of UEFI itself. ArmPlatformPkg is completely separate from > >>>>>>> StandaloneMmPkg. > >>>>>>> > >>>>>>>> 3) Why is SecCore the only module relocated? Are all others guar= anteed 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 si= de 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 vast= ly.=E2=80=9D > >>>>>>>> > >>>>>>> trustedfirmware.org may have some useful documentation. > >>>>>> I'll check it some time, hopefully this weekend. Thanks! > >>>>>> > >>>>> My pleasure. >