kern/efi: Add initial stack protector implementation

It works only on UEFI platforms but can be quite easily extended to
others architectures and platforms if needed.

Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Marco A Benatto <mbenatto@redhat.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
This commit is contained in:
Chris Coulson authored and Daniel Kiper committed 2021-03-02 15:54:19 +01:00
1 parent 4ea7bae51f
commit 133d73079c
6 files changed
+179 -7

No files matched your search

+54
View File
@@ -27,6 +27,58 @@
#include <grub/env.h>
#include <grub/mm.h>
#include <grub/kernel.h>
#include <grub/stack_protector.h>
#ifdef GRUB_STACK_PROTECTOR
static grub_efi_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
/*
* Don't put this on grub_efi_init()'s local stack to avoid it
* getting a stack check.
*/
static grub_efi_uint8_t stack_chk_guard_buf[32];
grub_addr_t __stack_chk_guard;
void __attribute__ ((noreturn))
__stack_chk_fail (void)
{
/*
* Assume it's not safe to call into EFI Boot Services. Sorry, that
* means no console message here.
*/
do
{
/* Do not optimize out the loop. */
asm volatile ("");
}
while (1);
}
static void
stack_protector_init (void)
{
grub_efi_rng_protocol_t *rng;
/* Set up the stack canary. Make errors here non-fatal for now. */
rng = grub_efi_locate_protocol (&rng_protocol_guid, NULL);
if (rng != NULL)
{
grub_efi_status_t status;
status = efi_call_4 (rng->get_rng, rng, NULL, sizeof (stack_chk_guard_buf),
stack_chk_guard_buf);
if (status == GRUB_EFI_SUCCESS)
grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof (__stack_chk_guard));
}
}
#else
static void
stack_protector_init (void)
{
}
#endif
grub_addr_t grub_modbase;
@@ -38,6 +90,8 @@ grub_efi_init (void)
messages. */
grub_console_init ();
stack_protector_init ();
/* Initialize the memory management system. */
grub_efi_mm_init ();