From fe20400db5564d4478fb039e773dd43c1f546d7b Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 16 Dec 2019 10:40:29 -0800 Subject: 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 Signed-off-by: Brian Behlendorf Closes #9732 --- lib/libefi/rdwr_efi.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'lib/libefi') diff --git a/lib/libefi/rdwr_efi.c b/lib/libefi/rdwr_efi.c index 68038b911..2cb093f96 100644 --- a/lib/libefi/rdwr_efi.c +++ b/lib/libefi/rdwr_efi.c @@ -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; @@ -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); } } @@ -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); -- cgit v1.2.3