summaryrefslogtreecommitdiff
path: root/addrtostr.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-08-07 17:48:27 -0700
committerGuy Harris <guy@alum.mit.edu>2016-08-07 17:48:27 -0700
commit9e9347f3dce4a82a4b75230a39d3f382c6f15f2a (patch)
treef8a850b7b2a626d4ca2916830630c783c65bbbe0 /addrtostr.c
parent3ac642ee4cb3ba2f54052fdb7754525bd4a40709 (diff)
downloadtcpdump-9e9347f3dce4a82a4b75230a39d3f382c6f15f2a.tar.gz
Do the addrtostr6() bounds checking while we're generating the string.
That obviates the need for a temporary buffer, and eliminates complaints about using sprintf().
Diffstat (limited to 'addrtostr.c')
-rw-r--r--addrtostr.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/addrtostr.c b/addrtostr.c
index caea1775..92875622 100644
--- a/addrtostr.c
+++ b/addrtostr.c
@@ -106,8 +106,9 @@ addrtostr6 (const void *src, char *dst, size_t size)
* to use pointer overlays. All the world's not a VAX.
*/
const u_char *srcaddr = (const u_char *)src;
- char tmp [INET6_ADDRSTRLEN+1];
- char *tp;
+ char *dp;
+ size_t space_left, added_space;
+ int snprintfed;
struct {
long base;
long len;
@@ -149,7 +150,17 @@ addrtostr6 (const void *src, char *dst, size_t size)
/* Format the result.
*/
- tp = tmp;
+ dp = dst;
+ space_left = size;
+#define APPEND_CHAR(c) \
+ { \
+ if (space_left == 0) { \
+ errno = ENOSPC; \
+ return (NULL); \
+ } \
+ *dp++ = c; \
+ space_left--; \
+ }
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
{
/* Are we inside the best run of 0x00's?
@@ -157,43 +168,47 @@ addrtostr6 (const void *src, char *dst, size_t size)
if (best.base != -1 && i >= best.base && i < (best.base + best.len))
{
if (i == best.base)
- *tp++ = ':';
+ APPEND_CHAR(':');
continue;
}
/* Are we following an initial run of 0x00s or any real hex?
*/
if (i != 0)
- *tp++ = ':';
+ APPEND_CHAR(':');
/* Is this address an encapsulated IPv4?
*/
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
{
- if (!addrtostr(srcaddr+12, tp, sizeof(tmp) - (tp - tmp)))
+ if (!addrtostr(srcaddr+12, dp, space_left))
{
errno = ENOSPC;
return (NULL);
}
- tp += strlen(tp);
+ added_space = strlen(dp);
+ dp += added_space;
+ space_left -= added_space;
break;
}
- tp += sprintf (tp, "%lx", words[i]);
+ snprintfed = snprintf (dp, space_left, "%lx", words[i]);
+ if (snprintfed < 0)
+ return (NULL);
+ if ((size_t) snprintfed >= space_left)
+ {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ dp += snprintfed;
+ space_left -= snprintfed;
}
/* Was it a trailing run of 0x00's?
*/
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
- *tp++ = ':';
- *tp++ = '\0';
+ APPEND_CHAR(':');
+ APPEND_CHAR('\0');
- /* Copy and check for overflow.
- */
- if (strlcpy (dst, tmp, size) >= size)
- {
- errno = ENOSPC;
- return (NULL);
- }
return (dst);
}