diff options
author | Andris Zeila <andris.zeila@zabbix.com> | 2021-03-19 21:30:02 +0300 |
---|---|---|
committer | Andris Zeila <andris.zeila@zabbix.com> | 2021-03-19 21:30:02 +0300 |
commit | e7b4bdd84db90fa898a3e19b1570d47d00f209a8 (patch) | |
tree | 0d57834beb62ff7a4f0742b8238f2caef08ca6e5 | |
parent | e5f5361fa79c20f4c31858a596b7ad1e04711674 (diff) |
........S. [ZBXNEXT-6457] improved detection of mistakingly quoted item queries in trigger functions
-rw-r--r-- | include/zbxserver.h | 1 | ||||
-rw-r--r-- | src/libs/zbxeval/query.c | 6 | ||||
-rw-r--r-- | src/libs/zbxserver/evalfunc2.c | 37 | ||||
-rw-r--r-- | src/zabbix_server/poller/checks_calculated.c | 78 |
4 files changed, 106 insertions, 16 deletions
diff --git a/include/zbxserver.h b/include/zbxserver.h index 4cd35535b11..4ae907cc14b 100644 --- a/include/zbxserver.h +++ b/include/zbxserver.h @@ -63,6 +63,7 @@ int evaluate_function(char **value, DC_ITEM *item, const char *function, const c int evaluate_function2(zbx_variant_t *value, DC_ITEM *item, const char *function, const char *parameter, const zbx_timespec_t *ts, char **error); +int zbx_is_trigger_function(const char *name, size_t len); int substitute_simple_macros(zbx_uint64_t *actionid, const DB_EVENT *event, const DB_EVENT *r_event, zbx_uint64_t *userid, const zbx_uint64_t *hostid, const DC_HOST *dc_host, const DC_ITEM *dc_item, diff --git a/src/libs/zbxeval/query.c b/src/libs/zbxeval/query.c index f222643f793..61b21be73c7 100644 --- a/src/libs/zbxeval/query.c +++ b/src/libs/zbxeval/query.c @@ -62,8 +62,8 @@ void zbx_eval_parse_query(const char *str, size_t len, zbx_item_query_t *query) * Purpose: frees resources allocated by item reference * * * ******************************************************************************/ -void zbx_eval_clear_query(zbx_item_query_t *ref) +void zbx_eval_clear_query(zbx_item_query_t *query) { - zbx_free(ref->host); - zbx_free(ref->key); + zbx_free(query->host); + zbx_free(query->key); } diff --git a/src/libs/zbxserver/evalfunc2.c b/src/libs/zbxserver/evalfunc2.c index 97e4fc8304a..0b3eac34c05 100644 --- a/src/libs/zbxserver/evalfunc2.c +++ b/src/libs/zbxserver/evalfunc2.c @@ -2203,10 +2203,6 @@ static int evaluate_TREND(zbx_variant_t *value, DC_ITEM *item, const char *func, { ret = zbx_trends_eval_count(table, item->itemid, start, end, &value_dbl, error); } - else if (0 == strcmp(func, "delta")) - { - ret = zbx_trends_eval_delta(table, item->itemid, start, end, &value_dbl, error); - } else if (0 == strcmp(func, "max")) { ret = zbx_trends_eval_max(table, item->itemid, start, end, &value_dbl, error); @@ -2340,3 +2336,36 @@ int evaluate_function2(zbx_variant_t *value, DC_ITEM *item, const char *function return ret; } + +/****************************************************************************** + * * + * Function: zbx_is_trigger_function * + * * + * Purpose: check if the specified function is a trigger function * + * * + * Parameters: name - [IN] the function name to check * + * len - [IN] the length of function name * + * * + * Return value: SUCCEED - the function is a trigger function * + * FAIL - otherwise * + * * + ******************************************************************************/ +int zbx_is_trigger_function(const char *name, size_t len) +{ + char *functions[] = {"last", "min", "max", "avg", "sum", "percentile", "count", "nodata", "change", "find", + "fuzzytime", "logeventid", "logseverity", "logsource", "band", "forecast", "timeleft", + "trendavg", "trendcount", "trendmax", "trendmin", "trendsum", + NULL}; + char **ptr; + + for (ptr = functions; NULL != *ptr; ptr++) + { + size_t compare_len; + + compare_len = strlen(*ptr); + if (compare_len == len && 0 == memcmp(*ptr, name, len)) + return SUCCEED; + } + + return FAIL; +} diff --git a/src/zabbix_server/poller/checks_calculated.c b/src/zabbix_server/poller/checks_calculated.c index d6bc8cefa1d..737859b9841 100644 --- a/src/zabbix_server/poller/checks_calculated.c +++ b/src/zabbix_server/poller/checks_calculated.c @@ -45,16 +45,16 @@ zbx_calc_eval_t; * Return value: The allocated item reference or NULL in the case of error. * * * ******************************************************************************/ -static zbx_item_query_t *calcitem_parse_item_query(const char *query) +static zbx_item_query_t *calcitem_parse_item_query(const char *filter) { - zbx_item_query_t *ref; + zbx_item_query_t *query; - ref = (zbx_item_query_t *)zbx_malloc(NULL, sizeof(zbx_item_query_t)); - memset(ref, 0, sizeof(zbx_item_query_t)); + query = (zbx_item_query_t *)zbx_malloc(NULL, sizeof(zbx_item_query_t)); + memset(query, 0, sizeof(zbx_item_query_t)); - zbx_eval_parse_query(query, strlen(query), ref); + zbx_eval_parse_query(filter, strlen(filter), query); - return ref; + return query; } /****************************************************************************** @@ -257,7 +257,7 @@ out: /****************************************************************************** * * - * Function: calcitem_eval * + * Function: calcitem_eval_history * * * * Purpose: evaluate historical function * * * @@ -274,7 +274,7 @@ out: * FAIL - otherwise * * * ******************************************************************************/ -static int calcitem_eval(const char *name, size_t len, int args_num, const zbx_variant_t *args, +static int calcitem_eval_history(const char *name, size_t len, int args_num, const zbx_variant_t *args, void *data, const zbx_timespec_t *ts, zbx_variant_t *value, char **error) { int ret = FAIL; @@ -314,6 +314,65 @@ out: return ret; } +/****************************************************************************** + * * + * Function: calcitem_eval_common * + * * + * Purpose: evaluate common function * + * * + * Parameters: name - [IN] the function name (not zero terminated) * + * len - [IN] the function name length * + * args_num - [IN] the number of function arguments * + * args - [IN] an array of the function arguments. * + * data - [IN] the caller data used for function evaluation * + * ts - [IN] the function execution time * + * value - [OUT] the function return value * + * error - [OUT] the error message if function failed * + * * + * Return value: SUCCEED - the function was executed successfully * + * FAIL - otherwise * + * * + * Comments: There are no custom common functions for calculated items, but * + * it's used to check for /host/key query quoting errors instead. * + * * + ******************************************************************************/ +static int calcitem_eval_common(const char *name, size_t len, int args_num, const zbx_variant_t *args, + void *data, const zbx_timespec_t *ts, zbx_variant_t *value, char **error) +{ + ZBX_UNUSED(data); + ZBX_UNUSED(ts); + ZBX_UNUSED(value); + + if (SUCCEED != zbx_is_trigger_function(name, len)) + { + *error = zbx_strdup(NULL, "Cannot evaluate formula: unsupported function"); + return FAIL; + } + + if (0 == args_num) + { + *error = zbx_strdup(NULL, "Cannot evaluate function: invalid number of arguments"); + return FAIL; + } + + if (ZBX_VARIANT_STR == args[0].type) + { + zbx_item_query_t query; + + zbx_eval_parse_query(args[0].data.str, strlen(args[0].data.str), &query); + + if (ZBX_ITEM_QUERY_UNKNOWN != query.type) + { + zbx_eval_clear_query(&query); + *error = zbx_strdup(NULL, "Cannot evaluate function: quoted item query argument"); + return FAIL; + } + } + + *error = zbx_strdup(NULL, "Cannot evaluate function: invalid first argument"); + return FAIL; +} + int get_value_calculated(DC_ITEM *dc_item, AGENT_RESULT *result) { int ret = NOTSUPPORTED; @@ -348,7 +407,8 @@ int get_value_calculated(DC_ITEM *dc_item, AGENT_RESULT *result) calc_eval_init(&eval, dc_item, &ctx); zbx_timespec(&ts); - if (SUCCEED != zbx_eval_execute_ext(&ctx, &ts, NULL, calcitem_eval, (void *)&eval, &value, &error)) + if (SUCCEED != zbx_eval_execute_ext(&ctx, &ts, calcitem_eval_common, calcitem_eval_history, (void *)&eval, + &value, &error)) { zabbix_log(LOG_LEVEL_DEBUG, "%s() error:%s", __func__, error); SET_MSG_RESULT(result, error); |