From: Olivier Fourdan Date: Tue, 25 Nov 2008 12:36:22 +0000 (+0000) Subject: ip maddr show” on an infiniband address causes a stack corruption X-Git-Tag: v2.6.28~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f71c0cae2db61890474e04ba3a26e40219e5561;p=thirdparty%2Fiproute2.git ip maddr show” on an infiniband address causes a stack corruption “ip maddr show” on an infiniband address causes a stack corruption because the length of the address for Infiniband (20 bytes, as described in kernel doc Documentation/infiniband/ipoib.txt) does not fit on the 16 bytes of the field in which it gets stored. The proposed patch increases the size of the hardware address from 4 __u32 to 8 and also adds a check to avoid overriding the available size while parsing the hardware address. This bug affects current upstream code AFAICT. Hope this helps, Cheers, Olivier. “ip maddr show ib0” causes a stack corruption because the length of the address for Infiniband (20 see kernel doc Documentation/infiniband/ipoib.txt) does not fit on the 16 bytes of the field in which it gets stored. The proposed patch increases the size of the hardware address from 4 u32 to 8 and adds a check to avoid overriding the available size while parsing the hardware address. --- diff --git a/include/utils.h b/include/utils.h index 5daed6b31..f7ef939b3 100644 --- a/include/utils.h +++ b/include/utils.h @@ -46,7 +46,7 @@ typedef struct __u8 bytelen; __s16 bitlen; __u32 flags; - __u32 data[4]; + __u32 data[8]; } inet_prefix; #define PREFIXLEN_SPECIFIED 1 diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c index 1014f8321..44ffdfcfa 100644 --- a/ip/ipmaddr.c +++ b/ip/ipmaddr.c @@ -43,11 +43,11 @@ static void usage(void) exit(-1); } -static int parse_hex(char *str, unsigned char *addr) +static int parse_hex(char *str, unsigned char *addr, size_t size) { int len=0; - while (*str) { + while (*str && (len < 2 * size)) { int tmp; if (str[1] == 0) return -1; @@ -104,7 +104,7 @@ void read_dev_mcast(struct ma_info **result_p) m.addr.family = AF_PACKET; - len = parse_hex(hexa, (unsigned char*)&m.addr.data); + len = parse_hex(hexa, (unsigned char*)&m.addr.data, sizeof (m.addr.data)); if (len >= 0) { struct ma_info *ma = malloc(sizeof(m)); @@ -176,7 +176,7 @@ void read_igmp6(struct ma_info **result_p) m.addr.family = AF_INET6; - len = parse_hex(hexa, (unsigned char*)&m.addr.data); + len = parse_hex(hexa, (unsigned char*)&m.addr.data, sizeof (m.addr.data)); if (len >= 0) { struct ma_info *ma = malloc(sizeof(m));