From 9a96e260aa9c5ff4908431ae757781cdcfdedfa2 Mon Sep 17 00:00:00 2001 From: Ondrej Kozina Date: Mon, 23 Jan 2023 15:04:24 +0100 Subject: [PATCH] Fix unlikely occurences of json_object leaks on error path. In most cases it relates to error path triggering on general OOM. --- lib/luks2/luks2_json_format.c | 5 ++++- lib/luks2/luks2_keyslot.c | 10 ++++++++-- lib/luks2/luks2_keyslot_luks2.c | 6 +++++- lib/luks2/luks2_keyslot_reenc.c | 7 ++++++- lib/luks2/luks2_luks1_convert.c | 14 ++++++++++++-- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lib/luks2/luks2_json_format.c b/lib/luks2/luks2_json_format.c index 1aca50c0..532b5d0d 100644 --- a/lib/luks2/luks2_json_format.c +++ b/lib/luks2/luks2_json_format.c @@ -358,7 +358,10 @@ int LUKS2_generate_hdr( json_object_object_add(jobj_segment, "integrity", jobj_integrity); } - json_object_object_add_by_uint(jobj_segments, 0, jobj_segment); + if (json_object_object_add_by_uint(jobj_segments, 0, jobj_segment)) { + json_object_put(jobj_segment); + goto err; + } json_object_object_add(jobj_config, "json_size", crypt_jobj_new_uint64(metadata_size - LUKS2_HDR_BIN_LEN)); json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size)); diff --git a/lib/luks2/luks2_keyslot.c b/lib/luks2/luks2_keyslot.c index 8e6d99a4..98f0f55a 100644 --- a/lib/luks2/luks2_keyslot.c +++ b/lib/luks2/luks2_keyslot.c @@ -825,7 +825,10 @@ int placeholder_keyslot_alloc(struct crypt_device *cd, json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length)); json_object_object_add(jobj_keyslot, "area", jobj_area); - json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot); + if (json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot)) { + json_object_put(jobj_keyslot); + return -EINVAL; + } return 0; } @@ -972,14 +975,17 @@ int LUKS2_keyslot_swap(struct crypt_device *cd, struct luks2_hdr *hdr, json_object_object_del_by_uint(jobj_keyslots, keyslot); r = json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot2); if (r < 0) { + json_object_put(jobj_keyslot2); log_dbg(cd, "Failed to swap keyslot %d.", keyslot); return r; } json_object_object_del_by_uint(jobj_keyslots, keyslot2); r = json_object_object_add_by_uint(jobj_keyslots, keyslot2, jobj_keyslot); - if (r < 0) + if (r < 0) { + json_object_put(jobj_keyslot); log_dbg(cd, "Failed to swap keyslot2 %d.", keyslot2); + } return r; } diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c index 9c6986c7..31f49e9b 100644 --- a/lib/luks2/luks2_keyslot_luks2.c +++ b/lib/luks2/luks2_keyslot_luks2.c @@ -553,7 +553,11 @@ static int luks2_keyslot_alloc(struct crypt_device *cd, json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length)); json_object_object_add(jobj_keyslot, "area", jobj_area); - json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot); + r = json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot); + if (r) { + json_object_put(jobj_keyslot); + return r; + } r = luks2_keyslot_update_json(cd, jobj_keyslot, params); diff --git a/lib/luks2/luks2_keyslot_reenc.c b/lib/luks2/luks2_keyslot_reenc.c index 4291d0cb..2881cb5a 100644 --- a/lib/luks2/luks2_keyslot_reenc.c +++ b/lib/luks2/luks2_keyslot_reenc.c @@ -145,7 +145,12 @@ static int reenc_keyslot_alloc(struct crypt_device *cd, else json_object_object_add(jobj_keyslot, "direction", json_object_new_string("backward")); - json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot); + r = json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot); + if (r) { + json_object_put(jobj_keyslot); + return r; + } + if (LUKS2_check_json_size(cd, hdr)) { log_dbg(cd, "New keyslot too large to fit in free metadata space."); json_object_object_del_by_uint(jobj_keyslots, keyslot); diff --git a/lib/luks2/luks2_luks1_convert.c b/lib/luks2/luks2_luks1_convert.c index a51049c9..cd82202e 100644 --- a/lib/luks2/luks2_luks1_convert.c +++ b/lib/luks2/luks2_luks1_convert.c @@ -166,7 +166,12 @@ static int json_luks1_keyslots(const struct luks_phdr *hdr_v1, struct json_objec json_object_put(keyslot_obj); return r; } - json_object_object_add_by_uint(keyslot_obj, keyslot, field); + r = json_object_object_add_by_uint(keyslot_obj, keyslot, field); + if (r) { + json_object_put(field); + json_object_put(keyslot_obj); + return r; + } } *keyslots_object = keyslot_obj; @@ -261,7 +266,12 @@ static int json_luks1_segments(const struct luks_phdr *hdr_v1, struct json_objec json_object_put(segments_obj); return r; } - json_object_object_add_by_uint(segments_obj, 0, field); + r = json_object_object_add_by_uint(segments_obj, 0, field); + if (r) { + json_object_put(field); + json_object_put(segments_obj); + return r; + } *segments_object = segments_obj; return 0;