diff options
| author | Igor Opaniuk <[email protected]> | 2026-07-12 10:50:21 +0200 |
|---|---|---|
| committer | Mattijs Korpershoek <[email protected]> | 2026-07-24 14:43:24 +0200 |
| commit | f9c750ea306877432a525de1ebd9740ec815e5da (patch) | |
| tree | 5e75aa05f004b45e41118bc6b54d1141bb923730 | |
| parent | a7f65a6b6abc7119394e1ae7f16e3c60d39166c8 (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.c | 29 |
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; } |
