diff -u isc-dhcp-4.1.ESV-R4/debian/changelog isc-dhcp-4.1.ESV-R4/debian/changelog --- isc-dhcp-4.1.ESV-R4/debian/changelog +++ isc-dhcp-4.1.ESV-R4/debian/changelog @@ -1,3 +1,19 @@ +isc-dhcp (4.1.ESV-R4-0ubuntu5.11) precise; urgency=medium + + * Don't assume IPv6 prefix length of 64 (LP: #1609898). + Pulled from debian commit c347ab8a43587164486ce1f104eedfd638594e59. + + -- Dan Streetman Thu, 04 Aug 2016 13:07:23 -0400 + +isc-dhcp (4.1.ESV-R4-0ubuntu5.10) precise-security; urgency=medium + + * SECURITY UPDATE: denial of service via incorrect UDP payload length + - debian/patches/CVE-2015-8605.dpatch: properly check payload length in + common/packet.c. + - CVE-2015-8605 + + -- Marc Deslauriers Mon, 11 Jan 2016 07:59:30 -0500 + isc-dhcp (4.1.ESV-R4-0ubuntu5.9) precise-proposed; urgency=low * debian/dhclient-script.linux: Allow stateless DHCPv6 to complete diff -u isc-dhcp-4.1.ESV-R4/debian/dhclient-script.linux isc-dhcp-4.1.ESV-R4/debian/dhclient-script.linux --- isc-dhcp-4.1.ESV-R4/debian/dhclient-script.linux +++ isc-dhcp-4.1.ESV-R4/debian/dhclient-script.linux @@ -360,9 +360,9 @@ ;; BOUND6|RENEW6|REBIND6) - if [ "${new_ip6_address}" ] && [ "${new_ip6_prefixlen}" ]; then + if [ "${new_ip6_address}" ]; then # set leased IP - ip -6 addr add ${new_ip6_address}/${new_ip6_prefixlen} \ + ip -6 addr add ${new_ip6_address} \ dev ${interface} scope global fi @@ -376,23 +376,19 @@ ;; DEPREF6) - if [ -z "${cur_ip6_prefixlen}" ]; then - exit_with_hooks 2 - fi - # set preferred lifetime of leased IP to 0 - ip -6 addr change ${cur_ip6_address}/${cur_ip6_prefixlen} \ + ip -6 addr change ${cur_ip6_address} \ dev ${interface} scope global preferred_lft 0 ;; EXPIRE6|RELEASE6|STOP6) - if [ -z "${old_ip6_address}" ] || [ -z "${old_ip6_prefixlen}" ]; then + if [ -z "${old_ip6_address}" ]; then exit_with_hooks 2 fi # delete leased IP - ip -6 addr del ${old_ip6_address}/${old_ip6_prefixlen} \ + ip -6 addr del ${old_ip6_address} \ dev ${interface} ;; diff -u isc-dhcp-4.1.ESV-R4/debian/patches/00list isc-dhcp-4.1.ESV-R4/debian/patches/00list --- isc-dhcp-4.1.ESV-R4/debian/patches/00list +++ isc-dhcp-4.1.ESV-R4/debian/patches/00list @@ -30,6 +30,7 @@ # LP: #930962 udp_checksum_offloading +CVE-2015-8605 #ldap backend for dhcp server (docs and code) #these get reverted during the build, so put non-ldap #patches earlier only in patch2: unchanged: --- isc-dhcp-4.1.ESV-R4.orig/debian/patches/CVE-2015-8605.dpatch +++ isc-dhcp-4.1.ESV-R4/debian/patches/CVE-2015-8605.dpatch @@ -0,0 +1,146 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +# Description: fix denial of service via incorrect UDP payload length +# Origin: backport of patch provided by upstream + +@DPATCH@ +diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' isc-dhcp-4.1.ESV-R4~/common/packet.c isc-dhcp-4.1.ESV-R4/common/packet.c +--- isc-dhcp-4.1.ESV-R4~/common/packet.c 2016-01-11 07:57:39.000000000 -0500 ++++ isc-dhcp-4.1.ESV-R4/common/packet.c 2016-01-11 07:57:51.120726041 -0500 +@@ -205,7 +205,28 @@ + return decode_ethernet_header (interface, buf, bufix, from); + } + +-/* UDP header and IP header decoded together for convenience. */ ++/*! ++ * ++ * \brief UDP header and IP header decoded together for convenience. ++ * ++ * Attempt to decode the UDP and IP headers and, if necessary, checksum ++ * the packet. ++ * ++ * \param inteface - the interface on which the packet was recevied ++ * \param buf - a pointer to the buffer for the received packet ++ * \param bufix - where to start processing the buffer, previous ++ * routines may have processed parts of the buffer already ++ * \param from - space to return the address of the packet sender ++ * \param buflen - remaining length of the buffer, this will have been ++ * decremented by bufix by the caller ++ * \param rbuflen - space to return the length of the payload from the udp ++ * header ++ * \param csum_ready - indication if the checksum is valid for use ++ * non-zero indicates the checksum should be validated ++ * ++ * \return - the index to the first byte of the udp payload (that is the ++ * start of the DHCP packet ++ */ + + ssize_t + decode_udp_ip_header(struct interface_info *interface, +@@ -216,22 +237,19 @@ + unsigned char *data; + struct ip ip; + struct udphdr udp; +- unsigned char *upp, *endbuf; ++ unsigned char *upp; + u_int32_t ip_len, ulen, pkt_len; + u_int32_t sum, usum; +- static int ip_packets_seen; +- static int ip_packets_bad_checksum; +- static int udp_packets_seen; +- static int udp_packets_bad_checksum; +- static int udp_packets_length_checked; +- static int udp_packets_length_overflow; ++ static unsigned int ip_packets_seen = 0; ++ static unsigned int ip_packets_bad_checksum = 0; ++ static unsigned int udp_packets_seen = 0; ++ static unsigned int udp_packets_bad_checksum = 0; ++ static unsigned int udp_packets_length_checked = 0; ++ static unsigned int udp_packets_length_overflow = 0; + unsigned len; + +- /* Designate the end of the input buffer for bounds checks. */ +- endbuf = buf + bufix + buflen; +- + /* Assure there is at least an IP header there. */ +- if ((buf + bufix + sizeof(ip)) > endbuf) ++ if (sizeof(ip) > buflen) + return -1; + + /* Copy the IP header into a stack aligned structure for inspection. +@@ -243,13 +261,17 @@ + ip_len = (*upp & 0x0f) << 2; + upp += ip_len; + +- /* Check the IP packet length. */ ++ /* Check packet lengths are within the buffer: ++ * first the ip header (ip_len) ++ * then the packet length from the ip header (pkt_len) ++ * then the udp header (ip_len + sizeof(udp) ++ * We are liberal in what we accept, the udp payload should fit within ++ * pkt_len, but we only check against the full buffer size. ++ */ + pkt_len = ntohs(ip.ip_len); +- if (pkt_len > buflen) +- return -1; +- +- /* Assure after ip_len bytes that there is enough room for a UDP header. */ +- if ((upp + sizeof(udp)) > endbuf) ++ if ((ip_len > buflen) || ++ (pkt_len > buflen) || ++ ((ip_len + sizeof(udp)) > buflen)) + return -1; + + /* Copy the UDP header into a stack aligned structure for inspection. */ +@@ -270,12 +292,13 @@ + return -1; + + udp_packets_length_checked++; +- if ((upp + ulen) > endbuf) { ++ /* verify that the payload length from the udp packet fits in the buffer */ ++ if ((ip_len + ulen) > buflen) { + udp_packets_length_overflow++; +- if ((udp_packets_length_checked > 4) && +- ((udp_packets_length_checked / +- udp_packets_length_overflow) < 2)) { +- log_info("%d udp packets in %d too long - dropped", ++ if (((udp_packets_length_checked > 4) && ++ (udp_packets_length_overflow != 0)) && ++ ((udp_packets_length_checked / udp_packets_length_overflow) < 2)) { ++ log_info("%u udp packets in %u too long - dropped", + udp_packets_length_overflow, + udp_packets_length_checked); + udp_packets_length_overflow = 0; +@@ -284,16 +307,13 @@ + return -1; + } + +- if ((ulen < sizeof(udp)) || ((upp + ulen) > endbuf)) +- return -1; +- + /* Check the IP header checksum - it should be zero. */ +- ++ip_packets_seen; ++ ip_packets_seen++; + if (wrapsum (checksum (buf + bufix, ip_len, 0))) { + ++ip_packets_bad_checksum; +- if (ip_packets_seen > 4 && +- (ip_packets_seen / ip_packets_bad_checksum) < 2) { +- log_info ("%d bad IP checksums seen in %d packets", ++ if (((ip_packets_seen > 4) && (ip_packets_bad_checksum != 0)) && ++ ((ip_packets_seen / ip_packets_bad_checksum) < 2)) { ++ log_info ("%u bad IP checksums seen in %u packets", + ip_packets_bad_checksum, ip_packets_seen); + ip_packets_seen = ip_packets_bad_checksum = 0; + } +@@ -329,9 +349,9 @@ + udp_packets_seen++; + if (!nocsum && usum && usum != sum) { + udp_packets_bad_checksum++; +- if (udp_packets_seen > 4 && +- (udp_packets_seen / udp_packets_bad_checksum) < 2) { +- log_info ("%d bad udp checksums in %d packets", ++ if (((udp_packets_seen > 4) && (udp_packets_bad_checksum != 0)) ++ && ((udp_packets_seen / udp_packets_bad_checksum) < 2)) { ++ log_info ("%u bad udp checksums in %u packets", + udp_packets_bad_checksum, udp_packets_seen); + udp_packets_seen = udp_packets_bad_checksum = 0; + }