CVE-2015-8869: Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
value: OCaml before 4.03.0 does not properly handle sign extensions, which allows remote attackers to conduct buffer overflow attacks or obtain sensitive information as demonstrated by a long string to the String.copy function.
CWE description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
CVSS v3 base score: 9.1
Published: 2016-06-13T19:59Z
Repository: https://github.com/ocaml/ocaml
Language: C
Files changed: Changes, VERSION, byterun/alloc.c, byterun/intern.c, byterun/str.c
Commit date: 2015-10-19 15:47:33 +0000
Commit message: fix PR#7003 and a few other bugs caused by misuse of Int_val

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16525 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02

Diff: diff --git a/Changes b/Changes
index 047b437dd..668f85190 100644
--- a/Changes
+++ b/Changes
@@ -202,12 +202,14 @@ Bug fixes:
 - PR#6982: unexpected type error when packing a module alias
 - PR#6985: `module type of struct include Bar end exposes
            %s#row when Bar contains private row types
 - PR#6992: Segfault from bug in GADT/module typing
 - PR#6993: Segfault from recursive modules violating exhaustiveness assumptions
+- PR#7003: String.sub causes segmentation fault
+  (Damien Doligez, report by Radek Micek)
 - PR#7008: Fatal error in ocamlc with empty compilation unit name
-  (Damien Doligez)
+  (Damien Doligez, report by Cesar Kunz)
 - PR#7012: Variable name forgotten when it starts with a capital letter
   (Jacques Garrigue, Gabriel Scherer, report by Thomas Leonard and Octachron)
 - PR#7016: Stack overflow in GADT typing
 - GPR#205: Clear caml_backtrace_last_exn before registering as root (report
   and fix by Frederic Bour)
diff --git a/VERSION b/VERSION
index 5310f512b..fb6ef7133 100644
--- a/VERSION
+++ b/VERSION
@@ -1,4 +1,4 @@
-4.03.0+dev10-2015-07-29
+4.03.0+dev11-2015-10-19
 
 # The version string is the first line of this file.
 # It must be in the format described in stdlib/sys.mli
diff --git a/byterun/alloc.c b/byterun/alloc.c
index 96a21bf1f..0db994724 100644
--- a/byterun/alloc.c
+++ b/byterun/alloc.c
@@ -151,11 +151,11 @@ CAMLexport int caml_convert_flag_list(value list, int *flags)
 /* For compiling let rec over values */
 
 /* [size] is a [value] representing number of words (fields) */
 CAMLprim value caml_alloc_dummy(value size)
 {
-  mlsize_t wosize = Int_val(size);
+  mlsize_t wosize = Long_val(size);
 
   if (wosize == 0) return Atom(0);
   return caml_alloc (wosize, 0);
 }
 
@@ -167,11 +167,11 @@ CAMLprim value caml_alloc_dummy_function(value size,value arity)
 }
 
 /* [size] is a [value] representing number of floats. */
 CAMLprim value caml_alloc_dummy_float (value size)
 {
-  mlsize_t wosize = Int_val(size) * Double_wosize;
+  mlsize_t wosize = Long_val(size) * Double_wosize;
 
   if (wosize == 0) return Atom(0);
   return caml_alloc (wosize, 0);
 }
 
diff --git a/byterun/intern.c b/byterun/intern.c
index 89d13d116..7b8d0497b 100644
--- a/byterun/intern.c
+++ b/byterun/intern.c
@@ -289,11 +289,11 @@ static void intern_rec(value *dest)
   dest = sp->dest;
   switch (sp->op) {
   case OFreshOID:
     /* Refresh the object ID */
     /* but do not do it for predefined exception slots */
-    if (Int_val(Field((value)dest, 1)) >= 0)
+    if (Long_val(Field((value)dest, 1)) >= 0)
       caml_set_oo_id((value)dest);
     /* Pop item and iterate */
     sp--;
     break;
   case OShift:
diff --git a/byterun/str.c b/byterun/str.c
index 5ad4e2941..885772f74 100644
--- a/byterun/str.c
+++ b/byterun/str.c
@@ -264,11 +264,11 @@ CAMLprim value caml_string_greaterequal(value s1, value s2)
 }
 
 CAMLprim value caml_blit_string(value s1, value ofs1, value s2, value ofs2,
                                 value n)
 {
-  memmove(&Byte(s2, Long_val(ofs2)), &Byte(s1, Long_val(ofs1)), Int_val(n));
+  memmove(&Byte(s2, Long_val(ofs2)), &Byte(s1, Long_val(ofs1)), Long_val(n));
   return Val_unit;
 }
 
 CAMLprim value caml_fill_string(value s, value offset, value len, value init)
 {
@@ -276,11 +276,11 @@ CAMLprim value caml_fill_string(value s, value offset, value len, value init)
   return Val_unit;
 }
 
 CAMLprim value caml_bitvect_test(value bv, value n)
 {
-  int pos = Int_val(n);
+  intnat pos = Long_val(n);
   return Val_int(Byte_u(bv, pos >> 3) & (1 << (pos & 7)));
 }
 
 CAMLexport value caml_alloc_sprintf(const char * format, ...)
 {

Vulnerable code:   (Damien Doligez)
4.03.0+dev10-2015-07-29
  mlsize_t wosize = Int_val(size);
  mlsize_t wosize = Int_val(size) * Double_wosize;
    if (Int_val(Field((value)dest, 1)) >= 0)
  memmove(&Byte(s2, Long_val(ofs2)), &Byte(s1, Long_val(ofs1)), Int_val(n));
  int pos = Int_val(n);
Fixed code: - PR#7003: String.sub causes segmentation fault
  (Damien Doligez, report by Radek Micek)
  (Damien Doligez, report by Cesar Kunz)
4.03.0+dev11-2015-10-19
  mlsize_t wosize = Long_val(size);
  mlsize_t wosize = Long_val(size) * Double_wosize;
    if (Long_val(Field((value)dest, 1)) >= 0)
  memmove(&Byte(s2, Long_val(ofs2)), &Byte(s1, Long_val(ofs1)), Long_val(n));
  intnat pos = Long_val(n);