From 0ca6b8ebbb28a28c212ac0a72ae11d4d2ddc3594 Mon Sep 17 00:00:00 2001
From: wangzhiqiang <wangzhiqiang95@huawei.com>
Date: Wed, 22 Mar 2023 10:56:20 +0800
Subject: [PATCH] fix potential null pointer dereference.

Signed-off-by: wangzhiqiang <wangzhiqiang95@huawei.com>
(cherry picked from commit 128a1b9499f62969a190e5d0dc4a13915dff131a)
---
 ...x-potential-null-pointer-dereference.patch | 348 ++++++++++++++++++
 0007-Update-file-cryptsetup-ssh.c.patch       |  24 ++
 cryptsetup.spec                               |   7 +-
 3 files changed, 378 insertions(+), 1 deletion(-)
 create mode 100644 0006-fix-potential-null-pointer-dereference.patch
 create mode 100644 0007-Update-file-cryptsetup-ssh.c.patch

diff --git a/0006-fix-potential-null-pointer-dereference.patch b/0006-fix-potential-null-pointer-dereference.patch
new file mode 100644
index 0000000..fea8385
--- /dev/null
+++ b/0006-fix-potential-null-pointer-dereference.patch
@@ -0,0 +1,348 @@
+From 5dd515878f23610e541ab761f9c45c6dab1c9700 Mon Sep 17 00:00:00 2001
+From: wangzhiqiang <wangzhiqiang95@huawei.com>
+Date: Fri, 10 Feb 2023 15:02:23 +0800
+Subject: [PATCH 1/2] fix potential null pointer dereference.
+
+Signed-off-by: wangzhiqiang <wangzhiqiang95@huawei.com>
+---
+ lib/luks2/luks2_digest_pbkdf2.c |  3 +++
+ lib/luks2/luks2_json_format.c   | 38 +++++++++++++++++++++++++++++----
+ lib/luks2/luks2_json_metadata.c |  8 +++++++
+ lib/luks2/luks2_keyslot.c       |  8 +++++++
+ lib/luks2/luks2_keyslot_luks2.c | 18 ++++++++++++++++
+ lib/luks2/luks2_luks1_convert.c | 24 +++++++++++++++++++++
+ src/cryptsetup.c                |  3 +++
+ src/integritysetup.c            |  3 +++
+ src/veritysetup.c               |  3 +++
+ tokens/ssh/cryptsetup-ssh.c     |  8 ++++++-
+ 10 files changed, 111 insertions(+), 5 deletions(-)
+
+diff --git a/lib/luks2/luks2_digest_pbkdf2.c b/lib/luks2/luks2_digest_pbkdf2.c
+index 03c6f49..003d86d 100644
+--- a/lib/luks2/luks2_digest_pbkdf2.c
++++ b/lib/luks2/luks2_digest_pbkdf2.c
+@@ -148,6 +148,9 @@ static int PBKDF2_digest_store(struct crypt_device *cd,
+ 		json_object_object_get_ex(hdr->jobj, "digests", &jobj_digests);
+ 	}
+ 
++	if (!jobj_digest)
++		return -ENOMEM;
++
+ 	json_object_object_add(jobj_digest, "type", json_object_new_string("pbkdf2"));
+ 	json_object_object_add(jobj_digest, "keyslots", json_object_new_array());
+ 	json_object_object_add(jobj_digest, "segments", json_object_new_array());
+diff --git a/lib/luks2/luks2_json_format.c b/lib/luks2/luks2_json_format.c
+index 350ebf4..45541c3 100644
+--- a/lib/luks2/luks2_json_format.c
++++ b/lib/luks2/luks2_json_format.c
+@@ -300,29 +300,59 @@ int LUKS2_generate_hdr(
+ 		return -EINVAL;
+ 
+ 	hdr->jobj = json_object_new_object();
++	if (!hdr->jobj) {
++		r = -ENOMEM;
++		goto err;
++	}
+ 
+ 	jobj_keyslots = json_object_new_object();
++	if (!jobj_keyslots) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(hdr->jobj, "keyslots", jobj_keyslots);
+ 	json_object_object_add(hdr->jobj, "tokens", json_object_new_object());
+ 	jobj_segments = json_object_new_object();
++	if (!jobj_segments) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(hdr->jobj, "segments", jobj_segments);
+ 	json_object_object_add(hdr->jobj, "digests", json_object_new_object());
+ 	jobj_config = json_object_new_object();
++	if (!jobj_config) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(hdr->jobj, "config", jobj_config);
+ 
+ 	digest = LUKS2_digest_create(cd, "pbkdf2", hdr, vk);
+-	if (digest < 0)
++	if (digest < 0) {
++		r = -EINVAL;
+ 		goto err;
++	}
+ 
+-	if (LUKS2_digest_segment_assign(cd, hdr, 0, digest, 1, 0) < 0)
++	if (LUKS2_digest_segment_assign(cd, hdr, 0, digest, 1, 0) < 0) {
++		r = -EINVAL;
+ 		goto err;
++	}
+ 
+ 	jobj_segment = json_segment_create_crypt(data_offset, 0, NULL, cipher, sector_size, 0);
+-	if (!jobj_segment)
++	if (!jobj_segment) {
++		r = -EINVAL;
+ 		goto err;
++	}
+ 
+ 	if (integrity) {
+ 		jobj_integrity = json_object_new_object();
++		if (!jobj_integrity) {
++			r = -ENOMEM;
++			goto err;
++		}
++
+ 		json_object_object_add(jobj_integrity, "type", json_object_new_string(integrity));
+ 		json_object_object_add(jobj_integrity, "journal_encryption", json_object_new_string("none"));
+ 		json_object_object_add(jobj_integrity, "journal_integrity", json_object_new_string("none"));
+@@ -339,7 +369,7 @@ int LUKS2_generate_hdr(
+ err:
+ 	json_object_put(hdr->jobj);
+ 	hdr->jobj = NULL;
+-	return -EINVAL;
++	return r;
+ }
+ 
+ int LUKS2_wipe_header_areas(struct crypt_device *cd,
+diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c
+index 0c449ee..e12b3c7 100644
+--- a/lib/luks2/luks2_json_metadata.c
++++ b/lib/luks2/luks2_json_metadata.c
+@@ -90,6 +90,9 @@ struct json_object *LUKS2_array_remove(struct json_object *array, const char *nu
+ 
+ 	/* Create new array without jobj_removing. */
+ 	array_new = json_object_new_array();
++	if (!array_new)
++		return NULL;
++
+ 	for (i = 0; i < (int) json_object_array_length(array); i++) {
+ 		jobj1 = json_object_array_get_idx(array, i);
+ 		if (jobj1 != jobj_removing)
+@@ -456,6 +459,9 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj
+ 
+ 	json = json_object_to_json_string_ext(hdr_jobj,
+ 		JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
++	if (!json)
++		return 1;
++
+ 	json_area_size = crypt_jobj_get_uint64(jobj1);
+ 	json_size = (uint64_t)strlen(json);
+ 
+@@ -1362,6 +1368,8 @@ int LUKS2_config_set_flags(struct crypt_device *cd, struct luks2_hdr *hdr, uint3
+ 		return 0;
+ 
+ 	jobj_flags = json_object_new_array();
++	if (!jobj_flags)
++		return -ENOMEM;
+ 
+ 	for (i = 0; persistent_flags[i].description; i++) {
+ 		if (flags & persistent_flags[i].flag) {
+diff --git a/lib/luks2/luks2_keyslot.c b/lib/luks2/luks2_keyslot.c
+index 3d70186..c2a4088 100644
+--- a/lib/luks2/luks2_keyslot.c
++++ b/lib/luks2/luks2_keyslot.c
+@@ -838,6 +838,9 @@ int placeholder_keyslot_alloc(struct crypt_device *cd,
+ 		return -EINVAL;
+ 
+ 	jobj_keyslot = json_object_new_object();
++	if (!jobj_keyslot)
++		return -ENOMEM;
++
+ 	json_object_object_add(jobj_keyslot, "type", json_object_new_string("placeholder"));
+ 	/*
+ 	 * key_size = -1 makes placeholder keyslot impossible to pass validation.
+@@ -848,6 +851,11 @@ int placeholder_keyslot_alloc(struct crypt_device *cd,
+ 
+ 	/* Area object */
+ 	jobj_area = json_object_new_object();
++	if (!jobj_area) {
++		json_object_put(jobj_keyslot);
++		return -ENOMEM;
++	}
++
+ 	json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
+ 	json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
+ 	json_object_object_add(jobj_keyslot, "area", jobj_area);
+diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c
+index 49b3a75..1513d25 100644
+--- a/lib/luks2/luks2_keyslot_luks2.c
++++ b/lib/luks2/luks2_keyslot_luks2.c
+@@ -489,17 +489,32 @@ static int luks2_keyslot_alloc(struct crypt_device *cd,
+ 	}
+ 
+ 	jobj_keyslot = json_object_new_object();
++	if (!jobj_keyslot) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(jobj_keyslot, "type", json_object_new_string("luks2"));
+ 	json_object_object_add(jobj_keyslot, "key_size", json_object_new_int(volume_key_len));
+ 
+ 	/* AF object */
+ 	jobj_af = json_object_new_object();
++	if (!jobj_af) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(jobj_af, "type", json_object_new_string("luks1"));
+ 	json_object_object_add(jobj_af, "stripes", json_object_new_int(params->af.luks1.stripes));
+ 	json_object_object_add(jobj_keyslot, "af", jobj_af);
+ 
+ 	/* Area object */
+ 	jobj_area = json_object_new_object();
++	if (!jobj_area) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
+ 	json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
+ 	json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
+@@ -518,6 +533,9 @@ static int luks2_keyslot_alloc(struct crypt_device *cd,
+ 		json_object_object_del_by_uint(jobj_keyslots, keyslot);
+ 
+ 	return r;
++err:
++	json_object_put(jobj_keyslot);
++	return r;
+ }
+ 
+ static int luks2_keyslot_open(struct crypt_device *cd,
+diff --git a/lib/luks2/luks2_luks1_convert.c b/lib/luks2/luks2_luks1_convert.c
+index 84fd44f..8350dba 100644
+--- a/lib/luks2/luks2_luks1_convert.c
++++ b/lib/luks2/luks2_luks1_convert.c
+@@ -38,13 +38,24 @@ static int json_luks1_keyslot(const struct luks_phdr *hdr_v1, int keyslot, struc
+ 	size_t base64_len;
+ 	struct json_object *keyslot_obj, *field, *jobj_kdf, *jobj_af, *jobj_area;
+ 	uint64_t offset, area_size, offs_a, offs_b, length;
++	int r;
+ 
+ 	keyslot_obj = json_object_new_object();
++	if (!keyslot_obj) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(keyslot_obj, "type", json_object_new_string("luks2"));
+ 	json_object_object_add(keyslot_obj, "key_size", json_object_new_int64(hdr_v1->keyBytes));
+ 
+ 	/* KDF */
+ 	jobj_kdf = json_object_new_object();
++	if (!jobj_kdf) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(jobj_kdf, "type", json_object_new_string(CRYPT_KDF_PBKDF2));
+ 	json_object_object_add(jobj_kdf, "hash", json_object_new_string(hdr_v1->hashSpec));
+ 	json_object_object_add(jobj_kdf, "iterations", json_object_new_int64(hdr_v1->keyblock[keyslot].passwordIterations));
+@@ -64,6 +75,11 @@ static int json_luks1_keyslot(const struct luks_phdr *hdr_v1, int keyslot, struc
+ 
+ 	/* AF */
+ 	jobj_af = json_object_new_object();
++	if (!jobj_af) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(jobj_af, "type", json_object_new_string("luks1"));
+ 	json_object_object_add(jobj_af, "hash", json_object_new_string(hdr_v1->hashSpec));
+ 	/* stripes field ignored, fixed to LUKS_STRIPES (4000) */
+@@ -72,6 +88,11 @@ static int json_luks1_keyslot(const struct luks_phdr *hdr_v1, int keyslot, struc
+ 
+ 	/* Area */
+ 	jobj_area = json_object_new_object();
++	if (!jobj_area) {
++		r = -ENOMEM;
++		goto err;
++	}
++
+ 	json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
+ 
+ 	/* encryption algorithm field */
+@@ -97,6 +118,9 @@ static int json_luks1_keyslot(const struct luks_phdr *hdr_v1, int keyslot, struc
+ 
+ 	*keyslot_object = keyslot_obj;
+ 	return 0;
++err:
++	json_object_put(keyslot_obj);
++	return r;
+ }
+ 
+ static int json_luks1_keyslots(const struct luks_phdr *hdr_v1, struct json_object **keyslots_object)
+diff --git a/src/cryptsetup.c b/src/cryptsetup.c
+index e785dc3..78421a6 100644
+--- a/src/cryptsetup.c
++++ b/src/cryptsetup.c
+@@ -3767,6 +3767,9 @@ int main(int argc, const char **argv)
+ 	textdomain(PACKAGE);
+ 
+ 	popt_context = poptGetContext(PACKAGE, argc, argv, popt_options, 0);
++	if (!popt_context)
++		exit(EXIT_FAILURE);
++
+ 	poptSetOtherOptionHelp(popt_context,
+ 	                       _("[OPTION...] <action> <action-specific>"));
+ 
+diff --git a/src/integritysetup.c b/src/integritysetup.c
+index 4604302..468a8cf 100644
+--- a/src/integritysetup.c
++++ b/src/integritysetup.c
+@@ -569,6 +569,9 @@ int main(int argc, const char **argv)
+ 	textdomain(PACKAGE);
+ 
+ 	popt_context = poptGetContext("integrity", argc, argv, popt_options, 0);
++	if (!popt_context)
++		exit(EXIT_FAILURE);
++
+ 	poptSetOtherOptionHelp(popt_context,
+ 	                       _("[OPTION...] <action> <action-specific>"));
+ 
+diff --git a/src/veritysetup.c b/src/veritysetup.c
+index 04fd996..2a701af 100644
+--- a/src/veritysetup.c
++++ b/src/veritysetup.c
+@@ -588,6 +588,9 @@ int main(int argc, const char **argv)
+ 	textdomain(PACKAGE);
+ 
+ 	popt_context = poptGetContext("verity", argc, argv, popt_options, 0);
++	if (!popt_context)
++		exit(EXIT_FAILURE);
++
+ 	poptSetOtherOptionHelp(popt_context,
+ 	                       _("[OPTION...] <action> <action-specific>"));
+ 
+diff --git a/tokens/ssh/cryptsetup-ssh.c b/tokens/ssh/cryptsetup-ssh.c
+index c1d0a60..87c55d5 100644
+--- a/tokens/ssh/cryptsetup-ssh.c
++++ b/tokens/ssh/cryptsetup-ssh.c
+@@ -78,13 +78,19 @@ static int token_add(
+ 
+ 	r = -EINVAL;
+ 	jobj = json_object_new_object();
+-	if (!jobj)
++	if (!jobj) {
++		r = -ENOMEM;
+ 		goto out;
++	}
+ 
+ 	/* type is mandatory field in all tokens and must match handler name member */
+ 	json_object_object_add(jobj, "type", json_object_new_string(TOKEN_NAME));
+ 
+ 	jobj_keyslots = json_object_new_array();
++	if (!jobj_keyslots) {
++		r = -ENOMEM;
++		goto out;
++	}
+ 
+ 	/* mandatory array field (may be empty and assigned later */
+ 	json_object_object_add(jobj, "keyslots", jobj_keyslots);
+-- 
+2.33.0
+
diff --git a/0007-Update-file-cryptsetup-ssh.c.patch b/0007-Update-file-cryptsetup-ssh.c.patch
new file mode 100644
index 0000000..52bc974
--- /dev/null
+++ b/0007-Update-file-cryptsetup-ssh.c.patch
@@ -0,0 +1,24 @@
+From 7883cf7f2b8f2a37aea78aced53b7a445ec72c3b Mon Sep 17 00:00:00 2001
+From: wangzhiqiang <zhiqiangwang12_4@163.com>
+Date: Fri, 10 Feb 2023 16:48:19 +0000
+Subject: [PATCH 2/2] Update file cryptsetup-ssh.c
+
+---
+ tokens/ssh/cryptsetup-ssh.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tokens/ssh/cryptsetup-ssh.c b/tokens/ssh/cryptsetup-ssh.c
+index 87c55d5..0d06000 100644
+--- a/tokens/ssh/cryptsetup-ssh.c
++++ b/tokens/ssh/cryptsetup-ssh.c
+@@ -76,7 +76,6 @@ static int token_add(
+ 	if (r)
+ 		goto out;
+ 
+-	r = -EINVAL;
+ 	jobj = json_object_new_object();
+ 	if (!jobj) {
+ 		r = -ENOMEM;
+-- 
+2.33.0
+
diff --git a/cryptsetup.spec b/cryptsetup.spec
index 0df419b..06f5ec4 100644
--- a/cryptsetup.spec
+++ b/cryptsetup.spec
@@ -1,6 +1,6 @@
 Name:     cryptsetup
 Version:  2.4.1
-Release:  4
+Release:  5
 Summary:  Utility used to conveniently set up disk encryption
 License:  GPLv2+ and CC0-1.0 and LGPLv2+
 URL:      https://gitlab.com/cryptsetup/cryptsetup
@@ -11,6 +11,8 @@ Patch2:  0002-fix-compat-test.patch
 Patch3:  0003-add-test-case-for-sm4.patch
 Patch4:  0004-Fix-CVE-2021-4122-LUKS2-reencryption-crash-recovery-.patch
 Patch5:  0005-Fix-OpenSSL-2-crypto-backend-PBKDF2-possible-iterati.patch
+Patch6:  0006-fix-potential-null-pointer-dereference.patch
+Patch7:  0007-Update-file-cryptsetup-ssh.c.patch
 
 BuildRequires: openssl-devel, popt-devel, device-mapper-devel,  gcc, libssh-devel, gettext-devel libtool
 BuildRequires: libuuid-devel, json-c-devel, libargon2-devel, libpwquality-devel, libblkid-devel
@@ -117,6 +119,9 @@ make check
 %{_mandir}/man8/*
 
 %changelog
+* Wed Mar 22 2023 wangzhiqiang <wangzhiqiang95@huawei.com> - 2.4.1-5
+- fix potential null pointer dereference
+ 
 * Sat Feb 25 2023 volcanodragon <linfeilong@huawei.com> - 2.4.1-4
 - fix pbkdf-force-iterations in openssl
 
-- 
Gitee