boot: before starting the random seed logic, let's check if the backing volume is r/o
This is an attempt to fix #42307, but should be a good thing anyway. Related: #42307
This commit is contained in:
@@ -132,6 +132,7 @@ typedef uint64_t EFI_PHYSICAL_ADDRESS;
|
||||
* keep the GUID definitions in line with the UEFI spec. */
|
||||
#define EFI_GLOBAL_VARIABLE_GUID EFI_GLOBAL_VARIABLE
|
||||
#define EFI_FILE_INFO_GUID EFI_FILE_INFO_ID
|
||||
#define EFI_FILE_SYSTEM_INFO_GUID EFI_FILE_SYSTEM_INFO_ID
|
||||
|
||||
#define EFI_CUSTOM_MODE_ENABLE_GUID \
|
||||
GUID_DEF(0xc076ec0c, 0x7028, 0x4399, 0xa0, 0x72, 0x71, 0xee, 0x5c, 0x44, 0x8b, 0x9f)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
GUID_DEF(0x0964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
|
||||
#define EFI_FILE_INFO_ID \
|
||||
GUID_DEF(0x009576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
|
||||
#define EFI_FILE_SYSTEM_INFO_ID \
|
||||
GUID_DEF(0x009576e93, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
|
||||
|
||||
#define EFI_FILE_MODE_READ 0x0000000000000001U
|
||||
#define EFI_FILE_MODE_WRITE 0x0000000000000002U
|
||||
@@ -31,6 +33,15 @@ typedef struct {
|
||||
char16_t FileName[];
|
||||
} EFI_FILE_INFO;
|
||||
|
||||
typedef struct {
|
||||
uint64_t Size;
|
||||
bool ReadOnly;
|
||||
uint64_t VolumeSize;
|
||||
uint64_t FreeSpace;
|
||||
uint32_t BlockSize;
|
||||
char16_t VolumeLabel[];
|
||||
} EFI_FILE_SYSTEM_INFO;
|
||||
|
||||
/* Some broken firmware violates the EFI spec by still advancing the readdir
|
||||
* position when returning EFI_BUFFER_TOO_SMALL, effectively skipping over any files when
|
||||
* the buffer was too small. Therefore, we always start with a buffer that should handle FAT32
|
||||
|
||||
@@ -132,6 +132,17 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir) {
|
||||
|
||||
validate_sha256();
|
||||
|
||||
/* If the volume is read-only we cannot update the random seed, but if we cannot update it, then we
|
||||
* really don't want to use it since it would be the same on every boot. */
|
||||
bool volume_ro;
|
||||
err = get_volume_ro(root_dir, &volume_ro);
|
||||
if (err != EFI_SUCCESS)
|
||||
log_debug_status(err, "Failed to determine if volume is read-only, assuming not: %m");
|
||||
else if (volume_ro) {
|
||||
log_debug("Volume is read-only, not updating random seed.");
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* hash = LABEL || sizeof(input1) || input1 || ... || sizeof(inputN) || inputN */
|
||||
sha256_init_ctx(&hash);
|
||||
|
||||
|
||||
@@ -298,6 +298,28 @@ EFI_STATUS get_file_info(EFI_FILE *handle, EFI_FILE_INFO **ret, size_t *ret_size
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS get_volume_ro(EFI_FILE *handle, bool *ret) {
|
||||
size_t size = offsetof(EFI_FILE_SYSTEM_INFO, VolumeLabel) + 256U * sizeof(char16_t);
|
||||
_cleanup_free_ EFI_FILE_SYSTEM_INFO *fsi = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(handle);
|
||||
assert(ret);
|
||||
|
||||
fsi = xmalloc(size);
|
||||
err = handle->GetInfo(handle, MAKE_GUID_PTR(EFI_FILE_SYSTEM_INFO), &size, fsi);
|
||||
if (err == EFI_BUFFER_TOO_SMALL) {
|
||||
free(fsi);
|
||||
fsi = xmalloc(size); /* GetInfo tells us the required size, let's use that now */
|
||||
err = handle->GetInfo(handle, MAKE_GUID_PTR(EFI_FILE_SYSTEM_INFO), &size, fsi);
|
||||
}
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
*ret = fsi->ReadOnly;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS readdir(
|
||||
EFI_FILE *handle,
|
||||
EFI_FILE_INFO **buffer,
|
||||
|
||||
@@ -168,6 +168,7 @@ typedef int (*compare_pointer_func_t)(const void *a, const void *b);
|
||||
void sort_pointer_array(void **array, size_t n_members, compare_pointer_func_t compare);
|
||||
|
||||
EFI_STATUS get_file_info(EFI_FILE *handle, EFI_FILE_INFO **ret, size_t *ret_size);
|
||||
EFI_STATUS get_volume_ro(EFI_FILE *handle, bool *ret);
|
||||
EFI_STATUS readdir(EFI_FILE *handle, EFI_FILE_INFO **buffer, size_t *buffer_size);
|
||||
|
||||
bool is_ascii(const char16_t *f);
|
||||
|
||||
Reference in New Issue
Block a user