Avoid array overrun in getifaddrs
diff mbox

Message ID mvm8upbbbn1.fsf@hawking.suse.de
State New
Headers show

Commit Message

Andreas Schwab June 5, 2014, 3:48 p.m. UTC
[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

Ondřej Bílka June 5, 2014, 5:15 p.m. UTC | #1
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.

Patch
diff mbox

diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index d83e8f8..7022888 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -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;
 		    }
 		}
 	    }