From 4e469085c192017c5244bbc115bac90f4bb667cb Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Mon, 19 Feb 2018 16:25:30 +1100
Subject: [PATCH] py/objstr: Protect against creating bytes(n) with n negative.

Prior to this patch uPy (on a 32-bit arch) would have severe issues when
calling bytes(-1): such a call would call vstr_init_len(vstr, -1) which
would then +1 on the len and call vstr_init(vstr, 0), which would then
round this up and allocate a small amount of memory for the vstr.  The
bytes constructor would then attempt to zero out all this memory, thinking
it had allocated 2^32-1 bytes.
---
 py/objstr.c           | 5 ++++-
 tests/basics/bytes.py | 6 ++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/py/objstr.c b/py/objstr.c
index ed9ab4e45..13d957105 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -223,7 +223,10 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size
     }
 
     if (MP_OBJ_IS_SMALL_INT(args[0])) {
-        uint len = MP_OBJ_SMALL_INT_VALUE(args[0]);
+        mp_int_t len = MP_OBJ_SMALL_INT_VALUE(args[0]);
+        if (len < 0) {
+            mp_raise_ValueError(NULL);
+        }
         vstr_t vstr;
         vstr_init_len(&vstr, len);
         memset(vstr.buf, 0, len);
diff --git a/tests/basics/bytes.py b/tests/basics/bytes.py
index 1d97e6b16..0b6b14fa5 100644
--- a/tests/basics/bytes.py
+++ b/tests/basics/bytes.py
@@ -56,3 +56,9 @@ print(x[0], x[1], x[2], x[3])
 print(bytes([128, 255]))
 # For sequence of unknown len
 print(bytes(iter([128, 255])))
+
+# Shouldn't be able to make bytes with negative length
+try:
+    bytes(-1)
+except ValueError:
+    print('ValueError')
-- 
GitLab