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:
Jeff Epler
2025-08-06 10:15:57 -05:00
committed by Damien George
parent 803da9645f
commit 0615d13963
5 changed files with 60 additions and 11 deletions

View File

@@ -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);
}