From 738a00b0af7510b8323ba4f510069f8aefd449624607f31f3ef02733a0ffa7dc Mon Sep 17 00:00:00 2001 From: Marcus Schaefer Date: Fri, 4 Jun 2010 07:28:33 +0000 Subject: [PATCH 1/2] - fixed arping buffer overflow on Infiniband (bnc #610839) OBS-URL: https://build.opensuse.org/package/show/network:utilities/iputils?expand=0&rev=7 --- iputils-ss021109-arping-infiniband.diff | 209 ++++++++++++++++++++++++ iputils.changes | 5 + iputils.spec | 3 + 3 files changed, 217 insertions(+) create mode 100644 iputils-ss021109-arping-infiniband.diff diff --git a/iputils-ss021109-arping-infiniband.diff b/iputils-ss021109-arping-infiniband.diff new file mode 100644 index 0000000..14094e9 --- /dev/null +++ b/iputils-ss021109-arping-infiniband.diff @@ -0,0 +1,209 @@ +--- arping.c 2010-05-31 17:21:39.000000000 +0530 ++++ arping.c 2010-05-31 17:33:04.000000000 +0530 +@@ -32,6 +32,8 @@ + #include + #include + ++#include ++ + #include "SNAPSHOT.h" + + static void usage(void) __attribute__((noreturn)); +@@ -50,8 +52,8 @@ + int s; + int broadcast_only; + +-struct sockaddr_ll me; +-struct sockaddr_ll he; ++struct sockaddr_storage me; ++struct sockaddr_storage he; + + struct timeval start, last; + +@@ -61,6 +63,18 @@ + #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ + ((tv1).tv_usec-(tv2).tv_usec)/1000 ) + ++#define OFFSET_OF(name,ele) ((size_t)(((name *)0)->ele)) ++ ++static inline socklen_t sll_len(size_t halen) ++{ ++ socklen_t len = OFFSET_OF(struct sockaddr_ll, sll_addr) + halen; ++ if (len < sizeof(struct sockaddr_ll)) ++ len = sizeof(struct sockaddr_ll); ++ return len; ++} ++ ++#define SLL_LEN(hln) sll_len(hln) ++ + void usage(void) + { + fprintf(stderr, +@@ -124,7 +138,7 @@ + p+=4; + + gettimeofday(&now, NULL); +- err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, sizeof(*HE)); ++ err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, SLL_LEN(ah->ar_hln)); + if (err == p-buf) { + last = now; + sent++; +@@ -172,7 +186,8 @@ + finish(); + + if (last.tv_sec==0 || MS_TDIFF(tv,last) > 500) { +- send_pack(s, src, dst, &me, &he); ++ send_pack(s, src, dst, ++ (struct sockaddr_ll *)&me, (struct sockaddr_ll *)&he); + if (count == 0 && unsolicited) + finish(); + } +@@ -219,7 +234,7 @@ + return 0; + if (ah->ar_pln != 4) + return 0; +- if (ah->ar_hln != me.sll_halen) ++ if (ah->ar_hln != ((struct sockaddr_ll *)&me)->sll_halen) + return 0; + if (len < sizeof(*ah) + 2*(4 + ah->ar_hln)) + return 0; +@@ -230,7 +245,7 @@ + return 0; + if (src.s_addr != dst_ip.s_addr) + return 0; +- if (memcmp(p+ah->ar_hln+4, &me.sll_addr, ah->ar_hln)) ++ if (memcmp(p+ah->ar_hln+4, ((struct sockaddr_ll *)&me)->sll_addr, ah->ar_hln)) + return 0; + } else { + /* DAD packet was: +@@ -248,7 +263,7 @@ + */ + if (src_ip.s_addr != dst.s_addr) + return 0; +- if (memcmp(p, &me.sll_addr, me.sll_halen) == 0) ++ if (memcmp(p, ((struct sockaddr_ll *)&me)->sll_addr, ((struct sockaddr_ll *)&me)->sll_halen) == 0) + return 0; + if (src.s_addr && src.s_addr != dst_ip.s_addr) + return 0; +@@ -264,7 +279,7 @@ + printf("for %s ", inet_ntoa(dst_ip)); + s_printed = 1; + } +- if (memcmp(p+ah->ar_hln+4, me.sll_addr, ah->ar_hln)) { ++ if (memcmp(p+ah->ar_hln+4, ((struct sockaddr_ll *)&me)->sll_addr, ah->ar_hln)) { + if (!s_printed) + printf("for "); + printf("["); +@@ -290,12 +305,42 @@ + if (quit_on_reply) + finish(); + if(!broadcast_only) { +- memcpy(he.sll_addr, p, me.sll_halen); ++ memcpy(((struct sockaddr_ll *)&he)->sll_addr, p, ((struct sockaddr_ll *)&me)->sll_halen); + unicasting=1; + } + return 1; + } + ++void set_device_broadcast(char *device, unsigned char *ba, size_t balen) ++{ ++ struct sysfs_class_device *dev; ++ struct sysfs_attribute *brdcast; ++ unsigned char *p; ++ int ch; ++ ++ dev = sysfs_open_class_device("net", device); ++ if (!dev) { ++ perror("sysfs_open_class_device(net)"); ++ exit(2); ++ } ++ ++ brdcast = sysfs_get_classdev_attr(dev, "broadcast"); ++ if (!brdcast) { ++ perror("sysfs_get_classdev_attr(broadcast)"); ++ exit(2); ++ } ++ ++ if (sysfs_read_attribute(brdcast)) { ++ perror("sysfs_read_attribute"); ++ exit(2); ++ } ++ ++ for (p = ba, ch = 0; p < ba + balen; p++, ch += 3) ++ *p++ = strtoul(brdcast->value + ch * 3, NULL, 16); ++ ++ return; ++} ++ + int + main(int argc, char **argv) + { +@@ -456,9 +501,9 @@ + close(probe_fd); + }; + +- me.sll_family = AF_PACKET; +- me.sll_ifindex = ifindex; +- me.sll_protocol = htons(ETH_P_ARP); ++ ((struct sockaddr_ll *)&me)->sll_family = AF_PACKET; ++ ((struct sockaddr_ll *)&me)->sll_ifindex = ifindex; ++ ((struct sockaddr_ll *)&me)->sll_protocol = htons(ETH_P_ARP); + if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { + perror("bind"); + exit(2); +@@ -471,14 +516,20 @@ + exit(2); + } + } +- if (me.sll_halen == 0) { ++ if (((struct sockaddr_ll *)&me)->sll_halen == 0) { + if (!quiet) + printf("Interface \"%s\" is not ARPable (no ll address)\n", device); + exit(dad?0:2); + } + + he = me; +- memset(he.sll_addr, -1, he.sll_halen); ++ ++#if 1 ++ set_device_broadcast(device, ((struct sockaddr_ll *)&he)->sll_addr, ++ ((struct sockaddr_ll *)&he)->sll_halen); ++#else ++ memset(((struct sockaddr_ll *)&he)->sll_addr, -1, ((struct sockaddr_ll *)&he)->sll_halen); ++#endif + + if (!quiet) { + printf("ARPING %s ", inet_ntoa(dst)); +@@ -498,7 +549,7 @@ + while(1) { + sigset_t sset, osset; + char packet[4096]; +- struct sockaddr_ll from; ++ struct sockaddr_storage from; + int alen = sizeof(from); + int cc; + +@@ -507,11 +558,12 @@ + perror("arping: recvfrom"); + continue; + } ++ + sigemptyset(&sset); + sigaddset(&sset, SIGALRM); + sigaddset(&sset, SIGINT); + sigprocmask(SIG_BLOCK, &sset, &osset); +- recv_pack(packet, cc, &from); ++ recv_pack(packet, cc, (struct sockaddr_ll *)&from); + sigprocmask(SIG_SETMASK, &osset, NULL); + } + } +--- Makefile 2010-05-31 17:21:39.000000000 +0530 ++++ Makefile 2010-05-31 17:23:05.000000000 +0530 +@@ -41,6 +41,7 @@ + + + tftpd: tftpd.o tftpsubs.o ++arping: arping.o -lsysfs + ping: ping.o ping_common.o + ping6: ping6.o ping_common.o + ping.o ping6.o ping_common.o: ping_common.h diff --git a/iputils.changes b/iputils.changes index b4952ee..790b71a 100644 --- a/iputils.changes +++ b/iputils.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Fri Jun 4 09:22:08 CEST 2010 - ms@suse.de + +- fixed arping buffer overflow on Infiniband (bnc #610839) + ------------------------------------------------------------------- Fri Apr 23 16:16:33 CEST 2010 - ms@suse.de diff --git a/iputils.spec b/iputils.spec index 705eb51..985eab7 100644 --- a/iputils.spec +++ b/iputils.spec @@ -19,6 +19,7 @@ Name: iputils +Buildrequires: sysfsutils Summary: IPv4and IPv6 Networking Utilities Version: ss021109 Release: 294 @@ -48,6 +49,7 @@ Patch15: %name-%version-ping_common.dif Patch16: %name-ss021109-traceroute6-ttab.diff Patch17: %name-%version-open_max.diff Patch18: %name-%version-ping-interrupt.diff +Patch19: %name-%version-arping-infiniband.diff Prefix: %_prefix BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -82,6 +84,7 @@ Authors: %patch16 %patch17 -p1 %patch18 +%patch19 mkdir linux touch linux/autoconf.h From 9f2c3547e5f7d166a0acfa064e547f5c87ac9e845d77cb41301498cff9cccf95 Mon Sep 17 00:00:00 2001 From: OBS User autobuild Date: Fri, 4 Jun 2010 13:02:56 +0000 Subject: [PATCH 2/2] Accepting request 41079 from network:utilities checked in (request 41079) OBS-URL: https://build.opensuse.org/request/show/41079 OBS-URL: https://build.opensuse.org/package/show/network:utilities/iputils?expand=0&rev=8 --- iputils.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iputils.spec b/iputils.spec index 985eab7..9930f03 100644 --- a/iputils.spec +++ b/iputils.spec @@ -19,10 +19,10 @@ Name: iputils -Buildrequires: sysfsutils +BuildRequires: sysfsutils Summary: IPv4and IPv6 Networking Utilities Version: ss021109 -Release: 294 +Release: 295 License: BSD3c ; GPLv2+ Group: Productivity/Networking/Other Provides: nkitb