mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-13 03:40:05 +01:00
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.
This commit is contained in:
committed by
Milan Broz
parent
c3a54aa59a
commit
21e259d1a4
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user