* [PATCH] arm*: efi: drop permanent mapping of the UEFI System table
@ 2016-02-22 14:59 Ard Biesheuvel
[not found] ` <1456153179-27214-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
0 siblings, 1 reply; 6+ messages in thread
From: Ard Biesheuvel @ 2016-02-22 14:59 UTC (permalink / raw)
To: linux-efi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io
Cc: leif.lindholm-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
Ard Biesheuvel
The permanent, writable mapping of the UEFI System table is only
referenced during invocations of UEFI Runtime Services, at which time
the UEFI virtual mapping is available, which also covers the system
table (since the runtime services themselves need access to it)
So instead of creating this permanent mapping, record the virtual
address of the system table inside the UEFI virtual mapping, and
use that instead. This protects the contents of the system table
from inadvertent (or deliberate) modification.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
Something I spotted while working on the memory attribute table stuff.
Since this is low hanging fruit and otherwise completely unrelated to it,
I am posting it as a separate patch
drivers/firmware/efi/arm-init.c | 2 ++
drivers/firmware/efi/arm-runtime.c | 24 ++++++++++----------
2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index 022f11157acd..e995d61da747 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -85,6 +85,8 @@ static int __init uefi_init(void)
efi.systab->hdr.revision >> 16,
efi.systab->hdr.revision & 0xffff);
+ efi.runtime_version = efi.systab->hdr.revision;
+
/* Show what we know for posterity */
c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor),
sizeof(vendor) * sizeof(efi_char16_t));
diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
index 848ede1587dc..6ce13d6b7122 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -64,6 +64,16 @@ static bool __init efi_virtmap_init(void)
&phys, ret);
return false;
}
+ /*
+ * If this entry covers the address of the UEFI system table,
+ * calculate and record its virtual address.
+ */
+ if (efi_system_table >= phys &&
+ efi_system_table < phys + (md->num_pages * EFI_PAGE_SIZE)) {
+ efi.systab = (void *)(efi_system_table - phys +
+ md->virt_addr);
+ set_bit(EFI_SYSTEM_TABLES, &efi.flags);
+ }
}
if (efi_memattr_apply_permissions(&efi_mm, efi_set_mapping_permissions))
@@ -102,16 +112,8 @@ static int __init arm_enable_runtime_services(void)
memmap.map_end = memmap.map + mapsize;
efi.memmap = &memmap;
- efi.systab = (__force void *)ioremap_cache(efi_system_table,
- sizeof(efi_system_table_t));
- if (!efi.systab) {
- pr_err("Failed to remap EFI System Table\n");
- return -ENOMEM;
- }
- set_bit(EFI_SYSTEM_TABLES, &efi.flags);
-
- if (!efi_virtmap_init()) {
- pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
+ if (!efi_virtmap_init() || !efi_enabled(EFI_SYSTEM_TABLES)) {
+ pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n");
return -ENOMEM;
}
@@ -119,8 +121,6 @@ static int __init arm_enable_runtime_services(void)
efi_native_runtime_setup();
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
- efi.runtime_version = efi.systab->hdr.revision;
-
return 0;
}
early_initcall(arm_enable_runtime_services);
--
2.5.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] arm*: efi: drop permanent mapping of the UEFI System table
[not found] ` <1456153179-27214-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-02-22 15:43 ` Mark Rutland
2016-02-22 15:56 ` Ard Biesheuvel
0 siblings, 1 reply; 6+ messages in thread
From: Mark Rutland @ 2016-02-22 15:43 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A
On Mon, Feb 22, 2016 at 03:59:39PM +0100, Ard Biesheuvel wrote:
> The permanent, writable mapping of the UEFI System table is only
> referenced during invocations of UEFI Runtime Services, at which time
> the UEFI virtual mapping is available, which also covers the system
> table (since the runtime services themselves need access to it)
I'm not sure it's strictly true that the runtime services themselves
need access to the system table. Why would that be necessary? Are
runtime services mandated to indirect calls via the system table?
I would expect that the EFI system table and EFI runtime services table
are not in EfiConventionalMemory, but I'm not sure that we have the
guarnatee that they're both in EfiRuntimeServices* memory..
>From the spec, I couldn't find a mandate that the system table (nor the
runtime services table) were in a region of EfiRuntimeServicesData
memory. I suspect I'm looking in the wrong place...
> So instead of creating this permanent mapping, record the virtual
> address of the system table inside the UEFI virtual mapping, and
> use that instead. This protects the contents of the system table
> from inadvertent (or deliberate) modification.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>
> Something I spotted while working on the memory attribute table stuff.
> Since this is low hanging fruit and otherwise completely unrelated to it,
> I am posting it as a separate patch
>
> drivers/firmware/efi/arm-init.c | 2 ++
> drivers/firmware/efi/arm-runtime.c | 24 ++++++++++----------
> 2 files changed, 14 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
> index 022f11157acd..e995d61da747 100644
> --- a/drivers/firmware/efi/arm-init.c
> +++ b/drivers/firmware/efi/arm-init.c
> @@ -85,6 +85,8 @@ static int __init uefi_init(void)
> efi.systab->hdr.revision >> 16,
> efi.systab->hdr.revision & 0xffff);
>
> + efi.runtime_version = efi.systab->hdr.revision;
> +
> /* Show what we know for posterity */
> c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor),
> sizeof(vendor) * sizeof(efi_char16_t));
> diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
> index 848ede1587dc..6ce13d6b7122 100644
> --- a/drivers/firmware/efi/arm-runtime.c
> +++ b/drivers/firmware/efi/arm-runtime.c
> @@ -64,6 +64,16 @@ static bool __init efi_virtmap_init(void)
> &phys, ret);
> return false;
> }
> + /*
> + * If this entry covers the address of the UEFI system table,
> + * calculate and record its virtual address.
> + */
> + if (efi_system_table >= phys &&
> + efi_system_table < phys + (md->num_pages * EFI_PAGE_SIZE)) {
> + efi.systab = (void *)(efi_system_table - phys +
> + md->virt_addr);
> + set_bit(EFI_SYSTEM_TABLES, &efi.flags);
> + }
It seems very odd to me to set this given it's currently unused, and we
don't have permanent access to the table. That sounds like we're just
setting ourselves up for future fragility as users appear.
Thanks,
Mark.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] arm*: efi: drop permanent mapping of the UEFI System table
2016-02-22 15:43 ` Mark Rutland
@ 2016-02-22 15:56 ` Ard Biesheuvel
[not found] ` <CAKv+Gu_pnjL557dE1xez_y2tESOjZj9_2XEbNtm_b4yAA-WdYg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 6+ messages in thread
From: Ard Biesheuvel @ 2016-02-22 15:56 UTC (permalink / raw)
To: Mark Rutland, Matt Fleming
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Leif Lindholm
On 22 February 2016 at 16:43, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
> On Mon, Feb 22, 2016 at 03:59:39PM +0100, Ard Biesheuvel wrote:
>> The permanent, writable mapping of the UEFI System table is only
>> referenced during invocations of UEFI Runtime Services, at which time
>> the UEFI virtual mapping is available, which also covers the system
>> table (since the runtime services themselves need access to it)
>
> I'm not sure it's strictly true that the runtime services themselves
> need access to the system table. Why would that be necessary? Are
> runtime services mandated to indirect calls via the system table?
>
They don't need access per se, but they are allowed to reference it,
and so the memory remapping layer must make it accessible after
SetVirtualAddressMap(). The spec lists explicitly which fields are
still valid after ExitBootServices()
> I would expect that the EFI system table and EFI runtime services table
> are not in EfiConventionalMemory, but I'm not sure that we have the
> guarnatee that they're both in EfiRuntimeServices* memory..
>
SetVirtualAddressMap() is a runtime service, and one of the things it
does is update the pointers in the system table, hence it must be
located in RuntimeService memory, because anything else may be gone by
this time.
> From the spec, I couldn't find a mandate that the system table (nor the
> runtime services table) were in a region of EfiRuntimeServicesData
> memory. I suspect I'm looking in the wrong place...
>
We should clarify it if it is not clear (or if I turn out to be wrong)
>> So instead of creating this permanent mapping, record the virtual
>> address of the system table inside the UEFI virtual mapping, and
>> use that instead. This protects the contents of the system table
>> from inadvertent (or deliberate) modification.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
>>
>> Something I spotted while working on the memory attribute table stuff.
>> Since this is low hanging fruit and otherwise completely unrelated to it,
>> I am posting it as a separate patch
>>
>> drivers/firmware/efi/arm-init.c | 2 ++
>> drivers/firmware/efi/arm-runtime.c | 24 ++++++++++----------
>> 2 files changed, 14 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
>> index 022f11157acd..e995d61da747 100644
>> --- a/drivers/firmware/efi/arm-init.c
>> +++ b/drivers/firmware/efi/arm-init.c
>> @@ -85,6 +85,8 @@ static int __init uefi_init(void)
>> efi.systab->hdr.revision >> 16,
>> efi.systab->hdr.revision & 0xffff);
>>
>> + efi.runtime_version = efi.systab->hdr.revision;
>> +
>> /* Show what we know for posterity */
>> c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor),
>> sizeof(vendor) * sizeof(efi_char16_t));
>> diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
>> index 848ede1587dc..6ce13d6b7122 100644
>> --- a/drivers/firmware/efi/arm-runtime.c
>> +++ b/drivers/firmware/efi/arm-runtime.c
>> @@ -64,6 +64,16 @@ static bool __init efi_virtmap_init(void)
>> &phys, ret);
>> return false;
>> }
>> + /*
>> + * If this entry covers the address of the UEFI system table,
>> + * calculate and record its virtual address.
>> + */
>> + if (efi_system_table >= phys &&
>> + efi_system_table < phys + (md->num_pages * EFI_PAGE_SIZE)) {
>> + efi.systab = (void *)(efi_system_table - phys +
>> + md->virt_addr);
>> + set_bit(EFI_SYSTEM_TABLES, &efi.flags);
>> + }
>
> It seems very odd to me to set this given it's currently unused, and we
> don't have permanent access to the table. That sounds like we're just
> setting ourselves up for future fragility as users appear.
>
I wondered about the purpose as well. It is only ever set, and never
tested (until this patch)
@Matt: any thoughts?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] arm*: efi: drop permanent mapping of the UEFI System table
[not found] ` <CAKv+Gu_pnjL557dE1xez_y2tESOjZj9_2XEbNtm_b4yAA-WdYg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-02-22 16:09 ` Mark Rutland
2016-02-22 16:24 ` Ard Biesheuvel
2016-02-24 16:05 ` Matt Fleming
1 sibling, 1 reply; 6+ messages in thread
From: Mark Rutland @ 2016-02-22 16:09 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Matt Fleming, linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Leif Lindholm
On Mon, Feb 22, 2016 at 04:56:57PM +0100, Ard Biesheuvel wrote:
> On 22 February 2016 at 16:43, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
> > On Mon, Feb 22, 2016 at 03:59:39PM +0100, Ard Biesheuvel wrote:
> >> The permanent, writable mapping of the UEFI System table is only
> >> referenced during invocations of UEFI Runtime Services, at which time
> >> the UEFI virtual mapping is available, which also covers the system
> >> table (since the runtime services themselves need access to it)
> >
> > I'm not sure it's strictly true that the runtime services themselves
> > need access to the system table. Why would that be necessary? Are
> > runtime services mandated to indirect calls via the system table?
> >
>
> They don't need access per se, but they are allowed to reference it,
> and so the memory remapping layer must make it accessible after
> SetVirtualAddressMap(). The spec lists explicitly which fields are
> still valid after ExitBootServices()
I was language-lawyering ;)
I appreciate that they _can_, I just didn't think it was true that they
_must_ (i.e. that they always "need to access it"). Per the below that's
likely moot.
> SetVirtualAddressMap() is a runtime service, and one of the things it
> does is update the pointers in the system table, hence it must be
> located in RuntimeService memory, because anything else may be gone by
> this time.
Good point. That does imply that it must be in EfiRuntimeServices*
memory.
> > From the spec, I couldn't find a mandate that the system table (nor the
> > runtime services table) were in a region of EfiRuntimeServicesData
> > memory. I suspect I'm looking in the wrong place...
>
> We should clarify it if it is not clear (or if I turn out to be wrong)
I'm hoping that I've simply missed something. Perhaps the implication
above was intentional, albeit rather opaque.
Otherwise, I certainly agree a clarification would be a good thing!
Mark.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] arm*: efi: drop permanent mapping of the UEFI System table
2016-02-22 16:09 ` Mark Rutland
@ 2016-02-22 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 6+ messages in thread
From: Ard Biesheuvel @ 2016-02-22 16:24 UTC (permalink / raw)
To: Mark Rutland
Cc: Matt Fleming, linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Leif Lindholm
On 22 February 2016 at 17:09, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
> On Mon, Feb 22, 2016 at 04:56:57PM +0100, Ard Biesheuvel wrote:
>> On 22 February 2016 at 16:43, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
>> > On Mon, Feb 22, 2016 at 03:59:39PM +0100, Ard Biesheuvel wrote:
>> >> The permanent, writable mapping of the UEFI System table is only
>> >> referenced during invocations of UEFI Runtime Services, at which time
>> >> the UEFI virtual mapping is available, which also covers the system
>> >> table (since the runtime services themselves need access to it)
>> >
>> > I'm not sure it's strictly true that the runtime services themselves
>> > need access to the system table. Why would that be necessary? Are
>> > runtime services mandated to indirect calls via the system table?
>> >
>>
>> They don't need access per se, but they are allowed to reference it,
>> and so the memory remapping layer must make it accessible after
>> SetVirtualAddressMap(). The spec lists explicitly which fields are
>> still valid after ExitBootServices()
>
> I was language-lawyering ;)
>
> I appreciate that they _can_, I just didn't think it was true that they
> _must_ (i.e. that they always "need to access it"). Per the below that's
> likely moot.
>
Runtime services drivers must call ConvertPointer() to translate the
pointer variables in their global state to their virtual equivalents.
So unless a Runtime driver does not have such state at all, it needs
access to the runtime services table, which is usually retrieved
through the system table. So yes, you're right. And yes, it's moot :-)
>> SetVirtualAddressMap() is a runtime service, and one of the things it
>> does is update the pointers in the system table, hence it must be
>> located in RuntimeService memory, because anything else may be gone by
>> this time.
>
> Good point. That does imply that it must be in EfiRuntimeServices*
> memory.
>
>> > From the spec, I couldn't find a mandate that the system table (nor the
>> > runtime services table) were in a region of EfiRuntimeServicesData
>> > memory. I suspect I'm looking in the wrong place...
>>
>> We should clarify it if it is not clear (or if I turn out to be wrong)
>
> I'm hoping that I've simply missed something. Perhaps the implication
> above was intentional, albeit rather opaque.
>
> Otherwise, I certainly agree a clarification would be a good thing!
>
> Mark.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] arm*: efi: drop permanent mapping of the UEFI System table
[not found] ` <CAKv+Gu_pnjL557dE1xez_y2tESOjZj9_2XEbNtm_b4yAA-WdYg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-02-22 16:09 ` Mark Rutland
@ 2016-02-24 16:05 ` Matt Fleming
1 sibling, 0 replies; 6+ messages in thread
From: Matt Fleming @ 2016-02-24 16:05 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Mark Rutland, linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Leif Lindholm
On Mon, 22 Feb, at 04:56:57PM, Ard Biesheuvel wrote:
> On 22 February 2016 at 16:43, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
> > On Mon, Feb 22, 2016 at 03:59:39PM +0100, Ard Biesheuvel wrote:
> >> diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
> >> index 848ede1587dc..6ce13d6b7122 100644
> >> --- a/drivers/firmware/efi/arm-runtime.c
> >> +++ b/drivers/firmware/efi/arm-runtime.c
> >> @@ -64,6 +64,16 @@ static bool __init efi_virtmap_init(void)
> >> &phys, ret);
> >> return false;
> >> }
> >> + /*
> >> + * If this entry covers the address of the UEFI system table,
> >> + * calculate and record its virtual address.
> >> + */
> >> + if (efi_system_table >= phys &&
> >> + efi_system_table < phys + (md->num_pages * EFI_PAGE_SIZE)) {
> >> + efi.systab = (void *)(efi_system_table - phys +
> >> + md->virt_addr);
> >> + set_bit(EFI_SYSTEM_TABLES, &efi.flags);
> >> + }
> >
> > It seems very odd to me to set this given it's currently unused, and we
> > don't have permanent access to the table. That sounds like we're just
> > setting ourselves up for future fragility as users appear.
> >
>
> I wondered about the purpose as well. It is only ever set, and never
> tested (until this patch)
>
> @Matt: any thoughts?
Good question. EFI_SYSTEM_TABLES was introduced over 4 years ago, but
it looks like it has never had any users. I don't remember why I added
it, probably just be to be "complete" since we had bits for all the
other tables.
If somebody wants to rip it out, I wouldn't object.
To be fair, we don't have permanent access to any of the tables - you
always have to switch to the dedicated EFI page tables before
accessing regions.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-02-24 16:05 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-22 14:59 [PATCH] arm*: efi: drop permanent mapping of the UEFI System table Ard Biesheuvel
[not found] ` <1456153179-27214-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-22 15:43 ` Mark Rutland
2016-02-22 15:56 ` Ard Biesheuvel
[not found] ` <CAKv+Gu_pnjL557dE1xez_y2tESOjZj9_2XEbNtm_b4yAA-WdYg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-02-22 16:09 ` Mark Rutland
2016-02-22 16:24 ` Ard Biesheuvel
2016-02-24 16:05 ` Matt Fleming
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).