8000 Check sequence multiply for length overflow by tannewt · Pull Request #1520 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

Check sequence multiply for length overflow #1520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? 8000 Sign in to your account

Merged
merged 3 commits into from
Feb 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions ports/atmel-samd/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define MICROPY_PY_DESCRIPTORS (1)
#define MICROPY_PY_MATH (0)
#define MICROPY_PY_CMATH (0)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to disable across the port, or only for M0? Granted, I imagine few people utilize the full stack info...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the port to minimize inconsistencies. Hopefully the livestream helped show the alternative ways to debug.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me!

#define MICROPY_PY_URANDOM (0)
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0)
#define MICROPY_PY_STRUCT (0)
Expand Down Expand Up @@ -256,7 +257,6 @@ extern const struct _mp_obj_module_t pixelbuf_module;
#define MICROPY_PY_UERRNO (1)
#define MICROPY_PY_UERRNO_ERRORCODE (0)
#define MICROPY_PY_URE (1)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#ifndef MICROPY_PY_FRAMEBUF
#define MICROPY_PY_FRAMEBUF (0)
#endif
Expand Down Expand Up @@ -342,7 +342,6 @@ extern const struct _mp_obj_module_t pixelbuf_module;

#else
#define MICROPY_PY_BUILTINS_REVERSED (0)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
#define MICROPY_PY_FRAMEBUF (0)
#ifndef EXTRA_BUILTIN_MODULES
#define EXTRA_BUILTIN_MODULES
Expand Down
2 changes: 2 additions & 0 deletions py/obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,8 @@ typedef struct {
mp_int_t step;
} mp_bound_slice_t;

// Compute the new length of a sequence and ensure an exception is thrown on overflow.
size_t mp_seq_multiply_len(size_t item_sz, size_t len);
void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest);
#if MICROPY_PY_BUILTINS_SLICE
bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes);
Expand Down
3 changes: 2 additions & 1 deletion py/objlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
if (n < 0) {
n = 0;
}
mp_obj_list_t *s = list_new(o->len * n);
size_t new_len = mp_seq_multiply_len(o->len, n);
mp_obj_list_t *s = list_new(new_len);
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
return MP_OBJ_FROM_PTR(s);
}
Expand Down
3 changes: 2 additions & 1 deletion py/objstr.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,9 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
return mp_const_empty_bytes;
}
}
size_t new_len = mp_seq_multiply_len(lhs_len, n);
vstr_t vstr;
vstr_init_len(&vstr, lhs_len * n);
vstr_init_len(&vstr, new_len);
mp_seq_multiply(lhs_data, sizeof(*lhs_data), lhs_len, n, vstr.buf);
return mp_obj_new_str_from_vstr(lhs_type, &vstr);
}
Expand Down
3 changes: 2 additions & 1 deletion py/objtuple.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
if (n <= 0) {
return mp_const_empty_tuple;
}
mp_obj_tuple_t *s = MP_OBJ_TO_PTR(mp_obj_new_tuple(o->len * n, NULL));
size_t new_len = mp_seq_multiply_len(o->len, n);
mp_obj_tuple_t *s = MP_OBJ_TO_PTR(mp_obj_new_tuple(new_len, NULL));
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
return MP_OBJ_FROM_PTR(s);
}
Expand Down
9 changes: 9 additions & 0 deletions py/sequence.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@

#define SWAP(type, var1, var2) { type t = var2; var2 = var1; var1 = t; }

// Detect when a multiply causes an overflow.
size_t mp_seq_multiply_len(size_t item_sz, size_t len) {
size_t new_len;
if (__builtin_mul_overflow(item_sz, len, &new_len)) {
mp_raise_msg(&mp_type_OverflowError, translate("small int overflow"));
}
return new_len;
}

// Implements backend of sequence * integer operation. Assumes elements are
// memory-adjacent in sequence.
void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest) {
Expand Down
0