diff -Nru ruby1.8-1.8.7.352/debian/changelog ruby1.8-1.8.7.352/debian/changelog --- ruby1.8-1.8.7.352/debian/changelog 2011-07-24 10:31:49.000000000 +0000 +++ ruby1.8-1.8.7.352/debian/changelog 2012-03-03 13:36:17.000000000 +0000 @@ -1,3 +1,14 @@ +ruby1.8 (1.8.7.352-2ubuntu1) precise; urgency=low + + * SECURITY UPDATE: Denial of service via crafted hash table keys + (LP: #943451) + - debian/patches/CVE-2011-4815.patch: Add randomness to the key hashing + algorithm to prevent predictable results when inserting objects into a + hash table. Based on upstream patch. + - CVE-2011-4815 + + -- Tyler Hicks Wed, 29 Feb 2012 12:11:48 -0600 + ruby1.8 (1.8.7.352-2) unstable; urgency=low * Add -fno-tree-sra on armel. Workaround that Closes: #634260 diff -Nru ruby1.8-1.8.7.352/debian/control ruby1.8-1.8.7.352/debian/control --- ruby1.8-1.8.7.352/debian/control 2011-07-03 17:55:41.000000000 +0000 +++ ruby1.8-1.8.7.352/debian/control 2012-03-03 13:36:17.000000000 +0000 @@ -1,7 +1,8 @@ Source: ruby1.8 Section: ruby Priority: optional -Maintainer: akira yamada +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: akira yamada Uploaders: Daigo Moriwaki , Lucas Nussbaum Build-Depends: cdbs, debhelper (>= 5), autotools-dev, autoconf, m4, quilt (>= 0.40), patch, bison, binutils (>= 2.14.90.0.7), libgdbm-dev, libncurses5-dev, libreadline-gplv2-dev, tcl-dev, tk-dev, zlib1g-dev, libssl-dev (>= 0.9.6b), file Standards-Version: 3.9.2 diff -Nru ruby1.8-1.8.7.352/debian/patches/CVE-2011-4815.patch ruby1.8-1.8.7.352/debian/patches/CVE-2011-4815.patch --- ruby1.8-1.8.7.352/debian/patches/CVE-2011-4815.patch 1970-01-01 00:00:00.000000000 +0000 +++ ruby1.8-1.8.7.352/debian/patches/CVE-2011-4815.patch 2012-03-03 13:36:17.000000000 +0000 @@ -0,0 +1,253 @@ +Description: Create a random hash seed during process initialization +Origin: upstream, http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=34151 + +Index: ruby1.8-1.8.7.352/inits.c +=================================================================== +--- ruby1.8-1.8.7.352.orig/inits.c 2008-04-09 06:13:04.000000000 -0500 ++++ ruby1.8-1.8.7.352/inits.c 2012-02-21 16:22:41.862826373 -0600 +@@ -38,6 +38,7 @@ + void Init_sym _((void)); + void Init_process _((void)); + void Init_Random _((void)); ++void Init_RandomSeed _((void)); + void Init_Range _((void)); + void Init_Regexp _((void)); + void Init_signal _((void)); +@@ -46,10 +47,13 @@ + void Init_Time _((void)); + void Init_var_tables _((void)); + void Init_version _((void)); ++void Init_st _((void)); + + void + rb_call_inits() + { ++ Init_RandomSeed(); ++ Init_st(); + Init_sym(); + Init_var_tables(); + Init_Object(); +Index: ruby1.8-1.8.7.352/random.c +=================================================================== +--- ruby1.8-1.8.7.352.orig/random.c 2011-05-22 23:49:40.000000000 -0500 ++++ ruby1.8-1.8.7.352/random.c 2012-02-21 16:22:41.862826373 -0600 +@@ -189,6 +189,7 @@ + #include + #endif + ++static int seed_initialized = 0; + static VALUE saved_seed = INT2FIX(0); + + static VALUE +@@ -250,27 +251,22 @@ + return old; + } + +-static VALUE +-random_seed() ++#define DEFAULT_SEED_LEN (4 * sizeof(long)) ++ ++static void ++fill_random_seed(ptr) ++ char *ptr; + { + static int n = 0; ++ unsigned long *seed; + struct timeval tv; + int fd; + struct stat statbuf; ++ char *buf = (char*)ptr; + +- int seed_len; +- BDIGIT *digits; +- unsigned long *seed; +- NEWOBJ(big, struct RBignum); +- OBJSETUP(big, rb_cBignum, T_BIGNUM); +- +- seed_len = 4 * sizeof(long); +- big->sign = 1; +- big->len = seed_len / SIZEOF_BDIGITS + 1; +- digits = big->digits = ALLOC_N(BDIGIT, big->len); +- seed = (unsigned long *)big->digits; ++ seed = (unsigned long *)buf; + +- memset(digits, 0, big->len * SIZEOF_BDIGITS); ++ memset(buf, 0, DEFAULT_SEED_LEN); + + #ifdef S_ISCHR + if ((fd = open("/dev/urandom", O_RDONLY +@@ -285,7 +281,7 @@ + #endif + )) >= 0) { + if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) { +- read(fd, seed, seed_len); ++ read(fd, seed, DEFAULT_SEED_LEN); + } + close(fd); + } +@@ -296,13 +292,37 @@ + seed[1] ^= tv.tv_sec; + seed[2] ^= getpid() ^ (n++ << 16); + seed[3] ^= (unsigned long)&seed; ++} ++ ++static VALUE ++make_seed_value(char *ptr) ++{ ++ BDIGIT *digits; ++ NEWOBJ(big, struct RBignum); ++ OBJSETUP(big, rb_cBignum, T_BIGNUM); ++ ++ RBIGNUM_SET_SIGN(big, 1); ++ ++ digits = ALLOC_N(char, DEFAULT_SEED_LEN); ++ RBIGNUM(big)->digits = digits; ++ RBIGNUM(big)->len = DEFAULT_SEED_LEN / SIZEOF_BDIGITS; ++ ++ MEMCPY(digits, ptr, char, DEFAULT_SEED_LEN); + + /* set leading-zero-guard if need. */ +- digits[big->len-1] = digits[big->len-2] <= 1 ? 1 : 0; ++ digits[RBIGNUM_LEN(big)-1] = digits[RBIGNUM_LEN(big)-2] <= 1 ? 1 : 0; + + return rb_big_norm((VALUE)big); + } + ++static VALUE ++random_seed(void) ++{ ++ char buf[DEFAULT_SEED_LEN]; ++ fill_random_seed(buf); ++ return make_seed_value(buf); ++} ++ + /* + * call-seq: + * srand(number=0) => old_seed +@@ -443,6 +463,9 @@ + long val, max; + + rb_scan_args(argc, argv, "01", &vmax); ++ if (!seed_initialized) { ++ rand_init(random_seed()); ++ } + switch (TYPE(vmax)) { + case T_FLOAT: + if (RFLOAT(vmax)->value <= LONG_MAX && RFLOAT(vmax)->value >= LONG_MIN) { +@@ -490,6 +513,8 @@ + return LONG2NUM(val); + } + ++static char initial_seed[DEFAULT_SEED_LEN]; ++ + void + rb_reset_random_seed() + { +@@ -497,9 +522,24 @@ + } + + void ++Init_RandomSeed(void) ++{ ++ fill_random_seed(initial_seed); ++ init_by_array((unsigned long*)initial_seed, DEFAULT_SEED_LEN/sizeof(unsigned long)); ++ seed_initialized = 1; ++} ++ ++static void ++Init_RandomSeed2(void) ++{ ++ saved_seed = make_seed_value(initial_seed); ++ memset(initial_seed, 0, DEFAULT_SEED_LEN); ++} ++ ++void + Init_Random() + { +- rb_reset_random_seed(); ++ Init_RandomSeed2(); + rb_define_global_function("srand", rb_f_srand, -1); + rb_define_global_function("rand", rb_f_rand, -1); + rb_global_variable(&saved_seed); +Index: ruby1.8-1.8.7.352/st.c +=================================================================== +--- ruby1.8-1.8.7.352.orig/st.c 2007-02-12 17:01:19.000000000 -0600 ++++ ruby1.8-1.8.7.352/st.c 2012-02-21 16:22:41.862826373 -0600 +@@ -9,6 +9,7 @@ + #include + #endif + #include ++#include + #include "st.h" + + typedef struct st_table_entry st_table_entry; +@@ -521,6 +522,8 @@ + return 0; + } + ++static unsigned long hash_seed = 0; ++ + static int + strhash(string) + register const char *string; +@@ -550,10 +553,11 @@ + + return val + (val << 15); + #else +- register int val = 0; ++ register unsigned long val = hash_seed; + + while ((c = *string++) != '\0') { + val = val*997 + c; ++ val = (val << 13) | (val >> (sizeof(st_data_t) * CHAR_BIT - 13)); + } + + return val + (val>>5); +@@ -573,3 +577,11 @@ + { + return n; + } ++ ++extern unsigned long rb_genrand_int32(void); ++ ++void ++Init_st(void) ++{ ++ hash_seed = rb_genrand_int32(); ++} +Index: ruby1.8-1.8.7.352/string.c +=================================================================== +--- ruby1.8-1.8.7.352.orig/string.c 2010-04-01 02:11:40.000000000 -0500 ++++ ruby1.8-1.8.7.352/string.c 2012-02-21 16:22:41.870826373 -0600 +@@ -875,13 +875,15 @@ + return str1; + } + ++static unsigned long hash_seed; ++ + int + rb_str_hash(str) + VALUE str; + { + register long len = RSTRING(str)->len; + register char *p = RSTRING(str)->ptr; +- register int key = 0; ++ register unsigned long key = hash_seed; + + #if defined(HASH_ELFHASH) + register unsigned int g; +@@ -905,6 +907,7 @@ + while (len--) { + key = key*65599 + *p; + p++; ++ key = (key << 13) | (key >> ((sizeof(unsigned long) * CHAR_BIT) - 13)); + } + key = key + (key>>5); + #endif +@@ -5062,4 +5065,6 @@ + rb_fs = Qnil; + rb_define_variable("$;", &rb_fs); + rb_define_variable("$-F", &rb_fs); ++ ++ hash_seed = rb_genrand_int32(); + } diff -Nru ruby1.8-1.8.7.352/debian/patches/series ruby1.8-1.8.7.352/debian/patches/series --- ruby1.8-1.8.7.352/debian/patches/series 2011-07-03 17:53:00.000000000 +0000 +++ ruby1.8-1.8.7.352/debian/patches/series 2012-03-03 13:36:17.000000000 +0000 @@ -12,3 +12,4 @@ 100901_threading_fixes.patch 110703_CVE-2011-0188.patch tcltk-no-rpath.patch +CVE-2011-4815.patch