From: Derrick Lyndon Pallas Date: Tue, 3 Sep 2019 20:39:33 +0000 (+0000) Subject: rrd_client: avoid invalid read X-Git-Tag: v1.8.0~59 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=53586d61ef52d1819e7a7040c44981ed7871eda0;p=thirdparty%2Frrdtool-1.x.git rrd_client: avoid invalid read In rrd_client_last and rrd_client_first, the response value is in the message prior to any additional lines. Unfortunately, the buffer that contains this data is on the stack for response_read and is no longer valid by the time the caller sees it. This change strdups the message line in response_read and subsequently frees it in response_free. Resolves issue #1047. --- diff --git a/src/rrd_client.c b/src/rrd_client.c index 433a2844..f00a73c6 100644 --- a/src/rrd_client.c +++ b/src/rrd_client.c @@ -496,6 +496,9 @@ static void response_free( free(res->lines); } + if (res->message != NULL) + free(res->message); + free(res); } /* }}} void response_free */ @@ -565,6 +568,7 @@ static int response_read( int status = 0; char buffer[RRD_CMD_MAX]; + char *message_ptr; size_t i; @@ -577,6 +581,7 @@ static int response_read( if (ret == NULL) DIE(-2); memset(ret, 0, sizeof(*ret)); + ret->message = NULL; ret->lines = NULL; ret->lines_num = 0; @@ -585,12 +590,16 @@ static int response_read( chomp(buffer); - ret->status = strtol(buffer, &ret->message, 0); - if (buffer == ret->message) + ret->status = strtol(buffer, &message_ptr, 0); + if (buffer == message_ptr) DIE(-4); /* Skip leading whitespace of the status message */ - ret->message += strspn(ret->message, " \t"); + message_ptr += strspn(message_ptr, " \t"); + + ret->message = strdup(message_ptr); + if (ret->message == NULL) + DIE(-5); if (ret->status <= 0) { if (ret->status < 0) @@ -600,20 +609,20 @@ static int response_read( ret->lines = (char **) malloc(sizeof(char *) * ret->status); if (ret->lines == NULL) - DIE(-5); + DIE(-6); memset(ret->lines, 0, sizeof(char *) * ret->status); ret->lines_num = (size_t) ret->status; for (i = 0; i < ret->lines_num; i++) { if (recvline(client, buffer, sizeof(buffer)) == -1) - DIE(-6); + DIE(-7); chomp(buffer); ret->lines[i] = strdup(buffer); if (ret->lines[i] == NULL) - DIE(-7); + DIE(-8); } out: