summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Opaniuk <[email protected]>2026-07-12 10:50:21 +0200
committerMattijs Korpershoek <[email protected]>2026-07-24 14:43:24 +0200
commitf9c750ea306877432a525de1ebd9740ec815e5da (patch)
tree5e75aa05f004b45e41118bc6b54d1141bb923730
parenta7f65a6b6abc7119394e1ae7f16e3c60d39166c8 (diff)
avb: free mmc_part allocated by get_partition()
get_partition() returns a malloc()'d struct mmc_part and only frees it on its own internal error path. None of its callers - mmc_byte_io(), get_unique_guid_for_partition() and get_size_of_partition() - free the returned pointer, so every partition access leaks one struct mmc_part. A single "avb verify" issues many such accesses (footer, vbmeta and the hashed image chunks), so the leak accumulates quickly. Free the descriptor in all three callers. mmc_byte_io() is reworked to use a single exit path so the partition is released on every return. Fixes: 3af30e4443aa ("avb2.0: implement AVB ops") Signed-off-by: Igor Opaniuk <[email protected]> Reviewed-by: Mattijs Korpershoek <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mattijs Korpershoek <[email protected]>
-rw-r--r--common/avb_verify.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/common/avb_verify.c b/common/avb_verify.c
index 29a3272579c..76c523fd0ba 100644
--- a/common/avb_verify.c
+++ b/common/avb_verify.c
@@ -452,6 +452,7 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
u64 start_offset, start_sector, sectors, residue;
u8 *tmp_buf;
size_t io_cnt = 0;
+ AvbIOResult io_ret = AVB_IO_RESULT_OK;
if (!partition || !buffer || io_type > IO_WRITE)
return AVB_IO_RESULT_ERROR_IO;
@@ -460,8 +461,10 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (!part)
return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
- if (!part->info.blksz)
- return AVB_IO_RESULT_ERROR_IO;
+ if (!part->info.blksz) {
+ io_ret = AVB_IO_RESULT_ERROR_IO;
+ goto out;
+ }
start_offset = calc_offset(part, offset);
while (num_bytes) {
@@ -489,7 +492,8 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (ret != 1) {
printf("%s: read error (%ld, %lld)\n",
__func__, ret, start_sector);
- return AVB_IO_RESULT_ERROR_IO;
+ io_ret = AVB_IO_RESULT_ERROR_IO;
+ goto out;
}
/*
* if this is not aligned at sector start,
@@ -506,7 +510,8 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (ret != 1) {
printf("%s: read error (%ld, %lld)\n",
__func__, ret, start_sector);
- return AVB_IO_RESULT_ERROR_IO;
+ io_ret = AVB_IO_RESULT_ERROR_IO;
+ goto out;
}
memcpy((void *)tmp_buf +
start_offset % part->info.blksz,
@@ -517,7 +522,8 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (ret != 1) {
printf("%s: write error (%ld, %lld)\n",
__func__, ret, start_sector);
- return AVB_IO_RESULT_ERROR_IO;
+ io_ret = AVB_IO_RESULT_ERROR_IO;
+ goto out;
}
}
@@ -543,7 +549,8 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (!ret) {
printf("%s: sector read error\n", __func__);
- return AVB_IO_RESULT_ERROR_IO;
+ io_ret = AVB_IO_RESULT_ERROR_IO;
+ goto out;
}
io_cnt += ret * part->info.blksz;
@@ -557,7 +564,9 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (io_type == IO_READ && out_num_read)
*out_num_read = io_cnt;
- return AVB_IO_RESULT_OK;
+out:
+ free(part);
+ return io_ret;
}
/**
@@ -867,12 +876,15 @@ static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
uuid_size = sizeof(part->info.uuid);
- if (uuid_size > guid_buf_size)
+ if (uuid_size > guid_buf_size) {
+ free(part);
return AVB_IO_RESULT_ERROR_IO;
+ }
memcpy(guid_buf, part->info.uuid, uuid_size);
guid_buf[uuid_size - 1] = 0;
+ free(part);
return AVB_IO_RESULT_OK;
}
@@ -903,6 +915,7 @@ static AvbIOResult get_size_of_partition(AvbOps *ops,
return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
*out_size_num_bytes = part->info.blksz * part->info.size;
+ free(part);
return AVB_IO_RESULT_OK;
}