]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Protect dst key metadata with lock
authorMatthijs Mekking <matthijs@isc.org>
Fri, 25 Jun 2021 08:51:21 +0000 (10:51 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 30 Jun 2021 15:28:49 +0000 (17:28 +0200)
The DST key metadata can be written by several threads in parralel.
Protect the dst_key_get* and dst_key_set* functions with a mutex.

lib/dns/dst_api.c
lib/dns/dst_internal.h

index f0af50f6d22df464ceeddb6750e2a8146e68b7fc..de40f929a7e7419aa94abf2939f7cad0094f5d18 100644 (file)
@@ -1015,10 +1015,15 @@ dst_key_getbool(const dst_key_t *key, int type, bool *valuep) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(valuep != NULL);
        REQUIRE(type <= DST_MAX_BOOLEAN);
+
+       isc_mutex_lock(&(((dst_key_t *)key)->mdlock));
        if (!key->boolset[type]) {
+               isc_mutex_unlock(&(((dst_key_t *)key)->mdlock));
                return (ISC_R_NOTFOUND);
        }
        *valuep = key->bools[type];
+       isc_mutex_unlock(&(((dst_key_t *)key)->mdlock));
+
        return (ISC_R_SUCCESS);
 }
 
@@ -1026,15 +1031,21 @@ void
 dst_key_setbool(dst_key_t *key, int type, bool value) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(type <= DST_MAX_BOOLEAN);
+
+       isc_mutex_lock(&key->mdlock);
        key->bools[type] = value;
        key->boolset[type] = true;
+       isc_mutex_unlock(&key->mdlock);
 }
 
 void
 dst_key_unsetbool(dst_key_t *key, int type) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(type <= DST_MAX_BOOLEAN);
+
+       isc_mutex_lock(&key->mdlock);
        key->boolset[type] = false;
+       isc_mutex_unlock(&key->mdlock);
 }
 
 isc_result_t
@@ -1042,10 +1053,15 @@ dst_key_getnum(const dst_key_t *key, int type, uint32_t *valuep) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(valuep != NULL);
        REQUIRE(type <= DST_MAX_NUMERIC);
+
+       isc_mutex_lock(&(((dst_key_t *)key)->mdlock));
        if (!key->numset[type]) {
+               isc_mutex_unlock(&(((dst_key_t *)key)->mdlock));
                return (ISC_R_NOTFOUND);
        }
        *valuep = key->nums[type];
+       isc_mutex_unlock(&(((dst_key_t *)key)->mdlock));
+
        return (ISC_R_SUCCESS);
 }
 
@@ -1053,15 +1069,21 @@ void
 dst_key_setnum(dst_key_t *key, int type, uint32_t value) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(type <= DST_MAX_NUMERIC);
+
+       isc_mutex_lock(&key->mdlock);
        key->nums[type] = value;
        key->numset[type] = true;
+       isc_mutex_unlock(&key->mdlock);
 }
 
 void
 dst_key_unsetnum(dst_key_t *key, int type) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(type <= DST_MAX_NUMERIC);
+
+       isc_mutex_lock(&key->mdlock);
        key->numset[type] = false;
+       isc_mutex_unlock(&key->mdlock);
 }
 
 isc_result_t
@@ -1069,10 +1091,14 @@ dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(timep != NULL);
        REQUIRE(type <= DST_MAX_TIMES);
+
+       isc_mutex_lock(&(((dst_key_t *)key)->mdlock));
        if (!key->timeset[type]) {
+               isc_mutex_unlock(&(((dst_key_t *)key)->mdlock));
                return (ISC_R_NOTFOUND);
        }
        *timep = key->times[type];
+       isc_mutex_unlock(&(((dst_key_t *)key)->mdlock));
        return (ISC_R_SUCCESS);
 }
 
@@ -1080,15 +1106,21 @@ void
 dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(type <= DST_MAX_TIMES);
+
+       isc_mutex_lock(&key->mdlock);
        key->times[type] = when;
        key->timeset[type] = true;
+       isc_mutex_unlock(&key->mdlock);
 }
 
 void
 dst_key_unsettime(dst_key_t *key, int type) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(type <= DST_MAX_TIMES);
+
+       isc_mutex_lock(&key->mdlock);
        key->timeset[type] = false;
+       isc_mutex_unlock(&key->mdlock);
 }
 
 isc_result_t
@@ -1096,10 +1128,15 @@ dst_key_getstate(const dst_key_t *key, int type, dst_key_state_t *statep) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(statep != NULL);
        REQUIRE(type <= DST_MAX_KEYSTATES);
+
+       isc_mutex_lock(&(((dst_key_t *)key)->mdlock));
        if (!key->keystateset[type]) {
+               isc_mutex_unlock(&(((dst_key_t *)key)->mdlock));
                return (ISC_R_NOTFOUND);
        }
        *statep = key->keystates[type];
+       isc_mutex_unlock(&(((dst_key_t *)key)->mdlock));
+
        return (ISC_R_SUCCESS);
 }
 
@@ -1107,15 +1144,21 @@ void
 dst_key_setstate(dst_key_t *key, int type, dst_key_state_t state) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(type <= DST_MAX_KEYSTATES);
+
+       isc_mutex_lock(&key->mdlock);
        key->keystates[type] = state;
        key->keystateset[type] = true;
+       isc_mutex_unlock(&key->mdlock);
 }
 
 void
 dst_key_unsetstate(dst_key_t *key, int type) {
        REQUIRE(VALID_KEY(key));
        REQUIRE(type <= DST_MAX_KEYSTATES);
+
+       isc_mutex_lock(&key->mdlock);
        key->keystateset[type] = false;
+       isc_mutex_unlock(&key->mdlock);
 }
 
 isc_result_t
@@ -1287,6 +1330,7 @@ dst_key_free(dst_key_t **keyp) {
                if (key->key_tkeytoken) {
                        isc_buffer_free(&key->key_tkeytoken);
                }
+               isc_mutex_destroy(&key->mdlock);
                isc_safe_memwipe(key, sizeof(*key));
                isc_mem_putanddetach(&mctx, key, sizeof(*key));
        }
@@ -1482,6 +1526,7 @@ get_key_struct(const dns_name_t *name, unsigned int alg, unsigned int flags,
                key->times[i] = 0;
                key->timeset[i] = false;
        }
+       isc_mutex_init(&key->mdlock);
        key->inactive = false;
        key->magic = KEY_MAGIC;
        return (key);
index 793606e013bae48c866e990d95d9dd0a1ff08aa4..5955072ef30f5d80a6e50e32552e641a34dcd07c 100644 (file)
@@ -79,6 +79,7 @@ typedef enum { DO_SIGN, DO_VERIFY } dst_use_t;
 struct dst_key {
        unsigned int magic;
        isc_refcount_t refs;
+       isc_mutex_t mdlock;         /*%< lock for read/write metadata */
        dns_name_t *key_name;       /*%< name of the key */
        unsigned int key_size;      /*%< size of the key in bits */
        unsigned int key_proto;     /*%< protocols this key is used for