eap-simaka-reauth: Prevent corrupting hashtables during concurrent accesses
Basically the same as the previous commit.
Fixes: edcb2dd35b ("Moved reauth/pseudonym functionality from eap-sim-file to separate plugins, usable by any SIM/AKA backend")
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <collections/hashtable.h>
|
#include <collections/hashtable.h>
|
||||||
|
#include <threading/mutex.h>
|
||||||
|
|
||||||
typedef struct private_eap_simaka_reauth_provider_t private_eap_simaka_reauth_provider_t;
|
typedef struct private_eap_simaka_reauth_provider_t private_eap_simaka_reauth_provider_t;
|
||||||
|
|
||||||
@@ -45,6 +46,11 @@ struct private_eap_simaka_reauth_provider_t {
|
|||||||
* RNG for pseudonyms/reauth identities
|
* RNG for pseudonyms/reauth identities
|
||||||
*/
|
*/
|
||||||
rng_t *rng;
|
rng_t *rng;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock for reauth mappings
|
||||||
|
*/
|
||||||
|
mutex_t *mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,21 +104,27 @@ METHOD(simaka_provider_t, is_reauth, identification_t*,
|
|||||||
identification_t *permanent;
|
identification_t *permanent;
|
||||||
reauth_data_t *data;
|
reauth_data_t *data;
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
|
|
||||||
/* look up permanent identity */
|
/* look up permanent identity */
|
||||||
permanent = this->permanent->get(this->permanent, id);
|
permanent = this->permanent->get(this->permanent, id);
|
||||||
if (!permanent)
|
if (!permanent)
|
||||||
{
|
{
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* look up reauthentication data */
|
/* look up reauthentication data */
|
||||||
data = this->reauth->get(this->reauth, permanent);
|
data = this->reauth->get(this->reauth, permanent);
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
*counter = ++data->counter;
|
*counter = ++data->counter;
|
||||||
memcpy(mk, data->mk, HASH_SIZE_SHA1);
|
memcpy(mk, data->mk, HASH_SIZE_SHA1);
|
||||||
return permanent->clone(permanent);
|
permanent = permanent->clone(permanent);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
return permanent;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(simaka_provider_t, gen_reauth, identification_t*,
|
METHOD(simaka_provider_t, gen_reauth, identification_t*,
|
||||||
@@ -122,10 +134,12 @@ METHOD(simaka_provider_t, gen_reauth, identification_t*,
|
|||||||
reauth_data_t *data;
|
reauth_data_t *data;
|
||||||
identification_t *permanent, *new_id;
|
identification_t *permanent, *new_id;
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
new_id = gen_identity(this);
|
new_id = gen_identity(this);
|
||||||
if (!new_id)
|
if (!new_id)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "failed to generate identity");
|
DBG1(DBG_CFG, "failed to generate identity");
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +169,9 @@ METHOD(simaka_provider_t, gen_reauth, identification_t*,
|
|||||||
}
|
}
|
||||||
memcpy(data->mk, mk, HASH_SIZE_SHA1);
|
memcpy(data->mk, mk, HASH_SIZE_SHA1);
|
||||||
|
|
||||||
return data->id->clone(data->id);
|
new_id = data->id->clone(data->id);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
return new_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(eap_simaka_reauth_provider_t, destroy, void,
|
METHOD(eap_simaka_reauth_provider_t, destroy, void,
|
||||||
@@ -183,7 +199,8 @@ METHOD(eap_simaka_reauth_provider_t, destroy, void,
|
|||||||
|
|
||||||
this->permanent->destroy(this->permanent);
|
this->permanent->destroy(this->permanent);
|
||||||
this->reauth->destroy(this->reauth);
|
this->reauth->destroy(this->reauth);
|
||||||
this->rng->destroy(this->rng);
|
this->mutex->destroy(this->mutex);
|
||||||
|
DESTROY_IF(this->rng);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,16 +224,16 @@ eap_simaka_reauth_provider_t *eap_simaka_reauth_provider_create()
|
|||||||
},
|
},
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
.permanent = hashtable_create((void*)hash, (void*)equals, 0),
|
||||||
|
.reauth = hashtable_create((void*)hash, (void*)equals, 0),
|
||||||
.rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
|
.rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
|
||||||
|
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||||
);
|
);
|
||||||
if (!this->rng)
|
if (!this->rng)
|
||||||
{
|
{
|
||||||
free(this);
|
destroy(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
this->permanent = hashtable_create((void*)hash, (void*)equals, 0);
|
|
||||||
this->reauth = hashtable_create((void*)hash, (void*)equals, 0);
|
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user