From 90274a56b2505997cd1677f0bd6a8b89b21df163 Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Wed, 26 Apr 2023 15:00:07 +0800
Subject: [PATCH] Fix CVE-2023-29451

.......PS. [DEV-2450] fixed JSON validation not detecting invalid unicode characters and out of bounds access with JSONPath on invalid unicode character

Merge in ZBX/zabbix from feature/DEV-2450-6.0 to release/6.0

* commit '97efb4ed5069d4febe825671e2c3d106478d082d':
  .......PS. [DEV-2450] added mock test
  .......PS. [DEV-2450] fixed JSON validation not detecting invalid unicode characters and out of bounds access with JSONPath on invalid unicode character
  .......PS. [DEV-2450] fixed JSON validation not detecting invalid unicode characters and out of bounds access with JSONPath on invalid unicode character

Upstream-Status: Backport
[https://git.zabbix.com/projects/ZBX/repos/zabbix/commits/3b6a8c84612a67daaf89879226349420104bff24]
CVE: CVE-2023-29451

Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
 src/libs/zbxdiag/diag.c                      |  3 ++-
 src/libs/zbxjson/json.c                      |  2 +-
 src/libs/zbxjson/json.h                      |  1 +
 src/libs/zbxjson/json_parser.c               | 15 +++++----------
 src/zabbix_server/reporter/report_protocol.c |  3 ++-
 5 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/libs/zbxdiag/diag.c b/src/libs/zbxdiag/diag.c
index 6fc5509..dc47407 100644
--- a/src/libs/zbxdiag/diag.c
+++ b/src/libs/zbxdiag/diag.c
@@ -673,7 +673,8 @@ static void	diag_get_simple_values(const struct zbx_json_parse *jp, char **msg)
 	{
 		if (FAIL == zbx_json_brackets_open(pnext, &jp_value))
 		{
-			zbx_json_decodevalue_dyn(pnext, &value, &value_alloc, &type);
+			if (NULL == zbx_json_decodevalue_dyn(pnext, &value, &value_alloc, &type))
+				type = ZBX_JSON_TYPE_NULL;
 
 			if (0 != msg_offset)
 				zbx_chrcpy_alloc(msg, &msg_alloc, &msg_offset, ' ');
diff --git a/src/libs/zbxjson/json.c b/src/libs/zbxjson/json.c
index 4161ef0..c043d7e 100644
--- a/src/libs/zbxjson/json.c
+++ b/src/libs/zbxjson/json.c
@@ -764,7 +764,7 @@ static unsigned int	zbx_hex2num(char c)
  *               0 on error (invalid escape sequence)                         *
  *                                                                            *
  ******************************************************************************/
-static unsigned int	zbx_json_decode_character(const char **p, unsigned char *bytes)
+unsigned int	zbx_json_decode_character(const char **p, unsigned char *bytes)
 {
 	bytes[0] = '\0';
 
diff --git a/src/libs/zbxjson/json.h b/src/libs/zbxjson/json.h
index c59646a..4008411 100644
--- a/src/libs/zbxjson/json.h
+++ b/src/libs/zbxjson/json.h
@@ -29,5 +29,6 @@
 	SKIP_WHITESPACE(src)
 
 void	zbx_set_json_strerror(const char *fmt, ...) __zbx_attr_format_printf(1, 2);
+unsigned int	zbx_json_decode_character(const char **p, unsigned char *bytes);
 
 #endif
diff --git a/src/libs/zbxjson/json_parser.c b/src/libs/zbxjson/json_parser.c
index c8dcee4..64d24cf 100644
--- a/src/libs/zbxjson/json_parser.c
+++ b/src/libs/zbxjson/json_parser.c
@@ -88,7 +88,7 @@ static zbx_int64_t	json_parse_string(const char *start, char **error)
 		if ('\\' == *ptr)
 		{
 			const char	*escape_start = ptr;
-			int		i;
+			unsigned char	uc[4];	/* decoded Unicode character takes 1-4 bytes in UTF-8 */
 
 			/* unexpected end of string data, failing */
 			if ('\0' == *(++ptr))
@@ -107,16 +107,11 @@ static zbx_int64_t	json_parse_string(const char *start, char **error)
 					break;
 				case 'u':
 					/* check if the \u is followed with 4 hex digits */
-					for (i = 0; i < 4; i++)
-					{
-						if (0 == isxdigit((unsigned char)*(++ptr)))
-						{
-							return json_error("invalid escape sequence in string",
-									escape_start, error);
-						}
+					if (0 == zbx_json_decode_character(&ptr, uc)) {
+						return json_error("invalid escape sequence in string",
+							escape_start, error);
 					}
-
-					break;
+					continue;
 				default:
 					return json_error("invalid escape sequence in string data",
 							escape_start, error);
diff --git a/src/zabbix_server/reporter/report_protocol.c b/src/zabbix_server/reporter/report_protocol.c
index 5f55f51..ee0e02e 100644
--- a/src/zabbix_server/reporter/report_protocol.c
+++ b/src/zabbix_server/reporter/report_protocol.c
@@ -421,7 +421,8 @@ void	zbx_report_test(const struct zbx_json_parse *jp, zbx_uint64_t userid, struc
 			size_t		value_alloc = 0;
 			zbx_ptr_pair_t	pair;
 
-			zbx_json_decodevalue_dyn(pnext, &value, &value_alloc, NULL);
+			if (NULL == zbx_json_decodevalue_dyn(pnext, &value, &value_alloc, NULL))
+				continue;
 			pair.first = zbx_strdup(NULL, key);
 			pair.second = value;
 			zbx_vector_ptr_pair_append(&params, pair);
-- 
2.25.1

