]> git.ipfire.org Git - thirdparty/systemd.git/commit
dissect-image: cast to uint64_t before *512 for sig lookup
authorChris Mason <clm@meta.com>
Fri, 22 May 2026 16:13:50 +0000 (09:13 -0700)
committerLennart Poettering <lennart@amutable.com>
Fri, 22 May 2026 20:16:07 +0000 (22:16 +0200)
commit2eff83757409db0a3eedfcdff1f2445a291c8ab7
tree22855b3bbafbf36ffd235bb0815ce862564ea5f3
parentfa0cd9b79f85dc6d24cd7d3f7c554b35bd5191fd
dissect-image: cast to uint64_t before *512 for sig lookup

In the PARTITION_ROOT_VERITY_SIG / PARTITION_USR_VERITY_SIG branch of
dissect_image(), the call to acquire_sig_for_roothash() passes the
partition offset and size as

    acquire_sig_for_roothash(fd,
                             start * 512,
                             size * 512,
                             &root_hash, NULL);

where start and size are blkid_loff_t (int64_t). The literal 512 is
int, so the multiplication is performed in int64_t and overflows for
LBA values in (INT64_MAX/512, INT64_MAX]. The overflowed signed result
is then converted to the uint64_t parameters of
acquire_sig_for_roothash(), yielding a near-UINT64_MAX
partition_offset that slips past the sole offset guard (an exact
== UINT64_MAX sentinel) and reaches pread() with a corrupt disk
offset. An overflowed partition_size would be rejected by the 4 MiB
EFBIG check at src/shared/dissect-image.c:710-712 before pread(); the
dangerous scenario is a corrupt offset combined with a legitimate
small size.

The three sibling call sites at src/shared/dissect-image.c:1284,
1589-1590 and 1671-1672 all cast to uint64_t before multiplying by
512; only this call site was missed.

Fix by casting start and size to uint64_t before the multiplication,
matching the sibling sites and making the arithmetic well-defined.

Fixes: 98ca65c36aa9 ("dissect: check that roothash in signature matches before selecting partition")
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
src/shared/dissect-image.c