diff --git a/bind-9.5-transfer-segv.patch b/bind-9.5-transfer-segv.patch new file mode 100644 index 0000000..656e0ff --- /dev/null +++ b/bind-9.5-transfer-segv.patch @@ -0,0 +1,197 @@ +diff -up bind-9.5.0b1/lib/dns/rbtdb.c.segv bind-9.5.0b1/lib/dns/rbtdb.c +--- bind-9.5.0b1/lib/dns/rbtdb.c.segv 2008-02-04 12:30:36.000000000 +0100 ++++ bind-9.5.0b1/lib/dns/rbtdb.c 2008-02-04 13:46:48.000000000 +0100 +@@ -763,23 +763,17 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boole + isc_mem_put(rbtdb->common.mctx, rbtdb->current_version, + sizeof(rbtdb_version_t)); + } +- if (IS_CACHE(rbtdb)) { +- /* +- * We assume the number of remaining dead nodes is reasonably +- * small; the overhead of unlinking all nodes here should be +- * negligible. +- */ +- for (i = 0; i < rbtdb->node_lock_count; i++) { +- dns_rbtnode_t *node; +- +- node = ISC_LIST_HEAD(rbtdb->deadnodes[i]); +- while (node != NULL) { +- ISC_LIST_UNLINK(rbtdb->deadnodes[i], node, +- deadlink); +- node = ISC_LIST_HEAD(rbtdb->deadnodes[i]); +- } ++ ++ for (i = 0; i < rbtdb->node_lock_count; i++) { ++ dns_rbtnode_t *node; ++ ++ node = ISC_LIST_HEAD(rbtdb->deadnodes[i]); ++ while (node != NULL) { ++ ISC_LIST_UNLINK(rbtdb->deadnodes[i], node, deadlink); ++ node = ISC_LIST_HEAD(rbtdb->deadnodes[i]); + } + } ++ + if (event == NULL) + rbtdb->quantum = (rbtdb->task != NULL) ? 100 : 0; + again: +@@ -1912,6 +1906,7 @@ closeversion(dns_db_t *db, dns_dbversion + } + + if (!EMPTY(cleanup_list)) { ++ RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); + for (changed = HEAD(cleanup_list); + changed != NULL; + changed = next_changed) { +@@ -1922,16 +1917,18 @@ closeversion(dns_db_t *db, dns_dbversion + lock = &rbtdb->node_locks[rbtnode->locknum].lock; + + NODE_LOCK(lock, isc_rwlocktype_write); ++ cleanup_dead_nodes(rbtdb, rbtnode->locknum); + if (rollback) + rollback_node(rbtnode, serial); + decrement_reference(rbtdb, rbtnode, least_serial, + isc_rwlocktype_write, +- isc_rwlocktype_none); ++ isc_rwlocktype_write); + NODE_UNLOCK(lock, isc_rwlocktype_write); + + isc_mem_put(rbtdb->common.mctx, changed, + sizeof(*changed)); + } ++ RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); + } + + end: +@@ -2009,6 +2006,7 @@ findnode(dns_db_t *db, dns_name_t *name, + dns_name_t nodename; + isc_result_t result; + isc_rwlocktype_t locktype = isc_rwlocktype_read; ++ isc_boolean_t need_relock; + + REQUIRE(VALID_RBTDB(rbtdb)); + +@@ -2064,29 +2062,27 @@ findnode(dns_db_t *db, dns_name_t *name, + * happen to hold a write lock on the tree, it's a good chance to purge + * dead nodes. + */ +- if (IS_CACHE(rbtdb)) { +- isc_boolean_t need_relock = ISC_FALSE; ++ need_relock = ISC_FALSE; ++ NODE_WEAKLOCK(&rbtdb->node_locks[node->locknum].lock, ++ isc_rwlocktype_read); ++ if (ISC_LINK_LINKED(node, deadlink) && isc_rwlocktype_write) ++ need_relock = ISC_TRUE; ++ else if (!ISC_LIST_EMPTY(rbtdb->deadnodes[node->locknum]) && ++ locktype == isc_rwlocktype_write) ++ need_relock = ISC_TRUE; ++ NODE_WEAKUNLOCK(&rbtdb->node_locks[node->locknum].lock, ++ isc_rwlocktype_read); ++ if (need_relock) { + + NODE_WEAKLOCK(&rbtdb->node_locks[node->locknum].lock, +- isc_rwlocktype_read); +- if (ISC_LINK_LINKED(node, deadlink) && isc_rwlocktype_write) +- need_relock = ISC_TRUE; +- else if (!ISC_LIST_EMPTY(rbtdb->deadnodes[node->locknum]) && +- locktype == isc_rwlocktype_write) +- need_relock = ISC_TRUE; ++ isc_rwlocktype_write); ++ if (ISC_LINK_LINKED(node, deadlink)) ++ ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], ++ node, deadlink); ++ if (locktype == isc_rwlocktype_write) ++ cleanup_dead_nodes(rbtdb, node->locknum); + NODE_WEAKUNLOCK(&rbtdb->node_locks[node->locknum].lock, +- isc_rwlocktype_read); +- if (need_relock) { +- NODE_WEAKLOCK(&rbtdb->node_locks[node->locknum].lock, +- isc_rwlocktype_write); +- if (ISC_LINK_LINKED(node, deadlink)) +- ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], +- node, deadlink); +- if (locktype == isc_rwlocktype_write) +- cleanup_dead_nodes(rbtdb, node->locknum); +- NODE_WEAKUNLOCK(&rbtdb->node_locks[node->locknum].lock, +- isc_rwlocktype_write); +- } ++ isc_rwlocktype_write); + } + + NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); +@@ -6149,15 +6145,6 @@ dns_rbtdb_create + for (i = 0; i < (int)rbtdb->node_lock_count; i++) + ISC_LIST_INIT(rbtdb->rdatasets[i]); + +- rbtdb->deadnodes = isc_mem_get(mctx, rbtdb->node_lock_count * +- sizeof(rbtnodelist_t)); +- if (rbtdb->deadnodes == NULL) { +- result = ISC_R_NOMEMORY; +- goto cleanup_rdatasets; +- } +- for (i = 0; i < (int)rbtdb->node_lock_count; i++) +- ISC_LIST_INIT(rbtdb->deadnodes[i]); +- + /* + * Create the heaps. + */ +@@ -6165,7 +6152,7 @@ dns_rbtdb_create + sizeof(isc_heap_t *)); + if (rbtdb->heaps == NULL) { + result = ISC_R_NOMEMORY; +- goto cleanup_deadnodes; ++ goto cleanup_rdatasets; + } + for (i = 0; i < (int)rbtdb->node_lock_count; i++) + rbtdb->heaps[i] = NULL; +@@ -6178,10 +6165,18 @@ dns_rbtdb_create + } + } else { + rbtdb->rdatasets = NULL; +- rbtdb->deadnodes = NULL; + rbtdb->heaps = NULL; + } + ++ rbtdb->deadnodes = isc_mem_get(mctx, rbtdb->node_lock_count * ++ sizeof(rbtnodelist_t)); ++ if (rbtdb->deadnodes == NULL) { ++ result = ISC_R_NOMEMORY; ++ goto cleanup_heaps; ++ } ++ for (i = 0; i < (int)rbtdb->node_lock_count; i++) ++ ISC_LIST_INIT(rbtdb->deadnodes[i]); ++ + rbtdb->active = rbtdb->node_lock_count; + + for (i = 0; i < (int)(rbtdb->node_lock_count); i++) { +@@ -6197,7 +6192,7 @@ dns_rbtdb_create + isc_refcount_decrement(&rbtdb->node_locks[i].references, NULL); + isc_refcount_destroy(&rbtdb->node_locks[i].references); + } +- goto cleanup_heaps; ++ goto cleanup_deadnodes; + } + rbtdb->node_locks[i].exiting = ISC_FALSE; + } +@@ -6310,6 +6305,10 @@ dns_rbtdb_create + + return (ISC_R_SUCCESS); + ++ cleanup_deadnodes: ++ isc_mem_put(mctx, rbtdb->deadnodes, ++ rbtdb->node_lock_count * sizeof(rbtnodelist_t)); ++ + cleanup_heaps: + if (rbtdb->heaps != NULL) { + for (i = 0 ; i < (int)rbtdb->node_lock_count ; i++) +@@ -6319,11 +6318,6 @@ dns_rbtdb_create + rbtdb->node_lock_count * sizeof(isc_heap_t *)); + } + +- cleanup_deadnodes: +- if (rbtdb->deadnodes != NULL) +- isc_mem_put(mctx, rbtdb->deadnodes, +- rbtdb->node_lock_count * sizeof(rbtnodelist_t)); +- + cleanup_rdatasets: + if (rbtdb->rdatasets != NULL) + isc_mem_put(mctx, rbtdb->rdatasets, rbtdb->node_lock_count * diff --git a/bind.spec b/bind.spec index d448d9a..5880c55 100644 --- a/bind.spec +++ b/bind.spec @@ -20,7 +20,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: ISC Version: 9.5.0 -Release: 23.%{RELEASEVER}%{?dist} +Release: 23.1.%{RELEASEVER}%{?dist} Epoch: 32 Url: http://www.isc.org/products/BIND/ Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -64,6 +64,7 @@ Patch72: bind-9.5-dlz-64bit.patch Patch80: bind-9.5-edns.patch Patch84: bind-9.5-gssapi-header.patch Patch86: bind-9.5-CVE-2008-0122.patch +Patch87: bind-9.5-transfer-segv.patch # SDB patches Patch11: bind-9.3.2b2-sdbsrc.patch @@ -254,6 +255,7 @@ cp -fp contrib/dbus/{dbus_mgr.h,dbus_service.h} bin/named/include/named %patch84 -p1 -b .gssapi-header %patch85 -p1 -b .libidn3 %patch86 -p0 -b .CVE-2008-0122 +%patch87 -p1 -b .transfer-segv :; @@ -410,7 +412,7 @@ for f in my.internal.zone.db slaves/my.slave.internal.zone.db slaves/my.ddns.int echo '@ in soa localhost. root 1 3H 15M 1W 1D ns localhost.' > sample/var/named/$f; done -/usr/bin/tail -n '+'`/bin/egrep -n '\\$Id: bind.spec,v 1.239 2008/01/21 10:05:57 atkac Exp $/+1/' | bc` bin/rndc/rndc.conf | sed '/Sample rndc configuration file./{p;i\ +/usr/bin/tail -n '+'`/bin/egrep -n '\\$Id: bind.spec,v 1.240 2008/02/04 13:11:57 atkac Exp $/+1/' | bc` bin/rndc/rndc.conf | sed '/Sample rndc configuration file./{p;i\ *\ * NOTE: you only need to create this file if it is to\ * differ from the following default contents: @@ -670,6 +672,9 @@ rm -rf ${RPM_BUILD_ROOT} %{_sbindir}/bind-chroot-admin %changelog +* Mon Feb 04 2008 Adam Tkac 32:9.5.0-24.b1 +- fixed segfault during sending notifies (#400461) + * Mon Jan 21 2008 Adam Tkac 32:9.5.0-23.b1 - CVE-2008-0122