[Bug libgcj/24461] array access in either GZIPInputStream, Inflater, natInflate.cc, or zlib
--- Comment #1 from jrandom-gcc at i2p dot net 2005-10-22 11:57 --- Found the cause can reproduce it. The bug can be reproduced by dealing with a truncated gzip stream, as shown below. The fix, I believe, would have GZIPInputStream using inf.getRemaining() to determine the tmp[] buffer size, instead of the fixed 8 bytes. Note that classpath does not have the same GZIPInputStream.read(byte[],int,int), and this bug hasn't been tested on a JVM using classpath, so it may be gcj-specific. [EMAIL PROTECTED] /tmp/b $ gcj -o bug --main=gunzipbug gunzipbug.java [EMAIL PROTECTED] /tmp/b $ ./bug java.lang.ArrayIndexOutOfBoundsException at java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int) (/usr/local/gcc-4.0.2/lib/libgcj.so.6.0.0) at java.util.zip.GZIPInputStream.read(byte[], int, int) (/usr/local/gcc-4.0.2/lib/libgcj.so.6.0.0) at gunzipbug.main(java.lang.String[]) (Unknown Source) at gnu.java.lang.MainThread.call_main() (/usr/local/gcc-4.0.2/lib/libgcj.so.6.0.0) at gnu.java.lang.MainThread.run() (/usr/local/gcc-4.0.2/lib/libgcj.so.6.0.0) [EMAIL PROTECTED] /tmp/b $ javac gunzipbug.java [EMAIL PROTECTED] /tmp/b $ java -cp . gunzipbug java.io.EOFException: Unexpected end of ZLIB input stream at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:215) at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:134) at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:87) at gunzipbug.main(gunzipbug.java:19) [EMAIL PROTECTED] /tmp/b $ cat gunzipbug.java import java.util.Random; import java.util.zip.*; import java.io.*; public class gunzipbug { public static void main(String args[]) { try { ByteArrayOutputStream full = new ByteArrayOutputStream(1024); GZIPOutputStream gzout = new GZIPOutputStream(full); byte buf[] = new byte[1024]; new Random().nextBytes(buf); gzout.write(buf); gzout.close(); byte gzdata[] = full.toByteArray(); // now only read the first 128 bytes of that data ByteArrayInputStream truncated = new ByteArrayInputStream(gzdata, 0, 128); GZIPInputStream gzin = new GZIPInputStream(truncated); byte read[] = new byte[1024]; int cur = 0; while ( (cur = gzin.read(read, cur, read.length-cur)) != -1) ; //noop } catch (Exception e) { e.printStackTrace(); } } } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24461
[Bug java/24481] New: SecureRandom.setSeed has no impact
java.security.SecureRandom in GCJ 4.0.2 has no impact, so SecureRandom always uses the same weak seed. This has obvious security issues, though they'd take a targetted attack to mount (e.g. force a JVM restart so the SecureRandom reverts to the default seed - new java.util.Random(0l).nextBytes(new byte[20]), per gnu.java.security.provider.SHA1PRNG.ensureIsSeeded()). [EMAIL PROTECTED] ~/dev/i2p/native $ gcj -o seed --main=seed seed.java [EMAIL PROTECTED] ~/dev/i2p/native $ ./seed Byte difference in a seeded PRNG: 0 Seed data: 8bc7ec2ec7c4f87a13ec6120616ead831baeaf40dfd0804c534145ddbd12c580926578f8e0fea3b8b69287e26841a91cfca9a63fa95e453494f495ff14c82 [EMAIL PROTECTED] ~/dev/i2p/native $ cat seed.java import java.security.SecureRandom; public class seed { public static void main(String args[]) { SecureRandom r = new SecureRandom(); byte unseededBuf[] = new byte[64]; r.nextBytes(unseededBuf); r = new SecureRandom(); byte seededBuf[] = new byte[64]; r.setSeed(unseededBuf); r.nextBytes(seededBuf); int diffs = 0; for (int i = 0; i 64; i++) { if (seededBuf[i] != unseededBuf[i]) diffs++; } System.out.println(Byte difference in a seeded PRNG: + diffs); System.out.print(Seed data: ); for (int i = 0; i 64; i++) System.out.print(Integer.toHexString((int)(unseededBuf[i]0xFF))); System.out.println(); } } The secureRandom.getProvider().toString() returns gnu.java.security.provider.Gnu: name=GNU version=1.0, which in turn uses the SHA1PRNG (in the 4.0.2 release, at least). The odd part is that the provider should be taking into account the seed - engineSetSeed *looks* right, and java.security.SecureRandom.java's setSeed just calls the spi.engineSetSeed, so I'm not sure whats going on here. =jr -- Summary: SecureRandom.setSeed has no impact Product: gcc Version: 4.0.2 Status: UNCONFIRMED Severity: normal Priority: P2 Component: java AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jrandom-gcc at i2p dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24481
[Bug java/24461] New: array access in either GZIPInputStream, Inflater, natInflate.cc, or zlib
I hate posting bug reports without test cases, but this one is a bit beyond me - hopefully someone else will know whats up. Symptom: java.lang.ArrayIndexOutOfBoundsException at java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int) (/usr/local/gcc-4.0.2/lib/libgcj.so.6.0.0) at java.util.zip.GZIPInputStream.read(byte[], int, int) (/usr/local/gcc-4.0.2/lib/libgcj.so.6.0.0) at java.io.FilterInputStream.read(byte[]) (/usr/local/gcc-4.0.2/lib/libgcj.so.6.0.0) at net.i2p.i2ptunnel.HTTPResponseOutputStream$Pusher.run() (/home/jrandom/dev/i2p/build/libi2p.so) at java.lang.Thread.run() (/usr/local/gcc-4.0.2/lib/libgcj.so.6.0.0) This occurs on EOF, the buffer passed in to GZIPInputStream is 8KB, and the length and offset fields are fine too (set by FilterInputStream as '0, buf.length'). The problem is, I believe, in the inf.getRemaining() and/or the fixed size buffer in GZIPInputStream: byte[] tmp = new byte[8]; // First copy remaining bytes from inflater input buffer. int avail = inf.getRemaining(); System.arraycopy(this.buf, this.len - avail, tmp, 0, avail); I have no idea why tmp is 8 bytes long, probably something I don't understand about zlib. inf.getRemaining() just returns 'z_streamp-avail_in', and from what I can see, that can either be set explicitly, via inflater.setInput(buf[], off, len), or implicitly, within zlib's inflate(z_streamp, Z_SYNC_FLUSH). My very cursory look into inflate(...) leads me nowhere, but InflaterInputStream.java seems to be allowing arbitrarily large setInput(buf, 0, buf.length) calls - e.g. line 157. The default buf.length is 4KB. Or, maybe is there something in the zlib format such that it will never have more than 8 bytes uninflated? FWIW, I'm on the latest zlib (1.2.3) and gcj 4.0.2 (and I haven't seen any updates on the related classes in gcj's cvsweb) =jr -- Summary: array access in either GZIPInputStream, Inflater, natInflate.cc, or zlib Product: gcc Version: 4.0.2 Status: UNCONFIRMED Severity: normal Priority: P2 Component: java AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jrandom-gcc at i2p dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24461