java/110912: Java krb5 client leaks UDP connections

jan grant jan.grant at bristol.ac.uk
Tue Mar 27 09:40:09 UTC 2007


>Number:         110912
>Category:       java
>Synopsis:       Java krb5 client leaks UDP connections
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-java
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Mar 27 09:40:08 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     jan grant
>Release:        Tracking STABLE
>Organization:
university of bristol
>Environment:
Irrelevant (it's a java security class bug)
>Description:
I'm trying to raise a bug with Sun about the sun.security.krb5 implementation; they're being recalcitrant (I keep on getting new hoops to jump through when actually examining the code in question would make the problem obvious in 10 minutes).

The problem is a straightforward resource leak, as you can see if you look at this:

    http://java.sun.com/j2se/jrl_download.html

in particular, at

    jdk_sec-1_5_0-src-scsl.zip

You'll see that sun.security.krb5.internal.UDPClient has no close() method; and the UDPClient-using code path in sun.security.krb5.KrbKdcReq (which has a few other close-to-the-coalface errors) consequently leaks FDs (unlike the TCP path, which has a try/finally that closes the socket properly).

We're seeing a krb5 client application (the Yale CAS SSO) keel over in no time due to FD exhaustion. A trivial fix (the non-whitespace part of the diff is 8 lines) sorts this out.

I attach a patch against the tree from an expanded jdk_sec-1_5_0-src-scsl.zip that addresses this. Unsure about the status of the patch since the JCL license looks a little confusing, however, the fix is trivial.

If this works for you, I'd appreciate it if you could punt this back upstream to sun (possibly ref. support case 37763365 ?)

(I did email this patch privately to Greg but I've no indication that he received it. Note that the patch includes whitespace changes to SCSLed/JCLed code which is why I was reluctant to send it to freebsd-java@; without the whitespace the meat of the patch is 8 lines)
>How-To-Repeat:
We're seeing it by installing Yale/JASIG's CAS system and having it do krb5 authentication against our AD. Having said that, a simple test case is available if you want to look at this, but examining the code makes this utterly obvious.
>Fix:
Patch against the security classes supplied.

Patch attached with submission follows:

diff -r -u jgss1.5.0-src-orig/src/share/classes/sun/security/krb5/internal/UDPClient.java jgss1.5.0-src/src/share/classes/sun/security/krb5/internal/UDPClient.java
--- jgss1.5.0-src-orig/src/share/classes/sun/security/krb5/internal/UDPClient.java	2004-09-21 00:05:08.000000000 +0100
+++ jgss1.5.0-src/src/share/classes/sun/security/krb5/internal/UDPClient.java	2007-01-09 20:06:53.742243561 +0000
@@ -85,4 +85,8 @@
 	return data;
     }
 
+    public void close() throws IOException {
+        dgSocket.close();
+    }
+
 }
diff -r -u jgss1.5.0-src-orig/src/share/classes/sun/security/krb5/KrbKdcReq.java jgss1.5.0-src/src/share/classes/sun/security/krb5/KrbKdcReq.java
--- jgss1.5.0-src-orig/src/share/classes/sun/security/krb5/KrbKdcReq.java	2004-09-21 00:05:08.000000000 +0100
+++ jgss1.5.0-src/src/share/classes/sun/security/krb5/KrbKdcReq.java	2007-01-09 20:13:13.977349280 +0000
@@ -256,37 +256,41 @@
 		// get the response
 		for (int i=1; i <= DEFAULT_KDC_RETRY_LIMIT; i++) {
 		    UDPClient kdcClient = new UDPClient(kdc, port, timeout);
+                    try {
 		    
-		    if (DEBUG) {
-	    		System.out.println(">>> KDCCommunication: kdc=" + kdc 
-			       + (useTCP ? " TCP:":" UDP:")
-			       +  port +  ", timeout="
-			       + timeout
-			       + ",Attempt =" + i 
-			       + ", #bytes=" + obuf.length);
-		    }
-		    /*
-		     * Send the data to the kdc.
-		     */
+		        if (DEBUG) {
+	    		    System.out.println(">>> KDCCommunication: kdc=" + kdc 
+			           + (useTCP ? " TCP:":" UDP:")
+			           +  port +  ", timeout="
+			           + timeout
+			           + ",Attempt =" + i 
+			           + ", #bytes=" + obuf.length);
+		        }
+		        /*
+		         * Send the data to the kdc.
+		         */
 		    
-		    kdcClient.send(obuf);
+		        kdcClient.send(obuf);
 		    
-		    /*
-		     * And get a response.
-		     */
-		    try {
-			ibuf = kdcClient.receive();
-			break;
-		    } catch (SocketTimeoutException se) {
-			if (DEBUG) {
-			    System.out.println ("SocketTimeOutException with " +
-						"attempt: " + i);
-			}
-			if (i == DEFAULT_KDC_RETRY_LIMIT) {
-			    ibuf = null;
-			    throw se;  
-			}
-		    }
+		        /*
+		         * And get a response.
+		         */
+		        try {
+			    ibuf = kdcClient.receive();
+			    break;
+		        } catch (SocketTimeoutException se) {
+			    if (DEBUG) {
+			        System.out.println ("SocketTimeOutException with " +
+						    "attempt: " + i);
+			    }
+			    if (i == DEFAULT_KDC_RETRY_LIMIT) {
+			        ibuf = null;
+			        throw se;  
+			    }
+		        }
+                    } finally {
+                        kdcClient.close();
+                    }
 		}
 	    }
 	    return ibuf;

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-java mailing list