From 2ec1fec7eb6a5e1aa3a39bd48ddf87b4f01dfa1ee6e87c18dec116f3d8aaf7c1 Mon Sep 17 00:00:00 2001 From: Reinhard Max Date: Tue, 15 Oct 2019 15:56:51 +0000 Subject: [PATCH 1/2] - bsc#1134078, CVE-2019-6470, dhcp-CVE-2019-6470.patch: DHCPv6 server crashes regularly. - Add compile option --enable-secs-byteorder to avoid duplicate lease warnings [bsc#1089524]. - bsc#1136572: Use IPv6 when called as dhclient6, dhcpd6, and dhcrelay6 (0021-dhcp-ip-family-symlinks.patch). OBS-URL: https://build.opensuse.org/package/show/network:dhcp/dhcp?expand=0&rev=201 --- 0021-dhcp-ip-family-symlinks.patch | 60 +++++++++ dhcp-CVE-2019-6470.patch | 191 +++++++++++++++++++++++++++++ dhcp.changes | 14 +++ dhcp.spec | 5 + 4 files changed, 270 insertions(+) create mode 100644 0021-dhcp-ip-family-symlinks.patch create mode 100644 dhcp-CVE-2019-6470.patch diff --git a/0021-dhcp-ip-family-symlinks.patch b/0021-dhcp-ip-family-symlinks.patch new file mode 100644 index 0000000..2b1faad --- /dev/null +++ b/0021-dhcp-ip-family-symlinks.patch @@ -0,0 +1,60 @@ +--- client/dhclient.c.orig ++++ client/dhclient.c +@@ -252,6 +252,17 @@ main(int argc, char **argv) { + progname = argv[0]; + #endif + ++#ifdef DHCPv6 ++ /* Support being called using `dhclient4` or `dhclient6` symlinks */ ++ if (argv[0][strlen(argv[0]) - 1] == '4') { ++ local_family_set = 1; ++ local_family = AF_INET; ++ } else if (argv[0][strlen(argv[0]) - 1] == '6') { ++ local_family_set = 1; ++ local_family = AF_INET6; ++ } ++#endif /* DHCPv6 */ ++ + /* Initialize client globals. */ + memset(&default_duid, 0, sizeof(default_duid)); + +--- relay/dhcrelay.c.orig ++++ relay/dhcrelay.c +@@ -237,6 +237,17 @@ main(int argc, char **argv) { + progname = argv[0]; + #endif + ++#ifdef DHCPv6 ++ /* Support being called using `dhcrelay4` or `dhcrelay6` symlinks */ ++ if (argv[0][strlen(argv[0]) - 1] == '4') { ++ local_family_set = 1; ++ local_family = AF_INET; ++ } else if (argv[0][strlen(argv[0]) - 1] == '6') { ++ local_family_set = 1; ++ local_family = AF_INET6; ++ } ++#endif /* DHCPv6 */ ++ + /* Make sure that file descriptors 0(stdin), 1,(stdout), and + 2(stderr) are open. To do this, we assume that when we + open a file the lowest available file descriptor is used. */ +--- server/dhcpd.c.orig ++++ server/dhcpd.c +@@ -260,6 +260,17 @@ main(int argc, char **argv) { + progname = argv[0]; + #endif + ++#ifdef DHCPv6 ++ /* Support being called using `dhcpd4` or `dhcpd6` symlinks */ ++ if (argv[0][strlen(argv[0]) - 1] == '4') { ++ local_family_set = 1; ++ local_family = AF_INET; ++ } else if (argv[0][strlen(argv[0]) - 1] == '6') { ++ local_family_set = 1; ++ local_family = AF_INET6; ++ } ++#endif /* DHCPv6 */ ++ + /* Make sure that file descriptors 0 (stdin), 1, (stdout), and + 2 (stderr) are open. To do this, we assume that when we + open a file the lowest available file descriptor is used. */ diff --git a/dhcp-CVE-2019-6470.patch b/dhcp-CVE-2019-6470.patch new file mode 100644 index 0000000..49ccab3 --- /dev/null +++ b/dhcp-CVE-2019-6470.patch @@ -0,0 +1,191 @@ +commit 21ae396088a3fbe046e3122286d1288eeacce7d3 +Author: Thomas Markwalder +Date: Fri Dec 1 09:21:42 2017 -0500 + + [v4_3] Use 0 instead of -1 to indicate empty heap index + + Merges in rt46719. + +--- includes/dhcpd.h.orig ++++ includes/dhcpd.h +@@ -1596,8 +1596,9 @@ struct iasubopt { + */ + #define EXPIRED_IPV6_CLEANUP_TIME (60*60) + +- int heap_index; /* index into heap, or -1 +- (internal use only) */ ++ /* index into heaps, or -1 (internal use only) */ ++ int active_index; ++ int inactive_index; + + /* + * A pointer to the state of the ddns update for this lease. +--- server/mdb6.c.orig ++++ server/mdb6.c +@@ -216,7 +216,8 @@ iasubopt_allocate(struct iasubopt **iasu + + tmp->refcnt = 1; + tmp->state = FTS_FREE; +- tmp->heap_index = -1; ++ tmp->active_index = 0; ++ tmp->inactive_index = 0; + tmp->plen = 255; + + *iasubopt = tmp; +@@ -600,14 +601,18 @@ lease_older(void *a, void *b) { + } + + /* +- * Helper function for lease address/prefix heaps. ++ * Helper functions for lease address/prefix heaps. + * Callback when an address's position in the heap changes. + */ + static void +-lease_index_changed(void *iasubopt, unsigned int new_heap_index) { +- ((struct iasubopt *)iasubopt)-> heap_index = new_heap_index; ++active_changed(void *iasubopt, unsigned int new_heap_index) { ++ ((struct iasubopt *)iasubopt)->active_index = new_heap_index; + } + ++static void ++inactive_changed(void *iasubopt, unsigned int new_heap_index) { ++ ((struct iasubopt *)iasubopt)->inactive_index = new_heap_index; ++} + + /*! + * +@@ -660,13 +665,13 @@ ipv6_pool_allocate(struct ipv6_pool **po + dfree(tmp, file, line); + return ISC_R_NOMEMORY; + } +- if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed, ++ if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, active_changed, + 0, &(tmp->active_timeouts)) != ISC_R_SUCCESS) { + iasubopt_free_hash_table(&(tmp->leases), file, line); + dfree(tmp, file, line); + return ISC_R_NOMEMORY; + } +- if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed, ++ if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, inactive_changed, + 0, &(tmp->inactive_timeouts)) != ISC_R_SUCCESS) { + isc_heap_destroy(&(tmp->active_timeouts)); + iasubopt_free_hash_table(&(tmp->leases), file, line); +@@ -1186,7 +1191,7 @@ cleanup_lease6(ia_hash_t *ia_table, + * Remove the old lease from the active heap and from the hash table + * then remove the lease from the IA and clean up the IA if necessary. + */ +- isc_heap_delete(pool->active_timeouts, test_iasubopt->heap_index); ++ isc_heap_delete(pool->active_timeouts, test_iasubopt->active_index); + pool->num_active--; + if (pool->ipv6_pond) + pool->ipv6_pond->num_active--; +@@ -1259,7 +1264,7 @@ add_lease6(struct ipv6_pool *pool, struc + if ((test_iasubopt->state == FTS_ACTIVE) || + (test_iasubopt->state == FTS_ABANDONED)) { + isc_heap_delete(pool->active_timeouts, +- test_iasubopt->heap_index); ++ test_iasubopt->active_index); + pool->num_active--; + if (pool->ipv6_pond) + pool->ipv6_pond->num_active--; +@@ -1271,7 +1276,7 @@ add_lease6(struct ipv6_pool *pool, struc + } + } else { + isc_heap_delete(pool->inactive_timeouts, +- test_iasubopt->heap_index); ++ test_iasubopt->inactive_index); + pool->num_inactive--; + } + +@@ -1392,14 +1397,13 @@ lease6_usable(struct iasubopt *lease) { + static isc_result_t + move_lease_to_active(struct ipv6_pool *pool, struct iasubopt *lease) { + isc_result_t insert_result; +- int old_heap_index; + +- old_heap_index = lease->heap_index; + insert_result = isc_heap_insert(pool->active_timeouts, lease); + if (insert_result == ISC_R_SUCCESS) { + iasubopt_hash_add(pool->leases, &lease->addr, + sizeof(lease->addr), lease, MDL); +- isc_heap_delete(pool->inactive_timeouts, old_heap_index); ++ isc_heap_delete(pool->inactive_timeouts, ++ lease->inactive_index); + pool->num_active++; + pool->num_inactive--; + lease->state = FTS_ACTIVE; +@@ -1449,16 +1453,16 @@ renew_lease6(struct ipv6_pool *pool, str + if (lease->state == FTS_ACTIVE) { + if (old_end_time <= lease->hard_lifetime_end_time) { + isc_heap_decreased(pool->active_timeouts, +- lease->heap_index); ++ lease->active_index); + } else { + isc_heap_increased(pool->active_timeouts, +- lease->heap_index); ++ lease->active_index); + } + return ISC_R_SUCCESS; + } else if (lease->state == FTS_ABANDONED) { + char tmp_addr[INET6_ADDRSTRLEN]; + lease->state = FTS_ACTIVE; +- isc_heap_increased(pool->active_timeouts, lease->heap_index); ++ isc_heap_increased(pool->active_timeouts, lease->active_index); + log_info("Reclaiming previously abandoned address %s", + inet_ntop(AF_INET6, &(lease->addr), tmp_addr, + sizeof(tmp_addr))); +@@ -1480,9 +1484,7 @@ static isc_result_t + move_lease_to_inactive(struct ipv6_pool *pool, struct iasubopt *lease, + binding_state_t state) { + isc_result_t insert_result; +- int old_heap_index; + +- old_heap_index = lease->heap_index; + insert_result = isc_heap_insert(pool->inactive_timeouts, lease); + if (insert_result == ISC_R_SUCCESS) { + /* +@@ -1533,7 +1535,7 @@ move_lease_to_inactive(struct ipv6_pool + + iasubopt_hash_delete(pool->leases, + &lease->addr, sizeof(lease->addr), MDL); +- isc_heap_delete(pool->active_timeouts, old_heap_index); ++ isc_heap_delete(pool->active_timeouts, lease->active_index); + lease->state = state; + pool->num_active--; + pool->num_inactive++; +@@ -1611,7 +1613,7 @@ decline_lease6(struct ipv6_pool *pool, s + pool->ipv6_pond->num_abandoned++; + + lease->hard_lifetime_end_time = MAX_TIME; +- isc_heap_decreased(pool->active_timeouts, lease->heap_index); ++ isc_heap_decreased(pool->active_timeouts, lease->active_index); + return ISC_R_SUCCESS; + } + +@@ -1884,7 +1886,7 @@ cleanup_old_expired(struct ipv6_pool *po + break; + } + +- isc_heap_delete(pool->inactive_timeouts, tmp->heap_index); ++ isc_heap_delete(pool->inactive_timeouts, tmp->inactive_index); + pool->num_inactive--; + + if (tmp->ia != NULL) { +--- server/tests/mdb6_unittest.c.orig ++++ server/tests/mdb6_unittest.c +@@ -65,8 +65,13 @@ ATF_TC_BODY(iaaddr_basic, tc) + if (iaaddr->state != FTS_FREE) { + atf_tc_fail("ERROR: bad state %s:%d", MDL); + } +- if (iaaddr->heap_index != -1) { +- atf_tc_fail("ERROR: bad heap_index %s:%d", MDL); ++ if (iaaddr->active_index != 0) { ++ atf_tc_fail("ERROR: bad active_index :%d %s:%d", ++ iaaddr->active_index, MDL); ++ } ++ if (iaaddr->inactive_index != 0) { ++ atf_tc_fail("ERROR: bad inactive_index %d %s:%d", ++ iaaddr->inactive_index, MDL); + } + if (iasubopt_reference(&iaaddr_copy, iaaddr, MDL) != ISC_R_SUCCESS) { + atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL); diff --git a/dhcp.changes b/dhcp.changes index b5e7476..0134331 100644 --- a/dhcp.changes +++ b/dhcp.changes @@ -1,3 +1,17 @@ +------------------------------------------------------------------- +Tue Oct 15 15:18:59 UTC 2019 - Reinhard Max + +- bsc#1134078, CVE-2019-6470, dhcp-CVE-2019-6470.patch: + DHCPv6 server crashes regularly. +- Add compile option --enable-secs-byteorder to avoid duplicate + lease warnings [bsc#1089524]. + +------------------------------------------------------------------- +Wed Aug 28 12:38:32 UTC 2019 - Reinhard Max + +- bsc#1136572: Use IPv6 when called as dhclient6, dhcpd6, and + dhcrelay6 (0021-dhcp-ip-family-symlinks.patch). + ------------------------------------------------------------------- Thu Aug 8 12:19:53 UTC 2019 - Dirk Mueller diff --git a/dhcp.spec b/dhcp.spec index fa403bc..b651829 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -86,6 +86,8 @@ Patch17: 0017-server-no-success-report-before-send.919959.patch Patch18: 0018-client-fail-on-script-pre-init-error-bsc-912098.patch # PATCH-FIX-SLE dhcp-4.2.4-P1-interval bsc#947780 Patch20: 0020-dhcp-4.x.x-fixed-improper-lease-duration-checking.patch +Patch21: 0021-dhcp-ip-family-symlinks.patch +Patch22: dhcp-CVE-2019-6470.patch BuildRequires: automake BuildRequires: dos2unix BuildRequires: libtool @@ -193,6 +195,8 @@ with the Internet Software Consortium (ISC) dhcpctl API. %patch17 -p1 %patch18 -p1 %patch20 +%patch21 +%patch22 ## find . -type f -name \*.cat\* -exec rm -f {} \; dos2unix contrib/ms2isc/* @@ -236,6 +240,7 @@ export CFLAGS LDFLAGS FFLAGS CXXFLAGS --enable-failover \ --enable-paranoia \ --enable-early-chroot \ + --enable-secs-byteorder \ --with-ldap \ --with-ldapcrypto \ --with-cli-pid-file=%{_localstatedir}/run/dhclient.pid \ From fb531fa37a81188d4bb86fddd89010226f82fd32fca21461f5357e4da5edfc0b Mon Sep 17 00:00:00 2001 From: Reinhard Max Date: Tue, 22 Oct 2019 13:55:46 +0000 Subject: [PATCH 2/2] Accepting request 734636 from home:kukuk:container - Make systemd a weak dependency as we don't want that in a container OBS-URL: https://build.opensuse.org/request/show/734636 OBS-URL: https://build.opensuse.org/package/show/network:dhcp/dhcp?expand=0&rev=202 --- dhcp.changes | 5 +++++ dhcp.spec | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/dhcp.changes b/dhcp.changes index 0134331..beeab0d 100644 --- a/dhcp.changes +++ b/dhcp.changes @@ -6,6 +6,11 @@ Tue Oct 15 15:18:59 UTC 2019 - Reinhard Max - Add compile option --enable-secs-byteorder to avoid duplicate lease warnings [bsc#1089524]. +------------------------------------------------------------------- +Wed Oct 2 16:50:48 CEST 2019 - kukuk@suse.de + +- Make systemd a weak dependency as we don't want that in a container + ------------------------------------------------------------------- Wed Aug 28 12:38:32 UTC 2019 - Reinhard Max diff --git a/dhcp.spec b/dhcp.spec index b651829..734390e 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -105,7 +105,7 @@ Requires: dhcp = %{version} Requires: net-tools Requires(post): %fillup_prereq Requires(pre): shadow -%systemd_requires +%systemd_ordering %if 0%{?suse_version} >= 1330 Requires(pre): group(nogroup) %endif