ringio: 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. Closes: #17847 Signed-off-by: Jeff Epler <jepler@gmail.com>
This commit is contained in:
parent
255d74b5a8
commit
b0175bb2f7
5 changed files with 60 additions and 11 deletions
|
|
@ -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) {
|
||||
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};
|
||||
|
||||
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);
|
||||
if (bufinfo.buf != NULL) {
|
||||
// buffer passed in, use it directly for ringbuffer.
|
||||
self->ringbuffer.buf = bufinfo.buf;
|
||||
self->ringbuffer.size = bufinfo.len;
|
||||
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);
|
||||
}
|
||||
self->ringbuffer.buf = bufinfo.buf;
|
||||
self->ringbuffer.size = bufinfo.len;
|
||||
self->ringbuffer.iget = self->ringbuffer.iput = 0;
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,3 +46,21 @@ try:
|
|||
micropython.RingIO(None)
|
||||
except TypeError as 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
|
||||
b'\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01'
|
||||
<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'>
|
||||
Loading…
Reference in a new issue