You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
5.0 KiB
147 lines
5.0 KiB
diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c |
|
--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c 2019-03-28 11:32:18.850058719 +0100 |
|
+++ cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c 2019-03-28 11:33:07.610800041 +0100 |
|
@@ -643,7 +643,7 @@ static int hdr_validate_areas(json_objec |
|
struct interval *intervals; |
|
json_object *jobj_keyslots, *jobj_offset, *jobj_length, *jobj_segments, *jobj_area; |
|
int length, ret, i = 0; |
|
- uint64_t first_offset; |
|
+ uint64_t first_offset, keyslots_size, keyslots_area_sum = 0; |
|
|
|
if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots)) |
|
return 1; |
|
@@ -652,6 +652,9 @@ static int hdr_validate_areas(json_objec |
|
if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments)) |
|
return 1; |
|
|
|
+ /* config is already validated */ |
|
+ keyslots_size = LUKS2_keyslots_size(hdr_jobj); |
|
+ |
|
length = json_object_object_length(jobj_keyslots); |
|
|
|
/* Empty section */ |
|
@@ -687,6 +690,8 @@ static int hdr_validate_areas(json_objec |
|
return 1; |
|
} |
|
|
|
+ keyslots_area_sum += intervals[i].length; |
|
+ |
|
i++; |
|
} |
|
|
|
@@ -694,6 +699,13 @@ static int hdr_validate_areas(json_objec |
|
free(intervals); |
|
return 1; |
|
} |
|
+ |
|
+ if (keyslots_area_sum > keyslots_size) { |
|
+ log_dbg("Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %" |
|
+ PRIu64, keyslots_area_sum, keyslots_size); |
|
+ free(intervals); |
|
+ return 1; |
|
+ } |
|
|
|
first_offset = get_first_data_offset(jobj_segments, NULL); |
|
|
|
@@ -739,45 +751,11 @@ static int hdr_validate_digests(json_obj |
|
return 0; |
|
} |
|
|
|
-/* requires keyslots and segments sections being already validated */ |
|
-static int validate_keyslots_size(json_object *hdr_jobj, uint64_t metadata_size, uint64_t keyslots_size) |
|
-{ |
|
- json_object *jobj_keyslots, *jobj, *jobj1; |
|
- uint64_t segment_offset, keyslots_area_sum = 0; |
|
- |
|
- json_object_object_get_ex(hdr_jobj, "segments", &jobj); |
|
- segment_offset = get_first_data_offset(jobj, "crypt"); |
|
- if (segment_offset && |
|
- (segment_offset < keyslots_size || |
|
- (segment_offset - keyslots_size) < (2 * metadata_size))) { |
|
- log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64 |
|
- ", keyslots offset: %" PRIu64, keyslots_size, segment_offset, 2 * metadata_size); |
|
- return 1; |
|
- } |
|
- |
|
- json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots); |
|
- |
|
- json_object_object_foreach(jobj_keyslots, key, val) { |
|
- UNUSED(key); |
|
- json_object_object_get_ex(val, "area", &jobj); |
|
- json_object_object_get_ex(jobj, "size", &jobj1); |
|
- keyslots_area_sum += json_object_get_uint64(jobj1); |
|
- } |
|
- |
|
- if (keyslots_area_sum > keyslots_size) { |
|
- log_dbg("Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %" |
|
- PRIu64, keyslots_area_sum, keyslots_size); |
|
- return 1; |
|
- } |
|
- |
|
- return 0; |
|
-} |
|
- |
|
static int hdr_validate_config(json_object *hdr_jobj) |
|
{ |
|
json_object *jobj_config, *jobj, *jobj1; |
|
int i; |
|
- uint64_t json_size, keyslots_size; |
|
+ uint64_t keyslots_size, metadata_size, segment_offset; |
|
|
|
if (!json_object_object_get_ex(hdr_jobj, "config", &jobj_config)) { |
|
log_dbg("Missing config section."); |
|
@@ -785,15 +763,19 @@ static int hdr_validate_config(json_obje |
|
} |
|
|
|
if (!(jobj = json_contains(jobj_config, "section", "Config", "json_size", json_type_string)) || |
|
- !json_str_to_uint64(jobj, &json_size)) |
|
+ !json_str_to_uint64(jobj, &metadata_size)) |
|
return 1; |
|
|
|
+ /* single metadata instance is assembled from json area size plus |
|
+ * binary header size */ |
|
+ metadata_size += LUKS2_HDR_BIN_LEN; |
|
+ |
|
if (!(jobj = json_contains(jobj_config, "section", "Config", "keyslots_size", json_type_string)) || |
|
!json_str_to_uint64(jobj, &keyslots_size)) |
|
return 1; |
|
|
|
- if (LUKS2_check_metadata_area_size(json_size + LUKS2_HDR_BIN_LEN)) { |
|
- log_dbg("Unsupported LUKS2 header size (%" PRIu64 ").", json_size + LUKS2_HDR_BIN_LEN); |
|
+ if (LUKS2_check_metadata_area_size(metadata_size)) { |
|
+ log_dbg("Unsupported LUKS2 header size (%" PRIu64 ").", metadata_size); |
|
return 1; |
|
} |
|
|
|
@@ -802,8 +784,19 @@ static int hdr_validate_config(json_obje |
|
return 1; |
|
} |
|
|
|
- if (validate_keyslots_size(hdr_jobj, json_size + LUKS2_HDR_BIN_LEN, keyslots_size)) |
|
- return 1; |
|
+ /* |
|
+ * validate keyslots_size fits in between (2 * metadata_size) and first |
|
+ * segment_offset (except detached header) |
|
+ */ |
|
+ json_object_object_get_ex(hdr_jobj, "segments", &jobj); |
|
+ segment_offset = get_first_data_offset(jobj, "crypt"); |
|
+ if (segment_offset && |
|
+ (segment_offset < keyslots_size || |
|
+ (segment_offset - keyslots_size) < (2 * metadata_size))) { |
|
+ log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64 |
|
+ ", keyslots offset: %" PRIu64, keyslots_size, segment_offset, 2 * metadata_size); |
|
+ return 1; |
|
+ } |
|
|
|
/* Flags array is optional */ |
|
if (json_object_object_get_ex(jobj_config, "flags", &jobj)) { |
|
@@ -845,8 +838,8 @@ int LUKS2_hdr_validate(json_object *hdr_ |
|
{ hdr_validate_digests }, |
|
{ hdr_validate_segments }, |
|
{ hdr_validate_keyslots }, |
|
- { hdr_validate_areas }, |
|
{ hdr_validate_config }, |
|
+ { hdr_validate_areas }, |
|
{ NULL } |
|
}; |
|
int i;
|
|
|