Files
buildroot/package/cryptsetup/0004-Check-segment-gaps-regardless-of-heap-space.patch
Peter Korsgaard 957ff8fa25 package/cryptsetup: backport upstream security fixes
Fixes CVE-2020-14382: A vulnerability was found in upstream release
cryptsetup-2.2.0 where, there's a bug in LUKS2 format validation code, that
is effectively invoked on every device/image presenting itself as LUKS2
container.  The bug is in segments validation code in file
'lib/luks2/luks2_json_metadata.c' in function hdr_validate_segments(struct
crypt_device *cd, json_object *hdr_jobj) where the code does not check for
possible overflow on memory allocation used for intervals array (see
statement "intervals = malloc(first_backup * sizeof(*intervals));").  Due to
the bug, library can be *tricked* to expect such allocation was successful
but for far less memory then originally expected.  Later it may read data
FROM image crafted by an attacker and actually write such data BEYOND
allocated memory.

Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
2020-10-30 09:32:00 +01:00

65 lines
2.4 KiB
Diff

From eaec63806b88aa2775271254734e78324c239622 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann <tobias@stoeckmann.org>
Date: Mon, 24 Aug 2020 19:21:43 +0200
Subject: [PATCH 4/6] Check segment gaps regardless of heap space.
Segments are validated in hdr_validate_segments. Gaps in segment keys
are detected when collecting offsets. But if an invalid segment is very
large, larger than count, it could happen that cryptsetup is unable to
allocate enough memory, not giving a clue about what actually is the
problem.
Therefore check for gaps even if not enough memory is available. This
gives much more information with debug output enabled.
Obviously cryptsetup still fails if segments are perfectly fine but not
enough RAM available. But at that stage, the user knows that it's the
fault of the system, not of an invalid segment.
(cherry picked from commit 52f5cb8cedf22fb3e14c744814ec8af7614146c7)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
---
lib/luks2/luks2_json_metadata.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c
index 19fb9588..67a5512d 100644
--- a/lib/luks2/luks2_json_metadata.c
+++ b/lib/luks2/luks2_json_metadata.c
@@ -679,11 +679,10 @@ static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
if (first_backup < 0)
first_backup = count;
- intervals = malloc(first_backup * sizeof(*intervals));
- if (!intervals) {
- log_dbg(cd, "Not enough memory.");
- return 1;
- }
+ if (first_backup <= count && (size_t)first_backup < SIZE_MAX / sizeof(*intervals))
+ intervals = malloc(first_backup * sizeof(*intervals));
+ else
+ intervals = NULL;
for (i = 0; i < first_backup; i++) {
jobj = json_segments_get_segment(jobj_segments, i);
@@ -692,8 +691,14 @@ static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
free(intervals);
return 1;
}
- intervals[i].offset = json_segment_get_offset(jobj, 0);
- intervals[i].length = json_segment_get_size(jobj, 0) ?: UINT64_MAX;
+ if (intervals != NULL) {
+ intervals[i].offset = json_segment_get_offset(jobj, 0);
+ intervals[i].length = json_segment_get_size(jobj, 0) ?: UINT64_MAX;
+ }
+ }
+ if (intervals == NULL) {
+ log_dbg(cd, "Not enough memory.");
+ return 1;
}
r = !validate_segment_intervals(cd, first_backup, intervals);
--
2.20.1