Reshuffle config and keyslots areas validation code.

Swap config and keyslot areas validation code order.

Also split original keyslots_size validation code in
between config and keyslot areas routines for furhter
changes in the code later. This commit has no funtional
impact.
This commit is contained in:
Ondrej Kozina
2018-11-28 13:17:30 +01:00
committed by Milan Broz
parent d7bd3d2d69
commit 3c0aceb9f7

View File

@@ -638,7 +638,7 @@ static int hdr_validate_areas(struct crypt_device *cd, json_object *hdr_jobj)
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;
@@ -647,6 +647,9 @@ static int hdr_validate_areas(struct crypt_device *cd, json_object *hdr_jobj)
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 */
@@ -682,6 +685,8 @@ static int hdr_validate_areas(struct crypt_device *cd, json_object *hdr_jobj)
return 1;
}
keyslots_area_sum += intervals[i].length;
i++;
}
@@ -690,6 +695,12 @@ static int hdr_validate_areas(struct crypt_device *cd, json_object *hdr_jobj)
return 1;
}
if (keyslots_area_sum > keyslots_size) {
log_dbg(cd, "Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %"
PRIu64, keyslots_area_sum, keyslots_size);
return 1;
}
first_offset = get_first_data_offset(jobj_segments, NULL);
ret = validate_intervals(cd, length, intervals, &first_offset) ? 0 : 1;
@@ -734,13 +745,43 @@ static int hdr_validate_digests(struct crypt_device *cd, json_object *hdr_jobj)
return 0;
}
/* requires keyslots and segments sections being already validated */
static int validate_keyslots_size(struct crypt_device *cd, json_object *hdr_jobj,
uint64_t metadata_size, uint64_t keyslots_size)
static int hdr_validate_config(struct crypt_device *cd, json_object *hdr_jobj)
{
json_object *jobj_keyslots, *jobj, *jobj1;
uint64_t segment_offset, keyslots_area_sum = 0;
json_object *jobj_config, *jobj, *jobj1;
int i;
uint64_t keyslots_size, metadata_size, segment_offset;
if (!json_object_object_get_ex(hdr_jobj, "config", &jobj_config)) {
log_dbg(cd, "Missing config section.");
return 1;
}
if (!(jobj = json_contains(cd, jobj_config, "section", "Config", "json_size", json_type_string)) ||
!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(cd, jobj_config, "section", "Config", "keyslots_size", json_type_string)) ||
!json_str_to_uint64(jobj, &keyslots_size))
return 1;
if (LUKS2_check_metadata_area_size(metadata_size)) {
log_dbg(cd, "Unsupported LUKS2 header size (%" PRIu64 ").", metadata_size);
return 1;
}
if (LUKS2_check_keyslots_area_size(keyslots_size)) {
log_dbg(cd, "Unsupported LUKS2 keyslots size (%" PRIu64 ").", 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 &&
@@ -751,56 +792,6 @@ static int validate_keyslots_size(struct crypt_device *cd, json_object *hdr_jobj
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(cd, "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(struct crypt_device *cd, json_object *hdr_jobj)
{
json_object *jobj_config, *jobj, *jobj1;
int i;
uint64_t json_size, keyslots_size;
if (!json_object_object_get_ex(hdr_jobj, "config", &jobj_config)) {
log_dbg(cd, "Missing config section.");
return 1;
}
if (!(jobj = json_contains(cd, jobj_config, "section", "Config", "json_size", json_type_string)) ||
!json_str_to_uint64(jobj, &json_size))
return 1;
if (!(jobj = json_contains(cd, 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(cd, "Unsupported LUKS2 header size (%" PRIu64 ").", json_size + LUKS2_HDR_BIN_LEN);
return 1;
}
if (LUKS2_check_keyslots_area_size(keyslots_size)) {
log_dbg(cd, "Unsupported LUKS2 keyslots size (%" PRIu64 ").", keyslots_size);
return 1;
}
if (validate_keyslots_size(cd, hdr_jobj, json_size + LUKS2_HDR_BIN_LEN, keyslots_size))
return 1;
/* Flags array is optional */
if (json_object_object_get_ex(jobj_config, "flags", &jobj)) {
if (!json_contains(cd, jobj_config, "section", "Config", "flags", json_type_array))
@@ -841,8 +832,8 @@ int LUKS2_hdr_validate(struct crypt_device *cd, json_object *hdr_jobj, uint64_t
{ hdr_validate_digests },
{ hdr_validate_segments },
{ hdr_validate_keyslots },
{ hdr_validate_areas },
{ hdr_validate_config },
{ hdr_validate_areas },
{ NULL }
};
int i;