--- whois-4.7.2/whois.c +++ whois-4.7.2/whois.c @@ -76,7 +76,7 @@ int main(int argc, char *argv[]) /* RIPE flags */ if (strchr(ripeflags, ch)) { for (p = fstring; *p; p++); - sprintf(p--, "-%c ", ch); + snprintf(p--, sizeof(fstring), "-%c ", ch); continue; } if (strchr(ripeflagsp, ch)) { @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) usage(); /* On some systems realloc only works on non-NULL buffers */ - qstring = malloc(64); + qstring = xmalloc(64); *qstring = '\0'; /* parse other parameters, if any */ @@ -130,11 +130,11 @@ int main(int argc, char *argv[]) while (1) { qslen += strlen(*argv) + 1 + 1; - qstring = realloc(qstring, qslen); - strcat(qstring, *argv++); + qstring = xrealloc(qstring, qslen); + strncat(qstring, *argv++, qslen-1); if (argc == 1) break; - strcat(qstring, " "); + strncat(qstring, " ", qslen-1); argc--; } } @@ -428,8 +428,10 @@ char *queryformat(const char *server, co char *buf; int i, isripe = 0; + /* buflen was always 0 in original patch and buf was allocated twice /Aye */ /* 64 bytes reserved for server-specific flags added later */ - buf = malloc(strlen(flags) + strlen(query) + strlen(client_tag) + 64); + int buflen = strlen(flags) + strlen(query) + strlen(client_tag) + 64; + buf = xmalloc(buflen); *buf = '\0'; for (i = 0; ripe_servers[i]; i++) if (strcmp(server, ripe_servers[i]) == 0) { @@ -442,7 +444,7 @@ char *queryformat(const char *server, co if (*flags) { if (!isripe && strcmp(server, "whois.corenic.net") != 0) puts(_("Warning: RIPE flags used with a traditional server.")); - strcat(buf, flags); + strncat(buf, flags, buflen-1); } #ifdef HAVE_LIBIDN @@ -451,28 +453,28 @@ char *queryformat(const char *server, co */ if (streq(server, "whois.denic.de") && domcmp(query, ".de") && !strchr(query, ' ') && !*flags) - sprintf(buf, "-T dn,ace -C US-ASCII %s", query); + snprintf(buf, buflen-1, "-T dn,ace -C US-ASCII %s", query); else /* here we have another registrar who could not make things simple * -C sets the language for both input and output */ if (!isripe && streq(server, "whois.cat") && domcmp(query, ".cat") && !strchr(query, ' ')) - sprintf(buf, "-C US-ASCII ace %s", query); + snprintf(buf, buflen-1, "-C US-ASCII ace %s", query); else #endif if (!isripe && (streq(server, "whois.nic.mil") || streq(server, "whois.nic.ad.jp")) && strncasecmp(query, "AS", 2) == 0 && isasciidigit(query[2])) /* FIXME: /e is not applied to .JP ASN */ - sprintf(buf, "AS %s", query + 2); /* fix query for DDN */ + snprintf(buf, buflen-1, "AS %s", query + 2); /* fix query for DDN */ else if (!isripe && (streq(server, "whois.nic.ad.jp") || streq(server, "whois.jprs.jp"))) { char *lang = getenv("LANG"); /* not a perfect check, but... */ if (!lang || !strneq(lang, "ja", 2)) - sprintf(buf, "%s/e", query); /* ask for english text */ + snprintf(buf, buflen-1, "%s/e", query); /* ask for english text */ else - strcat(buf, query); + strncat(buf, query, buflen-1); } else if (!isripe && streq(server, "whois.arin.net") && (p = strrchr(query, '/'))) { strncat(buf, query, p - query); /* strip CIDR */ @@ -533,7 +535,7 @@ const char *do_query(const int sock, con if (sscanf(buf, REFERTO_FORMAT, nh, np, nq) == 3) { /* XXX we are ignoring the new query string */ - referral_server = malloc(300); + referral_server = xmalloc(300); sprintf(referral_server, "%s:%s", nh, np); } } @@ -582,7 +584,7 @@ const char *query_crsnic(const int sock, int hide = hide_discl; int state = 0; - temp = malloc(strlen(query) + 1 + 2 + 1); + temp = xmalloc(strlen(query) + 1 + 2 + 1); *temp = '='; strcpy(temp + 1, query); strcat(temp, "\r\n"); @@ -600,7 +602,7 @@ const char *query_crsnic(const int sock, for (p = buf; *p != ':'; p++); /* skip until colon */ for (p++; *p == ' '; p++); /* skip colon and spaces */ - ret = malloc(strlen(p) + 1); + ret = xmalloc(strlen(p) + 1); for (q = ret; *p != '\n' && *p != '\r' && *p != ' '; *q++ = *p++) ; /*copy data*/ *q = '\0'; @@ -625,7 +627,7 @@ const char *query_pir(const int sock, co int hide = hide_discl; int state = 0; - temp = malloc(strlen(query) + 5 + 2 + 1); + temp = xmalloc(strlen(query) + 5 + 2 + 1); strcpy(temp, "FULL "); strcat(temp, query); strcat(temp, "\r\n"); @@ -646,7 +648,7 @@ const char *query_pir(const int sock, co for (p = buf; *p != ':'; p++); /* skip until colon */ for (p++; *p != ':'; p++); /* skip until 2nd colon */ for (p++; *p == ' '; p++); /* skip colon and spaces */ - ret = malloc(strlen(p) + 1); + ret = xmalloc(strlen(p) + 1); for (q = ret; *p != '\n' && *p != '\r'; *q++ = *p++); /*copy data*/ *q = '\0'; state = 2; @@ -785,7 +787,7 @@ void split_server_port(const char *const char *convert_6to4(const char *s) { - char *new = malloc(sizeof("255.255.255.255")); + char *new = xmalloc(sizeof("255.255.255.255")); unsigned int a, b; if (sscanf(s, "2002:%x:%x:", &a, &b) != 2) @@ -848,6 +850,21 @@ void usage(void) exit(0); } +/* Memory allocation routines */ +void *xmalloc(size_t size) +{ + void *ptr; + if ((ptr = malloc(size)) == NULL) + err_sys("malloc"); + return ptr; +} + +void *xrealloc(void *ptr, size_t size) +{ + if ((ptr = realloc(ptr, size)) == NULL) + err_sys("realloc"); + return ptr; +} /* Error routines */ void err_sys(const char *fmt, ...) --- whois-4.7.2/whois.h +++ whois-4.7.2/whois.h @@ -32,6 +32,8 @@ const char *handle_query(const char *ser void split_server_port(const char *const input, const char **server, const char **port); +void *xmalloc(size_t); +void *xrealloc(void *, size_t); void err_quit(const char *,...); void err_sys(const char *,...);