[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-security-dev
Subject:    [security-dev 00204]: NullPointerException at sun.security.ssl.OutputRecord.writeBuffer
From:       anvil () jumperz ! net (Kanatoko)
Date:       2008-06-24 8:48:12
Message-ID: 20080624174612.24C5.ANVIL () jumperz ! net
[Download RAW message or body]


Hello list

I found a bug. Please fix it.
Thanks in advance.

--
ERROR MESSAGES/STACK TRACES THAT OCCUR :

TRACE 307528: (thread=200004)
        java.lang.Throwable.<init>(Throwable.java:197)
        java.lang.Exception.<init>(Exception.java:46)
        java.lang.RuntimeException.<init>(RuntimeException.java:49)
        java.lang.NullPointerException.<init>(NullPointerException.java:53)
        sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:314)
        sun.security.ssl.OutputRecord.write(OutputRecord.java:303)
        sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:761)
        sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:746)
        sun.security.ssl.SSLSocketImpl.sendAlert(SSLSocketImpl.java:1722)
        sun.security.ssl.SSLSocketImpl.warning(SSLSocketImpl.java:1571)
        sun.security.ssl.SSLSocketImpl.closeInternal(SSLSocketImpl.java:1373)
        sun.security.ssl.SSLSocketImpl.close(SSLSocketImpl.java:1312)
        sun.security.ssl.BaseSSLSocketImpl.finalize(BaseSSLSocketImpl.java:249)
        java.lang.ref.Finalizer.invokeFinalizeMethod(Finalizer.java:Unknown line)
        java.lang.ref.Finalizer.runFinalizer(Finalizer.java:101)
        java.lang.ref.Finalizer.access$100(Finalizer.java:32)
        java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:178)


Type:        bug
SDN ID:       
status:      Waiting
Category:    jsse
Subcategory: runtime
Company:     bitforest Co.,Ltd. ( in Japan )
release:     6
hardware:    x86
OSversion:   linux
priority:    4
Synopsis:    SSLServerSocket file descriptor leak
Description:
 FULL PRODUCT VERSION :
java version "1.6.0_10-beta"
Java(TM) SE Runtime Environment (build 1.6.0_10-beta-b25)
Java HotSpot(TM) 64-Bit Server VM (build 11.0-b12, mixed mode)

java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b05)
Java HotSpot(TM) Client VM (build 1.6.0_02-b05, mixed mode, sharing)

java version "1.6.0_04"
Java(TM) SE Runtime Environment (build 1.6.0_04-b12)
Java HotSpot(TM) 64-Bit Server VM (build 10.0-b19, mixed mode)

java version "1.5.0_14"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_14-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux myserver1 2.6.22 #2 SMP Fri Jan 4 18:21:24 JST 2008 i686 i686 i386 GNU/Linux
Linux myserver2 2.6.22 #11 SMP Thu Feb 7 04:31:44 JST 2008 x86_64 x86_64 x86_64 \
GNU/Linux

A DESCRIPTION OF THE PROBLEM :
File descriptors of TCP sockets are not released properly when using SSLServerSocket \
class ( especially with many instances ) on Linux systems.

If a server application ( like Jakarta Tomcat ) runs very long time, this problem \
will cause a 'too many open files' error and a denial of the service.

Please note that we need to use 'lsof' command instead of 'netstat' command to see \
whether the file descriptor leak is happening or not. Because the leaked sockets are \
not binded to any TCP addresses, we can not see the sockets using 'netstat' command.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Save the source code as 'test1.java'.

2. Compile with 'javac test1.java'.

3. Run with 'java -Djavax.net.ssl.keyStore=.keystore \
-Djavax.net.ssl.keyStorePassword=changeit test1' (You need your own .keystore file \
and password ).

4. In another Linux shell, execute 'lsof' command.
'lsof -n -p PID_OF_JAVA_TEST1'
(PID_OF_JAVA_TEST1 is the process ID of out test case )

5. We will see many lines like below.
java    1919 root  884u  sock    0,5            10398 can't identify protocol
java    1919 root  885u  sock    0,5            10399 can't identify protocol
java    1919 root  886u  sock    0,5            10418 can't identify protocol
java    1919 root  887u  sock    0,5            10420 can't identify protocol
java    1919 root  888u  sock    0,5            10422 can't identify protocol
java    1919 root  890u  sock    0,5            10443 can't identify protocol
java    1919 root  891u  sock    0,5            10444 can't identify protocol
java    1919 root  892u  sock    0,5            10445 can't identify protocol
java    1919 root  893u  sock    0,5            10446 can't identify protocol
java    1919 root  894u  sock    0,5            10447 can't identify protocol
java    1919 root  895u  sock    0,5            10448 can't identify protocol

These are the leaked file descriptors.


In addition,

6. We can also see the leaked file descriptors in '/proc/PID_OF_JAVA_TEST1/fd'

7. And in /proc/net/sockstat, these leaked file descriptors are counted as allocated \
TCP sockets. For example: 'TCP: inuse 3 orphan 0 tw 0 alloc 663 mem 2'
When this java process ended, the number 'alloc 663' will be decreased.

8. If we repeat 'foo()' function more , we can see the 'too many open files 'error \
message. Please change the line
for( int i = 0; i < 1000; ++i )
to
for( int i = 0; i < 2000; ++i )
and test again to see the error message.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
'lsof' command does not show too many lines of 'can't identify protocol' sockets.
ACTUAL -
Please see the 'Steps to Reproduce' field.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.net.*;
import javax.net.*;
import javax.net.ssl.*;

public class test1
{
private static ServerSocketFactory ssf;
//------------------------------------------------
public static void main( String[] args )
throws Exception
{
ssf = SSLServerSocketFactory.getDefault();
for( int i = 0; i < 1000; ++i )
        {
        foo();
        }
Thread.sleep( 1000000 );
}
//------------------------------------------------
private static void foo()
throws Exception
{
ServerSocket sSocket = ssf.createServerSocket( 0, 1 );
Socket socket1  = new Socket( "127.0.0.1", sSocket.getLocalPort() );
Socket socket2 = sSocket.accept();
sSocket.close();
socket1.close();
socket2.close();
}
//------------------------------------------------
}

---------- END SOURCE ----------


-- 
Kanatoko<anvil at jumperz.net>
Open Source WebAppFirewall
http://guardian.jumperz.net/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic