diff options
| author | fumingwei <[email protected]> | 2023-08-29 16:27:13 +0800 |
|---|---|---|
| committer | fumingwei <[email protected]> | 2023-08-29 16:27:13 +0800 |
| commit | 7c96bc412f9ebb3b48bd96d75598cd0d20ab60b3 (patch) | |
| tree | f33b279c6011b31d5b57bc719c44f86d9bdc4517 /src | |
| parent | 061640cee505dd2b5fd29926a4f0ef13e206ec5d (diff) | |
bugfix:修复构建uthash metric key过程中存在的内存越界问题v3.0.12
Diffstat (limited to 'src')
| -rw-r--r-- | src/fieldstat_dynamic.cpp | 54 | ||||
| -rw-r--r-- | src/fieldstat_internal.h | 4 |
2 files changed, 55 insertions, 3 deletions
diff --git a/src/fieldstat_dynamic.cpp b/src/fieldstat_dynamic.cpp index 59faba5..04efa59 100644 --- a/src/fieldstat_dynamic.cpp +++ b/src/fieldstat_dynamic.cpp @@ -243,11 +243,21 @@ static int build_dynamic_metric_key(int table_id, const char *field_name, const /* part1: field name */ unsigned int field_name_len = strlen(field_name) + 1; + + if(field_name_len > out_key_size) + { + return 0; + } + memcpy(out_key + used_len, field_name, field_name_len); //escaping_special_chars(out_key); used_len += field_name_len; /* part2: table id */ + if(used_len + sizeof(table_id) > out_key_size) + { + return 0; + } memcpy(out_key + used_len, &table_id, sizeof(table_id)); used_len += sizeof(table_id); @@ -258,20 +268,39 @@ static int build_dynamic_metric_key(int table_id, const char *field_name, const /* tag key len */ unsigned int tag_key_len = strlen(tag->key) + 1; unsigned int tag_value_len; + + if(used_len + tag_key_len > out_key_size) + { + return 0; + } memcpy(out_key + used_len, tag->key, tag_key_len); used_len += tag_key_len; switch (tag->value_type) { case 0: + if(used_len + sizeof(tag->value_int) > out_key_size) + { + return 0; + } memcpy(out_key + used_len, &tag->value_int, sizeof(tag->value_int)); used_len += sizeof(tag->value_int); break; case 1: + if(used_len + sizeof(tag->value_double) > out_key_size) + { + return 0; + } + memcpy(out_key + used_len, &tag->value_double, sizeof(tag->value_double)); used_len += sizeof(tag->value_double); break; case 2: tag_value_len = strlen(tag->value_str) + 1; + if(used_len + tag_value_len > out_key_size) + { + return 0; + } + memcpy(out_key + used_len, tag->value_str, tag_value_len); used_len += tag_value_len; break; @@ -291,9 +320,13 @@ static struct metric * read_dynamic_metric(struct fieldstat_dynamic_instance *in struct dynamic_metric **head = &instance->n_thread_dynamic_metric[thread_id]; struct dynamic_metric *find = NULL; - char dynamic_metric_key[512]; + char dynamic_metric_key[METRIC_SIZE]; unsigned int dynamic_metric_keylen = 0; dynamic_metric_keylen = build_dynamic_metric_key(table_id, field_name, tags, n_tags, sizeof(dynamic_metric_key), dynamic_metric_key); + if(dynamic_metric_keylen == 0) + { + return NULL; + } HASH_FIND(hh, *head, dynamic_metric_key, dynamic_metric_keylen, find); if(find == NULL) @@ -332,6 +365,13 @@ static struct metric * create_dynamic_table_metric(struct fieldstat_dynamic_inst unsigned int metric_keylen; metric_keylen = build_dynamic_metric_key(table_id, row_name, tags, n_tags, sizeof(value->metric_key), value->metric_key); + if(metric_keylen == 0) + { + free(value); + value = NULL; + return NULL; + } + value->metric_keylen = metric_keylen; table = instance->table_metrics[table_id]; @@ -388,6 +428,12 @@ static struct metric * create_dynamic_metric(struct fieldstat_dynamic_instance * insert = (struct dynamic_metric *)calloc(1, sizeof(struct dynamic_metric)); insert->metric_keylen = build_dynamic_metric_key(-1, field_name, tags, n_tags, sizeof(insert->metric_key), insert->metric_key); + if(insert->metric_keylen == 0) + { + free(insert); + insert = NULL; + return NULL; + } insert->metrics = (struct metric **)calloc(1, sizeof(struct metric *)); metric = metric_new(type, field_name, tags, n_tags); @@ -598,11 +644,15 @@ static int table_row_metric_values_operate( enum field_op op) { struct metric **metrics = NULL; - char metric_key[512]; + char metric_key[METRIC_SIZE]; unsigned int metric_keylen = 0; metric_keylen = build_dynamic_metric_key(table_id, row_name, tags, n_tags, sizeof(metric_key), metric_key); + if(metric_keylen == 0) + { + return -1; + } metrics = read_dynamic_row_metrics(instance, metric_key, metric_keylen, thread_id); diff --git a/src/fieldstat_internal.h b/src/fieldstat_internal.h index 08ecd2a..5e3c33b 100644 --- a/src/fieldstat_internal.h +++ b/src/fieldstat_internal.h @@ -65,6 +65,8 @@ #define PROMETHEUS_ENDPOINT_DEFAULT_URL "/metrics" #define TABLE_LINE_SCALE_NUM 1024 +#define METRIC_SIZE 1024 + enum field_calc_algo @@ -213,7 +215,7 @@ struct prometheus_endpoint_instance struct dynamic_metric { - char metric_key[512]; + char metric_key[METRIC_SIZE]; unsigned int metric_keylen; struct metric **metrics; |
