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