cppcheck: (error) Memory leak: vtoc

Resolve the reported memory leak by using a dedicated local vptr
variable to store the pointer reported by calloc().  Only assign the
passed **vtoc function argument on success, in all other cases vptr
is freed.

[lib/libefi/rdwr_efi.c:403]: (error) Memory leak: vtoc
[lib/libefi/rdwr_efi.c:422]: (error) Memory leak: vtoc
[lib/libefi/rdwr_efi.c:440]: (error) Memory leak: vtoc
[lib/libefi/rdwr_efi.c:454]: (error) Memory leak: vtoc
[lib/libefi/rdwr_efi.c:470]: (error) Memory leak: vtoc

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #9732
This commit is contained in:
Brian Behlendorf 2019-12-16 10:40:29 -08:00
parent abfdb83607
commit fe20400db5
1 changed files with 19 additions and 14 deletions

View File

@ -399,10 +399,11 @@ efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc)
length = sizeof (struct dk_gpt) + length = sizeof (struct dk_gpt) +
sizeof (struct dk_part) * (nparts - 1); sizeof (struct dk_part) * (nparts - 1);
if ((*vtoc = calloc(1, length)) == NULL) vptr = calloc(1, length);
if (vptr == NULL)
return (-1); return (-1);
vptr = *vtoc; *vtoc = vptr;
vptr->efi_version = EFI_VERSION_CURRENT; vptr->efi_version = EFI_VERSION_CURRENT;
vptr->efi_lbasize = lbsize; vptr->efi_lbasize = lbsize;
@ -431,30 +432,32 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
int rval; int rval;
uint32_t nparts; uint32_t nparts;
int length; int length;
struct dk_gpt *vptr;
/* figure out the number of entries that would fit into 16K */ /* figure out the number of entries that would fit into 16K */
nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t); nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t);
length = (int) sizeof (struct dk_gpt) + length = (int) sizeof (struct dk_gpt) +
(int) sizeof (struct dk_part) * (nparts - 1); (int) sizeof (struct dk_part) * (nparts - 1);
if ((*vtoc = calloc(1, length)) == NULL) vptr = calloc(1, length);
if (vptr == NULL)
return (VT_ERROR); return (VT_ERROR);
(*vtoc)->efi_nparts = nparts; vptr->efi_nparts = nparts;
rval = efi_read(fd, *vtoc); rval = efi_read(fd, vptr);
if ((rval == VT_EINVAL) && (*vtoc)->efi_nparts > nparts) { if ((rval == VT_EINVAL) && vptr->efi_nparts > nparts) {
void *tmp; void *tmp;
length = (int) sizeof (struct dk_gpt) + length = (int) sizeof (struct dk_gpt) +
(int) sizeof (struct dk_part) * (int) sizeof (struct dk_part) * (vptr->efi_nparts - 1);
((*vtoc)->efi_nparts - 1); nparts = vptr->efi_nparts;
nparts = (*vtoc)->efi_nparts; if ((tmp = realloc(vptr, length)) == NULL) {
if ((tmp = realloc(*vtoc, length)) == NULL) { free(vptr);
free (*vtoc);
*vtoc = NULL; *vtoc = NULL;
return (VT_ERROR); return (VT_ERROR);
} else { } else {
*vtoc = tmp; vptr = tmp;
rval = efi_read(fd, *vtoc); rval = efi_read(fd, vptr);
} }
} }
@ -463,8 +466,10 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
(void) fprintf(stderr, (void) fprintf(stderr,
"read of EFI table failed, rval=%d\n", rval); "read of EFI table failed, rval=%d\n", rval);
} }
free (*vtoc); free(vptr);
*vtoc = NULL; *vtoc = NULL;
} else {
*vtoc = vptr;
} }
return (rval); return (rval);