Avoid array overrun in getifaddrs
Commit Message
[BZ #15698]
* sysdeps/unix/sysv/linux/ifaddrs.c (getifaddrs_internal): Avoid
writing beyond end of netmask. Remove redundant check for
positive max_prefixlen. Store netmask via unsigned char.
---
sysdeps/unix/sysv/linux/ifaddrs.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
Comments
On Thu, Jun 05, 2014 at 05:48:34PM +0200, Andreas Schwab wrote:
> [BZ #15698]
> * sysdeps/unix/sysv/linux/ifaddrs.c (getifaddrs_internal): Avoid
> writing beyond end of netmask. Remove redundant check for
> positive max_prefixlen. Store netmask via unsigned char.
I had same patch for that, and I thought that I commited it but did not,
see
https://sourceware.org/ml/libc-alpha/2014-01/msg00235.html
I will push that.
@@ -748,7 +748,7 @@ getifaddrs_internal (struct ifaddrs **ifap)
&& ifas[ifa_index].ifa.ifa_addr->sa_family != AF_PACKET)
{
uint32_t max_prefixlen = 0;
- char *cp = NULL;
+ unsigned char *cp = NULL;
ifas[ifa_index].ifa.ifa_netmask
= &ifas[ifa_index].netmask.sa;
@@ -756,12 +756,12 @@ getifaddrs_internal (struct ifaddrs **ifap)
switch (ifas[ifa_index].ifa.ifa_addr->sa_family)
{
case AF_INET:
- cp = (char *) &ifas[ifa_index].netmask.s4.sin_addr;
+ cp = (unsigned char *) &ifas[ifa_index].netmask.s4.sin_addr;
max_prefixlen = 32;
break;
case AF_INET6:
- cp = (char *) &ifas[ifa_index].netmask.s6.sin6_addr;
+ cp = (unsigned char *) &ifas[ifa_index].netmask.s6.sin6_addr;
max_prefixlen = 128;
break;
}
@@ -771,11 +771,10 @@ getifaddrs_internal (struct ifaddrs **ifap)
if (cp != NULL)
{
- char c;
+ unsigned char c;
unsigned int preflen;
- if ((max_prefixlen > 0) &&
- (ifam->ifa_prefixlen > max_prefixlen))
+ if (ifam->ifa_prefixlen > max_prefixlen)
preflen = max_prefixlen;
else
preflen = ifam->ifa_prefixlen;
@@ -784,7 +783,8 @@ getifaddrs_internal (struct ifaddrs **ifap)
*cp++ = 0xff;
c = 0xff;
c <<= (8 - (preflen % 8));
- *cp = c;
+ if (c != 0)
+ *cp = c;
}
}
}