* [PATCH v3 0/3] efi: Initialize canary to non-zero value
@ 2023-12-19 5:59 Glenn Washburn
2023-12-19 5:59 ` [PATCH v3 1/3] " Glenn Washburn
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Glenn Washburn @ 2023-12-19 5:59 UTC (permalink / raw)
To: The development of GNU GRUB, Daniel Kiper
Cc: Heinrich Schuchardt, Dimitri John Ledkov, Glenn Washburn
Updates from v2:
* Change NULL to NUL
* Describe more why it is desirable to have a NUL byte in the canary
Glenn
Glenn Washburn (3):
efi: Initialize canary to non-zero value
efi: Generate stack protector canary at build time if urandom is
available
efi: Add support for reproducible builds
config.h.in | 2 ++
configure.ac | 22 ++++++++++++++++++++++
grub-core/kern/efi/init.c | 3 ++-
3 files changed, 26 insertions(+), 1 deletion(-)
Range-diff against v2:
1: a993f050ce89 ! 1: c4d3769d2c26 efi: Initialize canary to non-zero value
@@ Commit message
support the RNG protocol, then the canary will not be randomized and will
be zero. This seems like a possibly easier value to write by an attacker.
Initialize canary to static random bytes, so that it is still random when
- there is no RNG protocol. Set at least one byte to NULL to protect against
- string buffer overflow attacks.
+ there is no RNG protocol. Set at least one byte to NUL to protect against
+ string buffer overflow attacks. Code that writes NUL terminated strings
+ will terminate when a NUL is encountered in the input byte stream. So the
+ attacker will not be able to forge the canary by including it in the input
+ stream without terminating the string operation and thus limiting the
+ stack corruption.
+
+ [1] https://www.sans.org/blog/stack-canaries-gingerly-sidestepping-the-cage/
## grub-core/kern/efi/init.c ##
@@ grub-core/kern/efi/init.c: static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
2: 177ae1cf1015 ! 2: 01a56aed2f26 efi: Generate stack protector canary at build time if urandom is available
@@ Commit message
Fallback to the statically generated random bytes if /dev/urandom is not
readable (eg. Windows).
- Reduce the canary to 3 bytes with a NULL upper byte on 32-bit architectures,
- which use a 32-bit canary, to filter out string buffer overflow attacks.
+ 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.
## config.h.in ##
@@
@@ configure.ac: else
+
+ 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 NULL to filter out string
++ # 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
@@ configure.ac: else
+
+ 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 NULL
++ # 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
3: c38fa7791697 ! 3: 5989c0102154 efi: Add support for reproducible builds
@@ configure.ac: else
+ GRUB_STACK_PROTECTOR_INIT="0x00f2b7e2$(printf "%x" "$SOURCE_DATE_EPOCH" | sed 's/.*\(........\)$/\1/')"
+ elif 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 NULL to filter out string
+ # is able to be read. The first byte should be NUL to filter out string
# buffer overflow attacks.
--
2.34.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v3 1/3] efi: Initialize canary to non-zero value
2023-12-19 5:59 [PATCH v3 0/3] efi: Initialize canary to non-zero value Glenn Washburn
@ 2023-12-19 5:59 ` Glenn Washburn
2023-12-19 6:00 ` [PATCH v3 2/3] efi: Generate stack protector canary at build time if urandom is available Glenn Washburn
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Glenn Washburn @ 2023-12-19 5:59 UTC (permalink / raw)
To: The development of GNU GRUB, Daniel Kiper
Cc: Heinrich Schuchardt, Dimitri John Ledkov, Glenn Washburn
The canary, __stack_chk_guard, is in the BSS and so will get initialized to
zero if it is not explicitly initialized. If the UEFI firmware does not
support the RNG protocol, then the canary will not be randomized and will
be zero. This seems like a possibly easier value to write by an attacker.
Initialize canary to static random bytes, so that it is still random when
there is no RNG protocol. Set at least one byte to NUL to protect against
string buffer overflow attacks. Code that writes NUL terminated strings
will terminate when a NUL is encountered in the input byte stream. So the
attacker will not be able to forge the canary by including it in the input
stream without terminating the string operation and thus limiting the
stack corruption.
[1] https://www.sans.org/blog/stack-canaries-gingerly-sidestepping-the-cage/
Signed-off-by: Glenn Washburn <development@efficientek.com>
---
grub-core/kern/efi/init.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index e759cc315b85..08e24d46fad9 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -45,7 +45,8 @@ static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
*/
static grub_efi_uint8_t stack_chk_guard_buf[32];
-grub_addr_t __stack_chk_guard;
+/* Initialize canary in case there is no RNG protocol. */
+grub_addr_t __stack_chk_guard = (grub_addr_t) 0x00f2b7e2f193b25c;
void __attribute__ ((noreturn))
__stack_chk_fail (void)
--
2.34.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v3 2/3] efi: Generate stack protector canary at build time if urandom is available
2023-12-19 5:59 [PATCH v3 0/3] efi: Initialize canary to non-zero value Glenn Washburn
2023-12-19 5:59 ` [PATCH v3 1/3] " Glenn Washburn
@ 2023-12-19 6:00 ` Glenn Washburn
2023-12-19 6:00 ` [PATCH v3 3/3] efi: Add support for reproducible builds Glenn Washburn
2023-12-20 13:09 ` [PATCH v3 0/3] efi: Initialize canary to non-zero value Daniel Kiper
3 siblings, 0 replies; 5+ messages in thread
From: Glenn Washburn @ 2023-12-19 6:00 UTC (permalink / raw)
To: The development of GNU GRUB, Daniel Kiper
Cc: Heinrich Schuchardt, Dimitri John Ledkov, Glenn Washburn
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 (eg. 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>
---
config.h.in | 2 ++
configure.ac | 20 ++++++++++++++++++++
grub-core/kern/efi/init.c | 2 +-
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/config.h.in b/config.h.in
index 4d1e50eba79c..9b1d39971858 100644
--- a/config.h.in
+++ b/config.h.in
@@ -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
diff --git a/configure.ac b/configure.ac
index c19779c14d08..f15d31ec4c0e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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 (eg. 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"
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index 08e24d46fad9..6c54af6e79e5 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -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)
--
2.34.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v3 3/3] efi: Add support for reproducible builds
2023-12-19 5:59 [PATCH v3 0/3] efi: Initialize canary to non-zero value Glenn Washburn
2023-12-19 5:59 ` [PATCH v3 1/3] " Glenn Washburn
2023-12-19 6:00 ` [PATCH v3 2/3] efi: Generate stack protector canary at build time if urandom is available Glenn Washburn
@ 2023-12-19 6:00 ` Glenn Washburn
2023-12-20 13:09 ` [PATCH v3 0/3] efi: Initialize canary to non-zero value Daniel Kiper
3 siblings, 0 replies; 5+ messages in thread
From: Glenn Washburn @ 2023-12-19 6:00 UTC (permalink / raw)
To: The development of GNU GRUB, Daniel Kiper
Cc: Heinrich Schuchardt, Dimitri John Ledkov, Glenn Washburn
Having randomly generated bytes in the binary output breaks reproducible
builds. Since build timestamps are usually the source of irreproducibility
there is a standard which defines an environment variable SOURCE_DATE_EPOCH
to be used when set for build timestamps. According to the standard[1], the
value of SOURCE_DATE_EPOCH is a base-10 integer of the number of seconds
since the UNIX epoch. Currently, this is a 10 digit number that fits into
32-bits, but will not shortly after the year 2100. So to be future-proof
only use the least significant 32-bits. On 64-bit architectures, where the
canary is also 64-bits, there is an extra 32-bits that can be filled to
provide more entropy. The first byte is null to filter out string buffer
overflow attacks and the remaining 24-bits are set to static random bytes.
[1] https://reproducible-builds.org/specs/source-date-epoch
Signed-off-by: Glenn Washburn <development@efficientek.com>
---
configure.ac | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index f15d31ec4c0e..0ba1cd71db00 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1439,7 +1439,9 @@ else
fi
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DGRUB_STACK_PROTECTOR=1"
- if test -r /dev/urandom; then
+ if test -n "$SOURCE_DATE_EPOCH"; then
+ GRUB_STACK_PROTECTOR_INIT="0x00f2b7e2$(printf "%x" "$SOURCE_DATE_EPOCH" | sed 's/.*\(........\)$/\1/')"
+ elif 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.
--
2.34.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v3 0/3] efi: Initialize canary to non-zero value
2023-12-19 5:59 [PATCH v3 0/3] efi: Initialize canary to non-zero value Glenn Washburn
` (2 preceding siblings ...)
2023-12-19 6:00 ` [PATCH v3 3/3] efi: Add support for reproducible builds Glenn Washburn
@ 2023-12-20 13:09 ` Daniel Kiper
3 siblings, 0 replies; 5+ messages in thread
From: Daniel Kiper @ 2023-12-20 13:09 UTC (permalink / raw)
To: Glenn Washburn
Cc: The development of GNU GRUB, Heinrich Schuchardt,
Dimitri John Ledkov
On Mon, Dec 18, 2023 at 11:59:58PM -0600, Glenn Washburn wrote:
> Updates from v2:
> * Change NULL to NUL
> * Describe more why it is desirable to have a NUL byte in the canary
>
> Glenn
>
> Glenn Washburn (3):
> efi: Initialize canary to non-zero value
> efi: Generate stack protector canary at build time if urandom is
> available
> efi: Add support for reproducible builds
For all patches Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>...
Daniel
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-12-20 13:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-19 5:59 [PATCH v3 0/3] efi: Initialize canary to non-zero value Glenn Washburn
2023-12-19 5:59 ` [PATCH v3 1/3] " Glenn Washburn
2023-12-19 6:00 ` [PATCH v3 2/3] efi: Generate stack protector canary at build time if urandom is available Glenn Washburn
2023-12-19 6:00 ` [PATCH v3 3/3] efi: Add support for reproducible builds Glenn Washburn
2023-12-20 13:09 ` [PATCH v3 0/3] efi: Initialize canary to non-zero value Daniel Kiper
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.