From 7f71c0cae2db61890474e04ba3a26e40219e5561 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Tue, 25 Nov 2008 12:36:22 +0000 Subject: [PATCH] =?utf-8?q?ip=20maddr=20show=E2=80=9D=20on=20an=20infiniband=20address=20causes=20a=20stack=20corruption?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit “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. --- include/utils.h | 2 +- ip/ipmaddr.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git iproute-2.6.27/iproute2-2.6.27/include/utils.h iproute-2.6.27/iproute2-2.6.27/include/utils.h index 5daed6b..f7ef939 100644 --- iproute-2.6.27/iproute2-2.6.27/include/utils.h +++ iproute-2.6.27/iproute2-2.6.27/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 iproute-2.6.27/iproute2-2.6.27/ip/ipmaddr.c iproute-2.6.27/iproute2-2.6.27/ip/ipmaddr.c index 1014f83..44ffdfc 100644 --- iproute-2.6.27/iproute2-2.6.27/ip/ipmaddr.c +++ iproute-2.6.27/iproute2-2.6.27/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)); -- 1.6.0.6