]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
efi: Generate stack protector canary at build time if urandom is available
authorGlenn Washburn <development@efficientek.com>
Tue, 19 Dec 2023 06:00:00 +0000 (00:00 -0600)
committerDaniel Kiper <daniel.kiper@oracle.com>
Wed, 20 Dec 2023 13:31:50 +0000 (14:31 +0100)
Generating the canary at build time allows the canary to be different for
every build which could limit the effectiveness of certain exploits.
Fallback to the statically generated random bytes if /dev/urandom is not
readable, e.g. Windows.

On 32-bit architectures, which use a 32-bit canary, reduce the canary to
4 bytes with one byte being NUL to filter out string buffer overflow attacks.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
config.h.in
configure.ac
grub-core/kern/efi/init.c

index 4d1e50eba79cef6086cea000ed51bb4302bfddd6..9b1d39971858778c8fb499675c3e5b287f8a0315 100644 (file)
@@ -64,6 +64,8 @@
 #  define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@"
 #  define GRUB_PLATFORM "@GRUB_PLATFORM@"
 
+#  define GRUB_STACK_PROTECTOR_INIT @GRUB_STACK_PROTECTOR_INIT@
+
 #  define RE_ENABLE_I18N 1
 
 #  define _GNU_SOURCE 1
index c1b98b13de38345476474760e53980c1e18ba5fa..b8c5c78d53eadb929c137e09bf54d514d345bb45 100644 (file)
@@ -1438,6 +1438,26 @@ else
     AC_MSG_ERROR([invalid value $enable_stack_protector for --enable-stack-protector])
   fi
   TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DGRUB_STACK_PROTECTOR=1"
+
+  if test -r /dev/urandom; then
+     # Generate the 8 byte stack protector canary at build time if /dev/urandom
+     # is able to be read. The first byte should be NUL to filter out string
+     # buffer overflow attacks.
+     GRUB_STACK_PROTECTOR_INIT="$($PYTHON -c 'import codecs; rf=open("/dev/urandom", "rb"); print("0x00"+codecs.encode(rf.read(7), "hex").decode("ascii"))')"
+  else
+    # Some hosts may not have a urandom, e.g. Windows, so use statically
+    # generated random bytes
+    GRUB_STACK_PROTECTOR_INIT="0x00f2b7e2f193b25c"
+  fi
+
+  if test x"$target_m32" = x1 ; then
+    # Make sure that the canary default value is 24-bits by only using the
+    # lower 3 bytes on 32 bit systems. This allows the upper byte to be NUL
+    # to filter out string buffer overflow attacks.
+    GRUB_STACK_PROTECTOR_INIT="0x00$(echo "$GRUB_STACK_PROTECTOR_INIT" | sed 's/.*\(......\)$/\1/')"
+  fi
+
+  AC_SUBST([GRUB_STACK_PROTECTOR_INIT])
 fi
 
 CFLAGS="$TARGET_CFLAGS"
index 08e24d46fad93dde59d23b32ab23589af546f5af..6c54af6e79e5b973006585cd3ad639f12218a269 100644 (file)
@@ -46,7 +46,7 @@ static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
 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) 0x00f2b7e2f193b25c;
+grub_addr_t __stack_chk_guard = (grub_addr_t) GRUB_STACK_PROTECTOR_INIT;
 
 void __attribute__ ((noreturn))
 __stack_chk_fail (void)