dissect: guard against ssize_t overflow in LUKS2 header parser (#42162)

The `json_len` variable in `partition_is_luks2_integrity()` is
`ssize_t`, but the subtraction `be64toh(header.hdr_len) -
LUKS2_FIXED_HDR_SIZE` can yield a value exceeding `SSIZE_MAX` when
`hdr_len` is a large crafted value. This causes signed integer overflow
and a subsequent oversized `malloc()` that fails with `-ENOMEM`,
producing a misleading out-of-memory error instead of a clear
invalid-header rejection.

Two call sites pass `size = UINT64_MAX`, which neutralizes the existing
`hdr_len > size` guard.

Add an explicit check against `SSIZE_MAX` before the cast to `ssize_t`.
This commit is contained in:
Lennart Poettering
2026-05-19 08:30:07 +02:00
committed by GitHub
+3
View File
@@ -446,6 +446,9 @@ static int partition_is_luks2_integrity(int part_fd, uint64_t offset, uint64_t s
if (be64toh(header.hdr_len) <= LUKS2_FIXED_HDR_SIZE || offset > UINT64_MAX - be64toh(header.hdr_len))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid LUKS header length: %" PRIu64 ".", be64toh(header.hdr_len));
if (be64toh(header.hdr_len) - LUKS2_FIXED_HDR_SIZE > 16U * 1024U * 1024U)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "LUKS header JSON area too large: %" PRIu64 ".", be64toh(header.hdr_len));
json_len = be64toh(header.hdr_len) - LUKS2_FIXED_HDR_SIZE;
json = malloc(json_len + 1);
if (!json)