From 63fcbf9a0a0ea575f075e3e0b20a4bfc0c8bbfbf Mon Sep 17 00:00:00 2001 From: Jiri Popelka Date: Aug 26 2013 10:20:12 +0000 Subject: don't crash on aliased infiniband interface (#996518) --- diff --git a/dhcp-4.2.2-gpxe-cid.patch b/dhcp-4.2.2-gpxe-cid.patch index fd73b2c..fd6cb24 100644 --- a/dhcp-4.2.2-gpxe-cid.patch +++ b/dhcp-4.2.2-gpxe-cid.patch @@ -70,14 +70,3 @@ diff -up dhcp-4.2.2/client/dhclient.c.gpxe-cid dhcp-4.2.2/client/dhclient.c } /* Individual States: -diff -up dhcp-4.2.2/common/lpf.c.gpxe-cid dhcp-4.2.2/common/lpf.c ---- dhcp-4.2.2/common/lpf.c.gpxe-cid 2011-09-16 18:23:20.183453996 +0200 -+++ dhcp-4.2.2/common/lpf.c 2011-09-16 18:25:28.235804421 +0200 -@@ -698,6 +698,7 @@ get_hw_addr(struct interface_info *info) - - hw->hlen = 1; - hw->hbuf[0] = HTYPE_INFINIBAND; -+ memcpy(&hw->hbuf[1], &sll->sll_addr[sll->sll_halen - 8], 8); - break; - #if defined(ARPHRD_PPP) - case ARPHRD_PPP: diff --git a/dhcp-4.2.5-lpf-ib.patch b/dhcp-4.2.5-lpf-ib.patch index c885331..58b924a 100644 --- a/dhcp-4.2.5-lpf-ib.patch +++ b/dhcp-4.2.5-lpf-ib.patch @@ -1,6 +1,6 @@ -diff -up dhcp-4.2.4-P2/client/dhclient.c.lpf-ib dhcp-4.2.4-P2/client/dhclient.c ---- dhcp-4.2.4-P2/client/dhclient.c.lpf-ib 2012-11-30 14:05:07.399394154 +0100 -+++ dhcp-4.2.4-P2/client/dhclient.c 2012-11-30 14:05:07.406394070 +0100 +diff -up dhcp-4.2.5/client/dhclient.c.lpf-ib dhcp-4.2.5/client/dhclient.c +--- dhcp-4.2.5/client/dhclient.c.lpf-ib 2013-08-26 12:13:31.509170257 +0200 ++++ dhcp-4.2.5/client/dhclient.c 2013-08-26 12:13:31.515170176 +0200 @@ -113,6 +113,8 @@ static int check_domain_name_list(const static int check_option_values(struct universe *universe, unsigned int opt, const char *ptr, size_t len); @@ -55,9 +55,9 @@ diff -up dhcp-4.2.4-P2/client/dhclient.c.lpf-ib dhcp-4.2.4-P2/client/dhclient.c /* Individual States: * * Each routine is called from the dhclient_state_machine() in one of -diff -up dhcp-4.2.4-P2/common/bpf.c.lpf-ib dhcp-4.2.4-P2/common/bpf.c ---- dhcp-4.2.4-P2/common/bpf.c.lpf-ib 2012-11-30 14:05:07.394394214 +0100 -+++ dhcp-4.2.4-P2/common/bpf.c 2012-11-30 14:05:07.407394058 +0100 +diff -up dhcp-4.2.5/common/bpf.c.lpf-ib dhcp-4.2.5/common/bpf.c +--- dhcp-4.2.5/common/bpf.c.lpf-ib 2013-08-26 12:13:31.503170337 +0200 ++++ dhcp-4.2.5/common/bpf.c 2013-08-26 12:13:31.515170176 +0200 @@ -198,11 +198,44 @@ struct bpf_insn dhcp_bpf_filter [] = { BPF_STMT(BPF_RET+BPF_K, 0), }; @@ -103,10 +103,10 @@ diff -up dhcp-4.2.4-P2/common/bpf.c.lpf-ib dhcp-4.2.4-P2/common/bpf.c #if defined (HAVE_TR_SUPPORT) struct bpf_insn dhcp_bpf_tr_filter [] = { /* accept all token ring packets due to variable length header */ -diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c ---- dhcp-4.2.4-P2/common/lpf.c.lpf-ib 2012-11-30 14:05:07.394394214 +0100 -+++ dhcp-4.2.4-P2/common/lpf.c 2012-11-30 14:19:27.211031532 +0100 -@@ -42,6 +42,7 @@ +diff -up dhcp-4.2.5/common/lpf.c.lpf-ib dhcp-4.2.5/common/lpf.c +--- dhcp-4.2.5/common/lpf.c.lpf-ib 2013-08-26 12:13:31.503170337 +0200 ++++ dhcp-4.2.5/common/lpf.c 2013-08-26 12:14:00.196783751 +0200 +@@ -43,6 +43,7 @@ #include "includes/netinet/udp.h" #include "includes/netinet/if_ether.h" #include @@ -114,7 +114,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c #ifndef PACKET_AUXDATA #define PACKET_AUXDATA 8 -@@ -59,6 +60,15 @@ struct tpacket_auxdata +@@ -60,6 +61,15 @@ struct tpacket_auxdata /* Reinitializes the specified interface after an address change. This is not required for packet-filter APIs. */ @@ -130,7 +130,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c #ifdef USE_LPF_SEND void if_reinitialize_send (info) struct interface_info *info; -@@ -86,10 +96,21 @@ int if_register_lpf (info) +@@ -87,10 +97,21 @@ int if_register_lpf (info) struct sockaddr common; } sa; struct ifreq ifr; @@ -154,7 +154,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || errno == EAFNOSUPPORT || errno == EINVAL) { -@@ -112,6 +133,7 @@ int if_register_lpf (info) +@@ -113,6 +134,7 @@ int if_register_lpf (info) /* Bind to the interface name */ memset (&sa, 0, sizeof sa); sa.ll.sll_family = AF_PACKET; @@ -162,7 +162,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c sa.ll.sll_ifindex = ifr.ifr_ifindex; if (bind (sock, &sa.common, sizeof sa)) { if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || -@@ -127,8 +149,6 @@ int if_register_lpf (info) +@@ -128,8 +150,6 @@ int if_register_lpf (info) log_fatal ("Bind socket to interface: %m"); } @@ -171,7 +171,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c return sock; } #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */ -@@ -183,6 +203,8 @@ void if_deregister_send (info) +@@ -184,6 +204,8 @@ void if_deregister_send (info) in bpf includes... */ extern struct sock_filter dhcp_bpf_filter []; extern int dhcp_bpf_filter_len; @@ -180,7 +180,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c #if defined (HAVE_TR_SUPPORT) extern struct sock_filter dhcp_bpf_tr_filter []; -@@ -200,11 +222,13 @@ void if_register_receive (info) +@@ -201,11 +223,13 @@ void if_register_receive (info) /* Open a LPF device and hang it on this interface... */ info -> rfdesc = if_register_lpf (info); @@ -199,7 +199,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c } #if defined (HAVE_TR_SUPPORT) -@@ -250,15 +274,28 @@ static void lpf_gen_filter_setup (info) +@@ -251,15 +275,28 @@ static void lpf_gen_filter_setup (info) memset(&p, 0, sizeof(p)); @@ -237,7 +237,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p, sizeof p) < 0) { -@@ -315,6 +352,54 @@ static void lpf_tr_filter_setup (info) +@@ -316,6 +353,54 @@ static void lpf_tr_filter_setup (info) #endif /* USE_LPF_RECEIVE */ #ifdef USE_LPF_SEND @@ -292,7 +292,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c ssize_t send_packet (interface, packet, raw, len, from, to, hto) struct interface_info *interface; struct packet *packet; -@@ -335,6 +420,11 @@ ssize_t send_packet (interface, packet, +@@ -336,6 +421,11 @@ ssize_t send_packet (interface, packet, return send_fallback (interface, packet, raw, len, from, to, hto); @@ -304,7 +304,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c if (hto == NULL && interface->anycast_mac_addr.hlen) hto = &interface->anycast_mac_addr; -@@ -356,6 +446,42 @@ ssize_t send_packet (interface, packet, +@@ -357,6 +447,42 @@ ssize_t send_packet (interface, packet, #endif /* USE_LPF_SEND */ #ifdef USE_LPF_RECEIVE @@ -347,7 +347,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c ssize_t receive_packet (interface, buf, len, from, hfrom) struct interface_info *interface; unsigned char *buf; -@@ -382,6 +508,10 @@ ssize_t receive_packet (interface, buf, +@@ -383,6 +509,10 @@ ssize_t receive_packet (interface, buf, }; struct cmsghdr *cmsg; @@ -358,7 +358,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c length = recvmsg (interface -> rfdesc, &msg, 0); if (length <= 0) return length; -@@ -461,11 +591,32 @@ void maybe_setup_fallback () +@@ -462,11 +592,33 @@ void maybe_setup_fallback () } } @@ -380,6 +380,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c + if (strcmp((*ifa)->ifa_name, name) == 0) + return (struct sockaddr_ll *)(void *)(*ifa)->ifa_addr; + } ++ *ifa = NULL; + return NULL; +} + @@ -394,7 +395,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c if (strlen(name) >= sizeof(tmp.ifr_name)) { log_fatal("Device name too long: \"%s\"", name); -@@ -479,16 +630,52 @@ get_hw_addr(const char *name, struct har +@@ -480,16 +632,62 @@ get_hw_addr(const char *name, struct har memset(&tmp, 0, sizeof(tmp)); strcpy(tmp.ifr_name, name); if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) { @@ -412,6 +413,14 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c + log_fatal("Unable to allocate memory for link layer address"); + memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype)); + memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr)); ++ switch (sll->sll_hatype) { ++ case ARPHRD_INFINIBAND: ++ /* ioctl limits hardware addresses to 8 bytes */ ++ sll->sll_halen = 8; ++ break; ++ default: ++ break; ++ } + return sll; +} + @@ -424,6 +433,8 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c + struct ifaddrs *ifa = NULL; + struct sockaddr_ll *sll = NULL; + int sll_allocated = 0; ++ char *dup = NULL; ++ char *colon = NULL; + + if (getifaddrs(&ifaddrs) == -1) + log_fatal("Failed to get interfaces"); @@ -437,7 +448,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c + if (sll != NULL) + sll_allocated = 1; + else -+ // shouldn't happed ++ // shouldn't happen + log_fatal("Unexpected internal error"); + } + @@ -450,7 +461,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c break; case ARPHRD_IEEE802: #ifdef ARPHRD_IEEE802_TR -@@ -496,18 +683,35 @@ get_hw_addr(const char *name, struct har +@@ -497,18 +695,48 @@ get_hw_addr(const char *name, struct har #endif /* ARPHRD_IEEE802_TR */ hw->hlen = 7; hw->hbuf[0] = HTYPE_IEEE802; @@ -464,10 +475,22 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c + memcpy(&hw->hbuf[1], sll->sll_addr, 6); + break; + case ARPHRD_INFINIBAND: ++ dup = strdup(name); ++ /* Aliased infiniband interface is special case where ++ * neither get_ll() nor ioctl_get_ll() get's correct hw ++ * address, so we have to truncate the :0 and run ++ * get_ll() again for the rest. ++ */ ++ if ((colon = strchr(dup, ':')) != NULL) { ++ *colon = '\0'; ++ if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL) ++ log_fatal("Error getting hardware address for \"%s\": %m", name); ++ } ++ free (dup); + /* For Infiniband, save the broadcast address and store + * the port GUID into the hardware address. + */ -+ if (ifa->ifa_flags & IFF_BROADCAST) { ++ if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) { + struct sockaddr_ll *bll; + + bll = (struct sockaddr_ll *)ifa->ifa_broadaddr; @@ -479,6 +502,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c + + hw->hlen = 1; + hw->hbuf[0] = HTYPE_INFINIBAND; ++ memcpy(&hw->hbuf[1], &sll->sll_addr[sll->sll_halen - 8], 8); break; #if defined(ARPHRD_PPP) case ARPHRD_PPP: @@ -490,7 +514,7 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c hw->hlen = 0; hw->hbuf[0] = HTYPE_RESERVED; /* 0xdeadbeef should never occur on the wire, -@@ -520,10 +724,13 @@ get_hw_addr(const char *name, struct har +@@ -521,10 +749,13 @@ get_hw_addr(const char *name, struct har break; #endif default: @@ -507,9 +531,9 @@ diff -up dhcp-4.2.4-P2/common/lpf.c.lpf-ib dhcp-4.2.4-P2/common/lpf.c + freeifaddrs(ifaddrs); } #endif -diff -up dhcp-4.2.4-P2/common/socket.c.lpf-ib dhcp-4.2.4-P2/common/socket.c ---- dhcp-4.2.4-P2/common/socket.c.lpf-ib 2012-08-24 21:11:21.000000000 +0200 -+++ dhcp-4.2.4-P2/common/socket.c 2012-11-30 14:05:07.408394046 +0100 +diff -up dhcp-4.2.5/common/socket.c.lpf-ib dhcp-4.2.5/common/socket.c +--- dhcp-4.2.5/common/socket.c.lpf-ib 2013-01-03 01:02:24.000000000 +0100 ++++ dhcp-4.2.5/common/socket.c 2013-08-26 12:13:31.516170162 +0200 @@ -325,7 +325,7 @@ void if_register_send (info) info->wfdesc = if_register_socket(info, AF_INET, 0); /* If this is a normal IPv4 address, get the hardware address. */ @@ -537,9 +561,9 @@ diff -up dhcp-4.2.4-P2/common/socket.c.lpf-ib dhcp-4.2.4-P2/common/socket.c if (!quiet_interface_discovery) { if (info->shared_network != NULL) { -diff -up dhcp-4.2.4-P2/includes/dhcpd.h.lpf-ib dhcp-4.2.4-P2/includes/dhcpd.h ---- dhcp-4.2.4-P2/includes/dhcpd.h.lpf-ib 2012-11-30 14:05:07.400394142 +0100 -+++ dhcp-4.2.4-P2/includes/dhcpd.h 2012-11-30 14:05:07.409394034 +0100 +diff -up dhcp-4.2.5/includes/dhcpd.h.lpf-ib dhcp-4.2.5/includes/dhcpd.h +--- dhcp-4.2.5/includes/dhcpd.h.lpf-ib 2013-08-26 12:13:31.510170243 +0200 ++++ dhcp-4.2.5/includes/dhcpd.h 2013-08-26 12:13:31.517170149 +0200 @@ -1249,6 +1249,7 @@ struct interface_info { struct shared_network *shared_network; /* Networks connected to this interface. */ @@ -548,7 +572,7 @@ diff -up dhcp-4.2.4-P2/includes/dhcpd.h.lpf-ib dhcp-4.2.4-P2/includes/dhcpd.h struct in_addr *addresses; /* Addresses associated with this * interface. */ -@@ -2368,7 +2369,7 @@ void print_dns_status (int, struct dhcp_ +@@ -2372,7 +2373,7 @@ void print_dns_status (int, struct dhcp_ #endif const char *print_time(TIME); diff --git a/dhcp.spec b/dhcp.spec index 191743c..82b1439 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -18,7 +18,7 @@ Summary: Dynamic host configuration protocol software Name: dhcp Version: 4.2.5 -Release: 18%{?dist} +Release: 19%{?dist} # NEVER CHANGE THE EPOCH on this package. The previous maintainer (prior to # dcantrell maintaining the package) made incorrect use of the epoch and # that's why it is at 12 now. It should have never been used, but it was. @@ -610,6 +610,9 @@ done %changelog +* Mon Aug 26 2013 Jiri Popelka - 12:4.2.5-19 +- don't crash on aliased infiniband interface (#996518) + * Sun Aug 04 2013 Jiri Popelka - 12:4.2.5-18 - BuildRequires: systemd due to %%{_unitdir}