mirror of
https://github.com/micropython/micropython.git
synced 2026-01-06 20:20:14 +01:00
py/objringio: Detect incorrect constructor calls.
ringbuffer.size must be at least 2, and is a 16-bit quantity. This fixes several cases including the one the fuzzer discovered, which would lead to a fatal signal when accessing the object. Fixes issue #17847. Signed-off-by: Jeff Epler <jepler@gmail.com>
This commit is contained in:
committed by
Damien George
parent
803da9645f
commit
0615d13963
@@ -39,22 +39,19 @@ typedef struct _micropython_ringio_obj_t {
|
|||||||
|
|
||||||
static mp_obj_t micropython_ringio_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 micropython_ringio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||||
mp_int_t buff_size = -1;
|
|
||||||
mp_buffer_info_t bufinfo = {NULL, 0, 0};
|
mp_buffer_info_t bufinfo = {NULL, 0, 0};
|
||||||
|
|
||||||
if (!mp_get_buffer(args[0], &bufinfo, MP_BUFFER_RW)) {
|
if (!mp_get_buffer(args[0], &bufinfo, MP_BUFFER_RW)) {
|
||||||
buff_size = mp_obj_get_int(args[0]);
|
bufinfo.len = mp_obj_get_int(args[0]) + 1;
|
||||||
|
bufinfo.buf = m_new(uint8_t, bufinfo.len);
|
||||||
|
}
|
||||||
|
if (bufinfo.len < 2 || bufinfo.len > UINT16_MAX) {
|
||||||
|
mp_raise_ValueError(NULL);
|
||||||
}
|
}
|
||||||
micropython_ringio_obj_t *self = mp_obj_malloc(micropython_ringio_obj_t, type);
|
micropython_ringio_obj_t *self = mp_obj_malloc(micropython_ringio_obj_t, type);
|
||||||
if (bufinfo.buf != NULL) {
|
|
||||||
// buffer passed in, use it directly for ringbuffer.
|
|
||||||
self->ringbuffer.buf = bufinfo.buf;
|
self->ringbuffer.buf = bufinfo.buf;
|
||||||
self->ringbuffer.size = bufinfo.len;
|
self->ringbuffer.size = bufinfo.len;
|
||||||
self->ringbuffer.iget = self->ringbuffer.iput = 0;
|
self->ringbuffer.iget = self->ringbuffer.iput = 0;
|
||||||
} else {
|
|
||||||
// Allocate new buffer, add one extra to buff_size as ringbuf consumes one byte for tracking.
|
|
||||||
ringbuf_alloc(&(self->ringbuffer), buff_size + 1);
|
|
||||||
}
|
|
||||||
return MP_OBJ_FROM_PTR(self);
|
return MP_OBJ_FROM_PTR(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,3 +46,21 @@ try:
|
|||||||
micropython.RingIO(None)
|
micropython.RingIO(None)
|
||||||
except TypeError as ex:
|
except TypeError as ex:
|
||||||
print(type(ex))
|
print(type(ex))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Buffer may not be empty
|
||||||
|
micropython.RingIO(bytearray(0))
|
||||||
|
except ValueError as ex:
|
||||||
|
print(type(ex))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Buffer may not be too small
|
||||||
|
micropython.RingIO(bytearray(1))
|
||||||
|
except ValueError as ex:
|
||||||
|
print(type(ex))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Size may not be too small
|
||||||
|
micropython.RingIO(0)
|
||||||
|
except ValueError as ex:
|
||||||
|
print(type(ex))
|
||||||
|
|||||||
@@ -14,3 +14,6 @@ b'\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01'
|
|||||||
0
|
0
|
||||||
b'\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01'
|
b'\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01'
|
||||||
<class 'TypeError'>
|
<class 'TypeError'>
|
||||||
|
<class 'ValueError'>
|
||||||
|
<class 'ValueError'>
|
||||||
|
<class 'ValueError'>
|
||||||
|
|||||||
29
tests/micropython/ringio_big.py
Normal file
29
tests/micropython/ringio_big.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Check that micropython.RingIO works correctly.
|
||||||
|
|
||||||
|
import micropython
|
||||||
|
|
||||||
|
try:
|
||||||
|
micropython.RingIO
|
||||||
|
except AttributeError:
|
||||||
|
print("SKIP")
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
|
try:
|
||||||
|
# The maximum possible size
|
||||||
|
micropython.RingIO(bytearray(65535))
|
||||||
|
micropython.RingIO(65534)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Buffer may not be too big
|
||||||
|
micropython.RingIO(bytearray(65536))
|
||||||
|
except ValueError as ex:
|
||||||
|
print(type(ex))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Size may not be too big
|
||||||
|
micropython.RingIO(65535)
|
||||||
|
except ValueError as ex:
|
||||||
|
print(type(ex))
|
||||||
|
except MemoryError:
|
||||||
|
print("SKIP")
|
||||||
|
raise SystemExit
|
||||||
2
tests/micropython/ringio_big.py.exp
Normal file
2
tests/micropython/ringio_big.py.exp
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<class 'ValueError'>
|
||||||
|
<class 'ValueError'>
|
||||||
Reference in New Issue
Block a user