Fix integer overflows when unmarshaling a bigarray
authorStephane Glondu <steph@glondu.net>
Fri, 25 Jan 2019 13:01:58 +0000 (14:01 +0100)
committerStephane Glondu <steph@glondu.net>
Fri, 25 Jan 2019 13:02:01 +0000 (14:02 +0100)
(Closes: #895472, CVE-2018-9838)

debian/patches/0012-Integer-overflows-when-unmarshaling-a-bigarray.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/0012-Integer-overflows-when-unmarshaling-a-bigarray.patch b/debian/patches/0012-Integer-overflows-when-unmarshaling-a-bigarray.patch
new file mode 100644 (file)
index 0000000..5fc85a6
--- /dev/null
@@ -0,0 +1,61 @@
+From: Xavier Leroy <xavier.leroy@inria.fr>
+Date: Fri, 25 Jan 2019 13:56:29 +0100
+Subject: Integer overflows when unmarshaling a bigarray
+
+Malicious or corrupted marshaled data can result in a bigarray
+with impossibly large dimensions that cause overflow when computing
+the in-memory size of the bigarray.  Disaster ensues when the data
+is read in a too small memory area.  This commit checks for overflows
+when computing the in-memory size of the bigarray.
+
+Origin: https://github.com/ocaml/ocaml/pull/1718
+Bug: https://caml.inria.fr/mantis/view.php?id=7765
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=895472
+Bug-CVE: CVE-2018-9838
+---
+ otherlibs/bigarray/bigarray_stubs.c | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/otherlibs/bigarray/bigarray_stubs.c b/otherlibs/bigarray/bigarray_stubs.c
+index cb38bef..df1ccc9 100644
+--- a/otherlibs/bigarray/bigarray_stubs.c
++++ b/otherlibs/bigarray/bigarray_stubs.c
+@@ -966,22 +966,31 @@ static void caml_ba_deserialize_longarray(void * dest, intnat num_elts)
+ uintnat caml_ba_deserialize(void * dst)
+ {
+   struct caml_ba_array * b = dst;
+-  int i, elt_size;
+-  uintnat num_elts;
++  int i;
++  uintnat num_elts, size;
+   /* Read back header information */
+   b->num_dims = caml_deserialize_uint_4();
++  if (b->num_dims < 0 || b->num_dims > CAML_BA_MAX_NUM_DIMS)
++    caml_deserialize_error("input_value: wrong number of bigarray dimensions");
+   b->flags = caml_deserialize_uint_4() | CAML_BA_MANAGED;
+   b->proxy = NULL;
+   for (i = 0; i < b->num_dims; i++) b->dim[i] = caml_deserialize_uint_4();
+-  /* Compute total number of elements */
+-  num_elts = caml_ba_num_elts(b);
+-  /* Determine element size in bytes */
++  /* Compute total number of elements.  Watch out for overflows (MPR#7765). */
++  num_elts = 1;
++  for (i = 0; i < b->num_dims; i++) {
++    if (caml_umul_overflow(num_elts, b->dim[i], &num_elts))
++      caml_deserialize_error("input_value: size overflow for bigarray");
++  }
++  /* Determine array size in bytes.  Watch out for overflows (MPR#7765). */
+   if ((b->flags & CAML_BA_KIND_MASK) > CAML_BA_CHAR)
+     caml_deserialize_error("input_value: bad bigarray kind");
+-  elt_size = caml_ba_element_size[b->flags & CAML_BA_KIND_MASK];
++  if (caml_umul_overflow(num_elts,
++                         caml_ba_element_size[b->flags & CAML_BA_KIND_MASK],
++                         &size))
++    caml_deserialize_error("input_value: size overflow for bigarray");
+   /* Allocate room for data */
+-  b->data = malloc(elt_size * num_elts);
++  b->data = malloc(size);
+   if (b->data == NULL)
+     caml_deserialize_error("input_value: out of memory for bigarray");
+   /* Read data */
index 1196040080034b1ed34fa5a3f2199309eab30f49..b64e943a63e48b0e6e3f574fff3bb9e8035b3061 100644 (file)
@@ -9,3 +9,4 @@
 0011-arm64-hide-symbols-for-stricter-binutils.patch
 0013-Use-CCLINKFLAGS-for-linking-all-executables-and-shar.patch
 0014-Compute-a-stable-name-for-preprocessed-files.patch
+0012-Integer-overflows-when-unmarshaling-a-bigarray.patch