File 0009-manual-backport-for-CVE-2016-2339.patch of Package ruby2.1

From 850b96c8b80200982fac43567313cd8180a83802 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcus=20R=C3=BCckert?= <mrueckert@suse.de>
Date: Thu, 9 Mar 2017 17:03:14 +0100
Subject: [PATCH 09/13] manual backport for CVE-2016-2339

---
 ext/fiddle/function.c | 57 +++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c
index 4a5a5892a6..8f0007a1d6 100644
--- a/ext/fiddle/function.c
+++ b/ext/fiddle/function.c
@@ -2,6 +2,22 @@
 
 VALUE cFiddleFunction;
 
+#define MAX_ARGS (SIZE_MAX / (sizeof(void *) + sizeof(fiddle_generic)) - 1)
+
+#define Check_Max_Args(name, len) \
+    Check_Max_Args_(name, len, "")
+#define Check_Max_Args_Long(name, len) \
+    Check_Max_Args_(name, len, "l")
+#define Check_Max_Args_(name, len, fmt) \
+    if ((size_t)(len) < MAX_ARGS) { \
+	/* OK */ \
+    } \
+    else { \
+	rb_raise(rb_eTypeError, \
+		 name" is so large that it can cause integer overflow (%"fmt"d)", \
+		 (len)); \
+    }
+
 static void
 deallocate(void *p)
 {
@@ -65,15 +81,34 @@ static VALUE
 initialize(int argc, VALUE argv[], VALUE self)
 {
     ffi_cif * cif;
-    ffi_type **arg_types;
+    ffi_type **arg_types, *rtype;
     ffi_status result;
-    VALUE ptr, args, ret_type, abi, kwds;
-    int i;
+    VALUE ptr, args, ret_type, abi, kwds, ary;
+    int i, len;
+    int nabi;
+    void *cfunc;
 
     rb_scan_args(argc, argv, "31:", &ptr, &args, &ret_type, &abi, &kwds);
-    if(NIL_P(abi)) abi = INT2NUM(FFI_DEFAULT_ABI);
+    ptr = rb_Integer(ptr);
+    cfunc = NUM2PTR(ptr);
+    PTR2NUM(cfunc);
+    nabi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
+    abi = INT2FIX(nabi);
+    i = NUM2INT(ret_type);
+    rtype = INT2FFI_TYPE(i);
+    ret_type = INT2FIX(i);
 
     Check_Type(args, T_ARRAY);
+    len = RARRAY_LENINT(args);
+    Check_Max_Args("args", len);
+    ary = rb_ary_subseq(args, 0, len);
+    for (i = 0; i < RARRAY_LEN(args); i++) {
+	VALUE a = RARRAY_PTR(args)[i];
+	int type = NUM2INT(a);
+	(void)INT2FFI_TYPE(type); /* raise */
+	if (INT2FIX(type) != a) rb_ary_store(ary, i, INT2FIX(type));
+    }
+    OBJ_FREEZE(ary);
 
     rb_iv_set(self, "@ptr", ptr);
     rb_iv_set(self, "@args", args);
@@ -84,20 +119,15 @@ initialize(int argc, VALUE argv[], VALUE self)
 
     TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);
 
-    arg_types = xcalloc(RARRAY_LEN(args) + 1, sizeof(ffi_type *));
+    arg_types = xcalloc(len + 1, sizeof(ffi_type *));
 
     for (i = 0; i < RARRAY_LEN(args); i++) {
-	int type = NUM2INT(RARRAY_PTR(args)[i]);
+	int type = NUM2INT(RARRAY_AREF(args, i));
 	arg_types[i] = INT2FFI_TYPE(type);
     }
-    arg_types[RARRAY_LEN(args)] = NULL;
+    arg_types[len] = NULL;
 
-    result = ffi_prep_cif (
-	    cif,
-	    NUM2INT(abi),
-	    RARRAY_LENINT(args),
-	    INT2FFI_TYPE(NUM2INT(ret_type)),
-	    arg_types);
+    result = ffi_prep_cif(cif, nabi, len, rtype, arg_types);
 
     if (result)
 	rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
@@ -119,6 +149,7 @@ function_call(int argc, VALUE argv[], VALUE self)
     types    = rb_iv_get(self, "@args");
     cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));
 
+    Check_Max_Args("number of arguments", argc);
     if(argc != RARRAY_LENINT(types)) {
 	rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
 		argc, RARRAY_LENINT(types));
-- 
2.12.0

openSUSE Build Service is sponsored by