tags 686867 patch thanks On Thu, Sep 06, 2012 at 10:03:58PM +0200, Moritz Muehlenhoff wrote: > Package: jruby > Severity: grave > Tags: security > Justification: user security hole > > Hi, > jruby in Wheezy is still affected by > http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-4838 > > http://www.nruns.com/_downloads/advisory28122011.pdf > > > Since Wheezy already has 1.6.5, updating to 1.6.5.1 seems like a good idea?
Wheezy has 1.5.6, not 1.6.5. Anyway, I've extracted the patch, it's attached. Cheers, Moritz
diff -Naur jruby-1.6.5/src/org/jruby/RubyHash.java jruby-1.6.5.1/src/org/jruby/RubyHash.java --- jruby-1.6.5/src/org/jruby/RubyHash.java 2011-10-25 16:54:53.000000000 +0200 +++ jruby-1.6.5.1/src/org/jruby/RubyHash.java 2011-12-27 20:04:20.000000000 +0100 @@ -824,7 +824,7 @@ oldTable[j] = null; while (entry != null) { RubyHashEntry next = entry.next; - entry.hash = entry.key.hashCode(); // update the hash value + entry.hash = hashValue(entry.key.hashCode()); // update the hash value int i = bucketIndex(entry.hash, newTable.length); entry.next = newTable[i]; newTable[i] = entry; diff -Naur jruby-1.6.5/src/org/jruby/Ruby.java jruby-1.6.5.1/src/org/jruby/Ruby.java --- jruby-1.6.5/src/org/jruby/Ruby.java 2011-10-25 16:54:53.000000000 +0200 +++ jruby-1.6.5.1/src/org/jruby/Ruby.java 2011-12-27 20:04:20.000000000 +0100 @@ -291,6 +291,8 @@ this.beanManager = BeanManagerFactory.create(this, config.isManagementEnabled()); this.jitCompiler = new JITCompiler(this); this.parserStats = new ParserStats(this); + + this.hashSeed = this.random.nextInt(); this.beanManager.register(new Config(this)); this.beanManager.register(parserStats); @@ -3929,6 +3931,10 @@ public boolean isBooting() { return booting; } + + public int getHashSeed() { + return hashSeed; + } public CoverageData getCoverageData() { return coverageData; @@ -3946,6 +3952,8 @@ private long randomSeed = 0; private long randomSeedSequence = 0; private Random random = new Random(); + /** The runtime-local seed for hash randomization */ + private int hashSeed = 0; private final List<EventHook> eventHooks = new Vector<EventHook>(); private boolean hasEventHooks; diff -Naur jruby-1.6.5/src/org/jruby/RubyString.java jruby-1.6.5.1/src/org/jruby/RubyString.java --- jruby-1.6.5/src/org/jruby/RubyString.java 2011-10-25 16:54:54.000000000 +0200 +++ jruby-1.6.5.1/src/org/jruby/RubyString.java 2011-12-27 20:04:21.000000000 +0100 @@ -93,6 +93,7 @@ import org.jruby.runtime.marshal.UnmarshalStream; import org.jruby.util.ByteList; import org.jruby.util.ConvertBytes; +import org.jruby.util.MurmurHash; import org.jruby.util.Numeric; import org.jruby.util.Pack; import org.jruby.util.RegexpOptions; @@ -1145,11 +1146,11 @@ } private int strHashCode(Ruby runtime) { + int hash = MurmurHash.hash32(value.getUnsafeBytes(), value.getBegin(), value.getRealSize(), runtime.getHashSeed()); if (runtime.is1_9()) { - return value.hashCode() ^ (value.getEncoding().isAsciiCompatible() && scanForCodeRange() == CR_7BIT ? 0 : value.getEncoding().getIndex()); - } else { - return value.hashCode(); + hash ^= (value.getEncoding().isAsciiCompatible() && scanForCodeRange() == CR_7BIT ? 0 : value.getEncoding().getIndex()); } + return hash; } @Override diff -Naur jruby-1.6.5/src/org/jruby/util/MurmurHash.java jruby-1.6.5.1/src/org/jruby/util/MurmurHash.java --- jruby-1.6.5/src/org/jruby/util/MurmurHash.java 1970-01-01 01:00:00.000000000 +0100 +++ jruby-1.6.5.1/src/org/jruby/util/MurmurHash.java 2011-12-27 20:04:21.000000000 +0100 @@ -0,0 +1,62 @@ +package org.jruby.util; + +public class MurmurHash { + // Based on Murmurhash 2.0 Java port at http://dmy999.com/article/50/murmurhash-2-java-port + // 2011-12-05: Modified by Hiroshi Nakamura <n...@ruby-lang.org> + // - signature change to use offset + // hash(byte[] data, int seed) to hash(byte[] src, int offset, int length, int seed) + // - extract 'm' and 'r' as murmurhash2.0 constants + + // Ported by Derek Young from the C version (specifically the endian-neutral + // version) from: + // http://murmurhash.googlepages.com/ + // + // released to the public domain - dmy...@gmail.com + + // 'm' and 'r' are mixing constants generated offline. + // They're not really 'magic', they just happen to work well. + private static final int MURMUR2_MAGIC = 0x5bd1e995; + // CRuby 1.9 uses 16 but original C++ implementation uses 24 with above Magic. + private static final int MURMUR2_R = 24; + + @SuppressWarnings("fallthrough") + public static int hash32(byte[] src, int offset, int length, int seed) { + // Initialize the hash to a 'random' value + int h = seed ^ length; + + int i = offset; + int len = length; + while (len >= 4) { + int k = src[i + 0] & 0xFF; + k |= (src[i + 1] & 0xFF) << 8; + k |= (src[i + 2] & 0xFF) << 16; + k |= (src[i + 3] & 0xFF) << 24; + + k *= MURMUR2_MAGIC; + k ^= k >>> MURMUR2_R; + k *= MURMUR2_MAGIC; + + h *= MURMUR2_MAGIC; + h ^= k; + + i += 4; + len -= 4; + } + + switch (len) { + case 3: + h ^= (src[i + 2] & 0xFF) << 16; + case 2: + h ^= (src[i + 1] & 0xFF) << 8; + case 1: + h ^= (src[i + 0] & 0xFF); + h *= MURMUR2_MAGIC; + } + + h ^= h >>> 13; + h *= MURMUR2_MAGIC; + h ^= h >>> 15; + + return h; + } +}