whois: fix a possible out-of-bounds stack access

If fgets() returns incomplete string, we replace NUL with
'\n', and then trim() runs on a non-NUL-terminated buffer.
Prevent that.

While at it, bump buffer from 1k to 2k.

function                                             old     new   delta
query                                                519     524      +5

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-09-04 14:48:00 +02:00
parent 8f1ae25634
commit 3d6f95ede6

View File

@ -39,20 +39,26 @@ static char *query(const char *host, int port, const char *domain)
bool success; bool success;
char *redir = NULL; char *redir = NULL;
const char *pfx = ""; const char *pfx = "";
char linebuf[1024]; /* some .io domains reported to have very long strings in whois
* responses, 1k was not enough:
*/
char linebuf[2 * 1024];
char *buf = NULL; char *buf = NULL;
unsigned bufpos = 0; unsigned bufpos = 0;
again: again:
printf("[Querying %s:%d '%s%s']\n", host, port, pfx, domain); printf("[Querying %s:%d '%s%s']\n", host, port, pfx, domain);
fd = create_and_connect_stream_or_die(host, port); fd = create_and_connect_stream_or_die(host, port);
success = 0;
fdprintf(fd, "%s%s\r\n", pfx, domain); fdprintf(fd, "%s%s\r\n", pfx, domain);
fp = xfdopen_for_read(fd); fp = xfdopen_for_read(fd);
while (fgets(linebuf, sizeof(linebuf), fp)) { success = 0;
unsigned len = strcspn(linebuf, "\r\n"); while (fgets(linebuf, sizeof(linebuf)-1, fp)) {
unsigned len;
len = strcspn(linebuf, "\r\n");
linebuf[len++] = '\n'; linebuf[len++] = '\n';
linebuf[len] = '\0';
buf = xrealloc(buf, bufpos + len + 1); buf = xrealloc(buf, bufpos + len + 1);
memcpy(buf + bufpos, linebuf, len); memcpy(buf + bufpos, linebuf, len);