From ff5f22abe67de212960cdd94e0ada52f2d8416e2 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 10:55:24 -0600 Subject: [PATCH 01/11] encode: splunk_hec: fix conditional (CID 508224) Signed-off-by: Eduardo Silva --- src/cmt_encode_splunk_hec.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cmt_encode_splunk_hec.c b/src/cmt_encode_splunk_hec.c index 3cbc966..7c8f73b 100644 --- a/src/cmt_encode_splunk_hec.c +++ b/src/cmt_encode_splunk_hec.c @@ -121,12 +121,15 @@ static void append_metric_value(cfl_sds_t *buf, struct cmt_map *map, static void format_context_common(struct cmt_splunk_hec_context *context, cfl_sds_t *buf, struct cmt_map *map, struct cmt_metric *metric) { - int len, tlen; + int len; + int tlen; + int result = CMT_ENCODE_SPLUNK_HEC_ALLOCATION_ERROR; + uint64_t ts; char hostname[256], timestamp[128]; - char *index = NULL, *source = NULL, *source_type = NULL; + char *index = NULL; + char *source = NULL; + char *source_type = NULL; struct timespec tms; - uint64_t ts; - int result = CMT_ENCODE_SPLUNK_HEC_ALLOCATION_ERROR; /* Open parenthesis */ cfl_sds_cat_safe(buf, "{", 1); @@ -180,7 +183,7 @@ static void format_context_common(struct cmt_splunk_hec_context *context, cfl_sd if (context->source_type != NULL) { tlen = strlen(context->source_type) + 18; /* adding snprintf template character length */ source_type = malloc(tlen); - if (source == NULL) { + if (source_type == NULL) { cmt_errno(); result = CMT_ENCODE_SPLUNK_HEC_ALLOCATION_ERROR; From 846a7edcc6930b01c2af6cbf90ec8b5ba5ab6f28 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 10:57:54 -0600 Subject: [PATCH 02/11] encode: splunk_hec: set pointers NULL after free (CID 507676) Signed-off-by: Eduardo Silva --- src/cmt_encode_splunk_hec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cmt_encode_splunk_hec.c b/src/cmt_encode_splunk_hec.c index 7c8f73b..49def33 100644 --- a/src/cmt_encode_splunk_hec.c +++ b/src/cmt_encode_splunk_hec.c @@ -162,6 +162,7 @@ static void format_context_common(struct cmt_splunk_hec_context *context, cfl_sd len = snprintf(index, tlen, "\"index\":\"%s\",", context->index); cfl_sds_cat_safe(buf, index, len); free(index); + index = NULL; } /* source */ @@ -177,6 +178,7 @@ static void format_context_common(struct cmt_splunk_hec_context *context, cfl_sd len = snprintf(source, tlen, "\"source\":\"%s\",", context->source); cfl_sds_cat_safe(buf, source, len); free(source); + source = NULL; } /* sourcetype */ @@ -192,6 +194,7 @@ static void format_context_common(struct cmt_splunk_hec_context *context, cfl_sd len = snprintf(source_type, tlen, "\"sourcetype\":\"%s\",", context->source_type); cfl_sds_cat_safe(buf, source_type, len); free(source_type); + source_type = NULL; } return; From 00f2466f2e9aaa902278332d23fbd7d3863ba7bb Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:06:37 -0600 Subject: [PATCH 03/11] cat: extra protection for invalid labels count (CID 507928) Signed-off-by: Eduardo Silva --- src/cmt_cat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmt_cat.c b/src/cmt_cat.c index 5ef28d4..a066a10 100644 --- a/src/cmt_cat.c +++ b/src/cmt_cat.c @@ -36,7 +36,7 @@ int cmt_cat_copy_label_keys(struct cmt_map *map, char **out) /* labels array */ s = map->label_count; - if (s == 0) { + if (s <= 0) { *out = NULL; return 0; } From ce383c84c4734e0645a97307f4a3367f4decd23d Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:10:34 -0600 Subject: [PATCH 04/11] cat: fix conditional in opts compare (CID 510613) Signed-off-by: Eduardo Silva --- src/cmt_cat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmt_cat.c b/src/cmt_cat.c index a066a10..dcd941b 100644 --- a/src/cmt_cat.c +++ b/src/cmt_cat.c @@ -242,7 +242,7 @@ static inline int cmt_opts_compare(struct cmt_opts *a, struct cmt_opts *b) { int ret; - ret = strcmp(a->ns, a->ns); + ret = strcmp(a->ns, b->ns); if (ret != 0) { return ret; } From 52fbd6997bbaecfd739c092c55737bb4f17d2385 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:13:11 -0600 Subject: [PATCH 05/11] decode: msgpack: reduce chance of leak with cfl_sds_cat_safe (CID 507768) Signed-off-by: Eduardo Silva --- src/cmt_decode_msgpack.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cmt_decode_msgpack.c b/src/cmt_decode_msgpack.c index 25942b3..3730af8 100644 --- a/src/cmt_decode_msgpack.c +++ b/src/cmt_decode_msgpack.c @@ -227,15 +227,15 @@ static int unpack_opts(mpack_reader_t *reader, struct cmt_opts *opts) } if (cfl_sds_len(opts->ns) > 0) { - cfl_sds_cat(opts->fqname, opts->ns, cfl_sds_len(opts->ns)); - cfl_sds_cat(opts->fqname, "_", 1); + cfl_sds_cat_safe(&opts->fqname, opts->ns, cfl_sds_len(opts->ns)); + cfl_sds_cat_safe(&opts->fqname, "_", 1); } if (cfl_sds_len(opts->subsystem) > 0) { - cfl_sds_cat(opts->fqname, opts->subsystem, cfl_sds_len(opts->subsystem)); - cfl_sds_cat(opts->fqname, "_", 1); + cfl_sds_cat_safe(&opts->fqname, opts->subsystem, cfl_sds_len(opts->subsystem)); + cfl_sds_cat_safe(&opts->fqname, "_", 1); } - cfl_sds_cat(opts->fqname, opts->name, cfl_sds_len(opts->name)); + cfl_sds_cat_safe(&opts->fqname, opts->name, cfl_sds_len(opts->name)); } return result; From 42b6d292e20b30d69d21c10e51032e66be5163f3 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:22:28 -0600 Subject: [PATCH 06/11] decode: prometheus: prevent string overflow with extra validation (CID 507560) Signed-off-by: Eduardo Silva --- include/cmetrics/cmt_decode_prometheus.h | 1 + src/cmt_decode_prometheus.c | 31 +++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/include/cmetrics/cmt_decode_prometheus.h b/include/cmetrics/cmt_decode_prometheus.h index 7500469..5087981 100644 --- a/include/cmetrics/cmt_decode_prometheus.h +++ b/include/cmetrics/cmt_decode_prometheus.h @@ -33,6 +33,7 @@ #define CMT_DECODE_PROMETHEUS_CMT_CREATE_ERROR 50 #define CMT_DECODE_PROMETHEUS_PARSE_VALUE_FAILED 60 #define CMT_DECODE_PROMETHEUS_PARSE_TIMESTAMP_FAILED 70 +#define CMT_DECODE_PROMETHEUS_SAMPLE_VALUE_TOO_LONG 80 #define CMT_DECODE_PROMETHEUS_MAX_LABEL_COUNT 128 diff --git a/src/cmt_decode_prometheus.c b/src/cmt_decode_prometheus.c index 134cb92..eab18c1 100644 --- a/src/cmt_decode_prometheus.c +++ b/src/cmt_decode_prometheus.c @@ -1143,17 +1143,36 @@ static int sample_start(struct cmt_decode_prometheus_context *context) return 0; } -static int parse_sample( - struct cmt_decode_prometheus_context *context, - const char *value1, - const char *value2) +static int parse_sample(struct cmt_decode_prometheus_context *context, + const char *value1, + const char *value2) { + int len; struct cmt_decode_prometheus_context_sample *sample; sample = cfl_list_entry_last(&context->metric.samples, struct cmt_decode_prometheus_context_sample, _head); - strcpy(sample->value1, value1); - strcpy(sample->value2, value2); + /* value1 */ + len = strlen(value1); + if (len >= sizeof(sample->value1) - 1) { + return report_error(context, + CMT_DECODE_PROMETHEUS_SAMPLE_VALUE_TOO_LONG, + "sample value is too long (max %zu characters)", sizeof(sample->value1) - 1); + } + + strncpy(sample->value1, value1, len); + sample->value1[len] = 0; + + /* value2 */ + len = strlen(value2); + if (len >= sizeof(sample->value2) - 1) { + return report_error(context, + CMT_DECODE_PROMETHEUS_SAMPLE_VALUE_TOO_LONG, + "sample value is too long (max %zu characters)", sizeof(sample->value2) - 1); + } + strncpy(sample->value2, value2, len); + sample->value2[len] = 0; + return 0; } From 816bf979007605bcc979545ea3c25b95ee5e7b5e Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:27:49 -0600 Subject: [PATCH 07/11] decode: prometheus: add missing initialization for sum var (CID 507569) Signed-off-by: Eduardo Silva --- src/cmt_decode_prometheus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cmt_decode_prometheus.c b/src/cmt_decode_prometheus.c index eab18c1..dd693e5 100644 --- a/src/cmt_decode_prometheus.c +++ b/src/cmt_decode_prometheus.c @@ -627,6 +627,7 @@ static int add_metric_histogram(struct cmt_decode_prometheus_context *context) context->current.histogram = h; } + if (cmt_histogram_set_default(h, timestamp, bucket_defaults, sum, count, label_i, label_i ? values_without_le : NULL)) { @@ -661,7 +662,7 @@ static int add_metric_summary(struct cmt_decode_prometheus_context *context) size_t quantile_index; double *quantiles = NULL; double *quantile_defaults = NULL; - double sum; + double sum = 0.0; double count_dbl; size_t label_count; uint64_t count = 0; From 551577a310fcfa9e24ad92c91b16ed3ccc73cfbc Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:33:30 -0600 Subject: [PATCH 08/11] decode: prometheus: validate samples before adding to histogram (CID 507626) Signed-off-by: Eduardo Silva --- src/cmt_decode_prometheus.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cmt_decode_prometheus.c b/src/cmt_decode_prometheus.c index dd693e5..d15af55 100644 --- a/src/cmt_decode_prometheus.c +++ b/src/cmt_decode_prometheus.c @@ -458,12 +458,20 @@ static int add_metric_histogram(struct cmt_decode_prometheus_context *context) int label_i; uint64_t timestamp; + if (cfl_list_size(&context->metric.samples) < 3) { + return report_error(context, + CMT_DECODE_PROMETHEUS_SYNTAX_ERROR, + "not enough samples for histogram"); + } + /* bucket_count = sample count - 3: * - "Inf" bucket * - sum * - count */ bucket_count = cfl_list_size(&context->metric.samples) - 3; - timestamp = context->opts.override_timestamp; + if (context->opts.override_timestamp) { + timestamp = context->opts.override_timestamp; + } bucket_defaults = calloc(bucket_count + 1, sizeof(*bucket_defaults)); if (!bucket_defaults) { From 333380a40e9bd172cbf2a59061394551e1e557c9 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:34:43 -0600 Subject: [PATCH 09/11] decode: prometheus: validate samples before adding to summary (CID 507803) Signed-off-by: Eduardo Silva --- src/cmt_decode_prometheus.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cmt_decode_prometheus.c b/src/cmt_decode_prometheus.c index d15af55..2f0ac7b 100644 --- a/src/cmt_decode_prometheus.c +++ b/src/cmt_decode_prometheus.c @@ -684,11 +684,19 @@ static int add_metric_summary(struct cmt_decode_prometheus_context *context) int label_i; uint64_t timestamp; + if (cfl_list_size(&context->metric.samples) < 2) { + return report_error(context, + CMT_DECODE_PROMETHEUS_SYNTAX_ERROR, + "not enough samples for summary"); + } + /* quantile_count = sample count - 2: * - sum * - count */ quantile_count = cfl_list_size(&context->metric.samples) - 2; - timestamp = context->opts.override_timestamp; + if (context->opts.override_timestamp) { + timestamp = context->opts.override_timestamp; + } quantile_defaults = calloc(quantile_count, sizeof(*quantile_defaults)); if (!quantile_defaults) { From 7d7a555c5b4715e859f9cbd2fd2b20fb3eeeb825 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:41:39 -0600 Subject: [PATCH 10/11] encode: prometheus: initialize variable (CID 507545) Signed-off-by: Eduardo Silva --- src/cmt_encode_prometheus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmt_encode_prometheus.c b/src/cmt_encode_prometheus.c index 287d701..f020288 100644 --- a/src/cmt_encode_prometheus.c +++ b/src/cmt_encode_prometheus.c @@ -139,7 +139,7 @@ static void append_metric_value(cfl_sds_t *buf, struct prom_fmt *fmt, int add_timestamp) { int len; - double val; + double val = 0.0; uint64_t ts; char tmp[128]; From f5bf5868d4e187afa1654b09b44dfc32737cf566 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 14 Oct 2024 11:50:42 -0600 Subject: [PATCH 11/11] decode: prometheus: initialize timestamp Signed-off-by: Eduardo Silva --- src/cmt_decode_prometheus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmt_decode_prometheus.c b/src/cmt_decode_prometheus.c index 2f0ac7b..ba7ec47 100644 --- a/src/cmt_decode_prometheus.c +++ b/src/cmt_decode_prometheus.c @@ -456,7 +456,7 @@ static int add_metric_histogram(struct cmt_decode_prometheus_context *context) cfl_sds_t *labels_without_le = NULL; cfl_sds_t *values_without_le = NULL; int label_i; - uint64_t timestamp; + uint64_t timestamp = 0; if (cfl_list_size(&context->metric.samples) < 3) { return report_error(context, @@ -682,7 +682,7 @@ static int add_metric_summary(struct cmt_decode_prometheus_context *context) cfl_sds_t *labels_without_quantile = NULL; cfl_sds_t *values_without_quantile = NULL; int label_i; - uint64_t timestamp; + uint64_t timestamp = 0; if (cfl_list_size(&context->metric.samples) < 2) { return report_error(context,