Date: Sun, 7 Oct 2001 20:38:52 -0400 From: Mike Barcroft <mike@FreeBSD.ORG> To: "Todd C. Miller" <Todd.Miller@courtesan.com> Cc: Peter Pentchev <roam@ringlet.net>, freebsd-net@FreeBSD.ORG, freebsd-audit@FreeBSD.ORG Subject: Final Patch for Review (was Re: [CFR] whois(1) out-of-bound access patch) Message-ID: <20011007203852.G37270@coffee.q9media.com> In-Reply-To: <200110041650.f94GoL10010161@xerxes.courtesan.com>; from Todd.Miller@courtesan.com on Thu, Oct 04, 2001 at 10:50:20AM -0600 References: <20011004121640.C1959@ringworld.oblivion.bg> <20011004121933.B31795@coffee.q9media.com> <200110041650.f94GoL10010161@xerxes.courtesan.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Todd C. Miller <Todd.Miller@courtesan.com> writes: > In message <20011004121933.B31795@coffee.q9media.com> > so spake Mike Barcroft (mike): > > > Would you please test the attached patch and confirm that it solves > > the problem? If it does, I'll commit it today. > > I doubt that is sufficient as "buf" is treated as a NUL terminated > string in the calls to strstr(). Also note that it is not necessary > to copy the buffer each time as in the original patch. You can > only get a line w/o a newline as the last line before EOF. After some discussion off the mailing list with Peter, I've come up with a total solution that is fairly elegant, but requires the new libc function strnstr(3) I posted earlier. Most of the patch is a cleanup of the current code. I'd appreciate reviews of this. I plan on committing it in a few days. The patch is at the end of this message and also at: http://people.FreeBSD.org/~mike/patches/whois.20011007.diff Best regards, Mike Barcroft ---------------------------------------------------------------------- whois.20011007.diff o Treat a buffer as a non-NUL terminated string, because the whois server may not return a new line character on the final line. o Remove the whois.networksolutions.com fallback code, which is no longer needed. o Instead of determining a hostname by terminating it when we see whitespace, only allow hostname characters and terminate the string when it's not such a character. o Add a small optimization in a for loop. PR: 30968 MFC after: 4 days Index: whois.c =================================================================== RCS file: /cvs/src/usr.bin/whois/whois.c,v retrieving revision 1.24 diff -u -r1.24 whois.c --- whois.c 5 Aug 2001 19:37:12 -0000 1.24 +++ whois.c 7 Oct 2001 21:38:04 -0000 @@ -71,11 +71,11 @@ #define SNICHOST "whois.6bone.net" #define DEFAULT_PORT "whois" #define WHOIS_SERVER_ID "Whois Server: " -#define NO_MATCH_ID "No match for \"" #define WHOIS_RECURSE 0x01 -#define WHOIS_INIC_FALLBACK 0x02 -#define WHOIS_QUICK 0x04 +#define WHOIS_QUICK 0x02 + +#define ishost(h) (isalnum((unsigned char)h) || h == '.' || h == '-') const char *ip_whois[] = { RNICHOST, PNICHOST, NULL }; const char *port = DEFAULT_PORT; @@ -164,7 +164,7 @@ use_qnichost = 1; host = NICHOST; if (!(flags & WHOIS_QUICK)) - flags |= WHOIS_INIC_FALLBACK | WHOIS_RECURSE; + flags |= WHOIS_RECURSE; } while (argc--) { if (country != NULL) { @@ -251,8 +251,8 @@ { FILE *sfi, *sfo; struct addrinfo *res2; - char *buf, *nhost, *p; - int i, nomatch, s; + char *buf, *host, *nhost, *p; + int i, s; size_t len; for (; res; res = res->ai_next) { @@ -273,45 +273,34 @@ fprintf(sfo, "%s\r\n", name); fflush(sfo); nhost = NULL; - nomatch = 0; while ((buf = fgetln(sfi, &len)) != NULL) { - while (len && isspace(buf[len - 1])) + while (len > 0 && isspace((unsigned char)buf[len - 1])) buf[--len] = '\0'; + printf("%.*s\n", (int)len, buf); if ((flags & WHOIS_RECURSE) && nhost == NULL) { - p = strstr(buf, WHOIS_SERVER_ID); - if (p != NULL) { - p += sizeof(WHOIS_SERVER_ID) - 1; - if ((len = strcspn(p, " \t\n\r")) != 0) { - s_asprintf(&nhost, "%s", p); + host = strnstr(buf, WHOIS_SERVER_ID, len); + if (host != NULL) { + host += sizeof(WHOIS_SERVER_ID) - 1; + for (p = host; p < buf + len; p++) { + if (!ishost(*p)) { + *p = '\0'; + break; + } } + s_asprintf(&nhost, "%.*s", + (int)(buf + len - host), host); } else { for (i = 0; ip_whois[i] != NULL; i++) { - if (strstr(buf, ip_whois[i]) == NULL) + if (strnstr(buf, ip_whois[i], len) == + NULL) continue; s_asprintf(&nhost, "%s", ip_whois[i]); + break; } } } - - if ((flags & WHOIS_INIC_FALLBACK) && nhost == NULL && - !nomatch && (p = strstr(buf, NO_MATCH_ID)) != NULL) { - p += sizeof(NO_MATCH_ID) - 1; - if ((len = strcspn(p, "\"")) && - strncasecmp(name, p, len) == 0 && - name[len] == '\0' && - strchr(name, '.') == NULL) - nomatch = 1; - } - printf("%s\n", buf); } - - /* Do second lookup as needed. */ - if (nomatch && nhost == NULL) { - printf("Looking up %s at %s.\n\n", name, INICHOST); - s_asprintf(&nhost, "%s", INICHOST); - } - if (nhost != NULL) { if ((res2 = gethostinfo(nhost, 0)) == NULL) { free(nhost); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011007203852.G37270>