Compare commits
22 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| 7bebe4975c | |||
| 2947cf51fa | |||
| 6ae9de2829 | |||
| 65b3a4a414 | |||
| 928faeb505 | |||
| 462262e6ea | |||
| 3872727a8d | |||
| 8c20cdcab0 | |||
| 4085ef8f96 | |||
| 7437f32a34 | |||
| 3db63b85e2 | |||
| f509f29f48 | |||
| c90e5054ec | |||
| ef9fe84701 | |||
| 29e0b8290c | |||
| 0108c5290e | |||
| 4962b71520 | |||
| e3c4848fca | |||
| 575dbfe9e9 | |||
| 0f03cac870 | |||
| 03767e119a | |||
| 5bb0fbd333 |
66
0001-getroot-Skip-mount-points-in-grub_find_device.patch
Normal file
66
0001-getroot-Skip-mount-points-in-grub_find_device.patch
Normal file
@@ -0,0 +1,66 @@
|
||||
From ff3165a3e519892ec4bf9a31f4f1132668f83394 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 15 Jul 2025 14:15:22 +0800
|
||||
Subject: [PATCH] getroot: Skip mount points in grub_find_device
|
||||
|
||||
The grub_find_device function scans a starting directory, typically
|
||||
/dev, for device files with matching major and minor numbers. During
|
||||
this process, it recursively descends into subdirectories.
|
||||
|
||||
However, this can significantly slow down the scan if a subdirectory is
|
||||
a mount point not related to devtmpfs, especially if it contains a large
|
||||
number of files.
|
||||
|
||||
This patch modifies grub_find_device() to skip subdirectories that are
|
||||
mount points. A mount point is detected by comparing the st_dev of the
|
||||
subdirectory against that of the parent or starting directory. While
|
||||
this method does not catch all types of mounts, for eg bind mounts, it
|
||||
is a practical solution that avoids the need to parse /proc/self/mounts.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/osdep/unix/getroot.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/grub-core/osdep/unix/getroot.c b/grub-core/osdep/unix/getroot.c
|
||||
index dce94b52e..9759cc59b 100644
|
||||
--- a/grub-core/osdep/unix/getroot.c
|
||||
+++ b/grub-core/osdep/unix/getroot.c
|
||||
@@ -353,6 +353,7 @@ grub_find_device (const char *dir, dev_t dev)
|
||||
DIR *dp;
|
||||
struct saved_cwd saved_cwd;
|
||||
struct dirent *ent;
|
||||
+ struct stat st_dir;
|
||||
|
||||
if (! dir)
|
||||
dir = "/dev";
|
||||
@@ -361,6 +362,12 @@ grub_find_device (const char *dir, dev_t dev)
|
||||
if (! dp)
|
||||
return 0;
|
||||
|
||||
+ if (stat (dir, &st_dir) < 0)
|
||||
+ {
|
||||
+ closedir (dp);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if (save_cwd (&saved_cwd) < 0)
|
||||
{
|
||||
grub_util_error ("%s", _("cannot save the original directory"));
|
||||
@@ -410,6 +417,13 @@ grub_find_device (const char *dir, dev_t dev)
|
||||
/* Find it recursively. */
|
||||
char *res;
|
||||
|
||||
+ /* Skip mount point */
|
||||
+ if (st.st_dev != st_dir.st_dev)
|
||||
+ {
|
||||
+ grub_util_info ("skip mount point %s/%s", dir, ent->d_name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
res = grub_find_device (ent->d_name, dev);
|
||||
|
||||
if (res)
|
||||
--
|
||||
2.50.0
|
||||
|
||||
116
0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch
Normal file
116
0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch
Normal file
@@ -0,0 +1,116 @@
|
||||
From 1fbd2a278cfc645adc45c0e1357e58bcd1909f8d Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 28 Aug 2025 15:03:35 +0800
|
||||
Subject: [PATCH] kern/misc: Implement faster grub_memcpy() for aligned buffers
|
||||
|
||||
When both "dest" and "src" are aligned, copying the data in chunks
|
||||
(unsigned long) is more efficient than a byte-by-byte copy.
|
||||
|
||||
Also tweak '__aeabi_memcpy()', '__aeabi_memcpy4()', and
|
||||
'__aeabi_memcpy8()', since 'grub_memcpy()' is not inline anymore.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/kern/compiler-rt.c | 8 ++++----
|
||||
grub-core/kern/misc.c | 30 ++++++++++++++++++++++++++++++
|
||||
include/grub/misc.h | 8 +-------
|
||||
3 files changed, 35 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c
|
||||
index eda689a0c..8f3865e95 100644
|
||||
--- a/grub-core/kern/compiler-rt.c
|
||||
+++ b/grub-core/kern/compiler-rt.c
|
||||
@@ -24,7 +24,7 @@
|
||||
void * GRUB_BUILTIN_ATTR
|
||||
memcpy (void *dest, const void *src, grub_size_t n)
|
||||
{
|
||||
- return grub_memmove (dest, src, n);
|
||||
+ return grub_memcpy (dest, src, n);
|
||||
}
|
||||
void * GRUB_BUILTIN_ATTR
|
||||
memmove (void *dest, const void *src, grub_size_t n)
|
||||
@@ -372,11 +372,11 @@ grub_int32_t
|
||||
__aeabi_idiv (grub_int32_t a, grub_int32_t b)
|
||||
__attribute__ ((alias ("__divsi3")));
|
||||
void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
|
||||
- __attribute__ ((alias ("grub_memcpy")));
|
||||
+ __attribute__ ((alias ("memcpy")));
|
||||
void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n)
|
||||
- __attribute__ ((alias ("grub_memcpy")));
|
||||
+ __attribute__ ((alias ("memcpy")));
|
||||
void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n)
|
||||
- __attribute__ ((alias ("grub_memcpy")));
|
||||
+ __attribute__ ((alias ("memcpy")));
|
||||
void *__aeabi_memset (void *s, int c, grub_size_t n)
|
||||
__attribute__ ((alias ("memset")));
|
||||
|
||||
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
|
||||
index 2b7922393..016932583 100644
|
||||
--- a/grub-core/kern/misc.c
|
||||
+++ b/grub-core/kern/misc.c
|
||||
@@ -99,6 +99,36 @@ grub_memmove (void *dest, const void *src, grub_size_t n)
|
||||
return dest;
|
||||
}
|
||||
|
||||
+static void *
|
||||
+__memcpy_aligned (void *dest, const void *src, grub_size_t n)
|
||||
+{
|
||||
+ unsigned long *dw = (unsigned long *) dest;
|
||||
+ const unsigned long *sw = (const unsigned long *) src;
|
||||
+ grub_uint8_t *d;
|
||||
+ const grub_uint8_t *s;
|
||||
+
|
||||
+ for (; n >= sizeof (unsigned long); n -= sizeof (unsigned long))
|
||||
+ *dw++ = *sw++;
|
||||
+
|
||||
+ d = (grub_uint8_t *) dw;
|
||||
+ s = (const grub_uint8_t *) sw;
|
||||
+ for (; n > 0; n--)
|
||||
+ *d++ = *s++;
|
||||
+
|
||||
+ return dest;
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+grub_memcpy (void *dest, const void *src, grub_size_t n)
|
||||
+{
|
||||
+ /* Check if 'dest' and 'src' are aligned */
|
||||
+ if (((grub_addr_t) dest & (sizeof (unsigned long) - 1)) == 0 &&
|
||||
+ ((grub_addr_t) src & (sizeof (unsigned long) - 1)) == 0)
|
||||
+ return __memcpy_aligned (dest, src, n);
|
||||
+
|
||||
+ return grub_memmove (dest, src, n);
|
||||
+}
|
||||
+
|
||||
char *
|
||||
grub_strcpy (char *dest, const char *src)
|
||||
{
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index e087e7b3e..b6b14ca55 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -38,6 +38,7 @@
|
||||
#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__)
|
||||
|
||||
void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
|
||||
+void *EXPORT_FUNC(grub_memcpy) (void *dest, const void *src, grub_size_t n);
|
||||
char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
|
||||
|
||||
static inline char *
|
||||
@@ -103,13 +104,6 @@ grub_strlcpy (char *dest, const char *src, grub_size_t size)
|
||||
return res;
|
||||
}
|
||||
|
||||
-/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
|
||||
-static inline void *
|
||||
-grub_memcpy (void *dest, const void *src, grub_size_t n)
|
||||
-{
|
||||
- return grub_memmove (dest, src, n);
|
||||
-}
|
||||
-
|
||||
#if defined(__x86_64__) && !defined (GRUB_UTIL)
|
||||
#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__)
|
||||
#define GRUB_ASM_ATTR __attribute__ ((sysv_abi))
|
||||
--
|
||||
2.51.0
|
||||
|
||||
234
0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch
Normal file
234
0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch
Normal file
@@ -0,0 +1,234 @@
|
||||
From e98e880b67be178f3a5951fb345ded8c002eb6e5 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Wed, 13 Aug 2025 11:43:40 +0800
|
||||
Subject: [PATCH 1/2] lib/crypto: Introduce new HMAC functions to reuse buffers
|
||||
|
||||
To enable more efficient buffer reuse for HMAC operations, three new
|
||||
functions have been introduced. This change prevents the need to
|
||||
reallocate memory for each HMAC operation.
|
||||
|
||||
* grub_crypto_hmac_reset(): Reinitializes the hash contexts in the HMAC
|
||||
handle.
|
||||
|
||||
* grub_crypto_hmac_final(): Provides the final HMAC result without
|
||||
freeing the handle, allowing it to be reused immediately.
|
||||
|
||||
* grub_crypto_hmac_free(): Deallocates the HMAC handle and its
|
||||
associated memory.
|
||||
|
||||
To further facilitate buffer reuse, 'ctx2' is now included within the HMAC
|
||||
handle struct, and the initialization of 'ctx2' is moved to
|
||||
grub_crypto_hmac_init().
|
||||
|
||||
The intermediate hash states ('ctx' and 'ctx2') for the inner and outer
|
||||
padded keys are now cached. grub_crypto_hmac_reset() restores these cached
|
||||
states for new operations, which avoids redundant hashing of the keys.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/disk/geli.c | 4 +-
|
||||
grub-core/lib/crypto.c | 91 ++++++++++++++++++++++++++++++------------
|
||||
include/grub/crypto.h | 8 +++-
|
||||
3 files changed, 74 insertions(+), 29 deletions(-)
|
||||
|
||||
Index: grub-2.12/grub-core/disk/geli.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/disk/geli.c
|
||||
+++ grub-2.12/grub-core/disk/geli.c
|
||||
@@ -464,9 +464,7 @@ geli_recover_key (grub_disk_t source, gr
|
||||
grub_crypto_hmac_write (hnd, header.salt, sizeof (header.salt));
|
||||
grub_crypto_hmac_write (hnd, cargs->key_data, cargs->key_len);
|
||||
|
||||
- gcry_err = grub_crypto_hmac_fini (hnd, geomkey);
|
||||
- if (gcry_err)
|
||||
- return grub_crypto_gcry_error (gcry_err);
|
||||
+ grub_crypto_hmac_fini (hnd, geomkey);
|
||||
}
|
||||
|
||||
gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey,
|
||||
Index: grub-2.12/grub-core/lib/crypto.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/lib/crypto.c
|
||||
+++ grub-2.12/grub-core/lib/crypto.c
|
||||
@@ -31,7 +31,9 @@ struct grub_crypto_hmac_handle
|
||||
{
|
||||
const struct gcry_md_spec *md;
|
||||
void *ctx;
|
||||
- void *opad;
|
||||
+ void *ctx2;
|
||||
+ void *ctx_cache;
|
||||
+ void *ctx2_cache;
|
||||
};
|
||||
|
||||
static gcry_cipher_spec_t *grub_ciphers = NULL;
|
||||
@@ -307,7 +309,8 @@ grub_crypto_hmac_init (const struct gcry
|
||||
{
|
||||
grub_uint8_t *helpkey = NULL;
|
||||
grub_uint8_t *ipad = NULL, *opad = NULL;
|
||||
- void *ctx = NULL;
|
||||
+ void *ctx = NULL, *ctx2 = NULL;
|
||||
+ void *ctx_cache = NULL, *ctx2_cache = NULL;
|
||||
struct grub_crypto_hmac_handle *ret = NULL;
|
||||
unsigned i;
|
||||
|
||||
@@ -318,6 +321,18 @@ grub_crypto_hmac_init (const struct gcry
|
||||
if (!ctx)
|
||||
goto err;
|
||||
|
||||
+ ctx2 = grub_malloc (md->contextsize);
|
||||
+ if (!ctx2)
|
||||
+ goto err;
|
||||
+
|
||||
+ ctx_cache = grub_malloc (md->contextsize);
|
||||
+ if (!ctx_cache)
|
||||
+ goto err;
|
||||
+
|
||||
+ ctx2_cache = grub_malloc (md->contextsize);
|
||||
+ if (!ctx2_cache)
|
||||
+ goto err;
|
||||
+
|
||||
if ( keylen > md->blocksize )
|
||||
{
|
||||
helpkey = grub_malloc (md->mdlen);
|
||||
@@ -347,26 +362,40 @@ grub_crypto_hmac_init (const struct gcry
|
||||
grub_free (helpkey);
|
||||
helpkey = NULL;
|
||||
|
||||
+ /* inner pad */
|
||||
md->init (ctx);
|
||||
-
|
||||
- md->write (ctx, ipad, md->blocksize); /* inner pad */
|
||||
+ md->write (ctx, ipad, md->blocksize);
|
||||
+ grub_memcpy (ctx_cache, ctx, md->contextsize);
|
||||
grub_memset (ipad, 0, md->blocksize);
|
||||
grub_free (ipad);
|
||||
ipad = NULL;
|
||||
|
||||
+ /* outer pad */
|
||||
+ md->init (ctx2);
|
||||
+ md->write (ctx2, opad, md->blocksize);
|
||||
+ grub_memcpy (ctx2_cache, ctx2, md->contextsize);
|
||||
+ grub_memset (opad, 0, md->blocksize);
|
||||
+ grub_free (opad);
|
||||
+ opad = NULL;
|
||||
+
|
||||
ret = grub_malloc (sizeof (*ret));
|
||||
if (!ret)
|
||||
goto err;
|
||||
|
||||
ret->md = md;
|
||||
ret->ctx = ctx;
|
||||
- ret->opad = opad;
|
||||
+ ret->ctx2 = ctx2;
|
||||
+ ret->ctx_cache = ctx_cache;
|
||||
+ ret->ctx2_cache = ctx2_cache;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
grub_free (helpkey);
|
||||
grub_free (ctx);
|
||||
+ grub_free (ctx2);
|
||||
+ grub_free (ctx_cache);
|
||||
+ grub_free (ctx2_cache);
|
||||
grub_free (ipad);
|
||||
grub_free (opad);
|
||||
return NULL;
|
||||
@@ -380,37 +409,48 @@ grub_crypto_hmac_write (struct grub_cryp
|
||||
hnd->md->write (hnd->ctx, data, datalen);
|
||||
}
|
||||
|
||||
-gcry_err_code_t
|
||||
+void
|
||||
grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out)
|
||||
{
|
||||
- grub_uint8_t *p;
|
||||
- grub_uint8_t *ctx2;
|
||||
+ grub_crypto_hmac_final (hnd, out);
|
||||
+ grub_crypto_hmac_free (hnd);
|
||||
+}
|
||||
|
||||
- ctx2 = grub_malloc (hnd->md->contextsize);
|
||||
- if (!ctx2)
|
||||
- return GPG_ERR_OUT_OF_MEMORY;
|
||||
+void
|
||||
+grub_crypto_hmac_reset (struct grub_crypto_hmac_handle *hnd)
|
||||
+{
|
||||
+ grub_memcpy (hnd->ctx, hnd->ctx_cache, hnd->md->contextsize);
|
||||
+ grub_memcpy (hnd->ctx2, hnd->ctx2_cache, hnd->md->contextsize);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_crypto_hmac_final (struct grub_crypto_hmac_handle *hnd, void *out)
|
||||
+{
|
||||
+ grub_uint8_t *p;
|
||||
|
||||
hnd->md->final (hnd->ctx);
|
||||
hnd->md->read (hnd->ctx);
|
||||
p = hnd->md->read (hnd->ctx);
|
||||
|
||||
- hnd->md->init (ctx2);
|
||||
- hnd->md->write (ctx2, hnd->opad, hnd->md->blocksize);
|
||||
- hnd->md->write (ctx2, p, hnd->md->mdlen);
|
||||
- hnd->md->final (ctx2);
|
||||
- grub_memset (hnd->opad, 0, hnd->md->blocksize);
|
||||
- grub_free (hnd->opad);
|
||||
- grub_memset (hnd->ctx, 0, hnd->md->contextsize);
|
||||
- grub_free (hnd->ctx);
|
||||
+ hnd->md->write (hnd->ctx2, p, hnd->md->mdlen);
|
||||
+ hnd->md->final (hnd->ctx2);
|
||||
|
||||
- grub_memcpy (out, hnd->md->read (ctx2), hnd->md->mdlen);
|
||||
- grub_memset (ctx2, 0, hnd->md->contextsize);
|
||||
- grub_free (ctx2);
|
||||
+ grub_memcpy (out, hnd->md->read (hnd->ctx2), hnd->md->mdlen);
|
||||
+}
|
||||
|
||||
+void
|
||||
+grub_crypto_hmac_free (struct grub_crypto_hmac_handle *hnd)
|
||||
+{
|
||||
+ grub_memset (hnd->ctx, 0, hnd->md->contextsize);
|
||||
+ grub_free (hnd->ctx);
|
||||
+ grub_memset (hnd->ctx2, 0, hnd->md->contextsize);
|
||||
+ grub_free (hnd->ctx2);
|
||||
+ grub_memset (hnd->ctx_cache, 0, hnd->md->contextsize);
|
||||
+ grub_free (hnd->ctx_cache);
|
||||
+ grub_memset (hnd->ctx2_cache, 0, hnd->md->contextsize);
|
||||
+ grub_free (hnd->ctx2_cache);
|
||||
grub_memset (hnd, 0, sizeof (*hnd));
|
||||
grub_free (hnd);
|
||||
-
|
||||
- return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
gcry_err_code_t
|
||||
@@ -425,7 +465,8 @@ grub_crypto_hmac_buffer (const struct gc
|
||||
return GPG_ERR_OUT_OF_MEMORY;
|
||||
|
||||
grub_crypto_hmac_write (hnd, data, datalen);
|
||||
- return grub_crypto_hmac_fini (hnd, out);
|
||||
+ grub_crypto_hmac_fini (hnd, out);
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
Index: grub-2.12/include/grub/crypto.h
|
||||
===================================================================
|
||||
--- grub-2.12.orig/include/grub/crypto.h
|
||||
+++ grub-2.12/include/grub/crypto.h
|
||||
@@ -358,8 +358,14 @@ void
|
||||
grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd,
|
||||
const void *data,
|
||||
grub_size_t datalen);
|
||||
-gcry_err_code_t
|
||||
+void
|
||||
grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out);
|
||||
+void
|
||||
+grub_crypto_hmac_reset (struct grub_crypto_hmac_handle *hnd);
|
||||
+void
|
||||
+grub_crypto_hmac_final (struct grub_crypto_hmac_handle *hnd, void *out);
|
||||
+void
|
||||
+grub_crypto_hmac_free (struct grub_crypto_hmac_handle *hnd);
|
||||
|
||||
gcry_err_code_t
|
||||
grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
|
||||
119
0001-linux-fallback-to-EFI-handover-on-x86_64.patch
Normal file
119
0001-linux-fallback-to-EFI-handover-on-x86_64.patch
Normal file
@@ -0,0 +1,119 @@
|
||||
From f770cc82c3d65c65d812e96e006c17861d357d99 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 26 Apr 2025 15:07:36 +0800
|
||||
Subject: [PATCH 1/4] linux: fallback to EFI handover on x86_64
|
||||
|
||||
On the x86_64 platform, when the shim loader protocol is unavailable and
|
||||
UEFI Secure Boot is enabled, fall back to the Linux EFI handover boot
|
||||
protocol. This legacy method supports the in-kernel EFI stub and is used
|
||||
instead of the 32-bit boot entry.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 2 ++
|
||||
grub-core/loader/efi/linux.c | 13 +++++++------
|
||||
grub-core/loader/i386/efi/linux.c | 30 ++++--------------------------
|
||||
3 files changed, 13 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 80ea6656a..1811661c3 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1902,6 +1902,8 @@ module = {
|
||||
loongarch64 = loader/efi/linux.c;
|
||||
riscv32 = loader/efi/linux.c;
|
||||
riscv64 = loader/efi/linux.c;
|
||||
+ i386_efi = loader/efi/linux.c;
|
||||
+ x86_64_efi = loader/efi/linux.c;
|
||||
emu = loader/emu/linux.c;
|
||||
common = loader/linux.c;
|
||||
i386_efi = loader/efi/linux_boot.c;
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index 394df6039..b20dec404 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -71,10 +71,10 @@ static initrd_media_device_path_t initrd_lf2_device_path = {
|
||||
};
|
||||
|
||||
extern grub_err_t
|
||||
-grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
|
||||
+grub_cmd_linux_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
|
||||
extern grub_err_t
|
||||
-grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
|
||||
+grub_cmd_initrd_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
|
||||
static grub_efi_status_t __grub_efi_api
|
||||
grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
|
||||
@@ -389,8 +389,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
- if (!initrd_use_loadfile2)
|
||||
- return grub_cmd_initrd_x86_legacy (cmd, argc, argv);
|
||||
+ if (grub_is_using_legacy_shim_lock_protocol () == true ||
|
||||
+ !initrd_use_loadfile2)
|
||||
+ return grub_cmd_initrd_efi_fallback (cmd, argc, argv);
|
||||
#endif
|
||||
|
||||
if (!loaded)
|
||||
@@ -474,7 +475,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
grub_dprintf ("linux", "using legacy shim_lock protocol, falling back to legacy Linux kernel loader\n");
|
||||
|
||||
- err = grub_cmd_linux_x86_legacy (cmd, argc, argv);
|
||||
+ err = grub_cmd_linux_efi_fallback (cmd, argc, argv);
|
||||
|
||||
if (err == GRUB_ERR_NONE)
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -513,7 +514,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
*/
|
||||
fallback:
|
||||
grub_file_close (file);
|
||||
- return grub_cmd_linux_x86_legacy (cmd, argc, argv);
|
||||
+ return grub_cmd_linux_efi_fallback (cmd, argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index ca3435a88..49e4a3f19 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -421,30 +421,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
-static grub_command_t cmd_linux, cmd_initrd;
|
||||
-static grub_command_t cmd_linuxefi, cmd_initrdefi;
|
||||
+extern grub_err_t __attribute__((alias("grub_cmd_linux")))
|
||||
+grub_cmd_linux_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
|
||||
-GRUB_MOD_INIT(linux)
|
||||
-{
|
||||
- cmd_linuxefi =
|
||||
- grub_register_command ("linuxefi", grub_cmd_linux,
|
||||
- 0, N_("Load Linux."));
|
||||
- cmd_initrdefi =
|
||||
- grub_register_command ("initrdefi", grub_cmd_initrd,
|
||||
- 0, N_("Load initrd."));
|
||||
- cmd_linux =
|
||||
- grub_register_command ("linux", grub_cmd_linux,
|
||||
- 0, N_("Load Linux."));
|
||||
- cmd_initrd =
|
||||
- grub_register_command ("initrd", grub_cmd_initrd,
|
||||
- 0, N_("Load initrd."));
|
||||
- my_mod = mod;
|
||||
-}
|
||||
-
|
||||
-GRUB_MOD_FINI(linux)
|
||||
-{
|
||||
- grub_unregister_command (cmd_linuxefi);
|
||||
- grub_unregister_command (cmd_initrdefi);
|
||||
- grub_unregister_command (cmd_linux);
|
||||
- grub_unregister_command (cmd_initrd);
|
||||
-}
|
||||
+extern grub_err_t __attribute__((alias("grub_cmd_initrd")))
|
||||
+grub_cmd_initrd_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
--
|
||||
2.50.1
|
||||
|
||||
35
0001-modules-Make-.module_license-read-only.patch
Normal file
35
0001-modules-Make-.module_license-read-only.patch
Normal file
@@ -0,0 +1,35 @@
|
||||
From a05d4896327e87b2986ddb44ef0947bbc9010da6 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 9 Oct 2024 09:16:36 +0100
|
||||
Subject: [PATCH 01/13] modules: Make .module_license read-only
|
||||
|
||||
Currently .module_license is set writable, that is, the section has the
|
||||
SHF_WRITE flag set, in the module's ELF headers. This probably never
|
||||
actually matters but it can't possibly be correct. The patch sets that
|
||||
data as "const" which causes that flag not to be set.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-By: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
include/grub/dl.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/grub/dl.h b/include/grub/dl.h
|
||||
index c5ab18cb1..fb4476797 100644
|
||||
--- a/include/grub/dl.h
|
||||
+++ b/include/grub/dl.h
|
||||
@@ -119,7 +119,7 @@ grub_mod_fini (void)
|
||||
#define ATTRIBUTE_USED __unused__
|
||||
#endif
|
||||
#define GRUB_MOD_LICENSE(license) \
|
||||
- static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
|
||||
+ static const char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
|
||||
#define GRUB_MOD_DEP(name) \
|
||||
static const char grub_module_depend_##name[] \
|
||||
__attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name
|
||||
--
|
||||
2.50.1
|
||||
|
||||
116
0001-tcp-Fix-TCP-port-number-reused-on-reboot.patch
Normal file
116
0001-tcp-Fix-TCP-port-number-reused-on-reboot.patch
Normal file
@@ -0,0 +1,116 @@
|
||||
From 468a37601083ef3352ff6e5d4f40ec8b1cebc4ef Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 8 Jul 2025 11:57:42 +0800
|
||||
Subject: [PATCH] tcp: Fix TCP port number reused on reboot
|
||||
|
||||
GRUB's TCP stack assigns source ports for outgoing connections starting
|
||||
at 21550 and increments sequentially by 1 (e.g., 21550, 21551, ...).
|
||||
While this generally works, it can lead to failures if the system
|
||||
reboots rapidly and reuses the same source port too soon.
|
||||
|
||||
This issue was observed on powerpc-ieee1275 platforms using CAS (Client
|
||||
Architecture Support) reboot. In such cases, loading the initrd over
|
||||
HTTP may fail with connection timeouts. Packet captures show the failed
|
||||
connections are flagged as "TCP Port Number Reused" by Wireshark.
|
||||
|
||||
The root cause is that GRUB reuses the same port shortly after reboot,
|
||||
while the server may still be tracking the previous connection in
|
||||
TIME_WAIT. This can result in the server rejecting the connection
|
||||
attempt or responding with a stale ACK or RST, leading to handshake
|
||||
failure.
|
||||
|
||||
This patch fixes the issue by introducing a time based source port
|
||||
selection strategy. Instead of always starting from port 21550, GRUB now
|
||||
computes an initial base port based on the current RTC time, divided
|
||||
into 5 minute windows. The purpose of this time based strategy is to
|
||||
ensure that GRUB avoids reusing the same source port within a 5 minute
|
||||
window, thereby preventing collisions with stale server side connection
|
||||
tracking that could interfere with a new TCP handshake.
|
||||
|
||||
A step size of 8 ensures that the same port will not be reused across
|
||||
reboots unless GRUB opens more than 8 TCP connections per second on
|
||||
average, something that is highly unlikely. In typical usage, a GRUB
|
||||
boot cycle lasts about 15 seconds and may open fewer than 100
|
||||
connections total, well below the reuse threshold. This makes the
|
||||
approach robust against short reboot intervals while keeping the logic
|
||||
simple and deterministic.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
---
|
||||
grub-core/net/tcp.c | 39 ++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 38 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c
|
||||
index 93dee0caa..d0cc602dc 100644
|
||||
--- a/grub-core/net/tcp.c
|
||||
+++ b/grub-core/net/tcp.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <grub/net/netbuff.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/priority_queue.h>
|
||||
+#include <grub/datetime.h>
|
||||
|
||||
#define TCP_SYN_RETRANSMISSION_TIMEOUT GRUB_NET_INTERVAL
|
||||
#define TCP_SYN_RETRANSMISSION_COUNT GRUB_NET_TRIES
|
||||
@@ -552,6 +553,36 @@ grub_net_tcp_accept (grub_net_tcp_socket_t sock,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Derive a time-based source port to avoid reusing the same port across
|
||||
+ * reboots. This helps prevent failures caused by server side TCP state (e.g.
|
||||
+ * TIME_WAIT) from interfering with new connections using the same socket.
|
||||
+ *
|
||||
+ * The base port starts at 21550 and increments every second by 8 across a 5
|
||||
+ * minute window (300 seconds), giving 2400 possible distinct base ports per
|
||||
+ * window. In typical GRUB usage, the number of connections per boot is small,
|
||||
+ * so reuse is effectively avoided.
|
||||
+ */
|
||||
+static grub_uint16_t
|
||||
+get_initial_base_port (void)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+ struct grub_datetime date;
|
||||
+ grub_int64_t t = 0;
|
||||
+ grub_uint64_t r = 0;
|
||||
+
|
||||
+ err = grub_get_datetime (&date);
|
||||
+ if (err != GRUB_ERR_NONE || !grub_datetime2unixtime (&date, &t))
|
||||
+ {
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ return 21550;
|
||||
+ }
|
||||
+
|
||||
+ grub_divmod64 (t, 300, &r);
|
||||
+
|
||||
+ return 21550 + (r << 3);
|
||||
+}
|
||||
+
|
||||
grub_net_tcp_socket_t
|
||||
grub_net_tcp_open (char *server,
|
||||
grub_uint16_t out_port,
|
||||
@@ -569,13 +600,19 @@ grub_net_tcp_open (char *server,
|
||||
struct grub_net_network_level_interface *inf;
|
||||
grub_net_network_level_address_t gateway;
|
||||
grub_net_tcp_socket_t socket;
|
||||
- static grub_uint16_t in_port = 21550;
|
||||
+ static grub_uint16_t in_port;
|
||||
struct grub_net_buff *nb;
|
||||
struct tcphdr *tcph;
|
||||
int i;
|
||||
grub_uint8_t *nbd;
|
||||
grub_net_link_level_address_t ll_target_addr;
|
||||
|
||||
+ if (!in_port)
|
||||
+ {
|
||||
+ in_port = get_initial_base_port ();
|
||||
+ grub_dprintf ("net", "base port: %d\n", in_port);
|
||||
+ }
|
||||
+
|
||||
err = grub_net_resolve_address (server, &addr);
|
||||
if (err)
|
||||
return NULL;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From f0a08324d0f923527ba611887a3780c1f2cb1578 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Tue, 21 Jan 2025 11:01:26 -0600
|
||||
Subject: [PATCH] term/ns8250-spcr: Return if redirection is disabled
|
||||
|
||||
The Microsoft spec for SPCR says "The base address of the Serial Port
|
||||
register set described using the ACPI Generic Address Structure, or
|
||||
0 if console redirection is disabled". So, return early if redirection
|
||||
is disabled (base address = 0). If this check is not done we may get
|
||||
invalid ports on machines with redirection disabled and boot may hang
|
||||
when reading the grub.cfg file.
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/term/ns8250-spcr.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/grub-core/term/ns8250-spcr.c b/grub-core/term/ns8250-spcr.c
|
||||
index 4efaaf768..428b2d59a 100644
|
||||
--- a/grub-core/term/ns8250-spcr.c
|
||||
+++ b/grub-core/term/ns8250-spcr.c
|
||||
@@ -76,6 +76,11 @@ grub_ns8250_spcr_init (void)
|
||||
config.speed = 115200;
|
||||
break;
|
||||
};
|
||||
+
|
||||
+ /* If base address is 0 it means redirection is disabled. */
|
||||
+ if (spcr->base_addr.addr == 0)
|
||||
+ return NULL;
|
||||
+
|
||||
switch (spcr->base_addr.space_id)
|
||||
{
|
||||
case GRUB_ACPI_GENADDR_MEM_SPACE:
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
From 6c06378c1bf6ae21788427e62ab0011b7f1bc2f0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 25 Nov 2022 16:11:24 +0800
|
||||
Subject: [PATCH] xen_boot: add missing grub_arch_efi_linux_load_image_header
|
||||
|
||||
The new xen_boot module has used grub_arch_efi_linux_load_image_header
|
||||
exported by grub-core/loader/arm64/linux.c. It is not a problem for
|
||||
upstream but many downstream projects may not use it and take
|
||||
grub-core/loader/arm64/efi/linux.c as a replacement as PE entry is the
|
||||
preferred way in combination with shim loader.
|
||||
|
||||
This patch did a trivial workaround just adding back the dropped
|
||||
defintion to the xen_boot itself.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/arm64/xen_boot.c | 50 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
|
||||
index 26e1472c9..b82a2db89 100644
|
||||
--- a/grub-core/loader/arm64/xen_boot.c
|
||||
+++ b/grub-core/loader/arm64/xen_boot.c
|
||||
@@ -84,6 +84,56 @@ static int loaded;
|
||||
static struct xen_boot_binary *xen_hypervisor;
|
||||
static struct xen_boot_binary *module_head;
|
||||
|
||||
+/* The function is exported by grub-core/loader/arm64/linux.c that is not built
|
||||
+ * because we use PE entry provided by grub-core/loader/arm64/efi/linux.c
|
||||
+ */
|
||||
+static bool initrd_use_loadfile2 = false;
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_arch_efi_linux_load_image_header (grub_file_t file,
|
||||
+ struct linux_arch_kernel_header * lh)
|
||||
+{
|
||||
+ grub_file_seek (file, 0);
|
||||
+ if (grub_file_read (file, lh, sizeof (*lh)) < (grub_ssize_t) sizeof (*lh))
|
||||
+ return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image header");
|
||||
+
|
||||
+ if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
|
||||
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
+ N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
|
||||
+
|
||||
+ grub_dprintf ("linux", "UEFI stub kernel:\n");
|
||||
+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
|
||||
+
|
||||
+ /*
|
||||
+ * The PE/COFF spec permits the COFF header to appear anywhere in the file, so
|
||||
+ * we need to double check whether it was where we expected it, and if not, we
|
||||
+ * must load it from the correct offset into the pe_image_header field of
|
||||
+ * struct linux_arch_kernel_header.
|
||||
+ */
|
||||
+ if ((grub_uint8_t *) lh + lh->hdr_offset != (grub_uint8_t *) &lh->pe_image_header)
|
||||
+ {
|
||||
+ if (grub_file_seek (file, lh->hdr_offset) == (grub_off_t) -1
|
||||
+ || grub_file_read (file, &lh->pe_image_header,
|
||||
+ sizeof (struct grub_pe_image_header))
|
||||
+ != sizeof (struct grub_pe_image_header))
|
||||
+ return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Linux kernels built for any architecture are guaranteed to support the
|
||||
+ * LoadFile2 based initrd loading protocol if the image version is >= 1.
|
||||
+ */
|
||||
+ if (lh->pe_image_header.optional_header.major_image_version >= 1)
|
||||
+ initrd_use_loadfile2 = true;
|
||||
+ else
|
||||
+ initrd_use_loadfile2 = false;
|
||||
+
|
||||
+ grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
|
||||
+ initrd_use_loadfile2 ? "en" : "dis");
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static __inline grub_addr_t
|
||||
xen_boot_address_align (grub_addr_t start, grub_size_t align)
|
||||
{
|
||||
--
|
||||
2.41.0
|
||||
|
||||
91
0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch
Normal file
91
0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch
Normal file
@@ -0,0 +1,91 @@
|
||||
From 7126da87f17ff41334b9fa6969ad032ff9940979 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Wed, 13 Aug 2025 09:57:04 +0800
|
||||
Subject: [PATCH 2/2] lib/pbkdf2: Optimize PBKDF2 by reusing HMAC handle
|
||||
|
||||
The previous PBKDF2 implementation used grub_crypto_hmac_buffer(), which
|
||||
allocates and frees an HMAC handle on every call. This approach caused
|
||||
significant performance overhead, slowing down the boot process
|
||||
considerably.
|
||||
|
||||
This commit refactors the PBKDF2 code to use the new HMAC functions,
|
||||
allowing the HMAC handle and its buffers to be allocated once and reused
|
||||
across multiple operations. This change significantly reduces disk
|
||||
unlocking time.
|
||||
|
||||
In a QEMU/OVMF test environment, this patch reduced the time to unlock a
|
||||
LUKS2(*) partition from approximately 15 seconds to 4 seconds.
|
||||
|
||||
(*) PBKDF2 SHA256 with 3454944 iterations
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/lib/pbkdf2.c | 21 +++++++++++++--------
|
||||
1 file changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/pbkdf2.c b/grub-core/lib/pbkdf2.c
|
||||
index 28aa96c46..410eff580 100644
|
||||
--- a/grub-core/lib/pbkdf2.c
|
||||
+++ b/grub-core/lib/pbkdf2.c
|
||||
@@ -39,6 +39,7 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
unsigned int c,
|
||||
grub_uint8_t *DK, grub_size_t dkLen)
|
||||
{
|
||||
+ struct grub_crypto_hmac_handle *hnd = NULL;
|
||||
unsigned int hLen = md->mdlen;
|
||||
grub_uint8_t U[GRUB_CRYPTO_MAX_MDLEN];
|
||||
grub_uint8_t T[GRUB_CRYPTO_MAX_MDLEN];
|
||||
@@ -47,7 +48,6 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
unsigned int r;
|
||||
unsigned int i;
|
||||
unsigned int k;
|
||||
- gcry_err_code_t rc;
|
||||
grub_uint8_t *tmp;
|
||||
grub_size_t tmplen = Slen + 4;
|
||||
|
||||
@@ -72,6 +72,13 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
|
||||
grub_memcpy (tmp, S, Slen);
|
||||
|
||||
+ hnd = grub_crypto_hmac_init (md, P, Plen);
|
||||
+ if (hnd == NULL)
|
||||
+ {
|
||||
+ grub_free (tmp);
|
||||
+ return GPG_ERR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+
|
||||
for (i = 1; i - 1 < l; i++)
|
||||
{
|
||||
grub_memset (T, 0, hLen);
|
||||
@@ -85,16 +92,13 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
|
||||
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
|
||||
|
||||
- rc = grub_crypto_hmac_buffer (md, P, Plen, tmp, tmplen, U);
|
||||
+ grub_crypto_hmac_write (hnd, tmp, tmplen);
|
||||
}
|
||||
else
|
||||
- rc = grub_crypto_hmac_buffer (md, P, Plen, U, hLen, U);
|
||||
+ grub_crypto_hmac_write (hnd, U, hLen);
|
||||
|
||||
- if (rc != GPG_ERR_NO_ERROR)
|
||||
- {
|
||||
- grub_free (tmp);
|
||||
- return rc;
|
||||
- }
|
||||
+ grub_crypto_hmac_final (hnd, U);
|
||||
+ grub_crypto_hmac_reset (hnd);
|
||||
|
||||
for (k = 0; k < hLen; k++)
|
||||
T[k] ^= U[k];
|
||||
@@ -103,6 +107,7 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
grub_memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
|
||||
}
|
||||
|
||||
+ grub_crypto_hmac_free (hnd);
|
||||
grub_free (tmp);
|
||||
|
||||
return GPG_ERR_NO_ERROR;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
113
0002-linux-fallback-to-direct-PE-entry-boot-on-arm64.patch
Normal file
113
0002-linux-fallback-to-direct-PE-entry-boot-on-arm64.patch
Normal file
@@ -0,0 +1,113 @@
|
||||
From 1e5d19972bb64b0fcb39083042a69cf05e0cb783 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 26 Apr 2025 15:33:28 +0800
|
||||
Subject: [PATCH 2/4] linux: fallback to direct PE entry boot on arm64
|
||||
|
||||
On the arm64 platform, when the shim loader protocol is unavailable and
|
||||
UEFI Secure Boot is enabled, fall back to booting via the direct PE/COFF
|
||||
image entry point instead of requesting UEFI to load and start the
|
||||
image. This fallback allows booting binaries validated by shim's vendor
|
||||
DB, even if they are not listed in the UEFI DB.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/loader/arm64/efi/linux.c | 26 +++++++-------------------
|
||||
grub-core/loader/efi/linux.c | 6 +++---
|
||||
3 files changed, 11 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 1811661c3..2100d7ff2 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1898,6 +1898,7 @@ module = {
|
||||
arm_coreboot = loader/arm/linux.c;
|
||||
arm_efi = loader/efi/linux.c;
|
||||
arm_uboot = loader/arm/linux.c;
|
||||
+ arm64 = loader/efi/linux.c;
|
||||
arm64 = loader/arm64/efi/linux.c;
|
||||
loongarch64 = loader/efi/linux.c;
|
||||
riscv32 = loader/efi/linux.c;
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index a9f5e05e4..8eab1dc86 100644
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -190,8 +190,8 @@ free_params (void)
|
||||
}
|
||||
}
|
||||
|
||||
-grub_err_t
|
||||
-grub_arch_efi_linux_boot_image (grub_addr_t addr,
|
||||
+static grub_err_t
|
||||
+grub_arm64_efi_linux_boot_image (grub_addr_t addr,
|
||||
grub_size_t size __attribute__ ((unused)),
|
||||
char *args)
|
||||
{
|
||||
@@ -213,7 +213,7 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr,
|
||||
static grub_err_t
|
||||
grub_linux_boot (void)
|
||||
{
|
||||
- return (grub_arch_efi_linux_boot_image ((grub_addr_t)kernel_addr, kernel_size, linux_args));
|
||||
+ return (grub_arm64_efi_linux_boot_image ((grub_addr_t)kernel_addr, kernel_size, linux_args));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -464,20 +464,8 @@ fail:
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
+extern grub_err_t __attribute__((alias("grub_cmd_linux")))
|
||||
+grub_cmd_linux_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
|
||||
-static grub_command_t cmd_linux, cmd_initrd;
|
||||
-
|
||||
-GRUB_MOD_INIT (linux)
|
||||
-{
|
||||
- cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
|
||||
- N_("Load Linux."));
|
||||
- cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
|
||||
- N_("Load initrd."));
|
||||
- my_mod = mod;
|
||||
-}
|
||||
-
|
||||
-GRUB_MOD_FINI (linux)
|
||||
-{
|
||||
- grub_unregister_command (cmd_linux);
|
||||
- grub_unregister_command (cmd_initrd);
|
||||
-}
|
||||
+extern grub_err_t __attribute__((alias("grub_cmd_initrd")))
|
||||
+grub_cmd_initrd_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index b20dec404..d29e32cba 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -388,7 +388,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
-#if defined(__i386__) || defined(__x86_64__)
|
||||
+#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
|
||||
if (grub_is_using_legacy_shim_lock_protocol () == true ||
|
||||
!initrd_use_loadfile2)
|
||||
return grub_cmd_initrd_efi_fallback (cmd, argc, argv);
|
||||
@@ -472,7 +472,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
if (grub_is_using_legacy_shim_lock_protocol () == true)
|
||||
{
|
||||
-#if defined(__i386__) || defined(__x86_64__)
|
||||
+#if defined(__i386__) || defined(__x86_64__) || defined (__aarch64__)
|
||||
grub_dprintf ("linux", "using legacy shim_lock protocol, falling back to legacy Linux kernel loader\n");
|
||||
|
||||
err = grub_cmd_linux_efi_fallback (cmd, argc, argv);
|
||||
@@ -499,7 +499,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
kernel_size = grub_file_size (file);
|
||||
|
||||
if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE)
|
||||
-#if !defined(__i386__) && !defined(__x86_64__)
|
||||
+#if !defined(__i386__) && !defined(__x86_64__) && !defined (__aarch64__)
|
||||
goto fail;
|
||||
#else
|
||||
goto fallback;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
44
0002-modules-Strip-.llvm_addrsig-sections-and-similar.patch
Normal file
44
0002-modules-Strip-.llvm_addrsig-sections-and-similar.patch
Normal file
@@ -0,0 +1,44 @@
|
||||
From 5407ea9241aae78a724f00126e4e6b49dd08e92b Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 9 Oct 2024 09:16:37 +0100
|
||||
Subject: [PATCH 02/13] modules: Strip .llvm_addrsig sections and similar
|
||||
|
||||
Currently GRUB modules built with Clang or GCC have several sections
|
||||
which we don't actually need or support. We already have a list of
|
||||
sections to skip in genmod.sh and this patch adds the following
|
||||
sections to that list (as well as a few newlines):
|
||||
- .note.gnu.property
|
||||
- .llvm*
|
||||
|
||||
Note that the glob there won't work without a new enough linker but the
|
||||
failure is just reversion to the status quo. So, that's not a big problem.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-By: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/genmod.sh.in | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in
|
||||
index e57c4d920..337753c57 100644
|
||||
--- a/grub-core/genmod.sh.in
|
||||
+++ b/grub-core/genmod.sh.in
|
||||
@@ -57,8 +57,11 @@ if test x@TARGET_APPLE_LINKER@ != x1; then
|
||||
@TARGET_STRIP@ --strip-unneeded \
|
||||
-K grub_mod_init -K grub_mod_fini \
|
||||
-K _grub_mod_init -K _grub_mod_fini \
|
||||
- -R .note.gnu.gold-version -R .note.GNU-stack \
|
||||
+ -R .note.GNU-stack \
|
||||
+ -R .note.gnu.gold-version \
|
||||
+ -R .note.gnu.property \
|
||||
-R .gnu.build.attributes \
|
||||
+ -R '.llvm*' \
|
||||
-R .rel.gnu.build.attributes \
|
||||
-R .rela.gnu.build.attributes \
|
||||
-R .eh_frame -R .rela.eh_frame -R .rel.eh_frame \
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
From 43b0319936f51dc6b4cba3518449195924e83dc8 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 26 Apr 2025 15:39:43 +0800
|
||||
Subject: [PATCH 3/4] efi/chainloader: fallback to direct image execution
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When the shim loader protocol is unavailable and UEFI Secure Boot is
|
||||
enabled, fall back to chainloading the PE/COFF image by manually
|
||||
relocating it to the loaded memory address and jumping to its entry
|
||||
point, rather than invoking UEFI to load and start the image. This
|
||||
fallback supports booting binaries validated by shim’s vendor DB, even
|
||||
if they are not present in the UEFI DB.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 1830de223..7e2847217 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -805,10 +805,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
#ifdef SUPPORT_SECURE_BOOT
|
||||
/* FIXME is secure boot possible also with universal binaries? */
|
||||
- if (debug_secureboot || (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED && grub_secure_validate ((void *)address, size)))
|
||||
+ if (debug_secureboot ||
|
||||
+ (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED &&
|
||||
+ grub_is_using_legacy_shim_lock_protocol () == true &&
|
||||
+ grub_secure_validate ((void *)address, size)))
|
||||
{
|
||||
struct grub_secureboot_chainloader_context *sb_context;
|
||||
|
||||
+ grub_dprintf ("chain", "Falling back to PE loader\n");
|
||||
sb_context = grub_malloc (sizeof (*sb_context));
|
||||
if (!sb_context)
|
||||
goto fail;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
From 5696bf9bebb17b6a7837163149287586b90dc14c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 9 Oct 2024 09:16:38 +0100
|
||||
Subject: [PATCH 03/13] modules: Don't allocate space for non-allocable
|
||||
sections
|
||||
|
||||
Currently when loading GRUB modules we allocate space for all sections
|
||||
including those without SHF_ALLOC set. We then copy the sections that
|
||||
/do/ have SHF_ALLOC set into the allocated memory leaving some of our
|
||||
allocation untouched forever. Additionally, on platforms with GOT fixups
|
||||
and trampolines we currently compute alignment round-ups for the
|
||||
sections and sections with sh_size = 0. This patch removes the extra
|
||||
space from the allocation computation and makes the allocation
|
||||
computation loop skip empty sections as the loading loop does.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-By: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/dl.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
||||
index 73a5b9e0f..6af031072 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -241,6 +241,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||
i < e->e_shnum;
|
||||
i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
|
||||
{
|
||||
+ if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC))
|
||||
+ continue;
|
||||
+
|
||||
tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size;
|
||||
if (talign < s->sh_addralign)
|
||||
talign = s->sh_addralign;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
From e2a6f238920ab547d216ce96283bca6faf36378b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 30 Apr 2025 21:16:50 +0800
|
||||
Subject: [PATCH 4/4] efi/chainloader: fix missing file_path in loaded_image
|
||||
|
||||
The file_path field in the loaded_image protocol may be unset for
|
||||
chainloaded target images. When this occurs, populate the file_path to
|
||||
ensure the target image can use the loaded_image protocol for location
|
||||
dependent operations, such as reading configuration files from its
|
||||
directory. Without this, the chainloaded image may fail to start due to
|
||||
an inability to reconfigure itself properly.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 52 +++++++++++++++++-------------
|
||||
1 file changed, 29 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 7e2847217..9b70e1e61 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -222,6 +222,29 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
||||
return file_path;
|
||||
}
|
||||
|
||||
+static grub_efi_device_path_t *
|
||||
+grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
|
||||
+{
|
||||
+ while (1)
|
||||
+ {
|
||||
+ grub_efi_uint8_t type;
|
||||
+ grub_efi_uint8_t subtype;
|
||||
+
|
||||
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
|
||||
+ break;
|
||||
+
|
||||
+ type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
+ subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
+
|
||||
+ if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
|
||||
+ return dp;
|
||||
+
|
||||
+ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
#ifdef SUPPORT_SECURE_BOOT
|
||||
#define SHIM_LOCK_GUID \
|
||||
{ 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
|
||||
@@ -461,29 +484,6 @@ relocate_coff (pe_coff_loader_image_context_t *context, void *data)
|
||||
return GRUB_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
-static grub_efi_device_path_t *
|
||||
-grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- grub_efi_uint8_t type;
|
||||
- grub_efi_uint8_t subtype;
|
||||
-
|
||||
- if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
|
||||
- break;
|
||||
-
|
||||
- type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
- subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
-
|
||||
- if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
|
||||
- return dp;
|
||||
-
|
||||
- dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
|
||||
- }
|
||||
-
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
static grub_efi_boolean_t
|
||||
handle_image (struct grub_secureboot_chainloader_context *load_context)
|
||||
{
|
||||
@@ -881,6 +881,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
loaded_image->device_handle = dev_handle;
|
||||
|
||||
+ if (! loaded_image->file_path)
|
||||
+ {
|
||||
+ grub_dprintf ("chain", "bailout file_path\n");
|
||||
+ loaded_image->file_path = grub_efi_get_media_file_path (file_path);
|
||||
+ }
|
||||
+
|
||||
/* Build load options with arguments from chainloader command line. */
|
||||
if (cmdline)
|
||||
{
|
||||
--
|
||||
2.50.1
|
||||
|
||||
170
0004-modules-Load-module-sections-at-page-aligned-address.patch
Normal file
170
0004-modules-Load-module-sections-at-page-aligned-address.patch
Normal file
@@ -0,0 +1,170 @@
|
||||
From db7bee2f67310219f7431b28a4b6c1385ac211d3 Mon Sep 17 00:00:00 2001
|
||||
From: Mate Kukri <mate.kukri@canonical.com>
|
||||
Date: Wed, 9 Oct 2024 09:16:39 +0100
|
||||
Subject: [PATCH 04/13] modules: Load module sections at page-aligned addresses
|
||||
|
||||
Currently we load module sections at whatever alignment gcc+ld happened
|
||||
to dump into the ELF section header which is often less then the page
|
||||
size. Since NX protections are page based this alignment must be rounded
|
||||
up to page size on platforms supporting NX protections. This patch
|
||||
switches EFI platforms to load module sections at 4 KiB page-aligned
|
||||
addresses. It then changes the allocation size computation and the
|
||||
loader code in grub_dl_load_segments() to align the locations and sizes
|
||||
up to these boundaries and fills any added padding with zeros. All of
|
||||
this happens before relocations are applied, so the relocations factor
|
||||
that in with no change.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/dl.c | 54 ++++++++++++++++++++++++++++++---------------
|
||||
1 file changed, 36 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
||||
index 6af031072..b384412d1 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <grub/cache.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+#include <grub/efi/memory.h>
|
||||
+#endif
|
||||
+
|
||||
/* Platforms where modules are in a readonly area of memory. */
|
||||
#if defined(GRUB_MACHINE_QEMU)
|
||||
#define GRUB_MODULES_MACHINE_READONLY
|
||||
@@ -40,10 +44,11 @@
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
#include <grub/efi/sb.h>
|
||||
+#define DL_ALIGN GRUB_EFI_PAGE_SIZE
|
||||
+#else
|
||||
+#define DL_ALIGN 1
|
||||
#endif
|
||||
|
||||
-
|
||||
-
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
grub_dl_t grub_dl_head = 0;
|
||||
@@ -228,25 +233,34 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||
{
|
||||
unsigned i;
|
||||
const Elf_Shdr *s;
|
||||
- grub_size_t tsize = 0, talign = 1;
|
||||
+ grub_size_t tsize = 0, talign = 1, arch_addralign = 1;
|
||||
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
|
||||
!defined (__loongarch__) && !defined (__s390x__)
|
||||
grub_size_t tramp;
|
||||
+ grub_size_t tramp_align;
|
||||
grub_size_t got;
|
||||
+ grub_size_t got_align;
|
||||
grub_err_t err;
|
||||
#endif
|
||||
char *ptr;
|
||||
|
||||
+ arch_addralign = DL_ALIGN;
|
||||
+
|
||||
for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
|
||||
i < e->e_shnum;
|
||||
i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
|
||||
{
|
||||
+ grub_size_t sh_addralign;
|
||||
+ grub_size_t sh_size;
|
||||
+
|
||||
if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC))
|
||||
continue;
|
||||
|
||||
- tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size;
|
||||
- if (talign < s->sh_addralign)
|
||||
- talign = s->sh_addralign;
|
||||
+ sh_addralign = ALIGN_UP (s->sh_addralign, arch_addralign);
|
||||
+ sh_size = ALIGN_UP (s->sh_size, sh_addralign);
|
||||
+
|
||||
+ tsize = ALIGN_UP (tsize, sh_addralign) + sh_size;
|
||||
+ talign = grub_max (talign, sh_addralign);
|
||||
}
|
||||
|
||||
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
|
||||
@@ -254,12 +268,12 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||
err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
|
||||
if (err)
|
||||
return err;
|
||||
- tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN);
|
||||
- if (talign < GRUB_ARCH_DL_TRAMP_ALIGN)
|
||||
- talign = GRUB_ARCH_DL_TRAMP_ALIGN;
|
||||
- tsize += ALIGN_UP (got, GRUB_ARCH_DL_GOT_ALIGN);
|
||||
- if (talign < GRUB_ARCH_DL_GOT_ALIGN)
|
||||
- talign = GRUB_ARCH_DL_GOT_ALIGN;
|
||||
+ tramp_align = grub_max (GRUB_ARCH_DL_TRAMP_ALIGN, arch_addralign);
|
||||
+ tsize += ALIGN_UP (tramp, tramp_align);
|
||||
+ talign = grub_max (talign, tramp_align);
|
||||
+ got_align = grub_max (GRUB_ARCH_DL_GOT_ALIGN, arch_addralign);
|
||||
+ tsize += ALIGN_UP (got, got_align);
|
||||
+ talign = grub_max (talign, got_align);
|
||||
#endif
|
||||
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
@@ -276,6 +290,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||
i < e->e_shnum;
|
||||
i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
|
||||
{
|
||||
+ grub_size_t sh_addralign = ALIGN_UP (s->sh_addralign, arch_addralign);
|
||||
+ grub_size_t sh_size = ALIGN_UP (s->sh_size, sh_addralign);
|
||||
+
|
||||
if (s->sh_flags & SHF_ALLOC)
|
||||
{
|
||||
grub_dl_segment_t seg;
|
||||
@@ -288,17 +305,18 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign);
|
||||
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, sh_addralign);
|
||||
addr = ptr;
|
||||
- ptr += s->sh_size;
|
||||
+ ptr += sh_size;
|
||||
|
||||
switch (s->sh_type)
|
||||
{
|
||||
case SHT_PROGBITS:
|
||||
grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
|
||||
+ grub_memset ((char *) addr + s->sh_size, 0, sh_size - s->sh_size);
|
||||
break;
|
||||
case SHT_NOBITS:
|
||||
- grub_memset (addr, 0, s->sh_size);
|
||||
+ grub_memset (addr, 0, sh_size);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -307,7 +325,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||
else
|
||||
seg->addr = 0;
|
||||
|
||||
- seg->size = s->sh_size;
|
||||
+ seg->size = sh_size;
|
||||
seg->section = i;
|
||||
seg->next = mod->segment;
|
||||
mod->segment = seg;
|
||||
@@ -315,11 +333,11 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
|
||||
}
|
||||
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
|
||||
!defined (__loongarch__) && !defined (__s390x__)
|
||||
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
|
||||
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, tramp_align);
|
||||
mod->tramp = ptr;
|
||||
mod->trampptr = ptr;
|
||||
ptr += tramp;
|
||||
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN);
|
||||
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, got_align);
|
||||
mod->got = ptr;
|
||||
mod->gotptr = ptr;
|
||||
ptr += got;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
236
0005-nx-Add-memory-attribute-get-set-API.patch
Normal file
236
0005-nx-Add-memory-attribute-get-set-API.patch
Normal file
@@ -0,0 +1,236 @@
|
||||
From ae9bf340b0ae7b0b8f968e89468d7eac13583a8d Mon Sep 17 00:00:00 2001
|
||||
From: Mate Kukri <mate.kukri@canonical.com>
|
||||
Date: Wed, 9 Oct 2024 09:16:40 +0100
|
||||
Subject: [PATCH 05/13] nx: Add memory attribute get/set API
|
||||
|
||||
For NX we need to set the page access permission attributes for write
|
||||
and execute permissions. This patch adds two new primitives, grub_set_mem_attrs()
|
||||
and grub_clear_mem_attrs(), and associated constants definitions used
|
||||
for that purpose. For most platforms it adds a dummy implementation.
|
||||
On EFI platforms it implements the primitives using the EFI Memory
|
||||
Attribute Protocol, defined in UEFI 2.10 specification.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 109 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/grub/efi/api.h | 25 +++++++++
|
||||
include/grub/mm.h | 35 +++++++++++++
|
||||
3 files changed, 169 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||
index 9b1d3add7..93566e916 100644
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -736,3 +736,112 @@ grub_efi_get_ram_base(grub_addr_t *base_addr)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+static grub_uint64_t
|
||||
+grub_mem_attrs_to_uefi_mem_attrs (grub_mem_attr_t attrs)
|
||||
+{
|
||||
+ grub_efi_uint64_t ret = GRUB_EFI_MEMORY_RP | GRUB_EFI_MEMORY_RO | GRUB_EFI_MEMORY_XP;
|
||||
+
|
||||
+ if (attrs & GRUB_MEM_ATTR_R)
|
||||
+ ret &= ~GRUB_EFI_MEMORY_RP;
|
||||
+
|
||||
+ if (attrs & GRUB_MEM_ATTR_W)
|
||||
+ ret &= ~GRUB_EFI_MEMORY_RO;
|
||||
+
|
||||
+ if (attrs & GRUB_MEM_ATTR_X)
|
||||
+ ret &= ~GRUB_EFI_MEMORY_XP;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static grub_mem_attr_t
|
||||
+uefi_mem_attrs_to_grub_mem_attrs (grub_efi_uint64_t attrs)
|
||||
+{
|
||||
+ grub_mem_attr_t ret = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X;
|
||||
+
|
||||
+ if (attrs & GRUB_EFI_MEMORY_RP)
|
||||
+ ret &= ~GRUB_MEM_ATTR_R;
|
||||
+
|
||||
+ if (attrs & GRUB_EFI_MEMORY_RO)
|
||||
+ ret &= ~GRUB_MEM_ATTR_W;
|
||||
+
|
||||
+ if (attrs & GRUB_EFI_MEMORY_XP)
|
||||
+ ret &= ~GRUB_MEM_ATTR_X;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_get_mem_attrs (grub_addr_t addr, grub_size_t size, grub_mem_attr_t *attrs)
|
||||
+{
|
||||
+ grub_efi_memory_attribute_protocol_t *proto;
|
||||
+ grub_efi_physical_address_t physaddr = addr;
|
||||
+ static grub_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
|
||||
+ grub_efi_status_t efi_status;
|
||||
+ grub_efi_uint64_t efi_attrs;
|
||||
+
|
||||
+ if (physaddr & (GRUB_EFI_PAGE_SIZE - 1) || size & (GRUB_EFI_PAGE_SIZE - 1) || size == 0 || attrs == NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__);
|
||||
+
|
||||
+ proto = grub_efi_locate_protocol (&protocol_guid, 0);
|
||||
+ if (proto == NULL)
|
||||
+ {
|
||||
+ /* No protocol -> do nothing, all memory is RWX in boot services */
|
||||
+ *attrs = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ efi_status = proto->get_memory_attributes (proto, physaddr, size, &efi_attrs);
|
||||
+ if (efi_status != GRUB_EFI_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__);
|
||||
+
|
||||
+ *attrs = uefi_mem_attrs_to_grub_mem_attrs (efi_attrs);
|
||||
+
|
||||
+ grub_dprintf ("nx", "get 0x%" PRIxGRUB_ADDR "-0x%" PRIxGRUB_ADDR ":%c%c%c\n",
|
||||
+ addr, addr + size - 1,
|
||||
+ (*attrs & GRUB_MEM_ATTR_R) ? 'r' : '-',
|
||||
+ (*attrs & GRUB_MEM_ATTR_W) ? 'w' : '-',
|
||||
+ (*attrs & GRUB_MEM_ATTR_X) ? 'x' : '-');
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_update_mem_attrs (grub_addr_t addr, grub_size_t size,
|
||||
+ grub_mem_attr_t set_attrs, grub_mem_attr_t clear_attrs)
|
||||
+{
|
||||
+ grub_efi_memory_attribute_protocol_t *proto;
|
||||
+ grub_efi_physical_address_t physaddr = addr;
|
||||
+ static grub_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
|
||||
+ grub_efi_status_t efi_status = GRUB_EFI_SUCCESS;
|
||||
+ grub_efi_uint64_t uefi_set_attrs, uefi_clear_attrs;
|
||||
+
|
||||
+ if (physaddr & (GRUB_EFI_PAGE_SIZE - 1) || size & (GRUB_EFI_PAGE_SIZE - 1) || size == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__);
|
||||
+
|
||||
+ proto = grub_efi_locate_protocol (&protocol_guid, 0);
|
||||
+ if (proto == NULL)
|
||||
+ /* No protocol -> do nothing, all memory is RWX in boot services */
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ uefi_set_attrs = grub_mem_attrs_to_uefi_mem_attrs (set_attrs);
|
||||
+ uefi_clear_attrs = grub_mem_attrs_to_uefi_mem_attrs (clear_attrs);
|
||||
+ if (uefi_set_attrs)
|
||||
+ efi_status = proto->set_memory_attributes (proto, physaddr, size, uefi_set_attrs);
|
||||
+ if (efi_status == GRUB_EFI_SUCCESS && uefi_clear_attrs)
|
||||
+ efi_status = proto->clear_memory_attributes (proto, physaddr, size, uefi_clear_attrs);
|
||||
+
|
||||
+ if (efi_status != GRUB_EFI_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__);
|
||||
+
|
||||
+ grub_dprintf ("nx", "set +%s%s%s -%s%s%s on 0x%" PRIxGRUB_ADDR "-0x%" PRIxGRUB_ADDR "\n",
|
||||
+ (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
|
||||
+ (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
|
||||
+ (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
|
||||
+ (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
|
||||
+ (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
|
||||
+ (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
|
||||
+ addr, addr + size - 1);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
|
||||
index 975b90b09..5d1aada34 100644
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -394,6 +394,11 @@
|
||||
{ 0x93, 0x87, 0x6d, 0x87, 0x60, 0x50, 0xdc, 0x67 } \
|
||||
}
|
||||
|
||||
+#define GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \
|
||||
+ { 0xf4560cf6, 0x40ec, 0x4b4a, \
|
||||
+ { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \
|
||||
+ }
|
||||
+
|
||||
struct grub_efi_sal_system_table
|
||||
{
|
||||
grub_uint32_t signature;
|
||||
@@ -2105,4 +2110,24 @@ struct grub_efi_ip6_config_manual_address {
|
||||
};
|
||||
typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_address_t;
|
||||
|
||||
+struct grub_efi_memory_attribute_protocol
|
||||
+{
|
||||
+ grub_efi_status_t (__grub_efi_api *get_memory_attributes) (
|
||||
+ struct grub_efi_memory_attribute_protocol *this,
|
||||
+ grub_efi_physical_address_t base_address,
|
||||
+ grub_efi_uint64_t length,
|
||||
+ grub_efi_uint64_t *attributes);
|
||||
+ grub_efi_status_t (__grub_efi_api *set_memory_attributes) (
|
||||
+ struct grub_efi_memory_attribute_protocol *this,
|
||||
+ grub_efi_physical_address_t base_address,
|
||||
+ grub_efi_uint64_t length,
|
||||
+ grub_efi_uint64_t attributes);
|
||||
+ grub_efi_status_t (__grub_efi_api *clear_memory_attributes) (
|
||||
+ struct grub_efi_memory_attribute_protocol *this,
|
||||
+ grub_efi_physical_address_t base_address,
|
||||
+ grub_efi_uint64_t length,
|
||||
+ grub_efi_uint64_t attributes);
|
||||
+};
|
||||
+typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_protocol_t;
|
||||
+
|
||||
#endif /* ! GRUB_EFI_API_HEADER */
|
||||
diff --git a/include/grub/mm.h b/include/grub/mm.h
|
||||
index 75894dbbe..494133b4c 100644
|
||||
--- a/include/grub/mm.h
|
||||
+++ b/include/grub/mm.h
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <grub/err.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/symbol.h>
|
||||
+#include <grub/err.h>
|
||||
#include <config.h>
|
||||
|
||||
#ifndef NULL
|
||||
@@ -86,6 +87,40 @@ grub_calloc (grub_size_t nmemb, grub_size_t size)
|
||||
void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
|
||||
#endif
|
||||
|
||||
+typedef grub_uint64_t grub_mem_attr_t;
|
||||
+
|
||||
+#define GRUB_MEM_ATTR_R ((grub_mem_attr_t) 0x0000000000000004)
|
||||
+#define GRUB_MEM_ATTR_W ((grub_mem_attr_t) 0x0000000000000002)
|
||||
+#define GRUB_MEM_ATTR_X ((grub_mem_attr_t) 0x0000000000000001)
|
||||
+
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t EXPORT_FUNC(grub_get_mem_attrs) (grub_addr_t addr,
|
||||
+ grub_size_t size,
|
||||
+ grub_mem_attr_t *attrs);
|
||||
+grub_err_t EXPORT_FUNC(grub_update_mem_attrs) (grub_addr_t addr,
|
||||
+ grub_size_t size,
|
||||
+ grub_mem_attr_t set_attrs,
|
||||
+ grub_mem_attr_t clear_attrs);
|
||||
+#else /* !GRUB_MACHINE_EFI */
|
||||
+static inline grub_err_t
|
||||
+grub_get_mem_attrs (grub_addr_t addr __attribute__((__unused__)),
|
||||
+ grub_size_t size __attribute__((__unused__)),
|
||||
+ grub_mem_attr_t *attrs)
|
||||
+{
|
||||
+ *attrs = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static inline grub_err_t
|
||||
+grub_update_mem_attrs (grub_addr_t addr __attribute__((__unused__)),
|
||||
+ grub_size_t size __attribute__((__unused__)),
|
||||
+ grub_mem_attr_t set_attrs __attribute__((__unused__)),
|
||||
+ grub_mem_attr_t clear_attrs __attribute__((__unused__)))
|
||||
+{
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+#endif /* GRUB_MACHINE_EFI */
|
||||
+
|
||||
void grub_mm_check_real (const char *file, int line);
|
||||
#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__);
|
||||
|
||||
--
|
||||
2.50.1
|
||||
|
||||
135
0006-nx-Set-page-permissions-for-loaded-modules.patch
Normal file
135
0006-nx-Set-page-permissions-for-loaded-modules.patch
Normal file
@@ -0,0 +1,135 @@
|
||||
From 12e6c0f3ca23481a552cf3acd5365b1356add5c0 Mon Sep 17 00:00:00 2001
|
||||
From: Mate Kukri <mate.kukri@canonical.com>
|
||||
Date: Wed, 9 Oct 2024 09:16:41 +0100
|
||||
Subject: [PATCH 06/13] nx: Set page permissions for loaded modules
|
||||
|
||||
For NX we need to set write and executable permissions on the sections
|
||||
of GRUB modules when we load them. All allocatable sections are marked
|
||||
readable. In addition:
|
||||
- SHF_WRITE sections are marked as writable,
|
||||
- and SHF_EXECINSTR sections are marked as executable.
|
||||
|
||||
Where relevant for the platform the tramp and GOT areas are marked non-writable.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/dl.c | 91 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 90 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
||||
index b384412d1..da31db218 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -636,6 +636,94 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+/* Only define this on EFI to save space in core. */
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+static grub_err_t
|
||||
+grub_dl_set_mem_attrs (grub_dl_t mod, void *ehdr)
|
||||
+{
|
||||
+ unsigned i;
|
||||
+ const Elf_Shdr *s;
|
||||
+ const Elf_Ehdr *e = ehdr;
|
||||
+ grub_err_t err;
|
||||
+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
|
||||
+ !defined (__loongarch__)
|
||||
+ grub_size_t arch_addralign = GRUB_DL_ALIGN;
|
||||
+ grub_addr_t tgaddr;
|
||||
+ grub_size_t tgsz;
|
||||
+#endif
|
||||
+
|
||||
+ for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
|
||||
+ i < e->e_shnum;
|
||||
+ i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
|
||||
+ {
|
||||
+ grub_dl_segment_t seg;
|
||||
+ grub_uint64_t set_attrs = GRUB_MEM_ATTR_R;
|
||||
+ grub_uint64_t clear_attrs = GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X;
|
||||
+
|
||||
+ for (seg = mod->segment; seg; seg = seg->next)
|
||||
+ /* Does this ELF section's index match GRUB DL segment? */
|
||||
+ if (seg->section == s->sh_info)
|
||||
+ break;
|
||||
+
|
||||
+ /* No GRUB DL segment found for this ELF section, skip it. */
|
||||
+ if (!seg)
|
||||
+ continue;
|
||||
+
|
||||
+ if (seg->size == 0 || !(s->sh_flags & SHF_ALLOC))
|
||||
+ continue;
|
||||
+
|
||||
+ if (s->sh_flags & SHF_WRITE)
|
||||
+ {
|
||||
+ set_attrs |= GRUB_MEM_ATTR_W;
|
||||
+ clear_attrs &= ~GRUB_MEM_ATTR_W;
|
||||
+ }
|
||||
+
|
||||
+ if (s->sh_flags & SHF_EXECINSTR)
|
||||
+ {
|
||||
+ set_attrs |= GRUB_MEM_ATTR_X;
|
||||
+ clear_attrs &= ~GRUB_MEM_ATTR_X;
|
||||
+ }
|
||||
+
|
||||
+ err = grub_update_mem_attrs ((grub_addr_t) seg->addr, seg->size,
|
||||
+ set_attrs, clear_attrs);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
|
||||
+ !defined (__loongarch__)
|
||||
+ tgaddr = grub_min ((grub_addr_t) mod->tramp, (grub_addr_t) mod->got);
|
||||
+ tgsz = grub_max ((grub_addr_t) mod->trampptr, (grub_addr_t) mod->gotptr) - tgaddr;
|
||||
+
|
||||
+ if (tgsz)
|
||||
+ {
|
||||
+ tgsz = ALIGN_UP (tgsz, arch_addralign);
|
||||
+
|
||||
+ if (tgaddr < (grub_addr_t) mod->base ||
|
||||
+ tgsz > (grub_addr_t) -1 - tgaddr ||
|
||||
+ tgaddr + tgsz > (grub_addr_t) mod->base + mod->sz)
|
||||
+ return grub_error (GRUB_ERR_BUG,
|
||||
+ "BUG: trying to protect pages outside of module "
|
||||
+ "allocation (\"%s\"): module base %p, size 0x%"
|
||||
+ PRIxGRUB_SIZE "; tramp/GOT base 0x%" PRIxGRUB_ADDR
|
||||
+ ", size 0x%" PRIxGRUB_SIZE,
|
||||
+ mod->name, mod->base, mod->sz, tgaddr, tgsz);
|
||||
+ err = grub_update_mem_attrs (tgaddr, tgsz, GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_X, GRUB_MEM_ATTR_W);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+#else
|
||||
+static grub_err_t
|
||||
+grub_dl_set_mem_attrs (grub_dl_t mod __attribute__ ((unused)), void *ehdr __attribute__ ((unused)))
|
||||
+{
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* Load a module from core memory. */
|
||||
grub_dl_t
|
||||
grub_dl_load_core_noinit (void *addr, grub_size_t size)
|
||||
@@ -682,7 +770,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
|
||||
|| grub_dl_resolve_dependencies (mod, e)
|
||||
|| grub_dl_load_segments (mod, e)
|
||||
|| grub_dl_resolve_symbols (mod, e)
|
||||
- || grub_dl_relocate_symbols (mod, e))
|
||||
+ || grub_dl_relocate_symbols (mod, e)
|
||||
+ || grub_dl_set_mem_attrs (mod, e))
|
||||
{
|
||||
mod->fini = 0;
|
||||
grub_dl_unload (mod);
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From fad957c68f157ae0c30cab52d69d0dc4e74b9909 Mon Sep 17 00:00:00 2001
|
||||
From: Mate Kukri <mate.kukri@canonical.com>
|
||||
Date: Wed, 9 Oct 2024 09:16:42 +0100
|
||||
Subject: [PATCH 07/13] nx: Set the NX compatible flag for the GRUB EFI images
|
||||
|
||||
For NX the GRUB binary has to announce that it is compatible with the
|
||||
NX feature. This implies that when loading the executable GRUB image
|
||||
several attributes are true:
|
||||
- the binary doesn't need an executable stack,
|
||||
- the binary doesn't need sections to be both executable and writable,
|
||||
- the binary knows how to use the EFI Memory Attributes Protocol on code
|
||||
it is loading.
|
||||
|
||||
This patch:
|
||||
- adds a definition for the PE DLL Characteristics flag GRUB_PE32_NX_COMPAT,
|
||||
- changes grub-mkimage to set that flag.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
include/grub/efi/pe32.h | 2 ++
|
||||
util/mkimage.c | 1 +
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
|
||||
index 4e6e9d254..9887e14b2 100644
|
||||
--- a/include/grub/efi/pe32.h
|
||||
+++ b/include/grub/efi/pe32.h
|
||||
@@ -231,6 +231,8 @@ struct grub_pe64_optional_header
|
||||
|
||||
#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10
|
||||
|
||||
+#define GRUB_PE32_NX_COMPAT 0x0100
|
||||
+
|
||||
#define GRUB_PE32_NUM_DATA_DIRECTORIES 16
|
||||
|
||||
struct grub_pe32_section_table
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 6c0581836..5d7a47e70 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -1453,6 +1453,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdangling-pointer"
|
||||
#endif
|
||||
+ PE_OHDR (o32, o64, dll_characteristics) = grub_host_to_target16 (GRUB_PE32_NX_COMPAT);
|
||||
PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
|
||||
PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address);
|
||||
PE_OHDR (o32, o64, image_base) = 0;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
233
0008-efi-Provide-wrappers-for-load_image-start_image-and-.patch
Normal file
233
0008-efi-Provide-wrappers-for-load_image-start_image-and-.patch
Normal file
@@ -0,0 +1,233 @@
|
||||
From 24187b38b89d011f748e462b9ae684316c5e4d57 Mon Sep 17 00:00:00 2001
|
||||
From: Julian Andres Klode <julian.klode@canonical.com>
|
||||
Date: Tue, 8 Jul 2025 21:21:13 +0100
|
||||
Subject: [PATCH 08/13] efi: Provide wrappers for load_image, start_image and
|
||||
unload_image
|
||||
|
||||
These can be used to register a different implementation later,
|
||||
for example, when shim provides a protocol with those functions.
|
||||
|
||||
Signed-off-by: Julian Andres Klode <julian.klode@canonical.com>
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/efi/efi.c | 57 ++++++++++++++++++++++++++++++
|
||||
grub-core/loader/efi/chainloader.c | 13 +++----
|
||||
grub-core/loader/efi/linux.c | 12 +++----
|
||||
include/grub/efi/efi.h | 42 ++++++++++++++++++++++
|
||||
4 files changed, 109 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
||||
index b674816aa..1e330a2cc 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -1109,3 +1109,60 @@ grub_efi_find_configuration_table (const grub_guid_t *target_guid)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+static const grub_efi_loader_t *override_loader = NULL;
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_efi_register_loader (const grub_efi_loader_t *loader)
|
||||
+{
|
||||
+ if (override_loader != NULL)
|
||||
+ return grub_error (GRUB_ERR_BUG, "trying to register different loader");
|
||||
+ override_loader = loader;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_efi_unregister_loader (const grub_efi_loader_t *loader)
|
||||
+{
|
||||
+ if (loader != override_loader)
|
||||
+ return grub_error (GRUB_ERR_BUG, "trying to unregister different loader");
|
||||
+
|
||||
+ override_loader = NULL;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_efi_status_t
|
||||
+grub_efi_load_image (grub_efi_boolean_t boot_policy,
|
||||
+ grub_efi_handle_t parent_image_handle,
|
||||
+ grub_efi_device_path_t *file_path, void *source_buffer,
|
||||
+ grub_efi_uintn_t source_size,
|
||||
+ grub_efi_handle_t *image_handle)
|
||||
+{
|
||||
+ if (override_loader != NULL)
|
||||
+ return override_loader->load_image (boot_policy, parent_image_handle,
|
||||
+ file_path, source_buffer, source_size,
|
||||
+ image_handle);
|
||||
+ return grub_efi_system_table->boot_services->load_image (
|
||||
+ boot_policy, parent_image_handle, file_path, source_buffer, source_size,
|
||||
+ image_handle);
|
||||
+}
|
||||
+
|
||||
+grub_efi_status_t
|
||||
+grub_efi_start_image (grub_efi_handle_t image_handle,
|
||||
+ grub_efi_uintn_t *exit_data_size,
|
||||
+ grub_efi_char16_t **exit_data)
|
||||
+{
|
||||
+ if (override_loader != NULL)
|
||||
+ return override_loader->start_image (image_handle, exit_data_size,
|
||||
+ exit_data);
|
||||
+ return grub_efi_system_table->boot_services->start_image (
|
||||
+ image_handle, exit_data_size, exit_data);
|
||||
+}
|
||||
+
|
||||
+grub_efi_status_t
|
||||
+grub_efi_unload_image (grub_efi_handle_t image_handle)
|
||||
+{
|
||||
+ if (override_loader != NULL)
|
||||
+ return override_loader->unload_image (image_handle);
|
||||
+ return grub_efi_system_table->boot_services->unload_image (image_handle);
|
||||
+}
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 655aaad9d..04b9e3553 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -64,14 +64,12 @@ grub_chainloader_unload (void *context)
|
||||
{
|
||||
grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
|
||||
grub_efi_loaded_image_t *loaded_image;
|
||||
- grub_efi_boot_services_t *b;
|
||||
|
||||
loaded_image = grub_efi_get_loaded_image (image_handle);
|
||||
if (loaded_image != NULL)
|
||||
grub_free (loaded_image->load_options);
|
||||
|
||||
- b = grub_efi_system_table->boot_services;
|
||||
- b->unload_image (image_handle);
|
||||
+ grub_efi_unload_image (image_handle);
|
||||
|
||||
grub_dl_unref (my_mod);
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -87,7 +85,7 @@ grub_chainloader_boot (void *context)
|
||||
grub_efi_char16_t *exit_data = NULL;
|
||||
|
||||
b = grub_efi_system_table->boot_services;
|
||||
- status = b->start_image (image_handle, &exit_data_size, &exit_data);
|
||||
+ status = grub_efi_start_image (image_handle, &exit_data_size, &exit_data);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
if (exit_data)
|
||||
@@ -826,9 +824,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
#endif
|
||||
|
||||
- status = b->load_image (0, grub_efi_image_handle, file_path,
|
||||
- boot_image, size,
|
||||
- &image_handle);
|
||||
+ status = grub_efi_load_image (0, grub_efi_image_handle, file_path,
|
||||
+ boot_image, size, &image_handle);
|
||||
#ifdef SUPPORT_SECURE_BOOT
|
||||
if (status == GRUB_EFI_SECURITY_VIOLATION && grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
{
|
||||
@@ -907,7 +904,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
b->free_pages (address, pages);
|
||||
|
||||
if (image_handle != NULL)
|
||||
- b->unload_image (image_handle);
|
||||
+ grub_efi_unload_image (image_handle);
|
||||
|
||||
grub_dl_unref (my_mod);
|
||||
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index bfbd95aee..58be3c9f8 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -187,7 +187,6 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
|
||||
{
|
||||
grub_efi_memory_mapped_device_path_t *mempath;
|
||||
grub_efi_handle_t image_handle;
|
||||
- grub_efi_boot_services_t *b;
|
||||
grub_efi_status_t status;
|
||||
grub_efi_loaded_image_t *loaded_image;
|
||||
int len;
|
||||
@@ -207,10 +206,9 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
|
||||
mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
mempath[1].header.length = sizeof (grub_efi_device_path_t);
|
||||
|
||||
- b = grub_efi_system_table->boot_services;
|
||||
- status = b->load_image (0, grub_efi_image_handle,
|
||||
- (grub_efi_device_path_t *) mempath,
|
||||
- (void *) addr, size, &image_handle);
|
||||
+ status = grub_efi_load_image (0, grub_efi_image_handle,
|
||||
+ (grub_efi_device_path_t *)mempath,
|
||||
+ (void *)addr, size, &image_handle);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||
|
||||
@@ -235,14 +233,14 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
|
||||
(grub_uint8_t *) args, len, NULL);
|
||||
|
||||
grub_dprintf ("linux", "starting image %p\n", image_handle);
|
||||
- status = b->start_image (image_handle, 0, NULL);
|
||||
+ status = grub_efi_start_image (image_handle, 0, NULL);
|
||||
|
||||
/* When successful, not reached */
|
||||
grub_error (GRUB_ERR_BAD_OS, "start_image() returned 0x%" PRIxGRUB_EFI_UINTN_T, status);
|
||||
grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
|
||||
GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||
unload:
|
||||
- b->unload_image (image_handle);
|
||||
+ grub_efi_unload_image (image_handle);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
||||
index 87aa1ce25..6c7bfc865 100644
|
||||
--- a/include/grub/efi/efi.h
|
||||
+++ b/include/grub/efi/efi.h
|
||||
@@ -135,6 +135,48 @@ grub_err_t grub_arch_efi_linux_load_image_header(grub_file_t file,
|
||||
grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
|
||||
char *args);
|
||||
|
||||
+grub_efi_status_t
|
||||
+EXPORT_FUNC (grub_efi_load_image) (grub_efi_boolean_t boot_policy,
|
||||
+ grub_efi_handle_t parent_image_handle,
|
||||
+ grub_efi_device_path_t *file_path,
|
||||
+ void *source_buffer, grub_efi_uintn_t source_size,
|
||||
+ grub_efi_handle_t *image_handle);
|
||||
+
|
||||
+grub_efi_status_t
|
||||
+EXPORT_FUNC (grub_efi_start_image) (grub_efi_handle_t image_handle,
|
||||
+ grub_efi_uintn_t *exit_data_size,
|
||||
+ grub_efi_char16_t **exit_data);
|
||||
+
|
||||
+grub_efi_status_t
|
||||
+EXPORT_FUNC (grub_efi_unload_image) (grub_efi_handle_t image_handle);
|
||||
+
|
||||
+typedef struct grub_efi_loader
|
||||
+{
|
||||
+ grub_efi_status_t (__grub_efi_api *load_image) (grub_efi_boolean_t boot_policy,
|
||||
+ grub_efi_handle_t parent_image_handle,
|
||||
+ grub_efi_device_path_t *file_path,
|
||||
+ void *source_buffer,
|
||||
+ grub_efi_uintn_t source_size,
|
||||
+ grub_efi_handle_t *image_handle);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *start_image) (grub_efi_handle_t image_handle,
|
||||
+ grub_efi_uintn_t *exit_data_size,
|
||||
+ grub_efi_char16_t **exit_data);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *exit) (grub_efi_handle_t image_handle,
|
||||
+ grub_efi_status_t exit_status,
|
||||
+ grub_efi_uintn_t exit_data_size,
|
||||
+ grub_efi_char16_t *exit_data);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *unload_image) (grub_efi_handle_t image_handle);
|
||||
+} grub_efi_loader_t;
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC (grub_efi_register_loader) (const grub_efi_loader_t *loader);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC (grub_efi_unregister_loader) (const grub_efi_loader_t *loader);
|
||||
+
|
||||
grub_addr_t grub_efi_section_addr (const char *section);
|
||||
|
||||
void grub_efi_mm_init (void);
|
||||
--
|
||||
2.50.1
|
||||
|
||||
186
0009-efi-sb-Add-support-for-the-shim-loader-protocol.patch
Normal file
186
0009-efi-sb-Add-support-for-the-shim-loader-protocol.patch
Normal file
@@ -0,0 +1,186 @@
|
||||
From bd43c9011d3006a93b22861b6d3d18f62076d5f7 Mon Sep 17 00:00:00 2001
|
||||
From: Mate Kukri <mate.kukri@canonical.com>
|
||||
Date: Tue, 8 Jul 2025 21:21:14 +0100
|
||||
Subject: [PATCH 09/13] efi/sb: Add support for the shim loader protocol
|
||||
|
||||
Use loader protocol for image verification where available, otherwise
|
||||
fall back to the old shim lock protocol.
|
||||
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/efi/sb.c | 59 ++++++++++++++++++++----------------
|
||||
grub-core/loader/efi/linux.c | 6 ++--
|
||||
include/grub/efi/api.h | 5 +++
|
||||
include/grub/efi/sb.h | 2 +-
|
||||
4 files changed, 42 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
index 8d3e41360..48d1ea968 100644
|
||||
--- a/grub-core/kern/efi/sb.c
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -31,8 +31,10 @@
|
||||
#include <grub/verify.h>
|
||||
|
||||
static grub_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
+static grub_guid_t shim_loader_guid = GRUB_EFI_SHIM_IMAGE_LOADER_GUID;
|
||||
|
||||
-static bool shim_lock_enabled = false;
|
||||
+static grub_efi_loader_t *shim_loader = NULL;
|
||||
+static grub_efi_shim_lock_protocol_t *shim_lock = NULL;
|
||||
|
||||
/*
|
||||
* Determine whether we're in secure boot mode.
|
||||
@@ -95,14 +97,6 @@ grub_efi_get_secureboot (void)
|
||||
if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1)
|
||||
{
|
||||
secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED;
|
||||
- /*
|
||||
- * TODO: Replace this all with shim's LoadImage protocol, delegating policy to it.
|
||||
- *
|
||||
- * We need to set shim_lock_enabled here because we disabled secure boot
|
||||
- * validation *inside* shim but not in the firmware, so we set this variable
|
||||
- * here to trigger that code path, whereas the actual verifier is not enabled.
|
||||
- */
|
||||
- shim_lock_enabled = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -183,15 +177,25 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
|
||||
static grub_err_t
|
||||
shim_lock_verifier_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size)
|
||||
{
|
||||
- grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
+ grub_efi_handle_t image_handle;
|
||||
|
||||
- if (!sl)
|
||||
- return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found"));
|
||||
+ if (shim_loader != NULL)
|
||||
+ {
|
||||
+ if (shim_loader->load_image (false, grub_efi_image_handle, NULL, buf, size, &image_handle) != GRUB_EFI_SUCCESS)
|
||||
+ /* If verification fails no handle is produced */
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim loader signature"));
|
||||
|
||||
- if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
|
||||
- return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
|
||||
+ shim_loader->unload_image (image_handle);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ if (shim_lock != NULL)
|
||||
+ {
|
||||
+ if (shim_lock->verify (buf, size) != GRUB_EFI_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim lock signature"));
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
|
||||
- return GRUB_ERR_NONE;
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim protocols not found"));
|
||||
}
|
||||
|
||||
struct grub_file_verifier shim_lock_verifier =
|
||||
@@ -205,11 +209,17 @@ void
|
||||
grub_shim_lock_verifier_setup (void)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
- grub_efi_shim_lock_protocol_t *sl =
|
||||
- grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
|
||||
- /* shim_lock is missing, check if GRUB image is built with --disable-shim-lock. */
|
||||
- if (!sl)
|
||||
+ /* Secure Boot is off. Ignore shim. */
|
||||
+ if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
+ return;
|
||||
+
|
||||
+ /* Find both shim protocols. */
|
||||
+ shim_loader = grub_efi_locate_protocol (&shim_loader_guid, 0);
|
||||
+ shim_lock = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
+
|
||||
+ /* shim is missing, check if GRUB image is built with --disable-shim-lock. */
|
||||
+ if (shim_loader == NULL && shim_lock == NULL)
|
||||
{
|
||||
FOR_MODULES (header)
|
||||
{
|
||||
@@ -218,21 +228,18 @@ grub_shim_lock_verifier_setup (void)
|
||||
}
|
||||
}
|
||||
|
||||
- /* Secure Boot is off. Do not load shim_lock. */
|
||||
- if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
- return;
|
||||
-
|
||||
/* Enforce shim_lock_verifier. */
|
||||
grub_verifier_register (&shim_lock_verifier);
|
||||
|
||||
- shim_lock_enabled = true;
|
||||
+ /* Register shim loader if supported. */
|
||||
+ grub_efi_register_loader (shim_loader);
|
||||
|
||||
grub_env_set ("shim_lock", "y");
|
||||
grub_env_export ("shim_lock");
|
||||
}
|
||||
|
||||
bool
|
||||
-grub_is_shim_lock_enabled (void)
|
||||
+grub_is_using_legacy_shim_lock_protocol (void)
|
||||
{
|
||||
- return shim_lock_enabled;
|
||||
+ return (shim_loader == NULL && shim_lock != NULL) ? true : false;
|
||||
}
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index 58be3c9f8..993d18546 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -460,10 +460,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
- if (grub_is_shim_lock_enabled () == true)
|
||||
+ if (grub_is_using_legacy_shim_lock_protocol () == true)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
- grub_dprintf ("linux", "shim_lock enabled, falling back to legacy Linux kernel loader\n");
|
||||
+ grub_dprintf ("linux", "using legacy shim_lock protocol, falling back to legacy Linux kernel loader\n");
|
||||
|
||||
err = grub_cmd_linux_x86_legacy (cmd, argc, argv);
|
||||
|
||||
@@ -472,7 +472,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
else
|
||||
goto fail;
|
||||
#else
|
||||
- grub_dprintf ("linux", "shim_lock enabled, trying Linux kernel EFI stub loader\n");
|
||||
+ grub_dprintf ("linux", "using legacy shim_lock protocol on non-x86, only db verifiable kernels will work\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
|
||||
index 5d1aada34..72017eaa7 100644
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -364,6 +364,11 @@
|
||||
{ 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
|
||||
}
|
||||
|
||||
+#define GRUB_EFI_SHIM_IMAGE_LOADER_GUID \
|
||||
+ { 0x1f492041, 0xfadb, 0x4e59, \
|
||||
+ {0x9e, 0x57, 0x7c, 0xaf, 0xe7, 0x3a, 0x55, 0xab } \
|
||||
+ }
|
||||
+
|
||||
#define GRUB_EFI_RNG_PROTOCOL_GUID \
|
||||
{ 0x3152bca5, 0xeade, 0x433d, \
|
||||
{ 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
|
||||
diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h
|
||||
index 49a9ad01c..4cae88376 100644
|
||||
--- a/include/grub/efi/sb.h
|
||||
+++ b/include/grub/efi/sb.h
|
||||
@@ -32,7 +32,7 @@ extern grub_uint8_t
|
||||
EXPORT_FUNC (grub_efi_get_secureboot) (void);
|
||||
|
||||
extern bool
|
||||
-EXPORT_FUNC (grub_is_shim_lock_enabled) (void);
|
||||
+EXPORT_FUNC (grub_is_using_legacy_shim_lock_protocol) (void);
|
||||
|
||||
extern void
|
||||
grub_shim_lock_verifier_setup (void);
|
||||
--
|
||||
2.50.1
|
||||
|
||||
100
0010-efi-sb-Add-API-for-retrieving-shim-loader-image-hand.patch
Normal file
100
0010-efi-sb-Add-API-for-retrieving-shim-loader-image-hand.patch
Normal file
@@ -0,0 +1,100 @@
|
||||
From b0e9763fd6b4c7635d190439973276ed57ee7af8 Mon Sep 17 00:00:00 2001
|
||||
From: Mate Kukri <mate.kukri@canonical.com>
|
||||
Date: Tue, 8 Jul 2025 21:21:15 +0100
|
||||
Subject: [PATCH 10/13] efi/sb: Add API for retrieving shim loader image
|
||||
handles
|
||||
|
||||
Not reusing these handles will result in image measurements showing up
|
||||
twice in the event log.
|
||||
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/efi/sb.c | 34 ++++++++++++++++++++++++++++++++--
|
||||
include/grub/efi/sb.h | 4 ++++
|
||||
2 files changed, 36 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
index 48d1ea968..4409e03c5 100644
|
||||
--- a/grub-core/kern/efi/sb.c
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -36,6 +36,8 @@ static grub_guid_t shim_loader_guid = GRUB_EFI_SHIM_IMAGE_LOADER_GUID;
|
||||
static grub_efi_loader_t *shim_loader = NULL;
|
||||
static grub_efi_shim_lock_protocol_t *shim_lock = NULL;
|
||||
|
||||
+static grub_efi_handle_t last_verified_image_handle = NULL;
|
||||
+
|
||||
/*
|
||||
* Determine whether we're in secure boot mode.
|
||||
*
|
||||
@@ -181,11 +183,25 @@ shim_lock_verifier_write (void *context __attribute__ ((unused)), void *buf, gru
|
||||
|
||||
if (shim_loader != NULL)
|
||||
{
|
||||
+ if (last_verified_image_handle != NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * Unload the previous image because ownership of the handle was
|
||||
+ * not transfered to a loader, and a new image is being loaded.
|
||||
+ */
|
||||
+ shim_loader->unload_image (last_verified_image_handle);
|
||||
+ last_verified_image_handle = NULL;
|
||||
+ }
|
||||
+
|
||||
if (shim_loader->load_image (false, grub_efi_image_handle, NULL, buf, size, &image_handle) != GRUB_EFI_SUCCESS)
|
||||
- /* If verification fails no handle is produced */
|
||||
+ /* If verification fails no handle is produced. */
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim loader signature"));
|
||||
|
||||
- shim_loader->unload_image (image_handle);
|
||||
+ /*
|
||||
+ * Not unloading the image here because chainloader and linux
|
||||
+ * might use this handle to avoid double TPM measurements.
|
||||
+ */
|
||||
+ last_verified_image_handle = image_handle;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
if (shim_lock != NULL)
|
||||
@@ -243,3 +259,17 @@ grub_is_using_legacy_shim_lock_protocol (void)
|
||||
{
|
||||
return (shim_loader == NULL && shim_lock != NULL) ? true : false;
|
||||
}
|
||||
+
|
||||
+grub_efi_handle_t
|
||||
+grub_efi_get_last_verified_image_handle (void)
|
||||
+{
|
||||
+ grub_efi_handle_t tmp = last_verified_image_handle;
|
||||
+
|
||||
+ /*
|
||||
+ * This function is intended to act as a "transfer of ownership"
|
||||
+ * of the handle. We set it to NULL so that it cannot be buggily
|
||||
+ * retrieved more than once and reused for the wrong image.
|
||||
+ */
|
||||
+ last_verified_image_handle = NULL;
|
||||
+ return tmp;
|
||||
+}
|
||||
diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h
|
||||
index 4cae88376..149005ced 100644
|
||||
--- a/include/grub/efi/sb.h
|
||||
+++ b/include/grub/efi/sb.h
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/dl.h>
|
||||
+#include <grub/efi/api.h>
|
||||
|
||||
#define GRUB_EFI_SECUREBOOT_MODE_UNSET 0
|
||||
#define GRUB_EFI_SECUREBOOT_MODE_UNKNOWN 1
|
||||
@@ -34,6 +35,9 @@ EXPORT_FUNC (grub_efi_get_secureboot) (void);
|
||||
extern bool
|
||||
EXPORT_FUNC (grub_is_using_legacy_shim_lock_protocol) (void);
|
||||
|
||||
+extern grub_efi_handle_t
|
||||
+EXPORT_FUNC (grub_efi_get_last_verified_image_handle) (void);
|
||||
+
|
||||
extern void
|
||||
grub_shim_lock_verifier_setup (void);
|
||||
#else
|
||||
--
|
||||
2.50.1
|
||||
|
||||
107
0011-loader-efi-chainloader-Use-shim-loader-image-handle-.patch
Normal file
107
0011-loader-efi-chainloader-Use-shim-loader-image-handle-.patch
Normal file
@@ -0,0 +1,107 @@
|
||||
From 918af0d51fe594a7e6cbb0fe8a4889e773bba4bb Mon Sep 17 00:00:00 2001
|
||||
From: Mate Kukri <mate.kukri@canonical.com>
|
||||
Date: Tue, 8 Jul 2025 21:21:16 +0100
|
||||
Subject: [PATCH 11/13] loader/efi/chainloader: Use shim loader image handle
|
||||
where available
|
||||
|
||||
Not reusing these handles will result in image measurements showing up
|
||||
twice in the event log.
|
||||
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 67 ++++++++++++++++--------------
|
||||
1 file changed, 36 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 04b9e3553..1830de223 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/efi/disk.h>
|
||||
#include <grub/efi/memory.h>
|
||||
+#include <grub/efi/sb.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/net.h>
|
||||
@@ -824,41 +825,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
#endif
|
||||
|
||||
- status = grub_efi_load_image (0, grub_efi_image_handle, file_path,
|
||||
+ image_handle = grub_efi_get_last_verified_image_handle ();
|
||||
+ if (image_handle == NULL)
|
||||
+ {
|
||||
+ status = grub_efi_load_image (0, grub_efi_image_handle, file_path,
|
||||
boot_image, size, &image_handle);
|
||||
#ifdef SUPPORT_SECURE_BOOT
|
||||
- if (status == GRUB_EFI_SECURITY_VIOLATION && grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
- {
|
||||
- /* If it failed with security violation while not in secure boot mode,
|
||||
- the firmware might be broken. We try to workaround on that by forcing
|
||||
- the SB method! (bsc#887793) */
|
||||
- struct grub_secureboot_chainloader_context *sb_context;
|
||||
-
|
||||
- grub_dprintf ("chain", "Possible firmware flaw! Security violation while not in secure boot mode.\n");
|
||||
- sb_context = grub_malloc (sizeof (*sb_context));
|
||||
- if (!sb_context)
|
||||
- goto fail;
|
||||
- sb_context->cmdline = cmdline;
|
||||
- sb_context->cmdline_len = cmdline_len;
|
||||
- sb_context->fsize = size;
|
||||
- sb_context->dev_handle = dev_handle;
|
||||
- sb_context->address = address;
|
||||
- sb_context->pages = pages;
|
||||
- sb_context->file_path = file_path;
|
||||
- grub_file_close (file);
|
||||
- grub_loader_set_ex (grub_secureboot_chainloader_boot,
|
||||
- grub_secureboot_chainloader_unload, sb_context, 0);
|
||||
- return 0;
|
||||
- }
|
||||
+ if (status == GRUB_EFI_SECURITY_VIOLATION && grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
+ {
|
||||
+ /* If it failed with security violation while not in secure boot mode,
|
||||
+ the firmware might be broken. We try to workaround on that by forcing
|
||||
+ the SB method! (bsc#887793) */
|
||||
+ struct grub_secureboot_chainloader_context *sb_context;
|
||||
+
|
||||
+ grub_dprintf ("chain", "Possible firmware flaw! Security violation while not in secure boot mode.\n");
|
||||
+ sb_context = grub_malloc (sizeof (*sb_context));
|
||||
+ if (!sb_context)
|
||||
+ goto fail;
|
||||
+ sb_context->cmdline = cmdline;
|
||||
+ sb_context->cmdline_len = cmdline_len;
|
||||
+ sb_context->fsize = size;
|
||||
+ sb_context->dev_handle = dev_handle;
|
||||
+ sb_context->address = address;
|
||||
+ sb_context->pages = pages;
|
||||
+ sb_context->file_path = file_path;
|
||||
+ grub_file_close (file);
|
||||
+ grub_loader_set_ex (grub_secureboot_chainloader_boot,
|
||||
+ grub_secureboot_chainloader_unload, sb_context, 0);
|
||||
+ return 0;
|
||||
+ }
|
||||
#endif
|
||||
- if (status != GRUB_EFI_SUCCESS)
|
||||
- {
|
||||
- if (status == GRUB_EFI_OUT_OF_RESOURCES)
|
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
|
||||
- else
|
||||
- grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ if (status == GRUB_EFI_OUT_OF_RESOURCES)
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
|
||||
+ else
|
||||
+ grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||
|
||||
- goto fail;
|
||||
+ goto fail;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* LoadImage does not set a device handler when the image is
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From e4855838e156b3509a2fd774c69ab4681e774427 Mon Sep 17 00:00:00 2001
|
||||
From: Mate Kukri <mate.kukri@canonical.com>
|
||||
Date: Tue, 8 Jul 2025 21:21:17 +0100
|
||||
Subject: [PATCH 12/13] loader/efi/linux: Use shim loader image handle where
|
||||
available
|
||||
|
||||
Not reusing these handles will result in image measurements showing up
|
||||
twice in the event log.
|
||||
|
||||
On the occasion add missing grub_free() call.
|
||||
|
||||
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/loader/efi/linux.c | 19 ++++++++++++++-----
|
||||
1 file changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index 993d18546..394df6039 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -206,11 +206,20 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
|
||||
mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
mempath[1].header.length = sizeof (grub_efi_device_path_t);
|
||||
|
||||
- status = grub_efi_load_image (0, grub_efi_image_handle,
|
||||
- (grub_efi_device_path_t *)mempath,
|
||||
- (void *)addr, size, &image_handle);
|
||||
- if (status != GRUB_EFI_SUCCESS)
|
||||
- return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||
+ image_handle = grub_efi_get_last_verified_image_handle ();
|
||||
+ if (image_handle == NULL)
|
||||
+ {
|
||||
+ status = grub_efi_load_image (0, grub_efi_image_handle,
|
||||
+ (grub_efi_device_path_t *) mempath,
|
||||
+ (void *) addr, size, &image_handle);
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ grub_free (mempath);
|
||||
+ return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ grub_free (mempath);
|
||||
|
||||
grub_dprintf ("linux", "linux command line: '%s'\n", args);
|
||||
|
||||
--
|
||||
2.50.1
|
||||
|
||||
32
0013-nx-Rename-GRUB_DL_ALIGN-to-DL_ALIGN.patch
Normal file
32
0013-nx-Rename-GRUB_DL_ALIGN-to-DL_ALIGN.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From d36e8d9cc3bf2bbaf90d15fdb7a7594275892ec7 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Date: Wed, 16 Oct 2024 15:04:17 +0200
|
||||
Subject: [PATCH 13/13] nx: Rename GRUB_DL_ALIGN to DL_ALIGN
|
||||
|
||||
Rename has been skipped by mistake in the original commit.
|
||||
|
||||
Fixes: 94649c026 (nx: Set page permissions for loaded modules)
|
||||
|
||||
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Sudeep Holla <sudeep.holla@arm.com>
|
||||
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
|
||||
---
|
||||
grub-core/kern/dl.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
||||
index da31db218..cf1a5a24d 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -647,7 +647,7 @@ grub_dl_set_mem_attrs (grub_dl_t mod, void *ehdr)
|
||||
grub_err_t err;
|
||||
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
|
||||
!defined (__loongarch__)
|
||||
- grub_size_t arch_addralign = GRUB_DL_ALIGN;
|
||||
+ grub_size_t arch_addralign = DL_ALIGN;
|
||||
grub_addr_t tgaddr;
|
||||
grub_size_t tgsz;
|
||||
#endif
|
||||
--
|
||||
2.50.1
|
||||
|
||||
93
grub2-bls-loader-entry-default.patch
Normal file
93
grub2-bls-loader-entry-default.patch
Normal file
@@ -0,0 +1,93 @@
|
||||
Factoring out get_entry_from_efivar helper to reduce code duplication
|
||||
and add support for LoaderEntryDefault.
|
||||
|
||||
Index: grub-2.12/grub-core/normal/menu.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/normal/menu.c
|
||||
+++ grub-2.12/grub-core/normal/menu.c
|
||||
@@ -741,6 +741,38 @@ workaround_snapshot_menu_default_entry (
|
||||
return;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+static int
|
||||
+get_entry_from_efivar(grub_menu_t menu, const char* efivar)
|
||||
+{
|
||||
+ grub_efi_status_t status;
|
||||
+ grub_size_t entry_size;
|
||||
+ grub_efi_char16_t *entry_efi = NULL;
|
||||
+ char *entry_name = NULL;
|
||||
+ int entry_index = -1;
|
||||
+ status = grub_efi_get_variable(efivar,
|
||||
+ &grub_efi_loader_guid,
|
||||
+ &entry_size,
|
||||
+ (void**) &entry_efi);
|
||||
+ if (status == GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ grub_efi_char16_t *src = entry_efi;
|
||||
+ int size = 0;
|
||||
+ while (*src++)
|
||||
+ size++;
|
||||
+ if (size != 0)
|
||||
+ {
|
||||
+ entry_name = grub_malloc (size * sizeof (char));
|
||||
+ grub_utf16_to_utf8 ((grub_uint8_t*) entry_name,
|
||||
+ (grub_uint16_t*) entry_efi, size);
|
||||
+ entry_index = search_entry (menu, entry_name);
|
||||
+ }
|
||||
+ }
|
||||
+ grub_free(entry_name);
|
||||
+ return entry_index;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#define GRUB_MENU_PAGE_SIZE 10
|
||||
|
||||
/* Show the menu and handle menu entry selection. Returns the menu entry
|
||||
@@ -766,36 +798,19 @@ run_menu (grub_menu_t menu, int nested,
|
||||
const char* val = grub_env_get ("enable_blscfg");
|
||||
if (val && (val[0] == '1' || val[0] == 'y'))
|
||||
{
|
||||
- grub_efi_status_t status;
|
||||
- int oneshot_entry_index;
|
||||
- grub_efi_char16_t *oneshot_entry_efi = NULL;
|
||||
- char *oneshot_entry = NULL;
|
||||
- grub_size_t oneshot_entry_size;
|
||||
- status = grub_efi_get_variable("LoaderEntryOneShot",
|
||||
- &grub_efi_loader_guid,
|
||||
- &oneshot_entry_size,
|
||||
- (void**) &oneshot_entry_efi);
|
||||
- if (status == GRUB_EFI_SUCCESS)
|
||||
+ int oneshot_entry, default_entry_efi;
|
||||
+ oneshot_entry = get_entry_from_efivar(menu, "LoaderEntryOneShot");
|
||||
+ if (oneshot_entry != -1)
|
||||
{
|
||||
- grub_efi_char16_t *src = oneshot_entry_efi;
|
||||
- int size = 0;
|
||||
- while (*src++)
|
||||
- size++;
|
||||
- if (size == 0)
|
||||
+ default_entry = oneshot_entry;
|
||||
+ grub_efi_set_variable_to_string("LoaderEntryOneShot",
|
||||
+ &grub_efi_loader_guid, "", 0);
|
||||
+ } else {
|
||||
+ default_entry_efi = get_entry_from_efivar(menu, "LoaderEntryDefault");
|
||||
+ if (default_entry_efi != -1)
|
||||
{
|
||||
- oneshot_entry = grub_malloc (size * sizeof (char));
|
||||
- grub_utf16_to_utf8 ((grub_uint8_t*) oneshot_entry,
|
||||
- (grub_uint16_t*) oneshot_entry_efi, size);
|
||||
- oneshot_entry_index = search_entry (menu, oneshot_entry);
|
||||
- if (oneshot_entry_index != -1)
|
||||
- {
|
||||
- default_entry = oneshot_entry_index;
|
||||
- grub_efi_set_variable_to_string("LoaderEntryOneShot",
|
||||
- &grub_efi_loader_guid, "", 0);
|
||||
- }
|
||||
- grub_free(oneshot_entry);
|
||||
+ default_entry = default_entry_efi;
|
||||
}
|
||||
- grub_free(oneshot_entry_efi);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
59
grub2-constant-time-grub_crypto_memcmp.patch
Normal file
59
grub2-constant-time-grub_crypto_memcmp.patch
Normal file
@@ -0,0 +1,59 @@
|
||||
From be4670936bc86a14f20a8c9c40d34c45aad0d0b2 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Fri, 25 Jul 2025 13:50:23 +0800
|
||||
Subject: [PATCH] Constant-time grub_crypto_memcmp()
|
||||
|
||||
Use the constant-time algorithm to compare the given memory blocks.
|
||||
The code is extracted from the upstream commit:
|
||||
0739d24cd1648531d0708d1079ff6bbfa6140268
|
||||
|
||||
Fix: bsc#1234959
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/lib/crypto.c | 23 ++++++++++++++++-------
|
||||
1 file changed, 16 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c
|
||||
index 396f764..19db787 100644
|
||||
--- a/grub-core/lib/crypto.c
|
||||
+++ b/grub-core/lib/crypto.c
|
||||
@@ -433,19 +433,28 @@ grub_crypto_gcry_error (gcry_err_code_t in)
|
||||
return GRUB_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Compare byte arrays of length LEN, return 1 if it's not same,
|
||||
+ * 0, otherwise.
|
||||
+ */
|
||||
int
|
||||
-grub_crypto_memcmp (const void *a, const void *b, grub_size_t n)
|
||||
+grub_crypto_memcmp (const void *b1, const void *b2, grub_size_t len)
|
||||
{
|
||||
- register grub_size_t counter = 0;
|
||||
- const grub_uint8_t *pa, *pb;
|
||||
+ const grub_uint8_t *a = b1;
|
||||
+ const grub_uint8_t *b = b2;
|
||||
+ int ab, ba;
|
||||
+ grub_size_t i;
|
||||
|
||||
- for (pa = a, pb = b; n; pa++, pb++, n--)
|
||||
+ /* Constant-time compare. */
|
||||
+ for (i = 0, ab = 0, ba = 0; i < len; i++)
|
||||
{
|
||||
- if (*pa != *pb)
|
||||
- counter++;
|
||||
+ /* If a[i] != b[i], either ab or ba will be negative. */
|
||||
+ ab |= a[i] - b[i];
|
||||
+ ba |= b[i] - a[i];
|
||||
}
|
||||
|
||||
- return !!counter;
|
||||
+ /* 'ab | ba' is negative when buffers are not equal, extract sign bit. */
|
||||
+ return ((unsigned int)(ab | ba) >> (sizeof(unsigned int) * 8 - 1)) & 1;
|
||||
}
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
--
|
||||
2.43.0
|
||||
|
||||
20
grub2-i386-pc-no-pageflipping.patch
Normal file
20
grub2-i386-pc-no-pageflipping.patch
Normal file
@@ -0,0 +1,20 @@
|
||||
In x86 Legacy BIOS mode, on some Lenovo machines, the grub menu is not
|
||||
visible, although it demonstrably has been drawn (bsc#1245636).
|
||||
|
||||
A workaround to avoid this is to not use page flipping mode.
|
||||
|
||||
This patch enforces that no page flipping is used in the VBE framebuffer
|
||||
backend for i386-pc.
|
||||
|
||||
--- a/grub-core/video/i386/pc/vbe.c
|
||||
+++ b/grub-core/video/i386/pc/vbe.c
|
||||
@@ -1137,7 +1137,8 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
|
||||
|
||||
page_size = framebuffer.mode_info.pitch * framebuffer.mode_info.height;
|
||||
|
||||
- if (vram_size >= 2 * page_size)
|
||||
+ /* avoid page flipping mode (bsc#1245636) */
|
||||
+ if (0 && vram_size >= 2 * page_size)
|
||||
err = grub_video_fb_setup (mode_type, mode_mask,
|
||||
&framebuffer.mode_info,
|
||||
framebuffer.ptr,
|
||||
@@ -1,3 +1,75 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Sep 23 08:47:49 UTC 2025 - Steffen Winterfeldt <snwint@suse.com>
|
||||
|
||||
- turn off page flipping for i386-pc using VBE video backend (bsc#1245636)
|
||||
* grub2-i386-pc-no-pageflipping.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Sep 22 07:15:00 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix boot hangs in setting up serial console when ACPI SPCR table is present
|
||||
and redirection is disabled (bsc#1249088)
|
||||
* 0001-term-ns8250-spcr-Return-if-redirection-is-disabled.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Sep 9 14:25:42 UTC 2025 - Danilo Spinella <danilo.spinella@suse.com>
|
||||
|
||||
- Add support for `LoaderEntryDefault` EFI variable
|
||||
* grub2-bls-loader-entry-default.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Sep 2 07:46:46 UTC 2025 - Gary Ching-Pang Lin <glin@suse.com>
|
||||
|
||||
- Optimize PBKDF2 to reduce the decryption time
|
||||
* 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch
|
||||
* 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch
|
||||
* 0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Aug 11 02:57:30 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- UEFI NX support and NX Linux loader using shim loader protocol (bsc#1205588)
|
||||
(jsc#PED-13361)
|
||||
* 0001-modules-Make-.module_license-read-only.patch
|
||||
* 0002-modules-Strip-.llvm_addrsig-sections-and-similar.patch
|
||||
* 0003-modules-Don-t-allocate-space-for-non-allocable-secti.patch
|
||||
* 0004-modules-Load-module-sections-at-page-aligned-address.patch
|
||||
* 0005-nx-Add-memory-attribute-get-set-API.patch
|
||||
* 0006-nx-Set-page-permissions-for-loaded-modules.patch
|
||||
* 0007-nx-Set-the-NX-compatible-flag-for-the-GRUB-EFI-image.patch
|
||||
* 0008-efi-Provide-wrappers-for-load_image-start_image-and-.patch
|
||||
* 0009-efi-sb-Add-support-for-the-shim-loader-protocol.patch
|
||||
* 0010-efi-sb-Add-API-for-retrieving-shim-loader-image-hand.patch
|
||||
* 0011-loader-efi-chainloader-Use-shim-loader-image-handle-.patch
|
||||
* 0012-loader-efi-linux-Use-shim-loader-image-handle-where-.patch
|
||||
* 0013-nx-Rename-GRUB_DL_ALIGN-to-DL_ALIGN.patch
|
||||
- Fallback for legacy shim lock protocol while secure boot is enabled
|
||||
* 0001-linux-fallback-to-EFI-handover-on-x86_64.patch
|
||||
* 0002-linux-fallback-to-direct-PE-entry-boot-on-arm64.patch
|
||||
* 0003-efi-chainloader-fallback-to-direct-image-execution.patch
|
||||
* 0004-efi-chainloader-fix-missing-file_path-in-loaded_imag.patch
|
||||
- Removed patch
|
||||
* 0001-xen_boot-add-missing-grub_arch_efi_linux_load_image_.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Aug 7 06:19:53 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix timeout when loading initrd via http after PPC CAS reboot (bsc#1245953)
|
||||
* 0001-tcp-Fix-TCP-port-number-reused-on-reboot.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Aug 4 06:44:01 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Skip mount point in grub_find_device function (bsc#1246231)
|
||||
* 0001-getroot-Skip-mount-points-in-grub_find_device.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jul 25 05:56:26 UTC 2025 - Gary Ching-Pang Lin <glin@suse.com>
|
||||
|
||||
- Fix CVE-2024-56738: side-channel attack due to not constant-time
|
||||
algorithm in grub_crypto_memcmp (bsc#1234959)
|
||||
* grub2-constant-time-grub_crypto_memcmp.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jul 16 11:19:21 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
@@ -168,7 +240,7 @@ Mon Mar 17 08:27:29 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
Thu Mar 13 06:50:37 UTC 2025 - Gary Ching-Pang Lin <glin@suse.com>
|
||||
|
||||
- Update the patch to fix "SRK not matched" errors when unsealing
|
||||
the key (bsc#1232411)
|
||||
the key (bsc#1232411) (bsc#1247242)
|
||||
* 0001-tpm2-Add-extra-RSA-SRK-types.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
28
grub2.spec
28
grub2.spec
@@ -2,6 +2,7 @@
|
||||
# spec file for package grub2
|
||||
#
|
||||
# Copyright (c) 2025 SUSE LLC
|
||||
# Copyright (c) 2025 SUSE LLC and contributors
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@@ -369,7 +370,6 @@ Patch176: 0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch
|
||||
Patch177: 0002-Restrict-cryptsetup-key-file-permission-for-better-s.patch
|
||||
Patch178: 0001-openfw-Ensure-get_devargs-and-get_devname-functions-.patch
|
||||
Patch179: 0002-prep_loadenv-Fix-regex-for-Open-Firmware-device-spec.patch
|
||||
Patch180: 0001-xen_boot-add-missing-grub_arch_efi_linux_load_image_.patch
|
||||
Patch181: 0001-font-Try-memdisk-fonts-with-the-same-name.patch
|
||||
Patch182: 0001-Make-grub.cfg-compatible-to-old-binaries.patch
|
||||
Patch183: grub2-change-bash-completion-dir.patch
|
||||
@@ -493,6 +493,32 @@ Patch315: 0001-test-Fix-f-test-on-files-over-network.patch
|
||||
Patch316: 0002-http-Return-HTTP-status-code-in-http_establish.patch
|
||||
Patch317: 0003-docs-Clarify-test-for-files-on-TFTP-and-HTTP.patch
|
||||
Patch318: 0004-tftp-Fix-hang-when-file-is-a-directory.patch
|
||||
Patch319: grub2-constant-time-grub_crypto_memcmp.patch
|
||||
Patch320: 0001-getroot-Skip-mount-points-in-grub_find_device.patch
|
||||
Patch321: 0001-tcp-Fix-TCP-port-number-reused-on-reboot.patch
|
||||
Patch322: 0001-modules-Make-.module_license-read-only.patch
|
||||
Patch323: 0002-modules-Strip-.llvm_addrsig-sections-and-similar.patch
|
||||
Patch324: 0003-modules-Don-t-allocate-space-for-non-allocable-secti.patch
|
||||
Patch325: 0004-modules-Load-module-sections-at-page-aligned-address.patch
|
||||
Patch326: 0005-nx-Add-memory-attribute-get-set-API.patch
|
||||
Patch327: 0006-nx-Set-page-permissions-for-loaded-modules.patch
|
||||
Patch328: 0007-nx-Set-the-NX-compatible-flag-for-the-GRUB-EFI-image.patch
|
||||
Patch329: 0008-efi-Provide-wrappers-for-load_image-start_image-and-.patch
|
||||
Patch330: 0009-efi-sb-Add-support-for-the-shim-loader-protocol.patch
|
||||
Patch331: 0010-efi-sb-Add-API-for-retrieving-shim-loader-image-hand.patch
|
||||
Patch332: 0011-loader-efi-chainloader-Use-shim-loader-image-handle-.patch
|
||||
Patch333: 0012-loader-efi-linux-Use-shim-loader-image-handle-where-.patch
|
||||
Patch334: 0013-nx-Rename-GRUB_DL_ALIGN-to-DL_ALIGN.patch
|
||||
Patch335: 0001-linux-fallback-to-EFI-handover-on-x86_64.patch
|
||||
Patch336: 0002-linux-fallback-to-direct-PE-entry-boot-on-arm64.patch
|
||||
Patch337: 0003-efi-chainloader-fallback-to-direct-image-execution.patch
|
||||
Patch338: 0004-efi-chainloader-fix-missing-file_path-in-loaded_imag.patch
|
||||
Patch339: 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch
|
||||
Patch340: 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch
|
||||
Patch341: 0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch
|
||||
Patch342: grub2-bls-loader-entry-default.patch
|
||||
Patch343: 0001-term-ns8250-spcr-Return-if-redirection-is-disabled.patch
|
||||
Patch344: grub2-i386-pc-no-pageflipping.patch
|
||||
|
||||
%if 0%{?suse_version} < 1600
|
||||
Requires: gettext-runtime
|
||||
|
||||
Reference in New Issue
Block a user