Skip to content

Commit edbd446

Browse files
committed
[3.14] gh-155843: properly initialize HMAC objects to prevent crashes after allocation failures (GH-155845)
(cherry picked from commit 20d2786) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent a9152fb commit edbd446

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
@@ -370,14 +370,6 @@ get_hmacmodule_state(PyObject *module)
370370
return (hmacmodule_state *)state;
371371
}
372372

373-
static inline hmacmodule_state *
374-
get_hmacmodule_state_by_cls(PyTypeObject *cls)
375-
{
376-
void *state = PyType_GetModuleState(cls);
377-
assert(state != NULL);
378-
return (hmacmodule_state *)state;
379-
}
380-
381373
// --- HMAC Object ------------------------------------------------------------
382374

383375
typedef Hacl_Streaming_HMAC_agile_state HACL_HMAC_state;
@@ -734,6 +726,24 @@ has_uint32_t_buffer_length(const Py_buffer *buffer)
734726

735727
// --- HMAC object ------------------------------------------------------------
736728

729+
/*
730+
* Create a zero-initialized untracked HMAC object.
731+
*
732+
* Return NULL on failure with an exception set.
733+
*/
734+
static HMACObject *
735+
hmac_new_object(PyTypeObject *tp)
736+
{
737+
HMACObject *self = (HMACObject *)tp->tp_alloc(tp, 0);
738+
if (self == NULL) {
739+
return NULL;
740+
}
741+
HASHLIB_INIT_MUTEX(self);
742+
// tp_alloc initializes the memory to zero but the unknown kind is -1
743+
self->kind = Py_hmac_kind_hash_unknown;
744+
return self;
745+
}
746+
737747
/*
738748
* Use the HMAC information 'info' to populate the corresponding fields.
739749
*
@@ -745,7 +755,7 @@ hmac_set_hinfo(hmacmodule_state *state,
745755
HMACObject *self, const py_hmac_hinfo *info)
746756
{
747757
assert(info->display_name != NULL);
748-
self->name = Py_NewRef(info->display_name);
758+
Py_XSETREF(self->name, Py_NewRef(info->display_name));
749759
assert_is_static_hmac_hash_kind(info->kind);
750760
self->kind = narrow_hmac_hash_kind(state, info->kind);
751761
assert(info->block_size <= Py_hmac_hash_max_block_size);
@@ -853,16 +863,15 @@ _hmac_new_impl(PyObject *module, PyObject *keyobj, PyObject *msgobj,
853863
return NULL;
854864
}
855865

856-
HMACObject *self = PyObject_GC_New(HMACObject, state->hmac_type);
866+
HMACObject *self = hmac_new_object(state->hmac_type);
857867
if (self == NULL) {
858868
return NULL;
859869
}
860-
HASHLIB_INIT_MUTEX(self);
861870
hmac_set_hinfo(state, self, info);
862871
int rc;
863872
// Create the HACL* internal state with the given key.
864873
Py_buffer key;
865-
GET_BUFFER_VIEW_OR_ERROR(keyobj, &key, goto error_on_key);
874+
GET_BUFFER_VIEW_OR_ERROR(keyobj, &key, goto error);
866875
rc = hmac_new_initial_state(self, key.buf, key.len);
867876
PyBuffer_Release(&key);
868877
if (rc < 0) {
@@ -886,8 +895,6 @@ _hmac_new_impl(PyObject *module, PyObject *keyobj, PyObject *msgobj,
886895
PyObject_GC_Track(self);
887896
return (PyObject *)self;
888897

889-
error_on_key:
890-
self->state = NULL;
891898
error:
892899
Py_DECREF(self);
893900
return NULL;
@@ -900,7 +907,7 @@ static void
900907
hmac_copy_hinfo(HMACObject *out, const HMACObject *src)
901908
{
902909
assert(src->name != NULL);
903-
out->name = Py_NewRef(src->name);
910+
Py_XSETREF(out->name, Py_NewRef(src->name));
904911
assert(src->kind != Py_hmac_kind_hash_unknown);
905912
out->kind = src->kind;
906913
assert(src->block_size <= Py_hmac_hash_max_block_size);
@@ -943,8 +950,7 @@ static PyObject *
943950
_hmac_HMAC_copy_impl(HMACObject *self, PyTypeObject *cls)
944951
/*[clinic end generated code: output=a955bfa55b65b215 input=17b2c0ad0b147e36]*/
945952
{
946-
hmacmodule_state *state = get_hmacmodule_state_by_cls(cls);
947-
HMACObject *copy = PyObject_GC_New(HMACObject, state->hmac_type);
953+
HMACObject *copy = hmac_new_object(cls);
948954
if (copy == NULL) {
949955
return NULL;
950956
}
@@ -961,7 +967,6 @@ _hmac_HMAC_copy_impl(HMACObject *self, PyTypeObject *cls)
961967
return NULL;
962968
}
963969

964-
HASHLIB_INIT_MUTEX(copy);
965970
PyObject_GC_Track(copy);
966971
return (PyObject *)copy;
967972
}

0 commit comments

Comments
 (0)