The checksum size calculation uses on-disk max_dev (uint32_t) multiplied
by sizeof(dev_roles[0]). On 32-bit systems, this overflows size_t,
resulting in a truncated buffer and checksum computed over wrong data,
potentially allowing crafted images to bypass validation.
Fix by computing in uint64_t. Note that blkid_probe_get_buffer() has
a hardcoded 8 MiB limit, so unreasonably large (but non-overflowed)
values are still safely rejected.
Signed-off-by: Karel Zak <kzak@redhat.com>
static int raid1_verify_csum(blkid_probe pr, off_t off,
const struct mdp1_super_block *mdp1)
{
- size_t csummed_size = sizeof(struct mdp1_super_block)
- + le32_to_cpu(mdp1->max_dev) * sizeof(mdp1->dev_roles[0]);
+ uint64_t csummed_size = sizeof(struct mdp1_super_block)
+ + (uint64_t) le32_to_cpu(mdp1->max_dev) * sizeof(mdp1->dev_roles[0]);
const unsigned char *csummed = blkid_probe_get_buffer(pr, off, csummed_size);
if (!csummed)
return 1;