whois: fix a possible out-of-bounds stack access
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 4 Sep 2018 12:48:00 +0000 (14:48 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 4 Sep 2018 12:48:00 +0000 (14:48 +0200)
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>
networking/whois.c

index f0ec86301a900852343e35ca69c478ddcdefa788..f3da32b4e1461a9799b2c62b04aec9901709ad1e 100644 (file)
@@ -39,20 +39,26 @@ static char *query(const char *host, int port, const char *domain)
        bool success;
        char *redir = NULL;
        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;
        unsigned bufpos = 0;
 
  again:
        printf("[Querying %s:%d '%s%s']\n", host, port, pfx, domain);
        fd = create_and_connect_stream_or_die(host, port);
-       success = 0;
        fdprintf(fd, "%s%s\r\n", pfx, domain);
        fp = xfdopen_for_read(fd);
 
-       while (fgets(linebuf, sizeof(linebuf), fp)) {
-               unsigned len = strcspn(linebuf, "\r\n");
+       success = 0;
+       while (fgets(linebuf, sizeof(linebuf)-1, fp)) {
+               unsigned len;
+
+               len = strcspn(linebuf, "\r\n");
                linebuf[len++] = '\n';
+               linebuf[len] = '\0';
 
                buf = xrealloc(buf, bufpos + len + 1);
                memcpy(buf + bufpos, linebuf, len);