]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
avb: free mmc_part allocated by get_partition()
authorIgor Opaniuk <igor.opaniuk@gmail.com>
Sun, 12 Jul 2026 08:50:21 +0000 (10:50 +0200)
committerMattijs Korpershoek <mkorpershoek@kernel.org>
Fri, 24 Jul 2026 12:43:24 +0000 (14:43 +0200)
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 <igor.opaniuk@gmail.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@kernel.org>
Link: https://patch.msgid.link/20260712-avb-fix-memory-leaks-v1-2-51d6d5a42631@gmail.com
Signed-off-by: Mattijs Korpershoek <mkorpershoek@kernel.org>
common/avb_verify.c

index 29a3272579cff116349110c42347dbd793a59a53..76c523fd0ba33f9b489302f54888b9111ac5f708 100644 (file)
@@ -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;
 }