Change based on Yang Tse's excellent fix to reduce buffer overflow risk and

fixing a compiler warning in the append_scopeid() function.
This commit is contained in:
Daniel Stenberg 2005-11-25 22:14:28 +00:00
parent d2a27e02ce
commit 6aab5b57e1
1 changed files with 21 additions and 11 deletions

View File

@ -72,7 +72,8 @@ struct nameinfo_query {
static void nameinfo_callback(void *arg, int status, struct hostent *host); static void nameinfo_callback(void *arg, int status, struct hostent *host);
static char *lookup_service(unsigned short port, int flags, char *buf); static char *lookup_service(unsigned short port, int flags, char *buf);
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid, char *buf); static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid,
char *buf, size_t buflen);
#endif #endif
static char *ares_striendstr(const char *s1, const char *s2); static char *ares_striendstr(const char *s1, const char *s2);
@ -139,7 +140,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
port = addr6->sin6_port; port = addr6->sin6_port;
/* If the system supports scope IDs, use it */ /* If the system supports scope IDs, use it */
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
append_scopeid(addr6, flags, ipbuf); append_scopeid(addr6, flags, ipbuf, sizeof(ipbuf));
#endif #endif
} }
else else
@ -231,7 +232,7 @@ static void nameinfo_callback(void *arg, int status, struct hostent *host)
{ {
ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf, IPBUFSIZ); ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf, IPBUFSIZ);
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf); append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf, sizeof(ipbuf));
#endif #endif
} }
/* They want a service too */ /* They want a service too */
@ -321,30 +322,39 @@ static char *lookup_service(unsigned short port, int flags,
} }
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
char *buf) char *buf, size_t buflen)
{ {
char tmpbuf[IF_NAMESIZE + 1]; char fmt_u[] = "%u";
char fmt_lu[] = "%lu";
char tmpbuf[IF_NAMESIZE + 2];
size_t bufl;
char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))?fmt_lu:fmt_u;
tmpbuf[0] = '%'; tmpbuf[0] = '%';
#ifdef HAVE_IF_INDEXTONAME #ifdef HAVE_IF_INDEXTONAME
if ((flags & ARES_NI_NUMERICSCOPE) || if ((flags & ARES_NI_NUMERICSCOPE) ||
(!IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr) (!IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)
&& !IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr))) && !IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr)))
{ {
sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id); sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
} }
else else
{ {
if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL) if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id); sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
} }
#else #else
sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id); sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
(void) flags; (void) flags;
#endif #endif
strcat(buf, tmpbuf); tmpbuf[IF_NAMESIZE + 1] = '\0';
return buf; bufl = strlen(buf);
if(bufl + strlen(tmpbuf) < buflen)
/* only append the scopeid string if it fits in the target buffer */
strcpy(&buf[bufl], tmpbuf);
} }
#endif #endif