Skip to content
Snippets Groups Projects
Commit 76d4bf47 authored by q3k's avatar q3k
Browse files

usermodule/badge_link: fix UAF

We were keeping GCable pointers to JackPin inside static structures
without adding a GC root. That meant that the GC was free to collect
them and re-use memory for something else, leading to weird UAF bugs,
especially when soft resetting.

We could've added a GC root, but it's easier to just statically allocate
the JackPin objects, too.
parent 15ed740e
No related branches found
No related tags found
No related merge requests found
Pipeline #5750 passed
...@@ -18,41 +18,62 @@ ...@@ -18,41 +18,62 @@
// //
// See mypystubs/badge_link.pyi for more information. // See mypystubs/badge_link.pyi for more information.
typedef struct _badgelink_jack_t {
mp_obj_base_t base;
bool left;
// Lazy initialized on first access.
mp_obj_t pin_tip;
mp_obj_t pin_ring;
} badgelink_jack_t;
const mp_obj_type_t badgelink_jack_type;
typedef struct _badgelink_jack_pin_t { typedef struct _badgelink_jack_pin_t {
mp_obj_base_t base; mp_obj_base_t base;
bool left; bool left;
bool tip; bool tip;
// Lazy initialized on first access.
mp_obj_t pin; mp_obj_t pin;
} badgelink_jack_pin_t; } badgelink_jack_pin_t;
const mp_obj_type_t badgelink_jack_pin_type; const mp_obj_type_t badgelink_jack_pin_type;
typedef struct _badgelink_jack_t {
mp_obj_base_t base;
bool left;
badgelink_jack_pin_t tip;
badgelink_jack_pin_t ring;
} badgelink_jack_t;
const mp_obj_type_t badgelink_jack_type;
STATIC badgelink_jack_t left = { STATIC badgelink_jack_t left = {
.base = {&badgelink_jack_type}, .base = {&badgelink_jack_type},
.left = true, .left = true,
.pin_tip = mp_const_none, .tip = {
.pin_ring = mp_const_none, .base = {&badgelink_jack_pin_type},
.left = true,
.tip = true,
.pin = mp_const_none,
},
.ring = {
.base = {&badgelink_jack_pin_type},
.left = true,
.tip = false,
.pin = mp_const_none,
},
}; };
STATIC badgelink_jack_t right = { STATIC badgelink_jack_t right = {
.base = {&badgelink_jack_type}, .base = {&badgelink_jack_type},
.left = false, .left = false,
.pin_tip = mp_const_none, .tip = {
.pin_ring = mp_const_none, .base = {&badgelink_jack_pin_type},
.left = false,
.tip = true,
.pin = mp_const_none,
},
.ring = {
.base = {&badgelink_jack_pin_type},
.left = false,
.tip = false,
.pin = mp_const_none,
},
}; };
STATIC void badgelink_jack_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { STATIC void badgelink_jack_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
...@@ -83,12 +104,14 @@ STATIC void badgelink_jack_print(const mp_print_t *print, mp_obj_t self_in, mp_p ...@@ -83,12 +104,14 @@ STATIC void badgelink_jack_print(const mp_print_t *print, mp_obj_t self_in, mp_p
// From machine_pin.c. Used to make a machine.Pin below. // From machine_pin.c. Used to make a machine.Pin below.
mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
STATIC mp_obj_t badgelink_jack_pin_make_new(bool left, bool tip) { STATIC void badgelink_jack_pin_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
badgelink_jack_pin_t *self = m_new_obj(badgelink_jack_pin_t); badgelink_jack_pin_t *self = MP_OBJ_TO_PTR(self_in);
self->base.type = &badgelink_jack_pin_type; if (dest[0] != MP_OBJ_NULL) {
self->left = left; return;
self->tip = tip; }
if (self->pin == mp_const_none) {
bool left = self->left;
bool tip = self->tip;
uint32_t unum = left uint32_t unum = left
? (tip ? (tip
? flow3r_bsp_spio_programmable_pins.badgelink_left_tip ? flow3r_bsp_spio_programmable_pins.badgelink_left_tip
...@@ -98,14 +121,6 @@ STATIC mp_obj_t badgelink_jack_pin_make_new(bool left, bool tip) { ...@@ -98,14 +121,6 @@ STATIC mp_obj_t badgelink_jack_pin_make_new(bool left, bool tip) {
: flow3r_bsp_spio_programmable_pins.badgelink_right_ring); : flow3r_bsp_spio_programmable_pins.badgelink_right_ring);
mp_obj_t num = mp_obj_new_int_from_uint(unum); mp_obj_t num = mp_obj_new_int_from_uint(unum);
self->pin = mp_pin_make_new(NULL, 1, 0, &num); self->pin = mp_pin_make_new(NULL, 1, 0, &num);
return MP_OBJ_FROM_PTR(self);
}
STATIC void badgelink_jack_pin_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
badgelink_jack_pin_t *self = MP_OBJ_TO_PTR(self_in);
if (dest[0] != MP_OBJ_NULL) {
return;
} }
switch (attr) { switch (attr) {
case MP_QSTR_pin: dest[0] = self->pin; break; case MP_QSTR_pin: dest[0] = self->pin; break;
...@@ -119,15 +134,9 @@ STATIC void badgelink_jack_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { ...@@ -119,15 +134,9 @@ STATIC void badgelink_jack_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
if (dest[0] != MP_OBJ_NULL) { if (dest[0] != MP_OBJ_NULL) {
return; return;
} }
if (self->pin_tip == mp_const_none) {
self->pin_tip = badgelink_jack_pin_make_new(self->left, true);
}
if (self->pin_ring == mp_const_none) {
self->pin_ring = badgelink_jack_pin_make_new(self->left, false);
}
switch (attr) { switch (attr) {
case MP_QSTR_tip: dest[0] = self->pin_tip; break; case MP_QSTR_tip: dest[0] = MP_OBJ_FROM_PTR(&self->tip); break;
case MP_QSTR_ring: dest[0] = self->pin_ring; break; case MP_QSTR_ring: dest[0] = MP_OBJ_FROM_PTR(&self->ring); break;
default: default:
dest[1] = MP_OBJ_SENTINEL; dest[1] = MP_OBJ_SENTINEL;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment