ACK: [PATCH] uefivarinfo: allocate buffer rewrite to avoid realloc failure (LP: #1362540)
Colin Ian King
colin.king at canonical.com
Mon Sep 15 12:24:31 UTC 2014
On 15/09/14 07:34, Ivan Hu wrote:
> The data buffer which was brought into firmware seems to be changed that caused
> the realloc function failed below. Rewrite the function that allocate buffer
> with the max allowed variable size without reallocing the memory.
>
> *** glibc detected *** fwts: realloc(): invalid next size: 0x00007f5e807a7080 **
>
> Signed-off-by: Ivan Hu <ivan.hu at canonical.com>
> ---
> src/uefi/uefivarinfo/uefivarinfo.c | 55 +++++++++++++++++++-----------------
> 1 file changed, 29 insertions(+), 26 deletions(-)
>
> diff --git a/src/uefi/uefivarinfo/uefivarinfo.c b/src/uefi/uefivarinfo/uefivarinfo.c
> index 84e960b..a4d2783 100644
> --- a/src/uefi/uefivarinfo/uefivarinfo.c
> +++ b/src/uefi/uefivarinfo/uefivarinfo.c
> @@ -29,7 +29,6 @@
> #include "fwts_efi_module.h"
>
> #define MAX_VARNAME_LENGTH 1024
> -#define DATA_LENGTH 1024
>
> static int fd;
>
> @@ -66,7 +65,7 @@ static int do_checkvariables(
> fwts_framework *fw,
> uint64_t *usedvars,
> uint64_t *usedvarssize,
> - uint64_t maxvarsize)
> + const uint64_t maxvarsize)
> {
> long ioret;
> uint64_t status;
> @@ -114,46 +113,50 @@ static int do_checkvariables(
>
> (*usedvars)++;
>
> - data = malloc(DATA_LENGTH);
> + data = malloc(maxvarsize);
> if (!data) {
> fwts_log_info(fw, "Failed to allocate memory for test.");
> return FWTS_ERROR;
> }
>
> - getdatasize = DATA_LENGTH;
> + getdatasize = maxvarsize;
> getvariable.VariableName = variablename;
> getvariable.VendorGuid = &vendorguid;
> getvariable.DataSize = &getdatasize;
> getvariable.Data = data;
> - while (true) {
> - ioret = ioctl(fd, EFI_RUNTIME_GET_VARIABLE, &getvariable);
> - if (ioret == -1) {
> - if (status != EFI_BUFFER_TOO_SMALL) {
> - fwts_log_info(fw, "Failed to get variable with UEFI runtime service.");
> - fwts_uefi_print_status_info(fw, status);
> - free(data);
> +
> + ioret = ioctl(fd, EFI_RUNTIME_GET_VARIABLE, &getvariable);
> + if (ioret == -1) {
> + free(data);
> + if (status != EFI_BUFFER_TOO_SMALL) {
> + fwts_log_info(fw, "Failed to get variable with UEFI runtime service.");
> + fwts_uefi_print_status_info(fw, status);
> + return FWTS_ERROR;
> + } else if (getdatasize > maxvarsize) {
> + fwts_log_info(fw, "Variable is larger than maximum variable length.");
> + fwts_uefi_print_status_info(fw, status);
> +
> + /*
> + * Although the variable is larger than maximum variable length,
> + * still try to calculate the total sizes of the used variables.
> + */
> + data = malloc(getdatasize);
> + if (!data) {
> + fwts_log_info(fw, "Failed to allocate memory for test.");
> return FWTS_ERROR;
> }
> - if (getdatasize == maxvarsize) {
> - fwts_log_info(fw, "Variable is larger than maximum variable length.");
> +
> + getvariable.Data = data;
> + ioret = ioctl(fd, EFI_RUNTIME_GET_VARIABLE, &getvariable);
> + if (ioret == -1) {
> + fwts_log_info(fw, "Failed to get variable with variable larger than maximum variable length.");
> fwts_uefi_print_status_info(fw, status);
> free(data);
> return FWTS_ERROR;
> }
> - getdatasize += DATA_LENGTH;
> - getdatasize = (getdatasize > maxvarsize) ? maxvarsize : getdatasize;
> - data = realloc(data, getdatasize);
> - if (data) {
> - getvariable.DataSize = &getdatasize;
> - getvariable.Data = data;
> - continue;
> - } else {
> - fwts_log_info(fw, "Failed to allocate memory for test.");
> - return FWTS_ERROR;
> - }
> }
> - break;
> - };
> + }
> +
> free(data);
>
> (*usedvarssize) += getdatasize;
>
Looks very reasonable to me, I've not tested it though.
Acked-by: Colin Ian King <colin.king at canonical.com>
More information about the fwts-devel
mailing list