From 7b41fdb208680962bc9569c5aa4c14b8ecfde279 Mon Sep 17 00:00:00 2001 From: Jiri Popelka Date: Mon, 13 Dec 2010 11:36:02 +0100 Subject: [PATCH] 4.2.0-P2: fix for CVE-2010-3616 (#662326) - Use upstream fix for #628258 - Provide versioned symbols for rpmlint --- .gitignore | 2 +- 11-dhclient | 0 12-dhcpd | 0 56dhclient | 0 dhclient-script | 0 dhcp-4.2.0-64_bit_lease_parse.patch | 151 ------------ dhcp-4.2.0-P1-64_bit_lease_parse.patch | 215 ++++++++++++++++++ ....2.0-rfc3442-classless-static-routes.patch | 2 +- dhcp.spec | 45 ++-- sources | 2 +- 10 files changed, 247 insertions(+), 170 deletions(-) mode change 100755 => 100644 11-dhclient mode change 100755 => 100644 12-dhcpd mode change 100755 => 100644 56dhclient mode change 100755 => 100644 dhclient-script delete mode 100644 dhcp-4.2.0-64_bit_lease_parse.patch create mode 100644 dhcp-4.2.0-P1-64_bit_lease_parse.patch diff --git a/.gitignore b/.gitignore index 904589f..75ca1bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/dhcp-4.2.0-P1.tar.gz +/dhcp-4.2.0-P2.tar.gz diff --git a/11-dhclient b/11-dhclient old mode 100755 new mode 100644 diff --git a/12-dhcpd b/12-dhcpd old mode 100755 new mode 100644 diff --git a/56dhclient b/56dhclient old mode 100755 new mode 100644 diff --git a/dhclient-script b/dhclient-script old mode 100755 new mode 100644 diff --git a/dhcp-4.2.0-64_bit_lease_parse.patch b/dhcp-4.2.0-64_bit_lease_parse.patch deleted file mode 100644 index 0f37a37..0000000 --- a/dhcp-4.2.0-64_bit_lease_parse.patch +++ /dev/null @@ -1,151 +0,0 @@ -diff -up dhcp-4.2.0/common/dispatch.c.64-bit_lease_parse dhcp-4.2.0/common/dispatch.c ---- dhcp-4.2.0/common/dispatch.c.64-bit_lease_parse 2010-09-02 18:21:00.000000000 +0200 -+++ dhcp-4.2.0/common/dispatch.c 2010-09-02 18:29:50.000000000 +0200 -@@ -185,7 +185,7 @@ void add_timeout (when, where, what, ref - struct timeout *t, *q; - int usereset = 0; - isc_result_t status; -- int sec, usec; -+ struct timeval relative_time; - isc_interval_t interval; - isc_time_t expires; - -@@ -297,24 +297,24 @@ void add_timeout (when, where, what, ref - * about the usec value, if it's zero we assume the caller didn't care. - */ - -- sec = when->tv_sec - cur_tv.tv_sec; -- usec = when->tv_usec - cur_tv.tv_usec; -+ relative_time.tv_sec = when->tv_sec - cur_tv.tv_sec; -+ relative_time.tv_usec = when->tv_usec - cur_tv.tv_usec; - -- if ((when->tv_usec != 0) && (usec < 0)) { -- sec--; -- usec += USEC_MAX; -+ if ((when->tv_usec != 0) && (relative_time.tv_usec < 0)) { -+ relative_time.tv_sec--; -+ relative_time.tv_usec += USEC_MAX; - } - -- if (sec < 0) { -- sec = 0; -- usec = 0; -- } else if (usec < 0) { -- usec = 0; -- } else if (usec >= USEC_MAX) { -- usec = USEC_MAX - 1; -+ if (relative_time.tv_sec < 0) { -+ relative_time.tv_sec = 0; -+ relative_time.tv_usec = 0; -+ } else if (relative_time.tv_usec < 0) { -+ relative_time.tv_usec = 0; -+ } else if (relative_time.tv_usec >= USEC_MAX) { -+ relative_time.tv_usec = USEC_MAX - 1; - } - -- isc_interval_set(&interval, sec, usec * 1000); -+ isc_interval_set(&interval, relative_time.tv_sec, relative_time.tv_usec * 1000); - status = isc_time_nowplusinterval(&expires, &interval); - if (status != ISC_R_SUCCESS) { - /* -diff -up dhcp-4.2.0/common/parse.c.64-bit_lease_parse dhcp-4.2.0/common/parse.c ---- dhcp-4.2.0/common/parse.c.64-bit_lease_parse 2009-10-28 05:12:29.000000000 +0100 -+++ dhcp-4.2.0/common/parse.c 2010-09-02 18:21:00.000000000 +0200 -@@ -905,8 +905,8 @@ TIME - parse_date_core(cfile) - struct parse *cfile; - { -- int guess; -- int tzoff, wday, year, mon, mday, hour, min, sec; -+ TIME guess; -+ long int tzoff, wday, year, mon, mday, hour, min, sec; - const char *val; - enum dhcp_token token; - static int months [11] = { 31, 59, 90, 120, 151, 181, -@@ -931,7 +931,7 @@ parse_date_core(cfile) - return (TIME)0; - } - -- guess = atoi(val); -+ guess = atol(val); - - if (!parse_semi(cfile)) - return (TIME)0; -@@ -945,7 +945,7 @@ parse_date_core(cfile) - skip_to_semi (cfile); - return (TIME)0; - } -- wday = atoi (val); -+ wday = atol (val); - - /* Year... */ - token = next_token (&val, (unsigned *)0, cfile); -@@ -960,7 +960,7 @@ parse_date_core(cfile) - somebody invents a time machine, I think we can safely disregard - it. This actually works around a stupid Y2K bug that was present - in a very early beta release of dhcpd. */ -- year = atoi (val); -+ year = atol (val); - if (year > 1900) - year -= 1900; - -@@ -982,7 +982,7 @@ parse_date_core(cfile) - skip_to_semi (cfile); - return (TIME)0; - } -- mon = atoi (val) - 1; -+ mon = atol (val) - 1; - - /* Slash separating month from day... */ - token = next_token (&val, (unsigned *)0, cfile); -@@ -1002,7 +1002,7 @@ parse_date_core(cfile) - skip_to_semi (cfile); - return (TIME)0; - } -- mday = atoi (val); -+ mday = atol (val); - - /* Hour... */ - token = next_token (&val, (unsigned *)0, cfile); -@@ -1012,7 +1012,7 @@ parse_date_core(cfile) - skip_to_semi (cfile); - return (TIME)0; - } -- hour = atoi (val); -+ hour = atol (val); - - /* Colon separating hour from minute... */ - token = next_token (&val, (unsigned *)0, cfile); -@@ -1032,7 +1032,7 @@ parse_date_core(cfile) - skip_to_semi (cfile); - return (TIME)0; - } -- min = atoi (val); -+ min = atol (val); - - /* Colon separating minute from second... */ - token = next_token (&val, (unsigned *)0, cfile); -@@ -1052,12 +1052,12 @@ parse_date_core(cfile) - skip_to_semi (cfile); - return (TIME)0; - } -- sec = atoi (val); -+ sec = atol (val); - - token = peek_token (&val, (unsigned *)0, cfile); - if (token == NUMBER) { - token = next_token (&val, (unsigned *)0, cfile); -- tzoff = atoi (val); -+ tzoff = atol (val); - } else - tzoff = 0; - -@@ -1090,7 +1090,7 @@ TIME - parse_date(cfile) - struct parse *cfile; - { -- int guess; -+ TIME guess; - guess = parse_date_core(cfile); - - /* Make sure the date ends in a semicolon... */ diff --git a/dhcp-4.2.0-P1-64_bit_lease_parse.patch b/dhcp-4.2.0-P1-64_bit_lease_parse.patch new file mode 100644 index 0000000..2f9ad3b --- /dev/null +++ b/dhcp-4.2.0-P1-64_bit_lease_parse.patch @@ -0,0 +1,215 @@ +diff -up dhcp-4.2.0-P1/common/dispatch.c.64-bit_lease_parse dhcp-4.2.0-P1/common/dispatch.c +--- dhcp-4.2.0-P1/common/dispatch.c.64-bit_lease_parse 2010-12-13 11:06:36.000000000 +0100 ++++ dhcp-4.2.0-P1/common/dispatch.c 2010-12-13 10:56:59.000000000 +0100 +@@ -174,6 +174,7 @@ isclib_timer_callback(isc_task_t *taskp + + /* maximum value for usec */ + #define USEC_MAX 1000000 ++#define DHCP_SEC_MAX 0xFFFFFFFF + + void add_timeout (when, where, what, ref, unref) + struct timeval *when; +@@ -185,7 +186,8 @@ void add_timeout (when, where, what, ref + struct timeout *t, *q; + int usereset = 0; + isc_result_t status; +- int sec, usec; ++ int64_t sec; ++ int usec; + isc_interval_t interval; + isc_time_t expires; + +@@ -231,9 +233,49 @@ void add_timeout (when, where, what, ref + q->what = what; + } + +- /* We don't really need this, but keep it for now */ +- q->when.tv_sec = when->tv_sec; +- q->when.tv_usec = when->tv_usec; ++ /* ++ * The value passed in is a time from an epoch but we need a relative ++ * time so we need to do some math to try and recover the period. ++ * This is complicated by the fact that not all of the calls cared ++ * about the usec value, if it's zero we assume the caller didn't care. ++ * ++ * The ISC timer library doesn't seem to like negative values ++ * and can't accept any values above 4G-1 seconds so we limit ++ * the values to 0 <= value < 4G-1. We do it before ++ * checking the trace option so that both the trace code and ++ * the working code use the same values. ++ */ ++ ++ sec = when->tv_sec - cur_tv.tv_sec; ++ usec = when->tv_usec - cur_tv.tv_usec; ++ ++ if ((when->tv_usec != 0) && (usec < 0)) { ++ sec--; ++ usec += USEC_MAX; ++ } ++ ++ if (sec < 0) { ++ sec = 0; ++ usec = 0; ++ } else if (sec > DHCP_SEC_MAX) { ++ log_error("Timeout requested too large %lld " ++ "reducing to 2^^32-1", sec); ++ sec = DHCP_SEC_MAX; ++ usec = 0; ++ } ++ else if (usec < 0) { ++ usec = 0; ++ } else if (usec >= USEC_MAX) { ++ usec = USEC_MAX - 1; ++ } ++ ++ /* ++ * This is necessary for the tracing code but we put it ++ * here in case we want to compare timing information ++ * for some reason, like debugging. ++ */ ++ q->when.tv_sec = cur_tv.tv_sec + (sec & DHCP_SEC_MAX); ++ q->when.tv_usec = usec; + + #if defined (TRACING) + if (trace_playback()) { +@@ -283,38 +325,7 @@ void add_timeout (when, where, what, ref + q->next = timeouts; + timeouts = q; + +- /* +- * Set up the interval values - The previous timers allowed +- * negative values to be set, the ISC timer library doesn't like +- * that so we make any negative values 0 which sould amount to +- * the same thing. +- */ +- +- /* +- * The value passed in is a time from an epoch but we need a relative +- * time so we need to do some math to try and recover the period. +- * This is complicated by the fact that not all of the calls cared +- * about the usec value, if it's zero we assume the caller didn't care. +- */ +- +- sec = when->tv_sec - cur_tv.tv_sec; +- usec = when->tv_usec - cur_tv.tv_usec; +- +- if ((when->tv_usec != 0) && (usec < 0)) { +- sec--; +- usec += USEC_MAX; +- } +- +- if (sec < 0) { +- sec = 0; +- usec = 0; +- } else if (usec < 0) { +- usec = 0; +- } else if (usec >= USEC_MAX) { +- usec = USEC_MAX - 1; +- } +- +- isc_interval_set(&interval, sec, usec * 1000); ++ isc_interval_set(&interval, sec & 0xFFFFFFFF, usec * 1000); + status = isc_time_nowplusinterval(&expires, &interval); + if (status != ISC_R_SUCCESS) { + /* +diff -up dhcp-4.2.0-P1/common/parse.c.64-bit_lease_parse dhcp-4.2.0-P1/common/parse.c +--- dhcp-4.2.0-P1/common/parse.c.64-bit_lease_parse 2009-10-28 05:12:29.000000000 +0100 ++++ dhcp-4.2.0-P1/common/parse.c 2010-12-13 11:06:36.000000000 +0100 +@@ -905,8 +905,8 @@ TIME + parse_date_core(cfile) + struct parse *cfile; + { +- int guess; +- int tzoff, wday, year, mon, mday, hour, min, sec; ++ TIME guess; ++ long int tzoff, wday, year, mon, mday, hour, min, sec; + const char *val; + enum dhcp_token token; + static int months [11] = { 31, 59, 90, 120, 151, 181, +@@ -931,7 +931,7 @@ parse_date_core(cfile) + return (TIME)0; + } + +- guess = atoi(val); ++ guess = atol(val); + + if (!parse_semi(cfile)) + return (TIME)0; +@@ -945,7 +945,7 @@ parse_date_core(cfile) + skip_to_semi (cfile); + return (TIME)0; + } +- wday = atoi (val); ++ wday = atol (val); + + /* Year... */ + token = next_token (&val, (unsigned *)0, cfile); +@@ -960,7 +960,7 @@ parse_date_core(cfile) + somebody invents a time machine, I think we can safely disregard + it. This actually works around a stupid Y2K bug that was present + in a very early beta release of dhcpd. */ +- year = atoi (val); ++ year = atol (val); + if (year > 1900) + year -= 1900; + +@@ -982,7 +982,7 @@ parse_date_core(cfile) + skip_to_semi (cfile); + return (TIME)0; + } +- mon = atoi (val) - 1; ++ mon = atol (val) - 1; + + /* Slash separating month from day... */ + token = next_token (&val, (unsigned *)0, cfile); +@@ -1002,7 +1002,7 @@ parse_date_core(cfile) + skip_to_semi (cfile); + return (TIME)0; + } +- mday = atoi (val); ++ mday = atol (val); + + /* Hour... */ + token = next_token (&val, (unsigned *)0, cfile); +@@ -1012,7 +1012,7 @@ parse_date_core(cfile) + skip_to_semi (cfile); + return (TIME)0; + } +- hour = atoi (val); ++ hour = atol (val); + + /* Colon separating hour from minute... */ + token = next_token (&val, (unsigned *)0, cfile); +@@ -1032,7 +1032,7 @@ parse_date_core(cfile) + skip_to_semi (cfile); + return (TIME)0; + } +- min = atoi (val); ++ min = atol (val); + + /* Colon separating minute from second... */ + token = next_token (&val, (unsigned *)0, cfile); +@@ -1052,12 +1052,12 @@ parse_date_core(cfile) + skip_to_semi (cfile); + return (TIME)0; + } +- sec = atoi (val); ++ sec = atol (val); + + token = peek_token (&val, (unsigned *)0, cfile); + if (token == NUMBER) { + token = next_token (&val, (unsigned *)0, cfile); +- tzoff = atoi (val); ++ tzoff = atol (val); + } else + tzoff = 0; + +@@ -1090,7 +1090,7 @@ TIME + parse_date(cfile) + struct parse *cfile; + { +- int guess; ++ TIME guess; + guess = parse_date_core(cfile); + + /* Make sure the date ends in a semicolon... */ diff --git a/dhcp-4.2.0-rfc3442-classless-static-routes.patch b/dhcp-4.2.0-rfc3442-classless-static-routes.patch index c98ddc2..440004d 100644 --- a/dhcp-4.2.0-rfc3442-classless-static-routes.patch +++ b/dhcp-4.2.0-rfc3442-classless-static-routes.patch @@ -70,7 +70,7 @@ diff -up dhcp-4.2.0/common/dhcp-options.5.rfc3442 dhcp-4.2.0/common/dhcp-options .PP .nf +.B option \fBclassless-static-routes\fR \fIdestination-descriptor ip-address\fR -+ [\fB,\fR \fIdestination-descriptor ip-address\fR...]\fB;\fR ++ [\fB,\fR \fIdestination-descriptor ip-address\fR...]\fB;\fR +.fi +.RS 0.25i +.PP diff --git a/dhcp.spec b/dhcp.spec index e686010..0cb4425 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -5,14 +5,14 @@ %global dhcpconfdir %{_sysconfdir}/dhcp # Patch version -%global patchver P1 +%global patchver P2 %global VERSION %{version}-%{patchver} Summary: Dynamic host configuration protocol software Name: dhcp Version: 4.2.0 -Release: 21.%{patchver}%{?dist} +Release: 22.%{patchver}%{?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. @@ -53,7 +53,7 @@ Patch15: dhcp-4.2.0-invalid-dhclient-conf.patch Patch16: dhcp-4.2.0-missing-ipv6-not-fatal.patch Patch17: dhcp-4.2.0-IFNAMSIZ.patch Patch18: dhcp-4.2.0-add_timeout_when_NULL.patch -Patch19: dhcp-4.2.0-64_bit_lease_parse.patch +Patch19: dhcp-4.2.0-P1-64_bit_lease_parse.patch Patch20: dhcp-4.2.0-capability.patch Patch21: dhcp-4.2.0-logpid.patch Patch22: dhcp-4.2.0-UseMulticast.patch @@ -87,7 +87,8 @@ Requires(preun): systemd-units Requires(postun): initscripts Requires(postun): systemd-units -Obsoletes: dhcpv6 +Obsoletes: dhcpv6 <= 2.0.0alpha4-1 +Provides: dhcpv6 = 2.0.0alpha4-2 %description DHCP (Dynamic Host Configuration Protocol) is a protocol which allows @@ -108,10 +109,13 @@ Requires: initscripts Requires(post): coreutils Requires(post): grep Obsoletes: dhcpcd <= 1.3.22pl1-7 -Obsoletes: libdhcp4client -Obsoletes: libdhcp -Obsoletes: dhcpv6-client -Provides: dhcpcd = 1.3.22pl1-8 +Provides: dhcpcd = 1.3.22pl1-8 +Obsoletes: libdhcp4client <= 12:4.0.0-34 +Provides: libdhcp4client = 12:4.0.0-35 +Obsoletes: libdhcp <= 1.99.8-1 +Provides: libdhcp = 1.99.8-2 +Obsoletes: dhcpv6-client <= 2.0.0alpha4-1 +Provides: dhcpv6-client = 2.0.0alpha4-2 %description -n dhclient DHCP (Dynamic Host Configuration Protocol) is a protocol which allows @@ -135,8 +139,10 @@ This package contains shared libraries used by ISC dhcp client and server %package devel Summary: Development headers and libraries for interfacing to the DHCP server Group: Development/Libraries -Obsoletes: libdhcp4client-devel -Obsoletes: libdhcp-devel +Obsoletes: libdhcp4client-devel <= 12:4.0.0-34 +Provides: libdhcp4client-devel = 12:4.0.0-35 +Obsoletes: libdhcp-devel <= 1.99.8-1 +Provides: libdhcp-devel = 1.99.8-2 Requires: %{name}-libs = %{epoch}:%{version}-%{release} %description devel @@ -217,7 +223,7 @@ rm bind/bind.tar.gz # (Submitted to dhcp-bugs@isc.org - [ISC-Bugs #19867]) %patch18 -p1 -b .dracut -# Ensure 64-bit platforms parse lease file dates & times correctly (#448615) +# Ensure 64-bit platforms parse lease file dates & times correctly (#448615, #628258) # (Partly submitted to dhcp-bugs@isc.org - [ISC-Bugs #22033]) %patch19 -p1 -b .64-bit_lease_parse @@ -264,16 +270,18 @@ rm bind/bind.tar.gz # check whether there is any unexpired address in previous lease # prior to confirming (INIT-REBOOT) the lease (#585418) +# (Submitted to dhcp-suggest@isc.org - [ISC-Bugs #22675]) %patch30 -p1 -b .honor-expired # 1) When server has empty pool of addresses/prefixes it must send Advertise with # NoAddrsAvail/NoPrefixAvail status in response to clients Solicit. -# Without this patch server having empty pool of addresses/prefixes ignored +# Without this patch server having empty pool of addresses/prefixes was ignoring # client's' Solicit when client was also sending address in IA_NA or prefix in IA_PD as a preference. -# 2) When client sends prefix in IA_NA as a preference and server doesn't have +# 2) When client sends prefix in IA_PD as a preference and server doesn't have # this prefix in any pool the server should offer other free prefix. # Without this patch server ignored client's Solicit in which the client was sending # prefix in IA_PD (as a preference) and this prefix was not in any of server's pools. +# (Submitted to dhcp-bugs@isc.org - [ISC-Bugs #22676]) %patch31 -p1 -b .noprefixavail %patch32 -p1 -b .rh637017 @@ -561,9 +569,9 @@ fi %{_initddir}/dhcpd %{_initddir}/dhcpd6 %{_initddir}/dhcrelay -%attr(0644,root,root) /lib/systemd/system/dhcpd.service -%attr(0644,root,root) /lib/systemd/system/dhcpd6.service -%attr(0644,root,root) /lib/systemd/system/dhcrelay.service +%attr(0644,root,root) /lib/systemd/system/dhcpd.service +%attr(0644,root,root) /lib/systemd/system/dhcpd6.service +%attr(0644,root,root) /lib/systemd/system/dhcrelay.service %{_bindir}/omshell %{_sbindir}/dhcpd %{_sbindir}/dhcrelay @@ -611,6 +619,11 @@ fi %attr(0644,root,root) %{_mandir}/man3/omapi.3.gz %changelog +* Mon Dec 13 2010 Jiri Popelka - 12:4.2.0-22.P2 +- 4.2.0-P2: fix for CVE-2010-3616 (#662326) +- Use upstream fix for #628258 +- Provide versioned symbols for rpmlint + * Tue Dec 07 2010 Jiri Popelka - 12:4.2.0-21.P1 - Porting dhcpd/dhcpd6/dhcrelay services from SysV to Systemd diff --git a/sources b/sources index caf1eb6..7dd0d92 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -1c268a2368b2565252b5f9d7255d3c72 dhcp-4.2.0-P1.tar.gz +a98f4ce3ca651e7e28a5a1ae6398689e dhcp-4.2.0-P2.tar.gz