Skip to content

Commit

Permalink
cppcheck: (error) Memory leak: vtoc
Browse files Browse the repository at this point in the history
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 openzfs#9732
  • Loading branch information
behlendorf authored and tonyhutter committed Dec 27, 2019
1 parent 35e157c commit 0c3c858
Showing 1 changed file with 19 additions and 14 deletions.
33 changes: 19 additions & 14 deletions lib/libefi/rdwr_efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,11 @@ efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc)
length = sizeof (struct dk_gpt) +
sizeof (struct dk_part) * (nparts - 1);

if ((*vtoc = calloc(1, length)) == NULL)
vptr = calloc(1, length);
if (vptr == NULL)
return (-1);

vptr = *vtoc;
*vtoc = vptr;

vptr->efi_version = EFI_VERSION_CURRENT;
vptr->efi_lbasize = lbsize;
Expand Down Expand Up @@ -431,30 +432,32 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
int rval;
uint32_t nparts;
int length;
struct dk_gpt *vptr;

/* figure out the number of entries that would fit into 16K */
nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t);
length = (int) sizeof (struct dk_gpt) +
(int) sizeof (struct dk_part) * (nparts - 1);
if ((*vtoc = calloc(1, length)) == NULL)
vptr = calloc(1, length);

if (vptr == NULL)
return (VT_ERROR);

(*vtoc)->efi_nparts = nparts;
rval = efi_read(fd, *vtoc);
vptr->efi_nparts = nparts;
rval = efi_read(fd, vptr);

if ((rval == VT_EINVAL) && (*vtoc)->efi_nparts > nparts) {
if ((rval == VT_EINVAL) && vptr->efi_nparts > nparts) {
void *tmp;
length = (int) sizeof (struct dk_gpt) +
(int) sizeof (struct dk_part) *
((*vtoc)->efi_nparts - 1);
nparts = (*vtoc)->efi_nparts;
if ((tmp = realloc(*vtoc, length)) == NULL) {
free (*vtoc);
(int) sizeof (struct dk_part) * (vptr->efi_nparts - 1);
nparts = vptr->efi_nparts;
if ((tmp = realloc(vptr, length)) == NULL) {
free(vptr);
*vtoc = NULL;
return (VT_ERROR);
} else {
*vtoc = tmp;
rval = efi_read(fd, *vtoc);
vptr = tmp;
rval = efi_read(fd, vptr);
}
}

Expand All @@ -463,8 +466,10 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
(void) fprintf(stderr,
"read of EFI table failed, rval=%d\n", rval);
}
free (*vtoc);
free(vptr);
*vtoc = NULL;
} else {
*vtoc = vptr;
}

return (rval);
Expand Down

0 comments on commit 0c3c858

Please sign in to comment.