diff options
author | yallop <yallop@gmail.com> | 2016-09-26 14:06:57 +0100 |
---|---|---|
committer | Damien Doligez <damien.doligez@gmail.com> | 2016-09-26 15:06:57 +0200 |
commit | 89aff47a005f9a17417e7c76ee4e679e74bed5d5 (patch) | |
tree | 9ab69a3c09fdc031d8e69c5554df309ceca033f1 | |
parent | f872d67d4e97a6072f5891b5aef3c5f7e39e4a25 (diff) | |
download | ocaml-89aff47a005f9a17417e7c76ee4e679e74bed5d5.tar.gz |
Detect integer overflow in Array.concat (#810)
* Check for overflow in caml_array_gather.
* Add a changelog entry for the check for overflow in Array.concat.
-rw-r--r-- | Changes | 5 | ||||
-rw-r--r-- | byterun/array.c | 5 |
2 files changed, 8 insertions, 2 deletions
@@ -56,7 +56,10 @@ Next version (tbd): (Xavier Leroy) - GPR#814: fix the Buffer.add_substring bounds check to handle overflow - (Jeremy Yallop) + (Jeremy Yallop) + +- GPR#810: check for integer overflow in Array.concat + (Jeremy Yallop) OCaml 4.04.0: diff --git a/byterun/array.c b/byterun/array.c index dd694affc2..11f2b51ad5 100644 --- a/byterun/array.c +++ b/byterun/array.c @@ -26,6 +26,8 @@ /* Why is caml/spacetime.h included conditionnally sometimes and not here ? */ #include "caml/spacetime.h" +static const mlsize_t mlsize_t_max = -1; + /* returns number of elements (either fields or floats) */ CAMLexport mlsize_t caml_array_length(value array) { @@ -314,6 +316,7 @@ static value caml_array_gather(intnat num_arrays, size = 0; isfloat = 0; for (i = 0; i < num_arrays; i++) { + if (mlsize_t_max - lengths[i] < size) caml_invalid_argument("Array.concat"); size += lengths[i]; if (Tag_val(arrays[i]) == Double_array_tag) isfloat = 1; } @@ -323,8 +326,8 @@ static value caml_array_gather(intnat num_arrays, } else if (isfloat) { /* This is an array of floats. We can use memcpy directly. */ + if (size > Max_wosize/Double_wosize) caml_invalid_argument("Array.concat"); wsize = size * Double_wosize; - if (wsize > Max_wosize) caml_invalid_argument("Array.concat"); res = caml_alloc(wsize, Double_array_tag); for (i = 0, pos = 0; i < num_arrays; i++) { memcpy((double *)res + pos, |