Fixed stack buffer overflow in rrdcached and added more security checks
Resolves: RHEL-173264
This commit is contained in:
parent
73ae5165a7
commit
8eda0cddc1
275
rrdtool-1.8.0-CVE-2026-43958.patch
Normal file
275
rrdtool-1.8.0-CVE-2026-43958.patch
Normal file
@ -0,0 +1,275 @@
|
||||
diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
|
||||
index 5831c1b..db9589c 100644
|
||||
--- a/src/rrd_daemon.c
|
||||
+++ b/src/rrd_daemon.c
|
||||
@@ -343,7 +343,13 @@ static void do_log(
|
||||
pthread_mutex_lock(&log_lock);
|
||||
time_t now = time(NULL);
|
||||
|
||||
- strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", gmtime(&now));
|
||||
+ struct tm tm_buf;
|
||||
+
|
||||
+ if (gmtime_r(&now, &tm_buf) == NULL) {
|
||||
+ snprintf(buffer, sizeof(buffer), "(time error)");
|
||||
+ } else {
|
||||
+ strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm_buf);
|
||||
+ }
|
||||
fprintf(log_fh, "%s [%d] ", buffer, priority);
|
||||
vfprintf(log_fh, format, args);
|
||||
fprintf(log_fh, "\n");
|
||||
@@ -554,7 +560,7 @@ static int check_pidfile(
|
||||
{
|
||||
int pid_fd;
|
||||
pid_t pid;
|
||||
- char pid_str[16];
|
||||
+ char pid_str[16] = {0};
|
||||
|
||||
pid_fd = open_pidfile("open", O_RDWR);
|
||||
if (pid_fd < 0) {
|
||||
@@ -746,11 +752,7 @@ static int add_response_info(
|
||||
return 0; /* no extra info returned when in BATCH */
|
||||
|
||||
va_start(argp, fmt);
|
||||
-#ifdef HAVE_VSNPRINTF
|
||||
len = vsnprintf(buffer, sizeof(buffer), fmt, argp);
|
||||
-#else
|
||||
- len = vsprintf(buffer, fmt, argp);
|
||||
-#endif
|
||||
va_end(argp);
|
||||
if (len < 0) {
|
||||
RRDD_LOG(LOG_ERR, "add_response_info: vnsprintf failed");
|
||||
@@ -839,14 +841,12 @@ static int send_response(
|
||||
rc = RESP_OK;
|
||||
} else {
|
||||
rclen = snprintf(buffer, sizeof buffer, "%d ", lines);
|
||||
+ if (rclen < 0 || rclen >= (int) sizeof(buffer))
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
va_start(argp, fmt);
|
||||
-#ifdef HAVE_VSNPRINTF
|
||||
len = vsnprintf(buffer + rclen, sizeof(buffer) - rclen, fmt, argp);
|
||||
-#else
|
||||
- len = vsprintf(buffer + rclen, fmt, argp);
|
||||
-#endif
|
||||
va_end(argp);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
@@ -1829,7 +1829,7 @@ static int handle_request_tune(
|
||||
goto done;
|
||||
}
|
||||
argc = atoi(i);
|
||||
- if (argc < 0) {
|
||||
+ if (argc <= 0) {
|
||||
rc = send_response(sock, RESP_ERR, "Invalid argument count specified (%d)\n",
|
||||
argc);
|
||||
goto done;
|
||||
@@ -1842,6 +1842,11 @@ static int handle_request_tune(
|
||||
argc_tmp = 0;
|
||||
while ((status = buffer_get_field(&buffer, &buffer_size, &tok)) == 0
|
||||
&& tok) {
|
||||
+ if (argc_tmp >= argc) {
|
||||
+ rc = send_response(sock, RESP_ERR,
|
||||
+ "Too many arguments (expected %d)\n", argc);
|
||||
+ goto done;
|
||||
+ }
|
||||
argv[argc_tmp] = tok;
|
||||
argc_tmp += 1;
|
||||
}
|
||||
@@ -2388,7 +2393,8 @@ static int handle_request_create(
|
||||
char *file_copy = NULL, *dir = NULL, *dir2 = NULL;
|
||||
char *tok;
|
||||
int ac = 0;
|
||||
- char *av[128];
|
||||
+#define MAX_CREATE_AV 128
|
||||
+ char *av[MAX_CREATE_AV];
|
||||
char **sources = NULL;
|
||||
int sources_length = 0;
|
||||
char *template = NULL;
|
||||
@@ -2501,10 +2507,22 @@ static int handle_request_create(
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(tok, "DS:", 3)) {
|
||||
+ if (ac >= MAX_CREATE_AV) {
|
||||
+ rc = send_response(sock, RESP_ERR,
|
||||
+ "Too many DS/RRA definitions (max %d)\n",
|
||||
+ MAX_CREATE_AV);
|
||||
+ goto done;
|
||||
+ }
|
||||
av[ac++] = tok;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(tok, "RRA:", 4)) {
|
||||
+ if (ac >= MAX_CREATE_AV) {
|
||||
+ rc = send_response(sock, RESP_ERR,
|
||||
+ "Too many DS/RRA definitions (max %d)\n",
|
||||
+ MAX_CREATE_AV);
|
||||
+ goto done;
|
||||
+ }
|
||||
av[ac++] = tok;
|
||||
continue;
|
||||
}
|
||||
diff --git a/src/rrd_graph.c b/src/rrd_graph.c
|
||||
index fa8b4c4..0d3577f 100644
|
||||
--- a/src/rrd_graph.c
|
||||
+++ b/src/rrd_graph.c
|
||||
@@ -2515,8 +2515,9 @@ int draw_horizontal_grid(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- sprintf(graph_label, im->primary_axis_format,
|
||||
- scaledstep * (double) i, sisym);
|
||||
+ snprintf(graph_label, sizeof(graph_label),
|
||||
+ im->primary_axis_format,
|
||||
+ scaledstep * (double) i, sisym);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3858,11 +3859,14 @@ static cairo_status_t cairo_output(
|
||||
{
|
||||
image_desc_t *im = (image_desc_t *) closure;
|
||||
|
||||
- im->rendered_image =
|
||||
- (unsigned char *) realloc(im->rendered_image,
|
||||
- im->rendered_image_size + length);
|
||||
- if (im->rendered_image == NULL)
|
||||
- return CAIRO_STATUS_WRITE_ERROR;
|
||||
+ {
|
||||
+ unsigned char *tmp =
|
||||
+ (unsigned char *) realloc(im->rendered_image,
|
||||
+ im->rendered_image_size + length);
|
||||
+ if (tmp == NULL)
|
||||
+ return CAIRO_STATUS_WRITE_ERROR;
|
||||
+ im->rendered_image = tmp;
|
||||
+ }
|
||||
memcpy(im->rendered_image + im->rendered_image_size, data, length);
|
||||
im->rendered_image_size += length;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@@ -4153,6 +4157,15 @@ int graph_paint_timestring(
|
||||
(double *) malloc(sizeof(double) * im->xsize * 2);
|
||||
int drawem = 0;
|
||||
|
||||
+ if (foreY == NULL || foreX == NULL ||
|
||||
+ backY == NULL || backX == NULL) {
|
||||
+ free(foreY);
|
||||
+ free(foreX);
|
||||
+ free(backY);
|
||||
+ free(backX);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
for (ii = 0; ii <= im->xsize; ii++) {
|
||||
double ybase, ytop;
|
||||
|
||||
@@ -5881,6 +5894,12 @@ int vdef_calc(
|
||||
rrd_value_t *array;
|
||||
int field;
|
||||
|
||||
+ if (steps == 0) {
|
||||
+ dst->vf.val = DNAN;
|
||||
+ dst->vf.when = 0;
|
||||
+ dst->vf.never = 1;
|
||||
+ break;
|
||||
+ }
|
||||
if ((array = (rrd_value_t *) malloc(steps * sizeof(double))) == NULL) {
|
||||
rrd_set_error("malloc VDEV_PERCENT");
|
||||
return -1;
|
||||
@@ -5914,6 +5933,12 @@ int vdef_calc(
|
||||
}
|
||||
}
|
||||
/* and allocate it */
|
||||
+ if (nancount == 0) {
|
||||
+ dst->vf.val = DNAN;
|
||||
+ dst->vf.when = 0;
|
||||
+ dst->vf.never = 1;
|
||||
+ break;
|
||||
+ }
|
||||
if ((array =
|
||||
(rrd_value_t *) malloc(nancount * sizeof(double))) == NULL) {
|
||||
rrd_set_error("malloc VDEV_PERCENT");
|
||||
diff --git a/src/rrd_graph_helper.c b/src/rrd_graph_helper.c
|
||||
index dda0069..7a5683a 100644
|
||||
--- a/src/rrd_graph_helper.c
|
||||
+++ b/src/rrd_graph_helper.c
|
||||
@@ -1186,7 +1186,7 @@ static void legend_shift(
|
||||
if (!legend || !legend[0]) {
|
||||
return;
|
||||
}
|
||||
- memmove(legend + 2, legend, strlen(legend));
|
||||
+ memmove(legend + 2, legend, strlen(legend) + 1);
|
||||
legend[0] = ' ';
|
||||
legend[1] = ' ';
|
||||
}
|
||||
diff --git a/src/rrd_xport.c b/src/rrd_xport.c
|
||||
index 405c9d8..bd07c3a 100644
|
||||
--- a/src/rrd_xport.c
|
||||
+++ b/src/rrd_xport.c
|
||||
@@ -357,6 +357,16 @@ static int rrd_xport_fn(
|
||||
/* printf("step: %lu\n",*step); */
|
||||
free(step_list);
|
||||
|
||||
+ if (*step == 0) {
|
||||
+ rrd_set_error("xport step is zero");
|
||||
+ free(ref_list);
|
||||
+ for (unsigned long k = *col_cnt; k > 0; k--)
|
||||
+ free(legend_list[k - 1]);
|
||||
+ *col_cnt = 0;
|
||||
+ free(legend_list);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
*start = im->start - im->start % (*step);
|
||||
|
||||
*end = im->end - im->end % (*step);
|
||||
@@ -371,28 +381,30 @@ static int rrd_xport_fn(
|
||||
(rrd_value_t *) malloc((*col_cnt) * row_cnt *
|
||||
sizeof(rrd_value_t))) == NULL) {
|
||||
free(ref_list);
|
||||
- while ((*col_cnt)--)
|
||||
- free(legend_list[*col_cnt]);
|
||||
+ for (unsigned long k = *col_cnt; k > 0; k--)
|
||||
+ free(legend_list[k - 1]);
|
||||
+ *col_cnt = 0;
|
||||
free(legend_list);
|
||||
rrd_set_error("malloc xport data area");
|
||||
return (-1);
|
||||
}
|
||||
dstptr = (*data);
|
||||
|
||||
+ long unsigned int chosen_idx = 0;
|
||||
/* fill data structure */
|
||||
- for (dst_row = 0; (int) dst_row < (int) row_cnt; dst_row++) {
|
||||
- for (i = 0; i < (int) (*col_cnt); i++) {
|
||||
+ for (dst_row = 0; dst_row < row_cnt; dst_row++) {
|
||||
+ for (i = 0; (unsigned long) i < *col_cnt; i++) {
|
||||
long vidx = im->gdes[ref_list[i]].vidx;
|
||||
time_t now = *start + dst_row * *step;
|
||||
|
||||
- (*dstptr++) = im->gdes[vidx].data[(unsigned long)
|
||||
- floor((double)
|
||||
- (now -
|
||||
- im->gdes[vidx].start)
|
||||
- / im->gdes[vidx].step)
|
||||
- * im->gdes[vidx].ds_cnt +
|
||||
- im->gdes[vidx].ds];
|
||||
+ if (im->gdes[vidx].step > 0 &&
|
||||
+ now >= im->gdes[vidx].start) {
|
||||
+ chosen_idx = floor((double) (now - im->gdes[vidx].start) / im->gdes[vidx].step) * im->gdes[vidx].ds_cnt + im->gdes[vidx].ds;
|
||||
|
||||
+ (*dstptr++) = im->gdes[vidx].data[chosen_idx];
|
||||
+ } else {
|
||||
+ (*dstptr++) = DNAN;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -975,6 +987,9 @@ static void escapeJSON(
|
||||
size_t l = strlen(txt);
|
||||
size_t pos = 0;
|
||||
|
||||
+ if (tmp == NULL)
|
||||
+ return;
|
||||
+
|
||||
/* now iterate over the chars */
|
||||
for (size_t i = 0; (i < l) && (pos < len); i++, pos++) {
|
||||
switch (txt[i]) {
|
||||
10
rrdtool.spec
10
rrdtool.spec
@ -18,7 +18,7 @@
|
||||
Summary: Round Robin Database Tool to store and display time-series data
|
||||
Name: rrdtool
|
||||
Version: 1.8.0
|
||||
Release: 20%{?dist}
|
||||
Release: 21%{?dist}
|
||||
# gd license in php bindings isn't by default built-in
|
||||
License: gpl-1.0-or-later AND gpl-2.0-or-later AND gpl-2.0-or-later WITH rrdtool-floss-exception-2.0 AND mit AND lgpl-2.0-or-later AND lgpl-2.1-or-later AND bsd-source-code AND snprintf AND bsd-3-clause AND gpl-2.0-only AND licenseref-fedora-public-domain AND gtkbook
|
||||
URL: https://oss.oetiker.ch/rrdtool/
|
||||
@ -37,6 +37,9 @@ Patch6: rrdtool-configure-c99.patch
|
||||
# gcc-14 fix
|
||||
# https://github.com/oetiker/rrdtool-1.x/commit/b76e3c578f1e9f582e9c28f50d82b1f569602075
|
||||
Patch7: rrdtool-1.8.0-const-argv.patch
|
||||
# backported from:
|
||||
# https://github.com/oetiker/rrdtool-1.x/commit/4218ec7127ba6c7ea1c20d7c8ea6e2b3f83df73a
|
||||
Patch8: rrdtool-1.8.0-CVE-2026-43958.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: gcc-c++
|
||||
@ -187,6 +190,7 @@ The %{name}-lua package includes RRDtool bindings for Lua.
|
||||
%patch5 -p1 -b .BUILD_DATE-fix
|
||||
%patch6 -p1 -b .configure-c99
|
||||
%patch7 -p1 -b .const-argv
|
||||
%patch8 -p1 -b .CVE-2026-43958
|
||||
|
||||
# Fix to find correct python dir on lib64
|
||||
perl -pi -e 's|get_python_lib\(0,0,prefix|get_python_lib\(1,0,prefix|g' \
|
||||
@ -415,6 +419,10 @@ LD_LIBRARY_PATH=%{buildroot}%{_libdir} php -n \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed May 20 2026 Jaroslav Škarvada <jskarvad@redhat.com> - 1.8.0-21
|
||||
- Fixed stack buffer overflow in rrdcached and added more security checks
|
||||
Resolves: RHEL-173264
|
||||
|
||||
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 1.8.0-20
|
||||
- Bump release for October 2024 mass rebuild:
|
||||
Resolves: RHEL-64018
|
||||
|
||||
Loading…
Reference in New Issue
Block a user