Skip to content

Commit 20d2786

Browse files
authored
gh-155843: properly initialize HMAC objects to prevent crashes after allocation failures (#155845)
1 parent 83dbe6a commit 20d2786

2 files changed

Lines changed: 25 additions & 18 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`hmac`: ensure that HMAC objects are properly initialized to prevent
2+
rare crashes on allocation failures. Patch by Bénédikt Tran.

Modules/hmacmodule.c

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,6 @@ get_hmacmodule_state(PyObject *module)
271271
return (hmacmodule_state *)state;
272272
}
273273

274-
static inline hmacmodule_state *
275-
get_hmacmodule_state_by_cls(PyTypeObject *cls)
276-
{
277-
void *state = PyType_GetModuleState(cls);
278-
assert(state != NULL);
279-
return (hmacmodule_state *)state;
280-
}
281-
282274
// --- HMAC Object ------------------------------------------------------------
283275

284276
typedef Hacl_Streaming_HMAC_agile_state HACL_HMAC_state;
@@ -676,6 +668,24 @@ has_uint32_t_buffer_length(const Py_buffer *buffer)
676668

677669
// --- HMAC object ------------------------------------------------------------
678670

671+
/*
672+
* Create a zero-initialized untracked HMAC object.
673+
*
674+
* Return NULL on failure with an exception set.
675+
*/
676+
static HMACObject *
677+
hmac_new_object(PyTypeObject *tp)
678+
{
679+
HMACObject *self = (HMACObject *)tp->tp_alloc(tp, 0);
680+
if (self == NULL) {
681+
return NULL;
682+
}
683+
HASHLIB_INIT_MUTEX(self);
684+
// tp_alloc initializes the memory to zero but the unknown kind is -1
685+
self->kind = Py_hmac_kind_hash_unknown;
686+
return self;
687+
}
688+
679689
/*
680690
* Use the HMAC information 'info' to populate the corresponding fields.
681691
*
@@ -687,7 +697,7 @@ hmac_set_hinfo(hmacmodule_state *state,
687697
HMACObject *self, const py_hmac_hinfo *info)
688698
{
689699
assert(info->display_name != NULL);
690-
self->name = Py_NewRef(info->display_name);
700+
Py_XSETREF(self->name, Py_NewRef(info->display_name));
691701
assert_is_static_hmac_hash_kind(info->kind);
692702
self->kind = narrow_hmac_hash_kind(state, info->kind);
693703
assert(info->block_size <= Py_hmac_hash_max_block_size);
@@ -756,16 +766,15 @@ _hmac_new_impl(PyObject *module, PyObject *keyobj, PyObject *msgobj,
756766
return NULL;
757767
}
758768

759-
HMACObject *self = PyObject_New(HMACObject, state->hmac_type);
769+
HMACObject *self = hmac_new_object(state->hmac_type);
760770
if (self == NULL) {
761771
return NULL;
762772
}
763-
HASHLIB_INIT_MUTEX(self);
764773
hmac_set_hinfo(state, self, info);
765774
int rc;
766775
// Create the HACL* internal state with the given key.
767776
Py_buffer key;
768-
GET_BUFFER_VIEW_OR_ERROR(keyobj, &key, goto error_on_key);
777+
GET_BUFFER_VIEW_OR_ERROR(keyobj, &key, goto error);
769778
rc = hmac_new_initial_state(self, key.buf, key.len);
770779
PyBuffer_Release(&key);
771780
if (rc < 0) {
@@ -793,8 +802,6 @@ _hmac_new_impl(PyObject *module, PyObject *keyobj, PyObject *msgobj,
793802
assert(rc == 0);
794803
return (PyObject *)self;
795804

796-
error_on_key:
797-
self->state = NULL;
798805
error:
799806
Py_DECREF(self);
800807
return NULL;
@@ -807,7 +814,7 @@ static void
807814
hmac_copy_hinfo(HMACObject *out, const HMACObject *src)
808815
{
809816
assert(src->name != NULL);
810-
out->name = Py_NewRef(src->name);
817+
Py_XSETREF(out->name, Py_NewRef(src->name));
811818
assert(src->kind != Py_hmac_kind_hash_unknown);
812819
out->kind = src->kind;
813820
assert(src->block_size <= Py_hmac_hash_max_block_size);
@@ -850,8 +857,7 @@ static PyObject *
850857
_hmac_HMAC_copy_impl(HMACObject *self, PyTypeObject *cls)
851858
/*[clinic end generated code: output=a955bfa55b65b215 input=17b2c0ad0b147e36]*/
852859
{
853-
hmacmodule_state *state = get_hmacmodule_state_by_cls(cls);
854-
HMACObject *copy = PyObject_New(HMACObject, state->hmac_type);
860+
HMACObject *copy = hmac_new_object(cls);
855861
if (copy == NULL) {
856862
return NULL;
857863
}
@@ -868,7 +874,6 @@ _hmac_HMAC_copy_impl(HMACObject *self, PyTypeObject *cls)
868874
return NULL;
869875
}
870876

871-
HASHLIB_INIT_MUTEX(copy);
872877
return (PyObject *)copy;
873878
}
874879

0 commit comments

Comments
 (0)