From 240754ccee1b6b35ac47862be56dacec11e65b32 Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Thu, 27 Jul 2023 11:23:54 +0000 Subject: [PATCH] .......PS. [DEV-2387] added new limits for JS objects Merge in ZBX/zabbix from feature/DEV-2387-6.0 to release/6.0 * commit '16e5f15a70cfbf00c646cb92d1fcb8a362900285': .......PS. [DEV-2387] removed logsize check based on json buffer .......PS. [DEV-2387] removed logsize check based on json buffer .......PS. [DEV-2387] fixed pr comments .......PS. [DEV-2387] removed useless include .......PS. [DEV-2387] added limits for logging and adding httprequest headers .......PS. [DEV-2387] limited initialization of new HttpRequest objects CVE: CVE-2023-29449 Upstream-Status: Backport [https://git.zabbix.com/projects/ZBX/repos/zabbix/commits/240754ccee1] Signed-off-by: Yogita Urade --- src/libs/zbxembed/console.c | 23 ++++++++++++----------- src/libs/zbxembed/embed.c | 1 + src/libs/zbxembed/embed.h | 3 +++ src/libs/zbxembed/httprequest.c | 28 ++++++++++++++++++++++++++++ src/libs/zbxembed/zabbix.c | 23 ++++++++++++----------- 5 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/libs/zbxembed/console.c b/src/libs/zbxembed/console.c index c733487..60c48fc 100644 --- a/src/libs/zbxembed/console.c +++ b/src/libs/zbxembed/console.c @@ -90,27 +90,28 @@ static duk_ret_t es_log_message(duk_context *ctx, int level) else msg_output = zbx_strdup(msg_output, "undefined"); - zabbix_log(level, "%s", msg_output); - duk_get_memory_functions(ctx, &out_funcs); env = (zbx_es_env_t *)out_funcs.udata; - if (NULL == env->json) - goto out; - - if (ZBX_ES_LOG_MEMORY_LIMIT < env->json->buffer_size) /* approximate limit */ + if (ZBX_ES_LOG_MEMORY_LIMIT < env->log_size) { err_index = duk_push_error_object(ctx, DUK_RET_EVAL_ERROR, "log exceeds the maximum size of " ZBX_FS_UI64 " bytes.", ZBX_ES_LOG_MEMORY_LIMIT); goto out; } - zbx_json_addobject(env->json, NULL); - zbx_json_adduint64(env->json, "level", (zbx_uint64_t)level); - zbx_json_adduint64(env->json, "ms", zbx_get_duration_ms(&env->start_time)); - zbx_json_addstring(env->json, "message", msg_output, ZBX_JSON_TYPE_STRING); - zbx_json_close(env->json); + zabbix_log(level, "%s", msg_output); + + if (NULL != env->json) + { + zbx_json_addobject(env->json, NULL); + zbx_json_adduint64(env->json, "level", (zbx_uint64_t)level); + zbx_json_adduint64(env->json, "ms", zbx_get_duration_ms(&env->start_time)); + zbx_json_addstring(env->json, "message", msg_output, ZBX_JSON_TYPE_STRING); + zbx_json_close(env->json); + } out: + env->log_size += strlen(msg_output); zbx_free(msg_output); if (-1 != err_index) diff --git a/src/libs/zbxembed/embed.c b/src/libs/zbxembed/embed.c index 34d8d18..cc80925 100644 --- a/src/libs/zbxembed/embed.c +++ b/src/libs/zbxembed/embed.c @@ -444,6 +444,7 @@ int zbx_es_execute(zbx_es_t *es, const char *script, const char *code, int size, zabbix_log(LOG_LEVEL_DEBUG, "In %s() param:%s", __func__, param); zbx_timespec(&es->env->start_time); + es->env->http_req_objects = 0; if (NULL != es->env->json) { diff --git a/src/libs/zbxembed/embed.h b/src/libs/zbxembed/embed.h index a0a360c..2b954a8 100644 --- a/src/libs/zbxembed/embed.h +++ b/src/libs/zbxembed/embed.h @@ -48,6 +48,9 @@ struct zbx_es_env struct zbx_json *json; jmp_buf loc; + + int http_req_objects; + size_t log_size; }; zbx_es_env_t *zbx_es_get_env(duk_context *ctx); diff --git a/src/libs/zbxembed/httprequest.c b/src/libs/zbxembed/httprequest.c index 8c2839c..7f0eed9 100644 --- a/src/libs/zbxembed/httprequest.c +++ b/src/libs/zbxembed/httprequest.c @@ -52,6 +52,7 @@ typedef struct size_t headers_in_alloc; size_t headers_in_offset; unsigned char custom_header; + size_t headers_sz; } zbx_es_httprequest_t; @@ -145,13 +146,21 @@ static duk_ret_t es_httprequest_dtor(duk_context *ctx) ******************************************************************************/ static duk_ret_t es_httprequest_ctor(duk_context *ctx) { +#define MAX_HTTPREQUEST_OBJECT_COUNT 10 zbx_es_httprequest_t *request; CURLcode err; + zbx_es_env_t *env; int err_index = -1; if (!duk_is_constructor_call(ctx)) return DUK_RET_TYPE_ERROR; + if (NULL == (env = zbx_es_get_env(ctx))) + return duk_error(ctx, DUK_RET_TYPE_ERROR, "cannot access internal environment"); + + if (MAX_HTTPREQUEST_OBJECT_COUNT == env->http_req_objects) + return duk_error(ctx, DUK_RET_EVAL_ERROR, "maximum count of HttpRequest objects was reached"); + duk_push_this(ctx); request = (zbx_es_httprequest_t *)zbx_malloc(NULL, sizeof(zbx_es_httprequest_t)); @@ -189,7 +198,10 @@ out: return duk_throw(ctx); } + env->http_req_objects++; + return 0; +#undef MAX_HTTPREQUEST_OBJECT_COUNT } /****************************************************************************** @@ -201,10 +213,12 @@ out: ******************************************************************************/ static duk_ret_t es_httprequest_add_header(duk_context *ctx) { +#define ZBX_ES_MAX_HEADERS_SIZE ZBX_KIBIBYTE * 128 zbx_es_httprequest_t *request; CURLcode err; char *utf8 = NULL; int err_index = -1; + size_t header_sz; if (NULL == (request = es_httprequest(ctx))) return duk_error(ctx, DUK_RET_EVAL_ERROR, "internal scripting error: null object"); @@ -215,9 +229,20 @@ static duk_ret_t es_httprequest_add_header(duk_context *ctx) goto out; } + header_sz = strlen(utf8); + + if (ZBX_ES_MAX_HEADERS_SIZE < request->headers_sz + header_sz) + { + err_index = duk_push_error_object(ctx, DUK_RET_TYPE_ERROR, "headers exceeded maximum size of " + ZBX_FS_UI64 " bytes.", ZBX_ES_MAX_HEADERS_SIZE); + + goto out; + } + request->headers = curl_slist_append(request->headers, utf8); ZBX_CURL_SETOPT(ctx, request->handle, CURLOPT_HTTPHEADER, request->headers, err); request->custom_header = 1; + request->headers_sz += header_sz + 1; out: zbx_free(utf8); @@ -225,6 +250,7 @@ out: return duk_throw(ctx); return 0; +#undef ZBX_ES_MAX_HEADERS_SIZE } /****************************************************************************** @@ -244,6 +270,7 @@ static duk_ret_t es_httprequest_clear_header(duk_context *ctx) curl_slist_free_all(request->headers); request->headers = NULL; request->custom_header = 0; + request->headers_sz = 0; return 0; } @@ -311,6 +338,7 @@ static duk_ret_t es_httprequest_query(duk_context *ctx, const char *http_request { curl_slist_free_all(request->headers); request->headers = NULL; + request->headers_sz = 0; } if (NULL != contents) diff --git a/src/libs/zbxembed/zabbix.c b/src/libs/zbxembed/zabbix.c index 820768f..0ecde86 100644 --- a/src/libs/zbxembed/zabbix.c +++ b/src/libs/zbxembed/zabbix.c @@ -81,27 +81,28 @@ static duk_ret_t es_zabbix_log(duk_context *ctx) zbx_replace_invalid_utf8(message); } - zabbix_log(level, "%s", message); - duk_get_memory_functions(ctx, &out_funcs); env = (zbx_es_env_t *)out_funcs.udata; - if (NULL == env->json) - goto out; - - if (ZBX_ES_LOG_MEMORY_LIMIT < env->json->buffer_size) /* approximate limit */ + if (ZBX_ES_LOG_MEMORY_LIMIT < env->log_size) { err_index = duk_push_error_object(ctx, DUK_RET_EVAL_ERROR, "log exceeds the maximum size of " ZBX_FS_UI64 " bytes.", ZBX_ES_LOG_MEMORY_LIMIT); goto out; } - zbx_json_addobject(env->json, NULL); - zbx_json_adduint64(env->json, "level", (zbx_uint64_t)level); - zbx_json_adduint64(env->json, "ms", zbx_get_duration_ms(&env->start_time)); - zbx_json_addstring(env->json, "message", message, ZBX_JSON_TYPE_STRING); - zbx_json_close(env->json); + zabbix_log(level, "%s", message); + + if (NULL != env->json) + { + zbx_json_addobject(env->json, NULL); + zbx_json_adduint64(env->json, "level", (zbx_uint64_t)level); + zbx_json_adduint64(env->json, "ms", zbx_get_duration_ms(&env->start_time)); + zbx_json_addstring(env->json, "message", message, ZBX_JSON_TYPE_STRING); + zbx_json_close(env->json); + } out: + env->log_size += strlen(message); zbx_free(message); if (-1 != err_index) -- 2.35.5