diff --git a/core/embed/extmod/modtrezorio/modtrezorio-poll.h b/core/embed/extmod/modtrezorio/modtrezorio-poll.h index e2fe33442..5fa1508f5 100644 --- a/core/embed/extmod/modtrezorio/modtrezorio-poll.h +++ b/core/embed/extmod/modtrezorio/modtrezorio-poll.h @@ -52,7 +52,15 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref, mp_raise_TypeError("invalid list_ref"); } - const mp_uint_t timeout = trezor_obj_get_uint(timeout_ms); + // The value `timeout_ms` can be negative in a minority of cases, indicating a + // deadline overrun. This is not a problem because we use the `timeout` only + // to calculate a `deadline`, and having deadline in the past works fine + // (except when it overflows, but the code misbehaves near the overflow + // anyway). Instead of bothering to correct the negative value in Python, we + // just coerce it to an uint. Deliberately assigning *get_int* to *uint_t* + // will give us C's wrapping unsigned overflow behavior, and the `deadline` + // result will come out correct. + const mp_uint_t timeout = trezor_obj_get_int(timeout_ms); const mp_uint_t deadline = mp_hal_ticks_ms() + timeout; mp_obj_iter_buf_t iterbuf = {0}; diff --git a/core/embed/extmod/trezorobj.h b/core/embed/extmod/trezorobj.h index e9d59f105..af3289aff 100644 --- a/core/embed/extmod/trezorobj.h +++ b/core/embed/extmod/trezorobj.h @@ -52,6 +52,9 @@ static inline mp_int_t trezor_obj_get_int(mp_obj_t obj) { static inline mp_uint_t trezor_obj_get_uint(mp_obj_t obj) { if (MP_OBJ_IS_SMALL_INT(obj)) { mp_int_t i = MP_OBJ_SMALL_INT_VALUE(obj); + if (i < 0) { + mp_raise_TypeError("value is negative"); + } mp_uint_t u = i; return u; } else if (MP_OBJ_IS_TYPE(obj, &mp_type_int)) { @@ -78,6 +81,9 @@ static inline uint8_t trezor_obj_get_uint8(mp_obj_t obj) { static inline uint64_t trezor_obj_get_uint64(mp_const_obj_t obj) { if (MP_OBJ_IS_SMALL_INT(obj)) { mp_int_t i = MP_OBJ_SMALL_INT_VALUE(obj); + if (i < 0) { + mp_raise_TypeError("value is negative"); + } mp_uint_t u = i; return u; } else if (MP_OBJ_IS_TYPE(obj, &mp_type_int)) {