From 08c281304cd6fd7bf20f5eb7aaa81c7ee4283b0c Mon Sep 17 00:00:00 2001 From: TristanInSec Date: Mon, 18 May 2026 13:30:02 -0400 Subject: [PATCH 1/2] dissect: guard against ssize_t overflow in LUKS2 header parser The json_len variable 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. Add an explicit check against SSIZE_MAX before the cast to ssize_t. --- src/shared/dissect-image.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index c5bb52b2af..3aeb254fd4 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -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 > (uint64_t) SSIZE_MAX) + 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) From a190e64dfb348273c626267efa5876055939fdeb Mon Sep 17 00:00:00 2001 From: TristanInSec Date: Mon, 18 May 2026 14:39:44 -0400 Subject: [PATCH 2/2] dissect: use practical 16 MiB limit instead of SSIZE_MAX As suggested by @yuwata, SSIZE_MAX is still too large and would cause malloc() to fail anyway. Use a 16 MiB limit which is generous compared to the typical 4 MiB maximum in cryptsetup (LUKS2_HDR_OFFSET_MAX). --- src/shared/dissect-image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 3aeb254fd4..8483a16e94 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -446,7 +446,7 @@ 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 > (uint64_t) SSIZE_MAX) + 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;