@cryptotaxi247 / netdata-1 / commits / 1a0a47182

fixed an out-of-bounds memory access for datatable annotations

Costa Tsaousis (ktsaou) committed Nov 30, 2015 at 23:06 UTC 1a0a471828400e20c0ec8eb58b20a0a90f303bd7
1 file changed +33 -15
src/rrd2json.c
+33 -15
@@ -274,6 +274,7 @@ typedef struct rrdresult {
274
275 int d; // the number of dimensions
276 int n; // the number of values in the arrays
277 + int rows; // the number of rows used
278
279 uint8_t *od; // the options for the dimensions
280
@@ -286,7 +287,7 @@ typedef struct rrdresult {
287 int has_st_lock; // if st is read locked by us
288 } RRDR;
289
289 -#define rrdr_rows(r) ((r)->c + 1)
290 +#define rrdr_rows(r) ((r)->rows)
291
292 /*
293 static void rrdr_dump(RRDR *r)
@@ -307,15 +308,15 @@ static void rrdr_dump(RRDR *r)
308 );
309 }
310
310 - if(r->c < 0) {
311 + if(r->rows <= 0) {
312 fprintf(stderr, "RRDR does not have any values in it.\n");
313 return;
314 }
315
315 - fprintf(stderr, "RRDR includes %d values in it:\n", r->c + 1);
316 + fprintf(stderr, "RRDR includes %d values in it:\n", r->rows);
317
318 // for each line in the array
318 - for(i = 0; i <= r->c ;i++) {
319 + for(i = 0; i < r->rows ;i++) {
320 calculated_number *cn = &r->v[ i * r->d ];
321 uint8_t *co = &r->o[ i * r->d ];
322
@@ -374,7 +375,7 @@ void rrdr_disable_not_selected_dimensions(RRDR *r, const char *dims)
375
376 static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
377 {
377 - int annotations = 0, dates = JSON_DATES_JS, dates_with_new = 0;
378 + int row_annotations = 0, dates = JSON_DATES_JS, dates_with_new = 0;
379 char kq[2] = "", // key quote
380 sq[2] = "", // string quote
381 pre_label[101] = "", // before each label
@@ -399,7 +400,7 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
400 kq[0] = '"';
401 sq[0] = '"';
402 }
402 - annotations = 1;
403 + row_annotations = 1;
404 snprintf(pre_date, 100, " {%sc%s:[{%sv%s:%s", kq, kq, kq, kq, sq);
405 snprintf(post_date, 100, "%s}", sq);
406 snprintf(pre_label, 100, ",\n {%sid%s:%s%s,%slabel%s:%s", kq, kq, sq, sq, kq, kq, sq);
@@ -458,7 +459,7 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
459 long c, i;
460 RRDDIM *rd;
461
461 - // print the csv header
462 + // print the header lines
463 for(c = 0, i = 0, rd = r->st->dimensions; rd ;c++, rd = rd->next) {
464 if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
465 if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_NONZERO))) continue;
@@ -519,10 +520,17 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
520
521 buffer_strcat(wb, post_date);
522
522 - if(annotations) {
523 - if(co[c] & RRDR_RESET)
524 - buffer_strcat(wb, overflow_annotation);
525 - else
523 + if(row_annotations) {
524 + // google supports one annotation per row
525 + int annotation_found = 0;
526 + for(c = 0, rd = r->st->dimensions; rd ;c++, rd = rd->next) {
527 + if(co[c] & RRDR_RESET) {
528 + buffer_strcat(wb, overflow_annotation);
529 + annotation_found = 1;
530 + break;
531 + }
532 + }
533 + if(!annotation_found)
534 buffer_strcat(wb, normal_annotation);
535 }
536 }
@@ -733,9 +741,10 @@ inline static uint8_t *rrdr_line_options(RRDR *r)
741 inline static int rrdr_line_init(RRDR *r, time_t t)
742 {
743 r->c++;
744 +
745 if(unlikely(r->c >= r->n)) {
746 + error("requested to step above RRDR size for chart %s", r->st->name);
747 r->c = r->n - 1;
738 - return 0;
748 }
749
750 // save the time
@@ -781,6 +790,12 @@ inline static void rrdr_free(RRDR *r)
790 free(r);
791 }
792
793 +inline void rrdr_done(RRDR *r)
794 +{
795 + r->rows = r->c + 1;
796 + r->c = 0;
797 +}
798 +
799 static RRDR *rrdr_create(RRDSET *st, int n)
800 {
801 if(unlikely(!st)) {
@@ -799,19 +814,21 @@ static RRDR *rrdr_create(RRDSET *st, int n)
814 for(rd = st->dimensions ; rd ; rd = rd->next) r->d++;
815
816 r->n = n;
802 - r->t = malloc(n * sizeof(time_t));
817 +
818 + r->t = calloc(n, sizeof(time_t));
819 if(unlikely(!r->t)) goto cleanup;
820
805 - r->v = malloc(n * r->d * sizeof(calculated_number));
821 + r->v = calloc(n * r->d, sizeof(calculated_number));
822 if(unlikely(!r->v)) goto cleanup;
823
808 - r->o = malloc(n * r->d * sizeof(uint8_t));
824 + r->o = calloc(n * r->d, sizeof(uint8_t));
825 if(unlikely(!r->o)) goto cleanup;
826
827 r->od = calloc(r->d, sizeof(uint8_t));
828 if(unlikely(!r->od)) goto cleanup;
829
830 r->c = -1;
831 + r->rows = 0;
832
833 return r;
834
@@ -1063,6 +1080,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1080 }
1081 }
1082
1083 + rrdr_done(r);
1084 return r;
1085 }
1086