]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: guard against ssize_t overflow in LUKS2 header parser
authorTristanInSec <tristan.mtn@gmail.com>
Mon, 18 May 2026 17:30:02 +0000 (13:30 -0400)
committerTristanInSec <tristan.mtn@gmail.com>
Mon, 18 May 2026 17:30:02 +0000 (13:30 -0400)
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

index c5bb52b2afe27a94342238055341870b8135a291..3aeb254fd4dded1aad0a7c7b72a129bd54154f73 100644 (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 > (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)