Name: nt126004 Date: 02/18/2003
FULL PRODUCT VERSION :
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
SunOS 5.8 Generic Generic_108528-16 sun4u sparc
SUNW,Sun-Blade-1000
SunRay Server Software:
SRSS 1.3
A DESCRIPTION OF THE PROBLEM :
We ran into a problem where a server we had written in Java
was sporadically failing to start, and hanging. The server
was in the process of initializing the SSL context. It had
become blocked in java.security.SecureRandom.
I have lost the exact stack trace now, but I belive it was
in generateSeed() or next(). We then checked /dev/random,
(since the SecureRandom takes advantage of it if it present).
In fact, /dev/random was there, but it was out of random bits!
$ cat /dev/random
returned a few random bits then blocked. Subsequent
attempts to cat the device failed entirely to produce any
output.
We were able to work around the problem by taking the
following steps:
$ su
$ rm /dev/random
$ ln -s /dev/random /dev/urandom
Since /dev/urandom seemed to be working fine (i.e. could be
catted to produce many pages of random bits).
Subsequent restarts of the machine (indpendent of java)
showed that whatever implementation of /dev/random we had
was exhibiting some kind of problem where it ran out of
random bits or some process was consuming them faster than
they could be replaced.
We believe that the implementation may have come from a
Solaris 8 patch, we patched to the latest version and did
little else with the box. Nothing exotic.
Here is the stack trace, there is "Definitely" something wrong with
my dev random it seems like its returning 1024-1216 random bytes,
then hanging until you log in again
ERROR MESSAGES :
Full thread dump Java HotSpot(TM) Client VM (1.4.1_01-b01 mixed mode):
"Thread-1" daemon prio=5 tid=0x2fb850 nid=0x10 in Object.wait()
[e5101000..e5101994]
at java.lang.Object.wait(Native Method)
- waiting on <e66e04d8> (a java.util.TaskQueue)
at java.util.TimerThread.mainLoop(Timer.java:429)
- locked <e66e04d8> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:382)
"AWT-EventQueue-0" prio=6 tid=0x2e0318 nid=0xf in Object.wait()
[e5201000..e5201994]
at java.lang.Object.wait(Native Method)
- waiting on <e66e1d50> (a java.awt.EventQueue)
at java.lang.Object.wait(Object.java:426)
at java.awt.EventQueue.getNextEvent(EventQueue.java:333)
- locked <e66e1d50> (a java.awt.EventQueue)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:161)
at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)
"Java2D Disposer" daemon prio=10 tid=0x2dd0f8 nid=0xe in Object.wait()
[e5301000..e5301994]
at java.lang.Object.wait(Native Method)
- waiting on <e66e1de0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
- locked <e66e1de0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
at sun.java2d.Disposer.run(Disposer.java:97)
at java.lang.Thread.run(Thread.java:536)
"AWT-Motif" daemon prio=6 tid=0x1fe7b0 nid=0xc runnable [e5501000..e5501994]
at sun.awt.motif.MToolkit.run(Native Method)
at java.lang.Thread.run(Thread.java:536)
"AWT-Shutdown" prio=5 tid=0x1df3e8 nid=0xb in Object.wait()
[e5601000..e5601994]
at java.lang.Object.wait(Native Method)
- waiting on <e66e1f30> (a java.lang.Object)
at java.lang.Object.wait(Object.java:426)
at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:259)
- locked <e66e1f30> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:536)
"Finalizer" daemon prio=8 tid=0xb5060 nid=0x6 in Object.wait()
[fa281000..fa281994]
at java.lang.Object.wait(Native Method)
- waiting on <e66e2030> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
- locked <e66e2030> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0xb3708 nid=0x5 in Object.wait()
[fa381000..fa381994]
at java.lang.Object.wait(Native Method)
- waiting on <e66e0568> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:426)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:113)
- locked <e66e0568> (a java.lang.ref.Reference$Lock)
"main" prio=5 tid=0x2c888 nid=0x1 runnable [ffbed000..ffbee60c]
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:191)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:220)
at java.io.BufferedInputStream.read(BufferedInputStream.java:277)
- locked <e609d868> (a java.io.BufferedInputStream)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:183)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:222)
at java.io.BufferedInputStream.read(BufferedInputStream.java:277)
- locked <e609d708> (a java.io.BufferedInputStream)
at
sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedByte(SeedGenerator.java:467)
at
sun.security.provider.SeedGenerator.getSeedBytes(SeedGenerator.java:137)
at
sun.security.provider.SeedGenerator.generateSeed(SeedGenerator.java:132)
at
sun.security.provider.SecureRandom.engineGenerateSeed(SecureRandom.java:112)
at
sun.security.provider.SecureRandom.engineNextBytes(SecureRandom.java:169)
- locked <e609d288> (a sun.security.provider.SecureRandom)
at java.security.SecureRandom.nextBytes(SecureRandom.java:381)
- locked <e609c738> (a java.security.SecureRandom)
at java.security.SecureRandom.next(SecureRandom.java:403)
at java.util.Random.nextInt(Random.java:191)
at
com.sun.net.ssl.internal.ssl.SSLContextImpl.engineInit(DashoA6275)
at javax.net.ssl.SSLContext.init(DashoA6275)
at c.b(Unknown Source)
at c.f(Unknown Source)
at cd.a(Unknown Source)
at cc.a(Unknown Source)
at com.biobex.persistence.RemotePersister.init(Unknown Source)
at e.a(Unknown Source)
at f.d(Unknown Source)
at e.a(Unknown Source)
- locked <f6412af8> (a java.lang.Class)
at com.biobex.app.enroll.EnrollmentApp.b(Unknown Source)
at com.biobex.app.enroll.EnrollmentApp.a(Unknown Source)
at com.biobex.app.enroll.EnrollmentApp.main(Unknown Source)
"VM Thread" prio=5 tid=0xb2280 nid=0x4 runnable
"VM Periodic Task Thread" prio=10 tid=0xb8018 nid=0x7 waiting on condition
"Suspend Checker Thread" prio=10 tid=0xb8968 nid=0x8 runnable
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. $ cat /dev/random
2.
3.
EXPECTED VERSUS ACTUAL BEHAVIOR :
Call to SecureRandom.next() should not hang indefinitely,
although from a purist perspective, if there entropy
gathering daemon has no entropy, well you cant really
initialize a secure random number generator.
I would almost prefer some kind of exception to be thrown if
it could not not read any bits after 30 seconds.
REPRODUCIBILITY :
This bug can be reproduced often.
---------- BEGIN SOURCE ----------
new SecureRandom().next();
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
$ su
$ rm /dev/random
$ ln -s /dev/random /dev/urandom
(Review ID: 180903)
======================================================================