Blame SOURCES/cryptsetup-2.0.6-fix-keyslot-areas-validation.patch

7cdc99
diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c
7cdc99
--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c	2019-03-27 16:14:49.790420791 +0100
7cdc99
+++ cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c	2019-03-27 16:23:50.499187212 +0100
7cdc99
@@ -363,12 +363,13 @@ static json_bool segment_has_digest(cons
7cdc99
 	return FALSE;
7cdc99
 }
7cdc99
 
7cdc99
-static json_bool validate_intervals(int length, const struct interval *ix, uint64_t *data_offset)
7cdc99
+static json_bool validate_intervals(int length, const struct interval *ix,
7cdc99
+				    uint64_t metadata_size, uint64_t keyslots_area_end)
7cdc99
 {
7cdc99
 	int j, i = 0;
7cdc99
 
7cdc99
 	while (i < length) {
7cdc99
-		if (ix[i].offset < 2 * LUKS2_HDR_16K_LEN) {
7cdc99
+		if (ix[i].offset < 2 * metadata_size) {
7cdc99
 			log_dbg("Illegal area offset: %" PRIu64 ".", ix[i].offset);
7cdc99
 			return FALSE;
7cdc99
 		}
7cdc99
@@ -378,10 +379,9 @@ static json_bool validate_intervals(int
7cdc99
 			return FALSE;
7cdc99
 		}
7cdc99
 
7cdc99
-		/* first segment at offset 0 means we have detached header. Do not check then. */
7cdc99
-		if (*data_offset && (ix[i].offset + ix[i].length) > *data_offset) {
7cdc99
-			log_dbg("Area [%" PRIu64 ", %" PRIu64 "] intersects with segment starting at offset: %" PRIu64,
7cdc99
-				ix[i].offset, ix[i].offset + ix[i].length, *data_offset);
7cdc99
+		if ((ix[i].offset + ix[i].length) > keyslots_area_end) {
7cdc99
+			log_dbg("Area [%" PRIu64 ", %" PRIu64 "] overflows binary keyslots area (ends at offset: %" PRIu64 ").",
7cdc99
+				ix[i].offset, ix[i].offset + ix[i].length, keyslots_area_end);
7cdc99
 			return FALSE;
7cdc99
 		}
7cdc99
 
7cdc99
@@ -596,12 +596,24 @@ static int hdr_validate_segments(json_ob
7cdc99
 	return 0;
7cdc99
 }
7cdc99
 
7cdc99
+static uint64_t LUKS2_metadata_size(json_object *jobj)
7cdc99
+{
7cdc99
+	json_object *jobj1, *jobj2;
7cdc99
+	uint64_t json_size;
7cdc99
+
7cdc99
+	json_object_object_get_ex(jobj, "config", &jobj1);
7cdc99
+	json_object_object_get_ex(jobj1, "json_size", &jobj2);
7cdc99
+	json_str_to_uint64(jobj2, &json_size);
7cdc99
+
7cdc99
+	return json_size + LUKS2_HDR_BIN_LEN;
7cdc99
+}
7cdc99
+
7cdc99
 static int hdr_validate_areas(json_object *hdr_jobj)
7cdc99
 {
7cdc99
 	struct interval *intervals;
7cdc99
 	json_object *jobj_keyslots, *jobj_offset, *jobj_length, *jobj_segments, *jobj_area;
7cdc99
 	int length, ret, i = 0;
7cdc99
-	uint64_t first_offset, keyslots_size, keyslots_area_sum = 0;
7cdc99
+	uint64_t keyslots_size, metadata_size, keyslots_area_sum = 0;
7cdc99
 
7cdc99
 	if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
7cdc99
 		return 1;
7cdc99
@@ -611,6 +623,7 @@ static int hdr_validate_areas(json_objec
7cdc99
 
7cdc99
 	/* config is already validated */
7cdc99
 	keyslots_size = LUKS2_keyslots_size(hdr_jobj);
7cdc99
+	metadata_size = LUKS2_metadata_size(hdr_jobj);
7cdc99
 
7cdc99
 	length = json_object_object_length(jobj_keyslots);
7cdc99
 
7cdc99
@@ -663,9 +676,7 @@ static int hdr_validate_areas(json_objec
7cdc99
 		return 1;
7cdc99
 	}
7cdc99
 
7cdc99
-	first_offset = get_first_data_offset(jobj_segments, NULL);
7cdc99
-
7cdc99
-	ret = validate_intervals(length, intervals, &first_offset) ? 0 : 1;
7cdc99
+	ret = validate_intervals(length, intervals, metadata_size, LUKS2_hdr_and_areas_size(hdr_jobj)) ? 0 : 1;
7cdc99
 
7cdc99
 	free(intervals);
7cdc99
 
7cdc99
@@ -918,14 +929,7 @@ uint64_t LUKS2_keyslots_size(json_object
7cdc99
 
7cdc99
 uint64_t LUKS2_hdr_and_areas_size(json_object *jobj)
7cdc99
 {
7cdc99
-	json_object *jobj1, *jobj2;
7cdc99
-	uint64_t json_size;
7cdc99
-
7cdc99
-	json_object_object_get_ex(jobj, "config", &jobj1);
7cdc99
-	json_object_object_get_ex(jobj1, "json_size", &jobj2);
7cdc99
-	json_str_to_uint64(jobj2, &json_size);
7cdc99
-
7cdc99
-	return 2 * (json_size + LUKS2_HDR_BIN_LEN) + LUKS2_keyslots_size(jobj);
7cdc99
+	return 2 * LUKS2_metadata_size(jobj) + LUKS2_keyslots_size(jobj);
7cdc99
 }
7cdc99
 
7cdc99
 int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,