diff options
author | Internet Software Consortium, Inc <@isc.org> | 2013-08-14 06:36:37 -0600 |
---|---|---|
committer | Internet Software Consortium, Inc <@isc.org> | 2013-08-14 06:36:37 -0600 |
commit | 816cb5580f04b5989e0f952510d64201a16d0494 (patch) | |
tree | a08dd0d3a33801ef7e5d35a5b435121a577fdd01 /lib | |
parent | ebbc86ee1eae2231a10e23f4cda592085dbc7eef (diff) | |
download | bind9-816cb5580f04b5989e0f952510d64201a16d0494.tar.gz |
9.9.4rc1
Diffstat (limited to 'lib')
-rw-r--r-- | lib/dns/api | 2 | ||||
-rw-r--r-- | lib/dns/hmac_link.c | 15 | ||||
-rw-r--r-- | lib/dns/rdata/generic/keydata_65533.c | 4 | ||||
-rw-r--r-- | lib/dns/view.c | 2 | ||||
-rw-r--r-- | lib/dns/zone.c | 233 | ||||
-rw-r--r-- | lib/export/isc/Makefile.in | 7 | ||||
-rw-r--r-- | lib/isc/Makefile.in | 11 | ||||
-rw-r--r-- | lib/isc/api | 4 | ||||
-rw-r--r-- | lib/isc/hmacmd5.c | 5 | ||||
-rw-r--r-- | lib/isc/hmacsha.c | 13 | ||||
-rw-r--r-- | lib/isc/include/isc/Makefile.in | 2 | ||||
-rw-r--r-- | lib/isc/include/isc/safe.h | 36 | ||||
-rw-r--r-- | lib/isc/safe.c | 42 | ||||
-rw-r--r-- | lib/isc/tests/Makefile.in | 8 | ||||
-rw-r--r-- | lib/isc/tests/safe_test.c | 52 | ||||
-rw-r--r-- | lib/isc/win32/libisc.def | 1 | ||||
-rw-r--r-- | lib/isc/win32/libisc.dsp | 8 | ||||
-rw-r--r-- | lib/isc/win32/libisc.mak | 24 | ||||
-rw-r--r-- | lib/isccc/api | 2 | ||||
-rw-r--r-- | lib/isccc/cc.c | 6 |
20 files changed, 369 insertions, 108 deletions
diff --git a/lib/dns/api b/lib/dns/api index 09c345a9..60d0c931 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -5,5 +5,5 @@ # 9.9: 90-109 # 9.9-sub: 130-139 LIBINTERFACE = 100 -LIBREVISION = 0 +LIBREVISION = 1 LIBAGE = 0 diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c index 256abb6e..1f1a0ca6 100644 --- a/lib/dns/hmac_link.c +++ b/lib/dns/hmac_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -42,6 +42,7 @@ #include <isc/md5.h> #include <isc/sha1.h> #include <isc/mem.h> +#include <isc/safe.h> #include <isc/string.h> #include <isc/util.h> @@ -138,7 +139,7 @@ hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) { else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); - if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH) == 0) + if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); @@ -415,7 +416,7 @@ hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) { else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); - if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH) == 0) + if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); @@ -692,7 +693,7 @@ hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) { else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); - if (memcmp(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH) == 0) + if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); @@ -971,7 +972,7 @@ hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) { else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); - if (memcmp(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH) == 0) + if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); @@ -1250,7 +1251,7 @@ hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) { else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); - if (memcmp(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH) == 0) + if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); @@ -1529,7 +1530,7 @@ hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) { else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); - if (memcmp(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH) == 0) + if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); diff --git a/lib/dns/rdata/generic/keydata_65533.c b/lib/dns/rdata/generic/keydata_65533.c index 46bf6fce..f1fe45e4 100644 --- a/lib/dns/rdata/generic/keydata_65533.c +++ b/lib/dns/rdata/generic/keydata_65533.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -194,7 +194,7 @@ fromwire_keydata(ARGS_FROMWIRE) { UNUSED(options); isc_buffer_activeregion(source, &sr); - if (sr.length < 4) + if (sr.length < 16) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, sr.length); diff --git a/lib/dns/view.c b/lib/dns/view.c index 7daf64fa..142b09ed 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -1427,6 +1427,8 @@ dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, dns_zone_t **zp = NULL;; REQUIRE(list != NULL); + REQUIRE(zonep != NULL && *zonep == NULL); + for (view = ISC_LIST_HEAD(*list); view != NULL; view = ISC_LIST_NEXT(view, link)) { diff --git a/lib/dns/zone.c b/lib/dns/zone.c index bd2ad74a..6e9f49af 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -2737,14 +2737,22 @@ resume_signingwithkey(dns_zone_t *zone) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; isc_result_t result; + dns_db_t *db = NULL; + + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) + dns_db_attach(zone->db, &db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (db == NULL) + goto cleanup; - result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node); + result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto cleanup; - dns_db_currentversion(zone->db, &version); + dns_db_currentversion(db, &version); dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(zone->db, node, version, + result = dns_db_findrdataset(db, node, version, zone->privatetype, dns_rdatatype_none, 0, &rdataset, NULL); @@ -2777,10 +2785,13 @@ resume_signingwithkey(dns_zone_t *zone) { dns_rdataset_disassociate(&rdataset); cleanup: - if (node != NULL) - dns_db_detachnode(zone->db, &node); - if (version != NULL) - dns_db_closeversion(zone->db, &version, ISC_FALSE); + if (db != NULL) { + if (node != NULL) + dns_db_detachnode(db, &node); + if (version != NULL) + dns_db_closeversion(db, &version, ISC_FALSE); + dns_db_detach(&db); + } } static isc_result_t @@ -2793,18 +2804,33 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { unsigned int options = 0; char saltbuf[255*2+1]; char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; + dns_db_t *db = NULL; int i; - dns_db_currentversion(zone->db, &version); - result = dns_nsec_nseconly(zone->db, version, &nseconly); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) + dns_db_attach(zone->db, &db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + + if (db == NULL) { + result = ISC_R_SUCCESS; + goto cleanup; + } + + dns_db_currentversion(db, &version); + result = dns_nsec_nseconly(db, version, &nseconly); nsec3ok = (result == ISC_R_SUCCESS && !nseconly); - dns_db_closeversion(zone->db, &version, ISC_FALSE); - if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) - return (ISC_R_SUCCESS); + dns_db_closeversion(db, &version, ISC_FALSE); + if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) { + result = ISC_R_SUCCESS; + goto cleanup; + } nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); - if (nsec3chain == NULL) - return (ISC_R_NOMEMORY); + if (nsec3chain == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } nsec3chain->magic = 0; nsec3chain->done = ISC_FALSE; @@ -2866,7 +2892,7 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL; current = ISC_LIST_NEXT(current, link)) { - if (current->db == zone->db && + if (current->db == db && current->nsec3param.hash == nsec3param->hash && current->nsec3param.iterations == nsec3param->iterations && current->nsec3param.salt_length == nsec3param->salt_length @@ -2875,28 +2901,25 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { current->done = ISC_TRUE; } - if (zone->db != NULL) { - dns_db_attach(zone->db, &nsec3chain->db); - if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) - options = DNS_DB_NONSEC3; - result = dns_db_createiterator(nsec3chain->db, options, - &nsec3chain->dbiterator); - if (result == ISC_R_SUCCESS) - dns_dbiterator_first(nsec3chain->dbiterator); - if (result == ISC_R_SUCCESS) { - dns_dbiterator_pause(nsec3chain->dbiterator); - ISC_LIST_INITANDAPPEND(zone->nsec3chain, - nsec3chain, link); - nsec3chain = NULL; - if (isc_time_isepoch(&zone->nsec3chaintime)) { - TIME_NOW(&now); - zone->nsec3chaintime = now; - if (zone->task != NULL) - zone_settimer(zone, &now); - } + dns_db_attach(db, &nsec3chain->db); + if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) + options = DNS_DB_NONSEC3; + result = dns_db_createiterator(nsec3chain->db, options, + &nsec3chain->dbiterator); + if (result == ISC_R_SUCCESS) + dns_dbiterator_first(nsec3chain->dbiterator); + if (result == ISC_R_SUCCESS) { + dns_dbiterator_pause(nsec3chain->dbiterator); + ISC_LIST_INITANDAPPEND(zone->nsec3chain, + nsec3chain, link); + nsec3chain = NULL; + if (isc_time_isepoch(&zone->nsec3chaintime)) { + TIME_NOW(&now); + zone->nsec3chaintime = now; + if (zone->task != NULL) + zone_settimer(zone, &now); } - } else - result = ISC_R_NOTFOUND; + } if (nsec3chain != NULL) { if (nsec3chain->db != NULL) @@ -2905,6 +2928,10 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { dns_dbiterator_destroy(&nsec3chain->dbiterator); isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); } + + cleanup: + if (db != NULL) + dns_db_detach(&db); return (result); } @@ -2916,21 +2943,29 @@ resume_addnsec3chain(dns_zone_t *zone) { isc_result_t result; dns_rdata_nsec3param_t nsec3param; isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; + dns_db_t *db = NULL; if (zone->privatetype == 0) return; - result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) + dns_db_attach(zone->db, &db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (db == NULL) + goto cleanup; + + result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto cleanup; - dns_db_currentversion(zone->db, &version); + dns_db_currentversion(db, &version); - result = dns_nsec_nseconly(zone->db, version, &nseconly); + result = dns_nsec_nseconly(db, version, &nseconly); nsec3ok = (result == ISC_R_SUCCESS && !nseconly); dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(zone->db, node, version, + result = dns_db_findrdataset(db, node, version, zone->privatetype, dns_rdatatype_none, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) { @@ -2965,10 +3000,13 @@ resume_addnsec3chain(dns_zone_t *zone) { } dns_rdataset_disassociate(&rdataset); cleanup: - if (node != NULL) - dns_db_detachnode(zone->db, &node); - if (version != NULL) - dns_db_closeversion(zone->db, &version, ISC_FALSE); + if (db != NULL) { + if (node != NULL) + dns_db_detachnode(db, &node); + if (version != NULL) + dns_db_closeversion(db, &version, ISC_FALSE); + dns_db_detach(&db); + } } static void @@ -2978,20 +3016,34 @@ set_resigntime(dns_zone_t *zone) { unsigned int resign; isc_result_t result; isc_uint32_t nanosecs; + dns_db_t *db = NULL; dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); - result = dns_db_getsigningtime(zone->db, &rdataset, + + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) + dns_db_attach(zone->db, &db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (db == NULL) { + isc_time_settoepoch(&zone->resigntime); + return; + } + + result = dns_db_getsigningtime(db, &rdataset, dns_fixedname_name(&fixed)); if (result != ISC_R_SUCCESS) { isc_time_settoepoch(&zone->resigntime); - return; + goto cleanup; } resign = rdataset.resign; dns_rdataset_disassociate(&rdataset); isc_random_get(&nanosecs); nanosecs %= 1000000000; isc_time_set(&zone->resigntime, resign, nanosecs); + cleanup: + dns_db_detach(&db); + return; } static isc_result_t @@ -7340,8 +7392,13 @@ zone_sign(dns_zone_t *zone) { } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); - dns_db_attach(zone->db, &db); + if (zone->db != NULL) + dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (db == NULL) { + result = ISC_R_FAILURE; + goto failure; + } result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { @@ -9311,7 +9368,6 @@ forward_cancel(dns_zone_t *zone) { static void zone_unload(dns_zone_t *zone) { - /* * 'zone' locked by caller. */ @@ -12665,10 +12721,15 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) { UNUSED(task); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) + dns_db_attach(zone->db, &db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + /* * zone->db may be NULL if the load from disk failed. */ - if (zone->db == NULL || !inline_secure(zone)) { + if (db == NULL || !inline_secure(zone)) { result = ISC_R_FAILURE; goto failure; } @@ -12713,7 +12774,6 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) { } } - dns_db_attach(zone->db, &db); dns_db_currentversion(db, &oldver); CHECK(dns_db_newversion(db, &newver)); @@ -12891,18 +12951,24 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { rawdb = ((struct secure_event *)event)->db; isc_event_free(&event); - REQUIRE(inline_secure(zone)); - dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); + LOCK_ZONE(zone); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { + result = ISC_R_SHUTTINGDOWN; + goto unlock; + } + TIME_NOW(&loadtime); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { result = dns_db_getsoaserial(zone->db, NULL, &oldserial); if (result == ISC_R_SUCCESS) have_oldserial = ISC_TRUE; } + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, dns_dbtype_zone, zone->rdclass, @@ -12967,14 +13033,13 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { /* * Lock hierarchy: zmgr, zone, raw. */ - LOCK_ZONE(zone); - if (inline_secure(zone)) - LOCK_ZONE(zone->raw); + INSIST(zone != zone->raw); + LOCK_ZONE(zone->raw); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); zone_needdump(zone, 0); /* XXXMPA */ - if (inline_secure(zone)) - UNLOCK_ZONE(zone->raw); + UNLOCK_ZONE(zone->raw); + unlock: UNLOCK_ZONE(zone); failure: @@ -13632,6 +13697,7 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) { isc_sockaddr_t masteraddr; isc_time_t now; const char *soa_before = ""; + isc_boolean_t loaded; UNUSED(task); @@ -13665,7 +13731,11 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) { /* * Decide whether we should request IXFR or AXFR. */ - if (zone->db == NULL) { + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + loaded = ISC_TF(zone->db != NULL); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + + if (!loaded) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "no database exists yet, requesting AXFR of " "initial version from %s", master); @@ -15368,6 +15438,7 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, dns_signing_t *current; isc_result_t result = ISC_R_SUCCESS; isc_time_t now; + dns_db_t *db = NULL; signing = isc_mem_get(zone->mctx, sizeof *signing); if (signing == NULL) @@ -15383,10 +15454,22 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, TIME_NOW(&now); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) + dns_db_attach(zone->db, &db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + + if (db == NULL) { + result = ISC_R_NOTFOUND; + goto cleanup; + } + + dns_db_attach(db, &signing->db); + for (current = ISC_LIST_HEAD(zone->signing); current != NULL; current = ISC_LIST_NEXT(current, link)) { - if (current->db == zone->db && + if (current->db == signing->db && current->algorithm == signing->algorithm && current->keyid == signing->keyid) { if (current->delete != signing->delete) @@ -15396,25 +15479,21 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, } } - if (zone->db != NULL) { - dns_db_attach(zone->db, &signing->db); - result = dns_db_createiterator(signing->db, 0, - &signing->dbiterator); + result = dns_db_createiterator(signing->db, 0, + &signing->dbiterator); - if (result == ISC_R_SUCCESS) - result = dns_dbiterator_first(signing->dbiterator); - if (result == ISC_R_SUCCESS) { - dns_dbiterator_pause(signing->dbiterator); - ISC_LIST_INITANDAPPEND(zone->signing, signing, link); - signing = NULL; - if (isc_time_isepoch(&zone->signingtime)) { - zone->signingtime = now; - if (zone->task != NULL) - zone_settimer(zone, &now); - } + if (result == ISC_R_SUCCESS) + result = dns_dbiterator_first(signing->dbiterator); + if (result == ISC_R_SUCCESS) { + dns_dbiterator_pause(signing->dbiterator); + ISC_LIST_INITANDAPPEND(zone->signing, signing, link); + signing = NULL; + if (isc_time_isepoch(&zone->signingtime)) { + zone->signingtime = now; + if (zone->task != NULL) + zone_settimer(zone, &now); } - } else - result = ISC_R_NOTFOUND; + } cleanup: if (signing != NULL) { @@ -15424,6 +15503,8 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, dns_dbiterator_destroy(&signing->dbiterator); isc_mem_put(zone->mctx, signing, sizeof *signing); } + if (db != NULL) + dns_db_detach(&db); return (result); } diff --git a/lib/export/isc/Makefile.in b/lib/export/isc/Makefile.in index c04a9073..46df39df 100644 --- a/lib/export/isc/Makefile.in +++ b/lib/export/isc/Makefile.in @@ -70,8 +70,8 @@ OBJS = @ISC_EXTRA_OBJS@ \ md5.@O@ mutexblock.@O@ netaddr.@O@ netscope.@O@ \ ondestroy.@O@ parseint.@O@ portset.@O@ radix.@O@ \ random.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ - rwlock.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ \ - stats.@O@ string.@O@ \ + rwlock.@O@ safe.@O@ serial.@O@ sha1.@O@ sha2.@O@ \ + sockaddr.@O@ stats.@O@ string.@O@ \ symtab.@O@ \ version.@O@ \ ${APIOBJS} ${ISCDRIVEROBJS} \ @@ -94,7 +94,8 @@ SRCS = @ISC_EXTRA_SRCS@ \ ondestroy.c \ parseint.c portset.c radix.c \ random.c refcount.c region.c regex.c result.c rwlock.c \ - serial.c sha1.c sha2.c sockaddr.c stats.c string.c symtab.c \ + safe.c serial.c sha1.c sha2.c sockaddr.c \ + stats.c string.c symtab.c \ version.c \ ${APISRCS} ${ISCDRIVERSRCS} diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in index e68290cd..e8c28214 100644 --- a/lib/isc/Makefile.in +++ b/lib/isc/Makefile.in @@ -62,7 +62,7 @@ OBJS = @ISC_EXTRA_OBJS@ \ parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \ ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ rwlock.@O@ \ - serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \ + safe.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \ string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \ timer.@O@ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS} SYMTBLOBJS = backtrace-emptytbl.@O@ @@ -78,8 +78,9 @@ SRCS = @ISC_EXTRA_SRCS@ \ netaddr.c netscope.c pool.c ondestroy.c \ parseint.c portset.c quota.c radix.c random.c \ ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \ - serial.c sha1.c sha2.c sockaddr.c stats.c string.c strtoul.c \ - symtab.c symtbl-empty.c task.c taskpool.c timer.c version.c + safe.c serial.c sha1.c sha2.c sockaddr.c stats.c string.c \ + strtoul.c symtab.c symtbl-empty.c task.c taskpool.c timer.c \ + version.c LIBS = @LIBS@ @@ -93,6 +94,10 @@ TESTDIRS = @UNITTESTS@ @BIND9_MAKE_RULES@ +safe.@O@: safe.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} @CCNOOPT@ \ + -c ${srcdir}/safe.c + version.@O@: version.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ diff --git a/lib/isc/api b/lib/isc/api index 38d3b8f9..d6bb973d 100644 --- a/lib/isc/api +++ b/lib/isc/api @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 96 +LIBINTERFACE = 97 LIBREVISION = 0 -LIBAGE = 1 +LIBAGE = 2 diff --git a/lib/isc/hmacmd5.c b/lib/isc/hmacmd5.c index 6abe6e27..4c4046df 100644 --- a/lib/isc/hmacmd5.c +++ b/lib/isc/hmacmd5.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -28,6 +28,7 @@ #include <isc/hmacmd5.h> #include <isc/md5.h> #include <isc/platform.h> +#include <isc/safe.h> #include <isc/string.h> #include <isc/types.h> #include <isc/util.h> @@ -145,5 +146,5 @@ isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) { REQUIRE(len <= ISC_MD5_DIGESTLENGTH); isc_hmacmd5_sign(ctx, newdigest); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (isc_safe_memcmp(digest, newdigest, len)); } diff --git a/lib/isc/hmacsha.c b/lib/isc/hmacsha.c index d7b9f189..38709637 100644 --- a/lib/isc/hmacsha.c +++ b/lib/isc/hmacsha.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2005-2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -27,6 +27,7 @@ #include <isc/assertions.h> #include <isc/hmacsha.h> #include <isc/platform.h> +#include <isc/safe.h> #include <isc/sha1.h> #include <isc/sha2.h> #include <isc/string.h> @@ -538,7 +539,7 @@ isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (isc_safe_memcmp(digest, newdigest, len)); } /* @@ -551,7 +552,7 @@ isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (isc_safe_memcmp(digest, newdigest, len)); } /* @@ -564,7 +565,7 @@ isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (isc_safe_memcmp(digest, newdigest, len)); } /* @@ -577,7 +578,7 @@ isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (isc_safe_memcmp(digest, newdigest, len)); } /* @@ -590,5 +591,5 @@ isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (isc_safe_memcmp(digest, newdigest, len)); } diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in index 8afcfa73..3b2b0369 100644 --- a/lib/isc/include/isc/Makefile.in +++ b/lib/isc/include/isc/Makefile.in @@ -37,7 +37,7 @@ HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \ namespace.h netaddr.h ondestroy.h os.h parseint.h \ print.h quota.h radix.h random.h ratelimiter.h \ refcount.h regex.h region.h resource.h \ - result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \ + result.h resultclass.h rwlock.h safe.h serial.h sha1.h sha2.h \ sockaddr.h socket.h stdio.h stdlib.h string.h \ symtab.h \ task.h taskpool.h timer.h types.h util.h version.h \ diff --git a/lib/isc/include/isc/safe.h b/lib/isc/include/isc/safe.h new file mode 100644 index 00000000..89d56def --- /dev/null +++ b/lib/isc/include/isc/safe.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id$ */ + +#ifndef ISC_SAFE_H +#define ISC_SAFE_H 1 + +/*! \file isc/safe.h */ + +#include <isc/types.h> + +ISC_LANG_BEGINDECLS + +isc_boolean_t +isc_safe_memcmp(const void *s1, const void *s2, size_t n); +/*%< + * Clone of libc memcmp() safe to differential timing attacks. + */ + +ISC_LANG_ENDDECLS + +#endif /* ISC_SAFE_H */ diff --git a/lib/isc/safe.c b/lib/isc/safe.c new file mode 100644 index 00000000..fd276871 --- /dev/null +++ b/lib/isc/safe.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id$ */ + +/*! \file */ + +#include <config.h> + +#include <isc/safe.h> +#include <isc/util.h> + +#ifdef _MSC_VER +#pragma optimize("", off) +#endif + +isc_boolean_t +isc_safe_memcmp(const void *s1, const void *s2, size_t n) { + isc_uint8_t acc = 0; + + if (n != 0U) { + const isc_uint8_t *p1 = s1, *p2 = s2; + + do { + acc |= *p1++ ^ *p2++; + } while (--n != 0U); + } + return (ISC_TF(acc == 0)); +} diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in index 89e11576..564d3cd9 100644 --- a/lib/isc/tests/Makefile.in +++ b/lib/isc/tests/Makefile.in @@ -37,13 +37,13 @@ LIBS = @LIBS@ @ATFLIBS@ OBJS = isctest.@O@ SRCS = isctest.c taskpool_test.c socket_test.c hash_test.c \ sockaddr_test.c symtab_test.c task_test.c queue_test.c \ - parse_test.c pool_test.c regex_test.c + parse_test.c pool_test.c regex_test.c safe_test.c SUBDIRS = TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \ sockaddr_test@EXEEXT@ symtab_test@EXEEXT@ task_test@EXEEXT@ \ queue_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \ - regex_test@EXEEXT@ + regex_test@EXEEXT@ safe_test@EXEEXT@ @BIND9_MAKE_RULES@ @@ -87,6 +87,10 @@ regex_test@EXEEXT@: regex_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ regex_test.@O@ ${ISCLIBS} ${LIBS} +safe_test@EXEEXT@: safe_test.@O@ ${ISCDEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + safe_test.@O@ ${ISCLIBS} ${LIBS} + unit:: sh ${top_srcdir}/unit/unittest.sh diff --git a/lib/isc/tests/safe_test.c b/lib/isc/tests/safe_test.c new file mode 100644 index 00000000..7b7ac399 --- /dev/null +++ b/lib/isc/tests/safe_test.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id$ */ + +/* ! \file */ + +#include <config.h> + +#include <atf-c.h> + +#include <stdio.h> +#include <string.h> + +#include <isc/safe.h> +#include <isc/util.h> + +ATF_TC(isc_safe_memcmp); +ATF_TC_HEAD(isc_safe_memcmp, tc) { + atf_tc_set_md_var(tc, "descr", "safe memcmp()"); +} +ATF_TC_BODY(isc_safe_memcmp, tc) { + UNUSED(tc); + + ATF_CHECK(isc_safe_memcmp("test", "test", 4)); + ATF_CHECK(!isc_safe_memcmp("test", "tesc", 4)); + ATF_CHECK(isc_safe_memcmp("\x00\x00\x00\x00", "\x00\x00\x00\x00", 4)); + ATF_CHECK(!isc_safe_memcmp("\x00\x00\x00\x00", "\x00\x00\x00\x01", 4)); + ATF_CHECK(!isc_safe_memcmp("\x00\x00\x00\x02", "\x00\x00\x00\x00", 4)); +} + +/* + * Main + */ +ATF_TP_ADD_TCS(tp) { + ATF_TP_ADD_TC(tp, isc_safe_memcmp); + return (atf_no_error()); +} + diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def index 8b698683..0c7a829f 100644 --- a/lib/isc/win32/libisc.def +++ b/lib/isc/win32/libisc.def @@ -467,6 +467,7 @@ isc_rwlock_lock isc_rwlock_trylock isc_rwlock_tryupgrade isc_rwlock_unlock +isc_safe_memcmp isc_serial_eq isc_serial_ge isc_serial_gt diff --git a/lib/isc/win32/libisc.dsp b/lib/isc/win32/libisc.dsp index 0d3131a8..0f14a899 100644 --- a/lib/isc/win32/libisc.dsp +++ b/lib/isc/win32/libisc.dsp @@ -487,6 +487,10 @@ SOURCE=..\include\isc\rwlock.h # End Source File
# Begin Source File
+SOURCE=..\include\isc\safe.h
+# End Source File
+# Begin Source File
+
SOURCE=..\include\isc\serial.h
# End Source File
# Begin Source File
@@ -759,6 +763,10 @@ SOURCE=..\rwlock.c # End Source File
# Begin Source File
+SOURCE=..\safe.c
+# End Source File
+# Begin Source File
+
SOURCE=..\serial.c
# End Source File
# Begin Source File
diff --git a/lib/isc/win32/libisc.mak b/lib/isc/win32/libisc.mak index cd0267e2..96e44e4a 100644 --- a/lib/isc/win32/libisc.mak +++ b/lib/isc/win32/libisc.mak @@ -174,6 +174,7 @@ CLEAN : -@erase "$(INTDIR)\resource.obj"
-@erase "$(INTDIR)\result.obj"
-@erase "$(INTDIR)\rwlock.obj"
+ -@erase "$(INTDIR)\safe.obj"
-@erase "$(INTDIR)\serial.obj"
-@erase "$(INTDIR)\sha1.obj"
-@erase "$(INTDIR)\sha2.obj"
@@ -277,6 +278,7 @@ LINK32_OBJS= \ "$(INTDIR)\refcount.obj" \
"$(INTDIR)\result.obj" \
"$(INTDIR)\rwlock.obj" \
+ "$(INTDIR)\safe.obj" \
"$(INTDIR)\serial.obj" \
"$(INTDIR)\sha1.obj" \
"$(INTDIR)\sha2.obj" \
@@ -431,6 +433,8 @@ CLEAN : -@erase "$(INTDIR)\result.sbr"
-@erase "$(INTDIR)\rwlock.obj"
-@erase "$(INTDIR)\rwlock.sbr"
+ -@erase "$(INTDIR)\safe.obj"
+ -@erase "$(INTDIR)\safe.sbr"
-@erase "$(INTDIR)\serial.obj"
-@erase "$(INTDIR)\serial.sbr"
-@erase "$(INTDIR)\sha1.obj"
@@ -552,6 +556,7 @@ BSC32_SBRS= \ "$(INTDIR)\refcount.sbr" \
"$(INTDIR)\result.sbr" \
"$(INTDIR)\rwlock.sbr" \
+ "$(INTDIR)\safe.sbr" \
"$(INTDIR)\serial.sbr" \
"$(INTDIR)\sha1.sbr" \
"$(INTDIR)\sha2.sbr" \
@@ -642,6 +647,7 @@ LINK32_OBJS= \ "$(INTDIR)\refcount.obj" \
"$(INTDIR)\result.obj" \
"$(INTDIR)\rwlock.obj" \
+ "$(INTDIR)\safe.obj" \
"$(INTDIR)\serial.obj" \
"$(INTDIR)\sha1.obj" \
"$(INTDIR)\sha2.obj" \
@@ -1901,6 +1907,24 @@ SOURCE=..\rwlock.c !ENDIF
+SOURCE=..\safe.c
+
+!IF "$(CFG)" == "libisc - Win32 Release"
+
+
+"$(INTDIR)\safe.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "libisc - Win32 Debug"
+
+
+"$(INTDIR)\safe.obj" "$(INTDIR)\safe.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
SOURCE=..\serial.c
!IF "$(CFG)" == "libisc - Win32 Release"
diff --git a/lib/isccc/api b/lib/isccc/api index 47724c51..95bd2046 100644 --- a/lib/isccc/api +++ b/lib/isccc/api @@ -5,5 +5,5 @@ # 9.9: 90-109 # 9.9-sub: 130-139 LIBINTERFACE = 90 -LIBREVISION = 3 +LIBREVISION = 4 LIBAGE = 0 diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c index 07f8157b..ae5391a5 100644 --- a/lib/isccc/cc.c +++ b/lib/isccc/cc.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2007, 2012 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -42,6 +42,7 @@ #include <isc/assertions.h> #include <isc/hmacmd5.h> #include <isc/print.h> +#include <isc/safe.h> #include <isc/stdlib.h> #include <isccc/alist.h> @@ -311,7 +312,8 @@ verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length, /* * Verify. */ - if (strcmp((char *)digestb64, isccc_sexpr_tostring(hmd5)) != 0) + if (!isc_safe_memcmp((unsigned char *) isccc_sexpr_tostring(hmd5), + digestb64, HMD5_LENGTH)) return (ISCCC_R_BADAUTH); return (ISC_R_SUCCESS); |