From 9137f89fa4996b672549800231e364a3428e5426 Mon Sep 17 00:00:00 2001 From: itojun <> Date: Mon, 19 Aug 2002 03:01:54 +0000 Subject: snprintf audit. debug inet_neta() on non-continuous masks (like 0.255.0.255), more pickier string manipulation. deraadt ok --- src/lib/libc/net/inet_net_ntop.c | 41 +++++++++++++++++++++++++++------------- src/lib/libc/net/inet_neta.c | 36 +++++++++++++++++++++-------------- src/lib/libc/net/inet_ntop.c | 35 +++++++++++++++++++++++++--------- 3 files changed, 76 insertions(+), 36 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libc/net/inet_net_ntop.c b/src/lib/libc/net/inet_net_ntop.c index f5cb588d10..18eea6bb6d 100644 --- a/src/lib/libc/net/inet_net_ntop.c +++ b/src/lib/libc/net/inet_net_ntop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inet_net_ntop.c,v 1.2 2002/02/17 19:42:23 millert Exp $ */ +/* $OpenBSD: inet_net_ntop.c,v 1.3 2002/08/19 03:01:54 itojun Exp $ */ /* * Copyright (c) 1996 by Internet Software Consortium. @@ -21,7 +21,7 @@ #if 0 static const char rcsid[] = "$From: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp $"; #else -static const char rcsid[] = "$OpenBSD: inet_net_ntop.c,v 1.2 2002/02/17 19:42:23 millert Exp $"; +static const char rcsid[] = "$OpenBSD: inet_net_ntop.c,v 1.3 2002/08/19 03:01:54 itojun Exp $"; #endif #endif @@ -88,13 +88,19 @@ inet_net_ntop_ipv4(src, bits, dst, size) char *t; u_int m; int b; + char *ep; + int advance; + + ep = dst + size; + if (ep <= dst) + goto emsgsize; if (bits < 0 || bits > 32) { errno = EINVAL; return (NULL); } if (bits == 0) { - if (size < sizeof "0") + if (ep - dst < sizeof "0") goto emsgsize; *dst++ = '0'; *dst = '\0'; @@ -102,34 +108,43 @@ inet_net_ntop_ipv4(src, bits, dst, size) /* Format whole octets. */ for (b = bits / 8; b > 0; b--) { - if (size < sizeof "255.") + if (ep - dst < sizeof "255.") + goto emsgsize; + advance = snprintf(dst, ep - dst, "%u", *src++); + if (advance <= 0 || advance >= ep - dst) goto emsgsize; - t = dst; - dst += sprintf(dst, "%u", *src++); + dst += advance; if (b > 1) { + if (dst + 1 >= ep) + goto emsgsize; *dst++ = '.'; *dst = '\0'; } - size -= (size_t)(dst - t); } /* Format partial octet. */ b = bits % 8; if (b > 0) { - if (size < sizeof ".255") + if (ep - dst < sizeof ".255") goto emsgsize; - t = dst; if (dst != odst) + if (dst + 1 >= ep) + goto emsgsize; *dst++ = '.'; m = ((1 << b) - 1) << (8 - b); - dst += sprintf(dst, "%u", *src & m); - size -= (size_t)(dst - t); + advance = snprintf(dst, ep - dst, "%u", *src & m); + if (advance <= 0 || advance >= ep - dst) + goto emsgsize; + dst += advance; } /* Format CIDR /width. */ - if (size < sizeof "/32") + if (ep - dst < sizeof "/32") + goto emsgsize; + advance = snprintf(dst, ep - dst, "/%u", bits); + if (advance <= 0 || advance >= ep - dst) goto emsgsize; - dst += sprintf(dst, "/%u", bits); + dst += advance; return (odst); emsgsize: diff --git a/src/lib/libc/net/inet_neta.c b/src/lib/libc/net/inet_neta.c index 881a328ab0..6960bcd0b5 100644 --- a/src/lib/libc/net/inet_neta.c +++ b/src/lib/libc/net/inet_neta.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inet_neta.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $ */ +/* $OpenBSD: inet_neta.c,v 1.4 2002/08/19 03:01:54 itojun Exp $ */ /* * Copyright (c) 1996 by Internet Software Consortium. @@ -19,9 +19,9 @@ #if defined(LIBC_SCCS) && !defined(lint) #if 0 -static const char rcsid[] = "$Id: inet_neta.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $"; +static const char rcsid[] = "$Id: inet_neta.c,v 1.4 2002/08/19 03:01:54 itojun Exp $"; #else -static const char rcsid[] = "$OpenBSD: inet_neta.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: inet_neta.c,v 1.4 2002/08/19 03:01:54 itojun Exp $"; #endif #endif @@ -52,29 +52,37 @@ inet_neta(src, dst, size) size_t size; { char *odst = dst; - char *tp; + char *ep; + int advance; + if (src == 0x00000000) { + if (size < sizeof "0.0.0.0") + goto emsgsize; + strlcpy(dst, "0.0.0.0", size); + return dst; + } + ep = dst + size; + if (ep <= dst) + goto emsgsize; while (src & 0xffffffff) { u_char b = (src & 0xff000000) >> 24; src <<= 8; - if (b) { - if (size < sizeof "255.") + if (b || src) { + if (ep - dst < sizeof "255.") + goto emsgsize; + advance = snprintf(dst, ep - dst, "%u", b); + if (advance <= 0 || advance >= ep - dst) goto emsgsize; - tp = dst; - dst += sprintf(dst, "%u", b); + dst += advance; if (src != 0L) { + if (dst + 1 >= ep) + goto emsgsize; *dst++ = '.'; *dst = '\0'; } - size -= (size_t)(dst - tp); } } - if (dst == odst) { - if (size < sizeof "0.0.0.0") - goto emsgsize; - strlcpy(dst, "0.0.0.0", size); - } return (odst); emsgsize: diff --git a/src/lib/libc/net/inet_ntop.c b/src/lib/libc/net/inet_ntop.c index 212c0396b2..5293e80fc0 100644 --- a/src/lib/libc/net/inet_ntop.c +++ b/src/lib/libc/net/inet_ntop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inet_ntop.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $ */ +/* $OpenBSD: inet_ntop.c,v 1.4 2002/08/19 03:01:54 itojun Exp $ */ /* Copyright (c) 1996 by Internet Software Consortium. * @@ -20,7 +20,7 @@ #if 0 static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; #else -static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.4 2002/08/19 03:01:54 itojun Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -116,10 +116,12 @@ inet_ntop6(src, dst, size) * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; + char *tp, *ep; struct { int base, len; } best, cur; u_int words[IN6ADDRSZ / INT16SZ]; int i; + int advance; /* * Preprocess: @@ -156,30 +158,45 @@ inet_ntop6(src, dst, size) * Format the result. */ tp = tmp; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + ep = tmp + sizeof(tmp); + for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { - if (i == best.base) + if (i == best.base) { + if (tp + 1 >= ep) + return (NULL); *tp++ = ':'; + } continue; } /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) + if (i != 0) { + if (tp + 1 >= ep) + return (NULL); *tp++ = ':'; + } /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + if (!inet_ntop4(src+12, tp, (size_t)(ep - tp))) return (NULL); tp += strlen(tp); break; } - tp += sprintf(tp, "%x", words[i]); + advance = snprintf(tp, ep - tp, "%x", words[i]); + if (advance <= 0 || advance >= ep - tp) + return (NULL); + tp += advance; } /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { + if (tp + 1 >= ep) + return (NULL); *tp++ = ':'; + } + if (tp + 1 >= ep) + return (NULL); *tp++ = '\0'; /* -- cgit v1.2.3-55-g6feb