Skip to content

Commit dcc1af5

Browse files
crassDaniel Kiper
authored and
Daniel Kiper
committed
efi: Generate stack protector canary at build time if urandom is available
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 <[email protected]> Reviewed-by: Daniel Kiper <[email protected]>
1 parent e424e94 commit dcc1af5

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

config.h.in

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@
6464
# define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@"
6565
# define GRUB_PLATFORM "@GRUB_PLATFORM@"
6666

67+
# define GRUB_STACK_PROTECTOR_INIT @GRUB_STACK_PROTECTOR_INIT@
68+
6769
# define RE_ENABLE_I18N 1
6870

6971
# define _GNU_SOURCE 1

configure.ac

+20
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,26 @@ else
14381438
AC_MSG_ERROR([invalid value $enable_stack_protector for --enable-stack-protector])
14391439
fi
14401440
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DGRUB_STACK_PROTECTOR=1"
1441+
1442+
if test -r /dev/urandom; then
1443+
# Generate the 8 byte stack protector canary at build time if /dev/urandom
1444+
# is able to be read. The first byte should be NUL to filter out string
1445+
# buffer overflow attacks.
1446+
GRUB_STACK_PROTECTOR_INIT="$($PYTHON -c 'import codecs; rf=open("/dev/urandom", "rb"); print("0x00"+codecs.encode(rf.read(7), "hex").decode("ascii"))')"
1447+
else
1448+
# Some hosts may not have a urandom, e.g. Windows, so use statically
1449+
# generated random bytes
1450+
GRUB_STACK_PROTECTOR_INIT="0x00f2b7e2f193b25c"
1451+
fi
1452+
1453+
if test x"$target_m32" = x1 ; then
1454+
# Make sure that the canary default value is 24-bits by only using the
1455+
# lower 3 bytes on 32 bit systems. This allows the upper byte to be NUL
1456+
# to filter out string buffer overflow attacks.
1457+
GRUB_STACK_PROTECTOR_INIT="0x00$(echo "$GRUB_STACK_PROTECTOR_INIT" | sed 's/.*\(......\)$/\1/')"
1458+
fi
1459+
1460+
AC_SUBST([GRUB_STACK_PROTECTOR_INIT])
14411461
fi
14421462

14431463
CFLAGS="$TARGET_CFLAGS"

grub-core/kern/efi/init.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
4646
static grub_efi_uint8_t stack_chk_guard_buf[32];
4747

4848
/* Initialize canary in case there is no RNG protocol. */
49-
grub_addr_t __stack_chk_guard = (grub_addr_t) 0x00f2b7e2f193b25c;
49+
grub_addr_t __stack_chk_guard = (grub_addr_t) GRUB_STACK_PROTECTOR_INIT;
5050

5151
void __attribute__ ((noreturn))
5252
__stack_chk_fail (void)

0 commit comments

Comments
 (0)