extmod/moductypes: Validate the descriptor tuple.
Fixes various null dereferencing, out-of-bounds memory accesses and `assert(0)` failures in the case of an invalid `uctypes` descriptor. By design `uctypes` can crash because it accesses arbitrary memory, but at least describing the descriptor layout should be forced to be correct and not crash. Fixes issue #12702. Signed-off-by: stijn <stijn@ignitron.net>
This commit is contained in:
parent
6db91dfefb
commit
444d7bacbe
@ -143,6 +143,10 @@ static inline mp_uint_t uctypes_struct_scalar_size(int val_type) {
|
||||
|
||||
// Get size of aggregate type descriptor
|
||||
static mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_uint_t *max_field_size) {
|
||||
if (t->len == 0) {
|
||||
syntax_error();
|
||||
}
|
||||
|
||||
mp_uint_t total_size = 0;
|
||||
|
||||
mp_int_t offset_ = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
|
||||
@ -150,8 +154,15 @@ static mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_
|
||||
|
||||
switch (agg_type) {
|
||||
case STRUCT:
|
||||
if (t->len != 2) {
|
||||
syntax_error();
|
||||
}
|
||||
return uctypes_struct_size(t->items[1], layout_type, max_field_size);
|
||||
case PTR:
|
||||
// Second field ignored, but should still be present for consistency.
|
||||
if (t->len != 2) {
|
||||
syntax_error();
|
||||
}
|
||||
if (sizeof(void *) > *max_field_size) {
|
||||
*max_field_size = sizeof(void *);
|
||||
}
|
||||
@ -167,15 +178,17 @@ static mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_
|
||||
if (item_s > *max_field_size) {
|
||||
*max_field_size = item_s;
|
||||
}
|
||||
} else {
|
||||
} else if (t->len == 3) {
|
||||
// Elements of array are aggregates
|
||||
item_s = uctypes_struct_size(t->items[2], layout_type, max_field_size);
|
||||
} else {
|
||||
syntax_error();
|
||||
}
|
||||
|
||||
return item_s * arr_sz;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
syntax_error();
|
||||
}
|
||||
|
||||
return total_size;
|
||||
|
||||
@ -43,8 +43,47 @@ assert uctypes.sizeof(S.arr4) == 6
|
||||
print(uctypes.sizeof(S.sub))
|
||||
assert uctypes.sizeof(S.sub) == 1
|
||||
|
||||
# invalid descriptor
|
||||
# invalid descriptors
|
||||
try:
|
||||
print(uctypes.sizeof([]))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
print(uctypes.sizeof(()))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
print(uctypes.sizeof(("garbage",)))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
# PTR * 3 is intended to be an invalid agg_type (STRUCT, PTR, ARRAY are valid ones).
|
||||
print(uctypes.sizeof((uctypes.PTR * 3,)))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
print(uctypes.sizeof((0, {}, "garbage")))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
print(uctypes.sizeof((uctypes.PTR | 0,)))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
print(uctypes.sizeof((uctypes.ARRAY | 0,)))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
print(uctypes.sizeof((uctypes.ARRAY | 0, 1, {}, "garbage")))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# empty descriptor
|
||||
print(uctypes.sizeof({}))
|
||||
|
||||
@ -5,3 +5,11 @@ TypeError
|
||||
6
|
||||
1
|
||||
TypeError
|
||||
TypeError
|
||||
TypeError
|
||||
TypeError
|
||||
TypeError
|
||||
TypeError
|
||||
TypeError
|
||||
TypeError
|
||||
0
|
||||
|
||||
@ -45,9 +45,3 @@ assert uctypes.sizeof(S.arr4) == 6
|
||||
|
||||
print(uctypes.sizeof(S.sub))
|
||||
assert uctypes.sizeof(S.sub) == 1
|
||||
|
||||
# invalid descriptor
|
||||
try:
|
||||
print(uctypes.sizeof([]))
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
@ -4,4 +4,3 @@
|
||||
TypeError
|
||||
6
|
||||
1
|
||||
TypeError
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user