Commit 21e259d1 authored by Ondrej Kozina's avatar Ondrej Kozina Committed by Milan Broz

Check json size matches value from binary LUKS2 header.

We have max json area length parameter stored twice. In
LUKS2 binary header and in json metadata. Those two values
must match.
parent c3a54aa5
......@@ -478,7 +478,7 @@ static int validate_json_area(const char *json_area, uint64_t json_len, uint64_t
return 0;
}
static int validate_luks2_json_object(json_object *jobj_hdr)
static int validate_luks2_json_object(json_object *jobj_hdr, uint64_t length)
{
int r;
......@@ -489,14 +489,14 @@ static int validate_luks2_json_object(json_object *jobj_hdr)
return r;
}
r = LUKS2_hdr_validate(jobj_hdr);
r = LUKS2_hdr_validate(jobj_hdr, length);
if (r) {
log_dbg("Repairing JSON metadata.");
/* try to correct known glitches */
LUKS2_hdr_repair(jobj_hdr);
/* run validation again */
r = LUKS2_hdr_validate(jobj_hdr);
r = LUKS2_hdr_validate(jobj_hdr, length);
}
if (r)
......@@ -518,7 +518,7 @@ static json_object *parse_and_validate_json(const char *json_area, uint64_t max_
r = validate_json_area(json_area, json_len, max_length);
if (!r)
r = validate_luks2_json_object(jobj);
r = validate_luks2_json_object(jobj, max_length);
if (r) {
json_object_put(jobj);
......
......@@ -73,7 +73,7 @@ void JSON_DBG(json_object *jobj, const char *desc);
json_object *json_contains(json_object *jobj, const char *name, const char *section,
const char *key, json_type type);
int LUKS2_hdr_validate(json_object *hdr_jobj);
int LUKS2_hdr_validate(json_object *hdr_jobj, uint64_t length);
int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, const char *key);
int LUKS2_check_json_size(const struct luks2_hdr *hdr);
int LUKS2_token_validate(json_object *hdr_jobj, json_object *jobj_token, const char *key);
......
......@@ -258,7 +258,7 @@ int LUKS2_wipe_header_areas(struct crypt_device *cd,
length = LUKS2_get_data_offset(hdr) * SECTOR_SIZE;
wipe_block = 1024 * 1024;
if (LUKS2_hdr_validate(hdr->jobj))
if (LUKS2_hdr_validate(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
return -EINVAL;
/* On detached header wipe at least the first 4k */
......
......@@ -446,7 +446,7 @@ int LUKS2_token_validate(json_object *hdr_jobj, json_object *jobj_token, const c
return 0;
}
static int hdr_validate_json_size(json_object *hdr_jobj)
static int hdr_validate_json_size(json_object *hdr_jobj, uint64_t hdr_json_size)
{
json_object *jobj, *jobj1;
const char *json;
......@@ -460,12 +460,22 @@ static int hdr_validate_json_size(json_object *hdr_jobj)
json_area_size = json_object_get_uint64(jobj1);
json_size = (uint64_t)strlen(json);
return json_size > json_area_size ? 1 : 0;
if (hdr_json_size != json_area_size) {
log_dbg("JSON area size doesn't match value in binary header.");
return 1;
}
if (json_size > json_area_size) {
log_dbg("JSON doesn't fit in the designated area.");
return 1;
}
return 0;
}
int LUKS2_check_json_size(const struct luks2_hdr *hdr)
{
return hdr_validate_json_size(hdr->jobj);
return hdr_validate_json_size(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
}
static int hdr_validate_keyslots(json_object *hdr_jobj)
......@@ -822,7 +832,7 @@ static int hdr_validate_config(json_object *hdr_jobj)
return 0;
}
int LUKS2_hdr_validate(json_object *hdr_jobj)
int LUKS2_hdr_validate(json_object *hdr_jobj, uint64_t json_size)
{
struct {
int (*validate)(json_object *);
......@@ -844,10 +854,8 @@ int LUKS2_hdr_validate(json_object *hdr_jobj)
if (checks[i].validate && checks[i].validate(hdr_jobj))
return 1;
if (hdr_validate_json_size(hdr_jobj)) {
log_dbg("Json header is too large.");
if (hdr_validate_json_size(hdr_jobj, json_size))
return 1;
}
/* validate keyslot implementations */
if (LUKS2_keyslots_validate(hdr_jobj))
......@@ -895,7 +903,7 @@ int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
/* erase unused digests (no assigned keyslot or segment) */
LUKS2_digests_erase_unused(cd, hdr);
if (LUKS2_hdr_validate(hdr->jobj))
if (LUKS2_hdr_validate(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
return -EINVAL;
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment