summaryrefslogtreecommitdiffstats
path: root/src/boot
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2022-11-17 19:49:40 +0100
committerGitHub <noreply@github.com>2022-11-17 19:49:40 +0100
commitdaefca4611b1413bc787421fbfcdbcc117842c23 (patch)
treeeac9f2d22e088daaa7191708547c6dfdf2bb63fb /src/boot
parentkmod-setup: Make sure the tpm module is available early (diff)
parentboot: only use __builtin_object_size with -O>0 (diff)
downloadsystemd-daefca4611b1413bc787421fbfcdbcc117842c23.tar.xz
systemd-daefca4611b1413bc787421fbfcdbcc117842c23.zip
Merge pull request #25414 from zx2c4-forks/krngseed
EFI random seed post #25319 review fixups
Diffstat (limited to 'src/boot')
-rw-r--r--src/boot/bootctl.c2
-rw-r--r--src/boot/efi/random-seed.c23
-rw-r--r--src/boot/efi/util.h12
3 files changed, 23 insertions, 14 deletions
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index e04424b379..afda914d52 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -1975,7 +1975,7 @@ static int verb_list(int argc, char *argv[], void *userdata) {
static int install_random_seed(const char *esp) {
_cleanup_(unlink_and_freep) char *tmp = NULL;
- unsigned char buffer[RANDOM_EFI_SEED_SIZE];
+ uint8_t buffer[RANDOM_EFI_SEED_SIZE];
_cleanup_free_ char *path = NULL;
_cleanup_close_ int fd = -1;
size_t token_size;
diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c
index 04bfd526f8..e6a317860d 100644
--- a/src/boot/efi/random-seed.c
+++ b/src/boot/efi/random-seed.c
@@ -59,7 +59,6 @@ static EFI_STATUS acquire_system_token(void **ret, UINTN *ret_size) {
assert(ret);
assert(ret_size);
- *ret_size = 0;
err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size);
if (err != EFI_SUCCESS) {
if (err != EFI_NOT_FOUND)
@@ -187,6 +186,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
/* Get some system specific seed that the installer might have placed in an EFI variable. We include
* it in our hash. This is protection against golden master image sloppiness, and it remains on the
* system, even when disk images are duplicated or swapped out. */
+ size = 0;
err = acquire_system_token(&system_token, &size);
if (mode != RANDOM_SEED_ALWAYS && (err != EFI_SUCCESS || size < DESIRED_SEED_SIZE) && !seeded_by_efi)
return err;
@@ -246,6 +246,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
size = sizeof(uefi_monotonic_counter);
sha256_process_bytes(&size, sizeof(size), &hash);
sha256_process_bytes(&uefi_monotonic_counter, size, &hash);
+
err = RT->GetTime(&now, NULL);
size = err == EFI_SUCCESS ? sizeof(now) : 0; /* Known to be flaky, so don't bark on error. */
sha256_process_bytes(&size, sizeof(size), &hash);
@@ -262,7 +263,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
sha256_finish_ctx(&hash, random_bytes);
size = sizeof(random_bytes);
- /* If the file size is too large, zero out the remaining bytes on disk, and then truncate. */
+ /* If the file size is too large, zero out the remaining bytes on disk. */
if (size < info->FileSize) {
err = handle->SetPosition(handle, size);
if (err != EFI_SUCCESS)
@@ -279,10 +280,17 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
err = handle->SetPosition(handle, 0);
if (err != EFI_SUCCESS)
return log_error_status_stall(err, L"Failed to seek to beginning of random seed file: %r", err);
- info->FileSize = size;
- err = handle->SetInfo(handle, &GenericFileInfo, info->Size, info);
- if (err != EFI_SUCCESS)
- return log_error_status_stall(err, L"Failed to truncate random seed file: %r", err);
+
+ /* We could truncate the file here with something like:
+ *
+ * info->FileSize = size;
+ * err = handle->SetInfo(handle, &GenericFileInfo, info->Size, info);
+ * if (err != EFI_SUCCESS)
+ * return log_error_status_stall(err, L"Failed to truncate random seed file: %r", err);
+ *
+ * But this is considered slightly risky, because EFI filesystem drivers are a little bit
+ * flimsy. So instead we rely on userspace eventually truncating this when it writes a new
+ * seed. For now the best we do is zero it. */
}
/* Update the random seed on disk before we use it */
wsize = size;
@@ -295,7 +303,8 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
if (err != EFI_SUCCESS)
return log_error_status_stall(err, L"Failed to flush random seed file: %r", err);
- err = BS->AllocatePool(EfiACPIReclaimMemory, sizeof(*new_seed_table) + DESIRED_SEED_SIZE,
+ err = BS->AllocatePool(EfiACPIReclaimMemory,
+ offsetof(struct linux_efi_random_seed, seed) + DESIRED_SEED_SIZE,
(void **) &new_seed_table);
if (err != EFI_SUCCESS)
return log_error_status_stall(err, L"Failed to allocate EFI table for random seed: %r", err);
diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
index 15dd87f774..4c5b6cab13 100644
--- a/src/boot/efi/util.h
+++ b/src/boot/efi/util.h
@@ -10,7 +10,6 @@
#define UINTN_MAX (~(UINTN)0)
#define INTN_MAX ((INTN)(UINTN_MAX>>1))
-#ifdef __OPTIMIZE__
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
@@ -20,10 +19,7 @@ __attribute__((noreturn)) extern void __assert_cl_failure__(void) __attribute__(
__attribute__((noreturn)) extern void __assert_cl_failure__(void);
#endif
/* assert_cl generates a later-stage compile-time assertion when constant folding occurs. */
-#define assert_cl(condition) if (!(condition)) __assert_cl_failure__()
-#else
-#define assert_cl(condition) assert(condition)
-#endif
+#define assert_cl(condition) ({ if (!(condition)) __assert_cl_failure__(); })
/* gnu-efi format specifiers for integers are fixed to either 64bit with 'l' and 32bit without a size prefix.
* We rely on %u/%d/%x to format regular ints, so ensure the size is what we expect. At the same time, we also
@@ -59,11 +55,15 @@ static inline void freep(void *p) {
#define _cleanup_free_ _cleanup_(freep)
static __always_inline void erase_obj(void *p) {
+#ifdef __OPTIMIZE__
size_t l;
- assert_cl(p != NULL);
+ assert_cl(p);
l = __builtin_object_size(p, 0);
assert_cl(l != (size_t) -1);
explicit_bzero_safe(p, l);
+#else
+#warning "Object will not be erased with -O0; do not release to production."
+#endif
}
#define _cleanup_erase_ _cleanup_(erase_obj)