Tomcat 5.0.28 and access to /dev/urandom

Issues and Questions related to running Apache Tomcat on z/OS
Post Reply
tfull
Posts: 15
Joined: Mon Oct 10, 2005 4:27 pm

Tomcat 5.0.28 and access to /dev/urandom

Post by tfull »

Most z/os implementations work fine with using /dev/urandom as a seed for the sessionid generator for Tomcat (class ManagerBase), but I have 2 instances that seem to cause Tomcat to hang on open of /dev/urandom. I have been unsuccessful in finding any overrides that would get the session manager to use something else for a seed. Do you know of any ways to get around this problem without having to modify Tomcat? It appears that I should be able to use an alternative class. The default is java.security.SecureRandom. With Tomcat 3.3, I was able circumvent the problem by having Tomcat use java.util.Random instead, but that does not seem to work on Tomcat 5.0.28. Are you aware of any z/OS configuration options that would cause /dev/urandom to not respond to a read? Racf maybe?

Thanks for any suggestions.
Tim
dovetail
Site Admin
Posts: 2022
Joined: Thu Jul 29, 2004 12:12 pm

Post by dovetail »

Its common for /dev/random and /dev/urandom on z/OS to return an error when you try to open them (because you don't have ICSF enabled, or security permissions), but I'm not aware of why they should hang.

Here's a DOC Apar on z/OS OPENSSH, which has some related info about enabling:

http://www-1.ibm.com/support/docview.ws ... sg1OA13836

Are you sure that reads are hanging rather than returning an error (java IOException?) Try to read a "line" from /dev/urandom :

REPLY=
read < /dev/urandom
echo $REPLY
tfull
Posts: 15
Joined: Mon Oct 10, 2005 4:27 pm

Post by tfull »

I ran your suggestion and the read responded fine, but the $REPLY value was null (or spaces). This image had ICSF up and running. I ran the same test on a system that does not have ICSF (has no cryto processor) and got similar results for $REPLY. This second system does not seem to have a problem with the urandom dev. I created a ManagerBase.class that does not open urandom to bypass the problem, but am still uncertain why it fails like this sometimes but not others. IBM had looked at a similar problem when I was using Tomcat 3.3 and they saw that urandom was on the read end of a pipe, and that the application (Tomcat) was the problem on the write end of the pipe. Tomcat 3.3 had an easy bypass that allowed me to use a different session randomizer, but this capability does not seem to work in 5.0.28. There was a similar override available in server.xml for the manager, but it did not seem to work. Thanks for the test.
dovetail
Site Admin
Posts: 2022
Joined: Thu Jul 29, 2004 12:12 pm

Post by dovetail »

(updated)

Just to verify: you are using JDK 1.4x or above, correct?

If ICSF is setup correctly, then you should be able to -read- random data from /dev/urandom. If not, then IMO there is something wrong with the device and I would probably open a problem with IBM.

Tomcat 5.0.28 uses the default provider via the default constructor for the java.security.SecureRandom class that is part of the Java JRE. If this class doesn't work, then there is something wrong.

In your original post you said that the "JRE is hanging opening the device". I don't believe that this should happen... it should either get an error or work, IMO.

If the java.security.SecureRandom class on z/OS is not working, then I strongly suggest opening a PMR with IBM. If possible, create a stand-alone test that demonstrates the failure. If you don't have luck with this route, please send a note to info@dovetail.com and we will try to help.

HTH
tfull
Posts: 15
Joined: Mon Oct 10, 2005 4:27 pm

Post by tfull »

I continue having problems with /dev/urandom, or /dev/random for that matter in regards to tomcat. I've since upgraded from tomcat 5.0.28 to tomcat 5.5.23. I continue having problems with the session seed randomizer. I have a z/800 but I don't have a crypto processor, so I can't start ICSF. If I try to cat /dev/urandom, I get a '/dev/urandom: EDC5157I An internal error has occurred.' message. So, I'm taking it to mean that if I don't have a cryto processor, I can't use /dev/urandom or /dev/random as a source of a seed. Does anyone have an alternative source for a seed in the case where /dev/random and /dev/urandom are unavailable? I'm current running with Java V5.
dovetail
Site Admin
Posts: 2022
Joined: Thu Jul 29, 2004 12:12 pm

Post by dovetail »

Tomcat uses class java.security.SecureRandom, which is part of the SDK. This class, by default, uses /dev/random (/dev/urandom?) to seed itself.

So, the first thing to verify is that the SecureRandom class is working.

Here is a tiny test class that will verify this:

Code: Select all

public class TestSecureRandom {

	public static void main(String[] args) throws Exception {
		java.security.SecureRandom random = java.security.SecureRandom.getInstance("SHA1PRNG"); 
		byte[]  b = new byte[16]; 
		random.nextBytes(b);
		System.out.println("Random bytes: " + b);
	}

}
Put this in "TestSecureRandom.java" and then compile and run it:

Code: Select all

javac TestSecureRandom.java
java -cp . TestSecureRandom
If it runs, it will print out something like: "Random bytes: [B@231232".

It if hangs, then you can press Cntrl-V and it will create a JavaDump, which will contain a stack trace to show exactly where it is hung up.
In this case, there is something wrong with the SDK, or more likely your environment (but I don't know what). Open a problem with the IBM support center ("java.security.SecureRandom hangs").

If it doesn't hang, we will have to get a JavaDump from the hung Tomcat job to see what is really hanging.

The easiest way to do this, while the job is running, is from a USS shell (with either UID 0 or the same userid as the job):

ps -ef
(find the running Tomcat process, the program name is the JZOS batch launcher load module, and get its process id (pid))

kill -s QUIT <pid>
tfull
Posts: 15
Joined: Mon Oct 10, 2005 4:27 pm

Post by tfull »

Thanks for the snippet. I ran the test and it seemed to work as you predicted, but I don't believe Tomcat is calling java.security.SecureRandom. I've tracked down the error I'm getting to the ManagerBase.class that is part of the org.apache.catalina.session package. It has /dev/urandom hardcoded as the location for the seed. I'm having the problem in the setRandomFile method. Here's a copy of the method (with my modification in bold):

public void setRandomFile( String s ) {
// as a hack, you can use a static file - and genarate the same
// session ids ( good for strange debugging )
if (System.getSecurityManager() != null){
randomIS = (DataInputStream)AccessController.doPrivileged(new PrivilegedSetRandomFile());
} else {
try{
devRandomSource=s;
File f=new File( devRandomSource );
if( ! f.exists() ) return;
randomIS= new DataInputStream( new FileInputStream(f));
randomIS.readLong();
if( log.isDebugEnabled() )
log.debug( "Opening " + devRandomSource );
} catch ( FileNotFoundException fnf) {
return;

} catch( IOException ex ) {
try { randomIS.close();
} catch (Exception e) {
log.warn("Failed to close randomIS." + e.toString());
e.printStackTrace();
}

randomIS=null;
}
}
}


The problem I was having is that the exists test would work fine , but the read would throw a FileNotFoundException. I modified the code to cause it to use the default action that would occur if the exists test failed. In the end, the fix only gets rid of the misleading "Failed to close randomIS." message. I'll need to see how it's handled on a system with ICSF.

Thanks for your comments.
dovetail
Site Admin
Posts: 2022
Joined: Thu Jul 29, 2004 12:12 pm

Post by dovetail »

I've opened a bug with Tomcat to address this problem:

https://issues.apache.org/bugzilla/show ... i?id=46967

In my suggested fix, I also set the devRandomSource variable to null, so that the file is not opened over and over again each type that random data is requested using the getRandomBytes() method.
Post Reply