Skip to content

Commit 0abef75

Browse files
committed
HACL*: fortify DEBUG checks for fetching the module state
1 parent 6fa08b0 commit 0abef75

File tree

7 files changed

+186
-123
lines changed

7 files changed

+186
-123
lines changed

Modules/blake2module.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515
#endif
1616

1717
#include "Python.h"
18+
#include "pycore_moduleobject.h" // _PyModule_GetState()
19+
#include "pycore_strhex.h" // _Py_strhex()
20+
#include "pycore_typeobject.h" // _PyType_GetModuleState()
21+
1822
#include "hashlib.h"
19-
#include "pycore_strhex.h" // _Py_strhex()
20-
#include "pycore_typeobject.h"
21-
#include "pycore_moduleobject.h"
2223

2324
// QUICK CPU AUTODETECTION
2425
//
@@ -67,6 +68,7 @@
6768

6869
// MODULE TYPE SLOTS
6970

71+
static struct PyModuleDef blake2module_def;
7072
static PyType_Spec blake2b_type_spec;
7173
static PyType_Spec blake2s_type_spec;
7274

@@ -78,23 +80,24 @@ typedef struct {
7880
PyTypeObject *blake2s_type;
7981
bool can_run_simd128;
8082
bool can_run_simd256;
81-
} Blake2State;
83+
} blake2module_state;
8284

83-
static inline Blake2State *
84-
blake2_get_state(PyObject *module)
85+
static inline blake2module_state *
86+
get_blake2module_state(PyObject *module)
8587
{
8688
void *state = _PyModule_GetState(module);
8789
assert(state != NULL);
88-
return (Blake2State *)state;
90+
return (blake2module_state *)state;
8991
}
9092

9193
#if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256)
92-
static inline Blake2State *
93-
blake2_get_state_from_type(PyTypeObject *module)
94+
static inline blake2module_state *
95+
get_blake2module_state_by_cls(PyTypeObject *cls)
9496
{
95-
void *state = _PyType_GetModuleState(module);
97+
_Py_hashlib_check_exported_type(cls, &blake2module_def);
98+
void *state = _PyType_GetModuleState(cls);
9699
assert(state != NULL);
97-
return (Blake2State *)state;
100+
return (blake2module_state *)state;
98101
}
99102
#endif
100103

@@ -105,7 +108,7 @@ static struct PyMethodDef blake2mod_functions[] = {
105108
static int
106109
_blake2_traverse(PyObject *module, visitproc visit, void *arg)
107110
{
108-
Blake2State *state = blake2_get_state(module);
111+
blake2module_state *state = get_blake2module_state(module);
109112
Py_VISIT(state->blake2b_type);
110113
Py_VISIT(state->blake2s_type);
111114
return 0;
@@ -114,7 +117,7 @@ _blake2_traverse(PyObject *module, visitproc visit, void *arg)
114117
static int
115118
_blake2_clear(PyObject *module)
116119
{
117-
Blake2State *state = blake2_get_state(module);
120+
blake2module_state *state = get_blake2module_state(module);
118121
Py_CLEAR(state->blake2b_type);
119122
Py_CLEAR(state->blake2s_type);
120123
return 0;
@@ -127,7 +130,7 @@ _blake2_free(void *module)
127130
}
128131

129132
static void
130-
blake2module_init_cpu_features(Blake2State *state)
133+
blake2module_init_cpu_features(blake2module_state *state)
131134
{
132135
/* This must be kept in sync with hmacmodule_init_cpu_features()
133136
* in hmacmodule.c */
@@ -205,7 +208,7 @@ blake2module_init_cpu_features(Blake2State *state)
205208
static int
206209
blake2_exec(PyObject *m)
207210
{
208-
Blake2State *st = blake2_get_state(m);
211+
blake2module_state *st = get_blake2module_state(m);
209212
blake2module_init_cpu_features(st);
210213

211214
#define ADD_INT(DICT, NAME, VALUE) \
@@ -285,11 +288,11 @@ static PyModuleDef_Slot _blake2_slots[] = {
285288
{0, NULL}
286289
};
287290

288-
static struct PyModuleDef blake2_module = {
291+
static struct PyModuleDef blake2module_def = {
289292
.m_base = PyModuleDef_HEAD_INIT,
290293
.m_name = "_blake2",
291294
.m_doc = blake2mod__doc__,
292-
.m_size = sizeof(Blake2State),
295+
.m_size = sizeof(blake2module_state),
293296
.m_methods = blake2mod_functions,
294297
.m_slots = _blake2_slots,
295298
.m_traverse = _blake2_traverse,
@@ -300,7 +303,7 @@ static struct PyModuleDef blake2_module = {
300303
PyMODINIT_FUNC
301304
PyInit__blake2(void)
302305
{
303-
return PyModuleDef_Init(&blake2_module);
306+
return PyModuleDef_Init(&blake2module_def);
304307
}
305308

306309
// IMPLEMENTATION OF METHODS
@@ -333,7 +336,7 @@ static inline blake2_impl
333336
type_to_impl(PyTypeObject *type)
334337
{
335338
#if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256)
336-
Blake2State *st = blake2_get_state_from_type(type);
339+
blake2module_state *st = get_blake2module_state_by_cls(type);
337340
#endif
338341
if (!strcmp(type->tp_name, blake2b_type_spec.name)) {
339342
#if HACL_CAN_COMPILE_SIMD256
@@ -385,6 +388,7 @@ class _blake2.blake2s "Blake2Object *" "&PyType_Type"
385388
static Blake2Object *
386389
new_Blake2Object(PyTypeObject *type)
387390
{
391+
_Py_hashlib_check_exported_type(type, &blake2module_def);
388392
Blake2Object *self = PyObject_GC_New(Blake2Object, type);
389393
if (self == NULL) {
390394
return NULL;

Modules/hashlib.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ _Py_hashlib_check_exported_type(PyTypeObject *type, PyModuleDef *moddef)
2222
/* ensure that the associated module definition matches 'moddef' */
2323
PyHeapTypeObject *ht = (PyHeapTypeObject *)type;
2424
assert(ht->ht_module != NULL);
25-
assert(moddef == _PyModule_GetDef(ht->ht_module));
25+
PyModuleDef *ht_moddef = _PyModule_GetDef(ht->ht_module);
26+
assert(ht_moddef != NULL);
27+
assert(ht_moddef == moddef);
2628
}
2729
#else
2830
#define _Py_hashlib_check_exported_type(_TYPE, _MODDEF)

Modules/hmacmodule.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
#include "Python.h"
2020
#include "pycore_hashtable.h"
21+
#include "pycore_moduleobject.h" // _PyModule_GetState()
2122
#include "pycore_strhex.h" // _Py_strhex()
23+
#include "pycore_typeobject.h" // _PyType_GetModuleState()
2224

2325
/*
2426
* Taken from blake2module.c. In the future, detection of SIMD support
@@ -250,6 +252,8 @@ typedef struct py_hmac_hinfo {
250252

251253
// --- HMAC module state ------------------------------------------------------
252254

255+
static struct PyModuleDef hmacmodule_def;
256+
253257
typedef struct hmacmodule_state {
254258
_Py_hashtable_t *hinfo_table;
255259
PyObject *unknown_hash_error;
@@ -265,15 +269,16 @@ typedef struct hmacmodule_state {
265269
static inline hmacmodule_state *
266270
get_hmacmodule_state(PyObject *module)
267271
{
268-
void *state = PyModule_GetState(module);
272+
void *state = _PyModule_GetState(module);
269273
assert(state != NULL);
270274
return (hmacmodule_state *)state;
271275
}
272276

273277
static inline hmacmodule_state *
274278
get_hmacmodule_state_by_cls(PyTypeObject *cls)
275279
{
276-
void *state = PyType_GetModuleState(cls);
280+
_Py_hashlib_check_exported_type(cls, &hmacmodule_def);
281+
void *state = _PyType_GetModuleState(cls);
277282
assert(state != NULL);
278283
return (hmacmodule_state *)state;
279284
}
@@ -301,13 +306,11 @@ typedef struct HMACObject {
301306

302307
/*[clinic input]
303308
module _hmac
304-
class _hmac.HMAC "HMACObject *" "clinic_state()->hmac_type"
309+
class _hmac.HMAC "HMACObject *" "&PyType_Type"
305310
[clinic start generated code]*/
306-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c8bab73fde49ba8a]*/
311+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=72bc06d6dc634770]*/
307312

308-
#define clinic_state() (get_hmacmodule_state_by_cls(Py_TYPE(self)))
309313
#include "clinic/hmacmodule.c.h"
310-
#undef clinic_state
311314

312315
// --- Helpers ----------------------------------------------------------------
313316
//
@@ -1683,7 +1686,7 @@ static struct PyModuleDef_Slot hmacmodule_slots[] = {
16831686
{0, NULL} /* sentinel */
16841687
};
16851688

1686-
static struct PyModuleDef _hmacmodule = {
1689+
static struct PyModuleDef hmacmodule_def = {
16871690
PyModuleDef_HEAD_INIT,
16881691
.m_name = "_hmac",
16891692
.m_size = sizeof(hmacmodule_state),
@@ -1697,5 +1700,5 @@ static struct PyModuleDef _hmacmodule = {
16971700
PyMODINIT_FUNC
16981701
PyInit__hmac(void)
16991702
{
1700-
return PyModuleDef_Init(&_hmacmodule);
1703+
return PyModuleDef_Init(&hmacmodule_def);
17011704
}

Modules/md5module.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
#endif
2323

2424
#include "Python.h"
25-
#include "pycore_strhex.h" // _Py_strhex()
25+
#include "pycore_moduleobject.h" // _PyModule_GetState()
26+
#include "pycore_strhex.h" // _Py_strhex()
27+
#include "pycore_typeobject.h" // _PyType_GetModuleState()
2628

2729
#include "hashlib.h"
2830

@@ -44,16 +46,27 @@ typedef struct {
4446

4547
// --- Module state -----------------------------------------------------------
4648

49+
static struct PyModuleDef md5module_def;
50+
4751
typedef struct {
48-
PyTypeObject* md5_type;
49-
} MD5State;
52+
PyTypeObject *md5_type;
53+
} md5module_state;
54+
55+
static inline md5module_state *
56+
get_md5module_state(PyObject *module)
57+
{
58+
void *state = _PyModule_GetState(module);
59+
assert(state != NULL);
60+
return (md5module_state *)state;
61+
}
5062

51-
static inline MD5State*
52-
md5_get_state(PyObject *module)
63+
static inline md5module_state *
64+
get_md5module_state_by_cls(PyTypeObject *cls)
5365
{
54-
void *state = PyModule_GetState(module);
66+
_Py_hashlib_check_exported_type(cls, &md5module_def);
67+
void *state = _PyType_GetModuleState(cls);
5568
assert(state != NULL);
56-
return (MD5State *)state;
69+
return (md5module_state *)state;
5770
}
5871

5972
// --- Module clinic configuration --------------------------------------------
@@ -69,7 +82,7 @@ class MD5Type "MD5object *" "&PyType_Type"
6982
// --- MD5 object interface ---------------------------------------------------
7083

7184
static MD5object *
72-
newMD5object(MD5State * st)
85+
newMD5object(md5module_state *st)
7386
{
7487
MD5object *md5 = PyObject_GC_New(MD5object, st->md5_type);
7588
if (!md5) {
@@ -115,7 +128,7 @@ static PyObject *
115128
MD5Type_copy_impl(MD5object *self, PyTypeObject *cls)
116129
/*[clinic end generated code: output=bf055e08244bf5ee input=d89087dcfb2a8620]*/
117130
{
118-
MD5State *st = PyType_GetModuleState(cls);
131+
md5module_state *st = get_md5module_state_by_cls(cls);
119132

120133
MD5object *newobj;
121134
if ((newobj = newMD5object(st)) == NULL) {
@@ -288,7 +301,7 @@ _md5_md5_impl(PyObject *module, PyObject *data, int usedforsecurity,
288301
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
289302
}
290303

291-
MD5State *st = md5_get_state(module);
304+
md5module_state *st = get_md5module_state(module);
292305
if ((new = newMD5object(st)) == NULL) {
293306
if (string) {
294307
PyBuffer_Release(&buf);
@@ -329,15 +342,15 @@ static struct PyMethodDef MD5_functions[] = {
329342
static int
330343
_md5_traverse(PyObject *module, visitproc visit, void *arg)
331344
{
332-
MD5State *state = md5_get_state(module);
345+
md5module_state *state = get_md5module_state(module);
333346
Py_VISIT(state->md5_type);
334347
return 0;
335348
}
336349

337350
static int
338351
_md5_clear(PyObject *module)
339352
{
340-
MD5State *state = md5_get_state(module);
353+
md5module_state *state = get_md5module_state(module);
341354
Py_CLEAR(state->md5_type);
342355
return 0;
343356
}
@@ -352,7 +365,7 @@ _md5_free(void *module)
352365
static int
353366
md5_exec(PyObject *m)
354367
{
355-
MD5State *st = md5_get_state(m);
368+
md5module_state *st = get_md5module_state(m);
356369

357370
st->md5_type = (PyTypeObject *)PyType_FromModuleAndSpec(
358371
m, &md5_type_spec, NULL);
@@ -375,10 +388,10 @@ static PyModuleDef_Slot _md5_slots[] = {
375388
};
376389

377390

378-
static struct PyModuleDef _md5module = {
391+
static struct PyModuleDef md5module_def = {
379392
PyModuleDef_HEAD_INIT,
380393
.m_name = "_md5",
381-
.m_size = sizeof(MD5State),
394+
.m_size = sizeof(md5module_state),
382395
.m_methods = MD5_functions,
383396
.m_slots = _md5_slots,
384397
.m_traverse = _md5_traverse,
@@ -389,5 +402,5 @@ static struct PyModuleDef _md5module = {
389402
PyMODINIT_FUNC
390403
PyInit__md5(void)
391404
{
392-
return PyModuleDef_Init(&_md5module);
405+
return PyModuleDef_Init(&md5module_def);
393406
}

0 commit comments

Comments
 (0)