summaryrefslogtreecommitdiff
path: root/ares_getnameinfo.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2005-11-25 22:14:28 +0000
committerDaniel Stenberg <daniel@haxx.se>2005-11-25 22:14:28 +0000
commit1638613891675f378487a987650b5e59d67cc0ff (patch)
tree9c7669ce620e23b732941b016e5e008787e65abe /ares_getnameinfo.c
parentfab5b5e1163b963865167c73b498a0d25a2453a9 (diff)
downloadc-ares-1638613891675f378487a987650b5e59d67cc0ff.tar.gz
c-ares-1638613891675f378487a987650b5e59d67cc0ff.tar.bz2
c-ares-1638613891675f378487a987650b5e59d67cc0ff.zip
Change based on Yang Tse's excellent fix to reduce buffer overflow risk and
fixing a compiler warning in the append_scopeid() function.
Diffstat (limited to 'ares_getnameinfo.c')
-rw-r--r--ares_getnameinfo.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/ares_getnameinfo.c b/ares_getnameinfo.c
index 0dbed73..35e611f 100644
--- a/ares_getnameinfo.c
+++ b/ares_getnameinfo.c
@@ -72,7 +72,8 @@ struct nameinfo_query {
static void nameinfo_callback(void *arg, int status, struct hostent *host);
static char *lookup_service(unsigned short port, int flags, char *buf);
#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
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;
/* If the system supports scope IDs, use it */
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
- append_scopeid(addr6, flags, ipbuf);
+ append_scopeid(addr6, flags, ipbuf, sizeof(ipbuf));
#endif
}
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);
#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
}
/* 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
-static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
- char *buf)
+static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
+ 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] = '%';
+
#ifdef HAVE_IF_INDEXTONAME
if ((flags & ARES_NI_NUMERICSCOPE) ||
(!IN6_IS_ADDR_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
{
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
- sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id);
+ sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
(void) flags;
#endif
- strcat(buf, tmpbuf);
- return buf;
+ tmpbuf[IF_NAMESIZE + 1] = '\0';
+ 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