diff options
| author | Shahriyar Jalayeri <[email protected]> | 2026-07-29 21:02:09 +0200 |
|---|---|---|
| committer | Mattijs Korpershoek <[email protected]> | 2026-08-12 09:46:11 +0200 |
| commit | 35432ef6fe2c79ab72709966e64815a45eb55c76 (patch) | |
| tree | 0c55c5a64601d49f66c1a4e519aa5e66548a8615 | |
| parent | 36c377b9859ffb53eb1e39ea31e8d96d1e0fe1e5 (diff) | |
bootstd: android: bound the boot image read by its partition size
read_slotted_partition() loads an Android boot/vendor_boot image into the
load address, sizing the read from the image header:
num_blks = DIV_ROUND_UP(image_size, desc->blksz);
...
blk_dread(desc, partition.start, num_blks, map_sysmem(addr, 0));
image_size is priv->boot_img_size / priv->vendor_boot_img_size, taken from
the boot image header and never bounded by the partition. A header
claiming a size larger than the partition makes blk_dread read past the
partition and write past the load buffer: an out-of-bounds write of
attacker-controlled length on media a physical attacker can supply. It is
reached during boot on a device where AVB does not gate the read (AVB
disabled, or an unlocked device).
Reject an image that does not fit in its partition before issuing the read.
Both the boot and vendor_boot reads go through this function.
Fixes: abadcda24b10 ("bootstd: android: don't read whole partition sizes")
Signed-off-by: Shahriyar Jalayeri <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Mattijs Korpershoek <[email protected]>
| -rw-r--r-- | boot/bootmeth_android.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/boot/bootmeth_android.c b/boot/bootmeth_android.c index ec255b072af..0db08d4f861 100644 --- a/boot/bootmeth_android.c +++ b/boot/bootmeth_android.c @@ -384,6 +384,14 @@ static int read_slotted_partition(struct blk_desc *desc, const char *const name, if (ret < 0) return log_msg_ret("part", ret); + /* + * The image size comes from the (untrusted) boot image header, so bound + * the read by the partition size: a valid image cannot be larger than + * the partition holding it. + */ + if (num_blks > partition.size) + return log_msg_ret("image larger than partition", -EFBIG); + n = blk_dread(desc, partition.start, num_blks, map_sysmem(addr, 0)); if (n < num_blks) return log_msg_ret("part read", -EIO); |
