efi_var_collect() walks the variable store with GetNextVariableName() and reads every variable it finds into a buffer the size of the store, then keeps only those matching the attribute mask. Reading a variable whose value does not fit aborts the collection, and with it the write of the variable file:
efi-loader: var-file: Failed to persist EFI variables Out of memory VarToFile is such a variable. Its value is not stored anywhere: reading it serializes all non-volatile variables, so it needed as much room as everything collected before it. Assisted-by: Claude:opus-5 Signed-off-by: Ahmad Fatoum <[email protected]> --- efi/loader/efi_var_common.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/efi/loader/efi_var_common.c b/efi/loader/efi_var_common.c index 4c6cb77e7c2c..dcdfa6fb0165 100644 --- a/efi/loader/efi_var_common.c +++ b/efi/loader/efi_var_common.c @@ -454,6 +454,14 @@ efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t * ret = efi_get_variable_int(var->name, &var->guid, &var->attr, &data_length, data, &var->time); + /* + * The attributes are valid even when the value did not fit. + * Variables we are not going to keep may thus be skipped + * without their value ever being copied, e.g. VarToFile. + */ + if (ret == EFI_BUFFER_TOO_SMALL && + (var->attr & check_attr_mask) != check_attr_mask) + continue; if (ret != EFI_SUCCESS) { free(buf); return ret; -- 2.47.3
