static grub_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];
-
/* Initialize canary in case there is no RNG protocol. */
grub_addr_t __stack_chk_guard = (grub_addr_t) GRUB_STACK_PROTECTOR_INIT;
while (1);
}
-static void
-stack_protector_init (void)
+grub_addr_t
+grub_stack_protector_init (void)
{
grub_efi_rng_protocol_t *rng;
if (rng != NULL)
{
grub_efi_status_t status;
+ grub_addr_t guard = 0;
- status = rng->get_rng (rng, NULL, sizeof (stack_chk_guard_buf),
- stack_chk_guard_buf);
+ status = rng->get_rng (rng, NULL, sizeof (guard) - 1,
+ (grub_efi_uint8_t *) &guard);
if (status == GRUB_EFI_SUCCESS)
- grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof (__stack_chk_guard));
+ return guard;
}
-}
-#else
-static void
-stack_protector_init (void)
-{
+ return 0;
}
#endif
grub_addr_t grub_modbase;
-__attribute__ ((__optimize__ ("-fno-stack-protector"))) void
+void
grub_efi_init (void)
{
grub_modbase = grub_efi_section_addr ("mods");
messages. */
grub_console_init ();
- stack_protector_init ();
-
/* Initialize the memory management system. */
grub_efi_mm_init ();
*/
#include <grub/kernel.h>
+#include <grub/stack_protector.h>
#include <grub/misc.h>
#include <grub/symbol.h>
#include <grub/dl.h>
void __attribute__ ((noreturn))
grub_main (void)
{
+#ifdef GRUB_STACK_PROTECTOR
+ /*
+ * This call should only be made from a function that does not return because
+ * functions that return will get instrumented to check that the stack cookie
+ * does not change and this call will change the stack cookie. Thus a stack
+ * guard failure will be triggered.
+ */
+ grub_update_stack_guard ();
+#endif
+
/* First of all, initialize the machine. */
grub_machine_init ();
static grub_addr_t __attribute__ ((weakref("__stack_chk_guard"))) EXPORT_VAR (_stack_chk_guard);
static void __attribute__ ((noreturn, weakref("__stack_chk_fail"))) EXPORT_FUNC (_stack_chk_fail) (void);
#endif
+
+extern grub_addr_t grub_stack_protector_init (void);
+
+static inline __attribute__((__always_inline__))
+void grub_update_stack_guard (void)
+{
+ grub_addr_t guard;
+
+ guard = grub_stack_protector_init ();
+ if (guard)
+ __stack_chk_guard = guard;
+}
#endif
#endif /* GRUB_STACK_PROTECTOR_H */