changeset 1993:1cdd796efef3

Second batch of security updates. 2010-10-11 Andrew John Hughes <ahughes@redhat.com> * patches/icedtea-timerqueue.patch: Dropped; superceded by 6623943. * Makefile.am: Add new security patches. * NEWS: List new security patches. * patches/security/20101012/6622002.patch, * patches/security/20101012/6623943.patch, * patches/security/20101012/6952017.patch, * patches/security/20101012/6952603.patch, * patches/security/20101012/6961084.patch, * patches/security/20101012/6963285.patch, * patches/security/20101012/6981426.patch, * patches/security/20101012/6990437.patch: Added.
author Andrew John Hughes <ahughes@redhat.com>
date Mon, 11 Oct 2010 21:52:05 +0100
parents a6202fb4b8c4
children 1c4624a3afe8
files ChangeLog Makefile.am NEWS patches/icedtea-timerqueue.patch patches/security/20101012/6622002.patch patches/security/20101012/6623943.patch patches/security/20101012/6952017.patch patches/security/20101012/6952603.patch patches/security/20101012/6961084.patch patches/security/20101012/6963285.patch patches/security/20101012/6981426.patch patches/security/20101012/6990437.patch
diffstat 12 files changed, 809 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Oct 08 00:46:01 2010 +0100
+++ b/ChangeLog	Mon Oct 11 21:52:05 2010 +0100
@@ -1,3 +1,19 @@
+2010-10-11  Andrew John Hughes  <ahughes@redhat.com>
+
+	* patches/icedtea-timerqueue.patch:
+	Dropped; superceded by 6623943.
+	* Makefile.am: Add new security patches.
+	* NEWS: List new security patches.
+	* patches/security/20101012/6622002.patch,
+	* patches/security/20101012/6623943.patch,
+	* patches/security/20101012/6952017.patch,
+	* patches/security/20101012/6952603.patch,
+	* patches/security/20101012/6961084.patch,
+	* patches/security/20101012/6963285.patch,
+	* patches/security/20101012/6981426.patch,
+	* patches/security/20101012/6990437.patch:
+	Added.
+
 2010-10-07  Andrew John Hughes  <ahughes@redhat.com>
 
 	* patches/icedtea-systemtap.patch:
--- a/Makefile.am	Fri Oct 08 00:46:01 2010 +0100
+++ b/Makefile.am	Mon Oct 11 21:52:05 2010 +0100
@@ -247,7 +247,15 @@
 	patches/security/20101012/6963489.patch \
 	patches/security/20101012/6966692.patch \
 	patches/security/20101012/6914943.patch \
-	patches/security/20101012/6559775.patch
+	patches/security/20101012/6559775.patch \
+	patches/security/20101012/6622002.patch \
+	patches/security/20101012/6623943.patch \
+	patches/security/20101012/6952017.patch \
+	patches/security/20101012/6952603.patch \
+	patches/security/20101012/6961084.patch \
+	patches/security/20101012/6963285.patch \
+	patches/security/20101012/6981426.patch \
+	patches/security/20101012/6990437.patch
 
 ICEDTEA_PATCHES = \
 	$(SECURITY_PATCHES) \
@@ -284,7 +292,6 @@
 	patches/icedtea-javafiles.patch \
 	patches/icedtea-jvmtiEnv.patch \
 	patches/icedtea-lcms.patch \
-	patches/icedtea-timerqueue.patch \
 	patches/icedtea-print-lsb-release.patch \
 	patches/icedtea-jpegclasses.patch \
 	patches/icedtea-uname.patch \
--- a/NEWS	Fri Oct 08 00:46:01 2010 +0100
+++ b/NEWS	Mon Oct 11 21:52:05 2010 +0100
@@ -21,6 +21,15 @@
   - S6963023, CVE-2010-3565: OpenJDK JPEG writeImage remote code execution
   - S6963489, CVE-2010-3566: OpenJDK ICC Profile remote code execution
   - S6966692, CVE-2010-3569: OpenJDK Serialization inconsistencies
+  - S6622002: UIDefault.ProxyLazyValue has unsafe reflection usage
+  - S6623943: javax.swing.TimerQueue's thread occasionally fails to start
+  - S6952017: HttpURLConnection chunked encoding issue (Http request splitting)
+  - S6952603: NetworkInterface reveals local network address to untrusted code
+  - S6961084: limit setting of some request headers in HttpURLConnection
+  - S6963285: Crash in ICU Opentype layout engine due to mismatch in character counts
+  - S6980004: limit HTTP request cookie headers in HttpURLConnection
+  - S6981426: limit use of TRACE method in HttpURLConnection
+  - S6990437: Update with correct copyright info for source and test files from SSR10_02 fixes
 * Fixes
   - G244901: Skip test_gamma on hardened (PaX-enabled) kernels
   - G266295: Provide font configuration for Gentoo.
--- a/patches/icedtea-timerqueue.patch	Fri Oct 08 00:46:01 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
---- TimerQueue.java.orig	2007-12-13 14:08:33.000000000 -0500
-+++ openjdk/jdk/src/share/classes/javax/swing/TimerQueue.java	2007-12-13 14:08:52.000000000 -0500
-@@ -106,7 +106,6 @@
-                     return null;
-                 }
-             });
--            running = true;
-         }
-     }
- 
-@@ -164,6 +163,7 @@
- 
- 
-     public void run() {
-+        running = true;
-         try {
-             while (running) {
-                 try {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20101012/6622002.patch	Mon Oct 11 21:52:05 2010 +0100
@@ -0,0 +1,64 @@
+# HG changeset patch
+# User alexp
+# Date 1285685944 -14400
+# Node ID bb1c74cae929a5903c0aca64b9e5a7f67726b02a
+# Parent  1eaaf0f77762dfa6120921f1d2d6ce96e7086513
+6622002: UIDefault.ProxyLazyValue has unsafe reflection usage
+Reviewed-by: malenkov
+
+diff --git a/src/share/classes/javax/swing/UIDefaults.java b/src/share/classes/javax/swing/UIDefaults.java
+--- openjdk.orig/jdk/src/share/classes/javax/swing/UIDefaults.java
++++ openjdk/jdk/src/share/classes/javax/swing/UIDefaults.java
+@@ -52,6 +52,7 @@ import java.security.PrivilegedAction;
+ import java.security.PrivilegedAction;
+ 
+ import sun.reflect.misc.MethodUtil;
++import sun.reflect.misc.ReflectUtil;
+ import sun.util.CoreResourceBundleControl;
+ 
+ /**
+@@ -1079,6 +1080,9 @@ public class UIDefaults extends Hashtabl
+             // In order to pick up the security policy in effect at the
+             // time of creation we use a doPrivileged with the
+             // AccessControlContext that was in place when this was created.
++            if (acc == null && System.getSecurityManager() != null) {
++                throw new SecurityException("null AccessControlContext");
++            } 
+             return AccessController.doPrivileged(new PrivilegedAction() {
+                 public Object run() {
+                     try {
+@@ -1094,7 +1098,9 @@ public class UIDefaults extends Hashtabl
+                                 cl = ClassLoader.getSystemClassLoader();
+                             }
+                         }
++                        ReflectUtil.checkPackageAccess(className);
+                         c = Class.forName(className, true, (ClassLoader)cl);
++                        checkAccess(c.getModifiers());
+                         if (methodName != null) {
+                             Class[] types = getClassArray(args);
+                             Method m = c.getMethod(methodName, types);
+@@ -1102,6 +1108,7 @@ public class UIDefaults extends Hashtabl
+                         } else {
+                             Class[] types = getClassArray(args);
+                             Constructor constructor = c.getConstructor(types);
++                            checkAccess(constructor.getModifiers());
+                             return constructor.newInstance(args);
+                         }
+                     } catch(Exception e) {
+@@ -1115,8 +1122,15 @@ public class UIDefaults extends Hashtabl
+                 }
+             }, acc);
+         }
++        
++        private void checkAccess(int modifiers) {
++            if(System.getSecurityManager() != null && 
++                    !Modifier.isPublic(modifiers)) {
++                throw new SecurityException("Resource is not accessible");
++            }
++        }
+ 
+-        /*
++        /* 
+          * Coerce the array of class types provided into one which
+          * looks the way the Reflection APIs expect.  This is done
+          * by substituting primitive types for their Object counterparts,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20101012/6623943.patch	Mon Oct 11 21:52:05 2010 +0100
@@ -0,0 +1,138 @@
+# HG changeset patch
+# User idk
+# Date 1214248897 14400
+# Node ID 2e8ca9a18288830f2dbfc20e8b6862f992a46dea
+# Parent  8dfe1491710546567e0583d7d745ebe5f3b4cb9b
+6623943: javax.swing.TimerQueue's thread occasionally fails to start
+Reviewed-by: alexp
+
+diff --git a/src/share/classes/javax/swing/JApplet.java b/src/share/classes/javax/swing/JApplet.java
+--- openjdk.orig/jdk/src/share/classes/javax/swing/JApplet.java
++++ openjdk/jdk/src/share/classes/javax/swing/JApplet.java
+@@ -131,10 +131,7 @@ public class JApplet extends Applet impl
+         // Check the timerQ and restart if necessary.
+         TimerQueue q = TimerQueue.sharedInstance();
+         if(q != null) {
+-            synchronized(q) {
+-                if(!q.running)
+-                    q.start();
+-            }
++            q.startIfNeeded();
+         }
+ 
+         /* Workaround for bug 4155072.  The shared double buffer image
+diff --git a/src/share/classes/javax/swing/TimerQueue.java b/src/share/classes/javax/swing/TimerQueue.java
+--- openjdk.orig/jdk/src/share/classes/javax/swing/TimerQueue.java
++++ openjdk/jdk/src/share/classes/javax/swing/TimerQueue.java
+@@ -30,6 +30,7 @@ package javax.swing;
+ 
+ 
+ import java.util.concurrent.*;
++import java.util.concurrent.locks.*;
+ import java.util.concurrent.atomic.AtomicLong;
+ import sun.awt.AppContext;
+ 
+@@ -48,7 +49,8 @@ class TimerQueue implements Runnable
+     private static final Object sharedInstanceKey = new Object(); // TimerQueue.sharedInstanceKey
+ 
+     private final DelayQueue<DelayedTimer> queue;
+-    volatile boolean running;
++    private volatile boolean running;
++    private final Lock runningLock;
+ 
+     /* Lock object used in place of class object for synchronization.
+      * (4187686)
+@@ -65,7 +67,8 @@ class TimerQueue implements Runnable
+         super();
+         queue = new DelayQueue<DelayedTimer>();
+         // Now start the TimerQueue thread.
+-        start();
++        runningLock = new ReentrantLock();
++        startIfNeeded();
+     }
+ 
+ 
+@@ -83,32 +86,29 @@ class TimerQueue implements Runnable
+     }
+ 
+ 
+-    synchronized void start() {
+-        if (running) {
+-            throw new RuntimeException("Can't start a TimerQueue " +
+-                                       "that is already running");
+-        }
+-        else {
+-            final ThreadGroup threadGroup =
+-                AppContext.getAppContext().getThreadGroup();
+-            java.security.AccessController.doPrivileged(
+-                new java.security.PrivilegedAction() {
+-                public Object run() {
+-                    Thread timerThread = new Thread(threadGroup, TimerQueue.this,
+-                                                    "TimerQueue");
+-                    timerThread.setDaemon(true);
+-                    timerThread.setPriority(Thread.NORM_PRIORITY);
+-                    timerThread.start();
+-                    return null;
+-                }
+-            });
+-            running = true;
++    void startIfNeeded() {
++        if (! running) {
++            runningLock.lock();
++            try {
++                final ThreadGroup threadGroup =
++                    AppContext.getAppContext().getThreadGroup();
++                java.security.AccessController.doPrivileged(
++                    new java.security.PrivilegedAction() {
++                    public Object run() {
++                        Thread timerThread = new Thread(threadGroup, TimerQueue.this,
++                                                        "TimerQueue");
++                        timerThread.setDaemon(true);
++                        timerThread.setPriority(Thread.NORM_PRIORITY);
++                        timerThread.start();
++                        return null;
++                    }
++                });
++                running = true;
++            } finally {
++                runningLock.unlock();
++            }
+         }
+     }
+-
+-     synchronized void stop() {
+-         running = false;
+-     }
+ 
+     void addTimer(Timer timer, long delayMillis) {
+         timer.getLock().lock();
+@@ -160,6 +160,7 @@ class TimerQueue implements Runnable
+ 
+ 
+     public void run() {
++        runningLock.lock();
+         try {
+             while (running) {
+                 try {
+@@ -191,14 +192,14 @@ class TimerQueue implements Runnable
+             }
+         }
+         catch (ThreadDeath td) {
+-            synchronized (this) {
+-                running = false;
+-                // Mark all the timers we contain as not being queued.
+-                for (DelayedTimer delayedTimer : queue) {
+-                    delayedTimer.getTimer().cancelEvent();
+-                }
+-                throw td;
++            // Mark all the timers we contain as not being queued.
++            for (DelayedTimer delayedTimer : queue) {
++                delayedTimer.getTimer().cancelEvent();
+             }
++            throw td;
++        } finally {
++            running = false;
++            runningLock.unlock();
+         }
+     }
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20101012/6952017.patch	Mon Oct 11 21:52:05 2010 +0100
@@ -0,0 +1,50 @@
+# HG changeset patch
+# User michaelm
+# Date 1280138166 -3600
+# Node ID 3f8ebe7db6e03ce47132bd92c18e88b9410439ed
+# Parent  7fe7aa39b5dcd501d49e88c1d5f672ca45af8658
+6952017: HttpURLConnection chunked encoding issue (Http request splitting)
+Reviewed-by: chegar
+
+diff --git a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+--- openjdk.orig/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
++++ openjdk/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+@@ -422,9 +422,12 @@ public class HttpURLConnection extends j
+                         "application/x-www-form-urlencoded");
+             }
+ 
++            boolean chunked = false;
++
+             if (streaming()) {
+                 if (chunkLength != -1) {
+                     requests.set ("Transfer-Encoding", "chunked");
++                    chunked = true;
+                 } else {
+                     requests.set ("Content-Length", String.valueOf(fixedContentLength));
+                 }
+@@ -435,6 +438,16 @@ public class HttpURLConnection extends j
+                     poster.close();
+                     requests.set("Content-Length",
+                                  String.valueOf(poster.size()));
++                }
++            }
++
++            if (!chunked) {
++                if (requests.findValue("Transfer-Encoding") != null) {
++                    requests.remove("Transfer-Encoding");
++                    if (logger.isLoggable(Level.WARNING)) {
++                        logger.warning(
++                            "use streaming mode for chunked encoding");
++                    }
+                 }
+             }
+ 
+@@ -562,7 +575,7 @@ public class HttpURLConnection extends j
+         if (instProxy instanceof sun.net.ApplicationProxy) {
+             /* Application set Proxies should not have access to cookies
+              * in a secure environment unless explicitly allowed. */
+-            try { 
++            try {
+                 cookieHandler = CookieHandler.getDefault();
+             } catch (SecurityException se) { /* swallow exception */ }
+         } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20101012/6952603.patch	Mon Oct 11 21:52:05 2010 +0100
@@ -0,0 +1,38 @@
+# HG changeset patch
+# User michaelm
+# Date 1280137222 -3600
+# Node ID 7fe7aa39b5dcd501d49e88c1d5f672ca45af8658
+# Parent  1f9e4b58a1f94bde7942b8caea4522c75d4f2180
+6952603: NetworkInterface reveals local network address to untrusted code
+Reviewed-by: chegar
+
+diff --git a/src/share/classes/java/net/NetworkInterface.java b/src/share/classes/java/net/NetworkInterface.java
+--- openjdk.orig/jdk/src/share/classes/java/net/NetworkInterface.java
++++ openjdk/jdk/src/share/classes/java/net/NetworkInterface.java
+@@ -393,6 +393,10 @@ public final class NetworkInterface {
+      * @since 1.6
+      */
+     public byte[] getHardwareAddress() throws SocketException {
++        if (!getInetAddresses().hasMoreElements()) {
++            // don't have connect permission to any local address
++            return null;
++        }
+         for (InetAddress addr : addrs) {
+             if (addr instanceof Inet4Address) {
+                 return getMacAddr0(((Inet4Address)addr).getAddress(), name, index);
+@@ -509,11 +513,10 @@ public final class NetworkInterface {
+     }
+ 
+     public int hashCode() {
+-        int count = 0;
+-        if (addrs != null) {
+-            for (int i = 0; i < addrs.length; i++) {
+-                count += addrs[i].hashCode();
+-            }
++        int count = name == null? 0: name.hashCode();
++        Enumeration<InetAddress> addrs = getInetAddresses();
++        while (addrs.hasMoreElements()) {
++            count += addrs.nextElement().hashCode();
+         }
+         return count;
+     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20101012/6961084.patch	Mon Oct 11 21:52:05 2010 +0100
@@ -0,0 +1,325 @@
+# HG changeset patch
+# User michaelm
+# Date 1285257017 25200
+# Node ID 6e389e6349c94fd9576657adcd2656a6e868acb1
+# Parent  65605bd0da24b31de86517af83ac4acbce624a94
+6980004: limit HTTP request cookie headers in HttpURLConnection
+6961084: limit setting of some request headers in HttpURLConnection
+Reviewed-by: chegar
+
+diff --git a/src/share/classes/sun/net/www/MessageHeader.java b/src/share/classes/sun/net/www/MessageHeader.java
+--- openjdk.orig/jdk/src/share/classes/sun/net/www/MessageHeader.java
++++ openjdk/jdk/src/share/classes/sun/net/www/MessageHeader.java
+@@ -196,6 +196,10 @@ class MessageHeader {
+     }
+ 
+     public synchronized Map getHeaders(String[] excludeList) {
++        return filterAndAddHeaders(excludeList, null);
++    }
++
++    public synchronized Map filterAndAddHeaders(String[] excludeList, Map include) {
+         boolean skipIt = false;
+         Map m = new HashMap();
+         for (int i = nkeys; --i >= 0;) {
+@@ -220,6 +224,19 @@ class MessageHeader {
+             } else {
+                 // reset the flag
+                 skipIt = false;
++            }
++        }
++
++        if (include != null) {
++            Iterator entries = include.entrySet().iterator();
++            while (entries.hasNext()) {
++                Map.Entry entry = (Map.Entry)entries.next();
++                List l = (List)m.get(entry.getKey());
++                if (l == null) {
++                    l = new ArrayList();
++                    m.put((String)entry.getKey(), l);
++                }
++                l.add(entry.getValue());
+             }
+         }
+ 
+diff --git a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+--- openjdk.orig/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
++++ openjdk/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+@@ -51,6 +51,9 @@ import java.util.Locale;
+ import java.util.Locale;
+ import java.util.StringTokenizer;
+ import java.util.Iterator;
++import java.util.HashSet;
++import java.util.HashMap;
++import java.util.Set;
+ import java.util.Set;
+ import java.util.logging.Level;
+ import java.util.logging.Logger;
+@@ -142,6 +145,56 @@ public class HttpURLConnection extends j
+     */
+     private static int bufSize4ES = 0;
+ 
++    /*
++     * Restrict setting of request headers through the public api
++     * consistent with JavaScript XMLHttpRequest2 with a few
++     * exceptions. Disallowed headers are silently ignored for
++     * backwards compatibility reasons rather than throwing a
++     * SecurityException. For example, some applets set the
++     * Host header since old JREs did not implement HTTP 1.1.
++     * Additionally, any header starting with Sec- is
++     * disallowed.
++     *
++     * The following headers are allowed for historical reasons:
++     *
++     * Accept-Charset, Accept-Encoding, Cookie, Cookie2, Date,
++     * Referer, TE, User-Agent, headers beginning with Proxy-.
++     *
++     * The following headers are allowed in a limited form:
++     *
++     * Connection: close
++     *
++     * See http://www.w3.org/TR/XMLHttpRequest2.
++     */
++    private static final boolean allowRestrictedHeaders;
++
++    private static final Set<String> restrictedHeaderSet;
++
++    private static final String[] restrictedHeaders = {
++        /* Restricted by XMLHttpRequest2 */
++        //"Accept-Charset",
++        //"Accept-Encoding",
++        "Access-Control-Request-Headers",
++        "Access-Control-Request-Method",
++        "Connection", /* close is allowed */
++        "Content-Length",
++        //"Cookie",
++        //"Cookie2",
++        "Content-Transfer-Encoding",
++        //"Date",
++        "Expect",
++        "Host",
++        "Keep-Alive",
++        "Origin",
++        // "Referer", 
++        // "TE",
++        "Trailer",
++        "Transfer-Encoding",
++        "Upgrade",
++        //"User-Agent",
++        "Via"
++    };
++
+     static {
+         maxRedirects = java.security.AccessController.doPrivileged(
+                 new sun.security.action.GetIntegerAction("http.maxRedirects",
+@@ -180,7 +233,17 @@ public class HttpURLConnection extends j
+             bufSize4ES = 4096; // use the default
+         }
+ 
+-
++        allowRestrictedHeaders = ((Boolean)java.security.AccessController.doPrivileged( 
++                new sun.security.action.GetBooleanAction( 
++                    "sun.net.http.allowRestrictedHeaders"))).booleanValue(); 
++        if (!allowRestrictedHeaders) { 
++            restrictedHeaderSet = new HashSet<String>(restrictedHeaders.length); 
++            for (int i=0; i < restrictedHeaders.length; i++) { 
++                restrictedHeaderSet.add(restrictedHeaders[i].toLowerCase()); 
++            }
++        } else {
++            restrictedHeaderSet = null;
++        }
+     }
+ 
+     static final String httpVersion = "HTTP/1.1";
+@@ -193,6 +256,15 @@ public class HttpURLConnection extends j
+             "Proxy-Authorization",
+             "Authorization"
+     };
++
++    // also exclude system cookies when any might be set
++    private static final String[] EXCLUDE_HEADERS2= {
++            "Proxy-Authorization", 
++            "Authorization",
++            "Cookie",
++            "Cookie2"
++    };
++
+     protected HttpClient http;
+     protected Handler handler;
+     protected Proxy instProxy;
+@@ -215,6 +287,7 @@ public class HttpURLConnection extends j
+     /* User set Cookies */
+     private boolean setUserCookies = true;
+     private String userCookies = null;
++    private String userCookies2 = null;
+ 
+     /* We only have a single static authenticator for now.
+      * REMIND:  backwards compatibility with JDK 1.1.  Should be
+@@ -300,6 +373,41 @@ public class HttpURLConnection extends j
+                         prompt, scheme, url, authType);
+                 }
+             });
++    }
++
++    private boolean isRestrictedHeader(String key, String value) {
++        if (allowRestrictedHeaders) {
++            return false;
++        }
++
++        key = key.toLowerCase();
++        if (restrictedHeaderSet.contains(key)) {
++            /*
++             * Exceptions to restricted headers:
++             *
++             * Allow "Connection: close".
++             */
++            if (key.equals("connection") && value.equalsIgnoreCase("close")) {
++                return false;
++            }
++            return true;
++        } else if (key.startsWith("sec-")) {
++            return true;
++        }
++        return false;
++    }
++
++    /*
++     * Checks the validity of http message header and whether the header
++     * is restricted and throws IllegalArgumentException if invalid or
++     * restricted.
++     */
++    private boolean isExternalMessageHeaderAllowed(String key, String value) {
++        checkMessageHeader(key, value);
++        if (!isRestrictedHeader(key, value)) {
++            return true;
++        }
++        return false;
+     }
+ 
+     /*
+@@ -917,15 +1025,21 @@ public class HttpURLConnection extends j
+             // we only want to capture the user defined Cookies once, as
+             // they cannot be changed by user code after we are connected,
+             // only internally.
+-            if (setUserCookies) {
+-                int k = requests.getKey("Cookie");
+-                if ( k != -1)
+-                    userCookies = requests.getValue(k);
+-                setUserCookies = false;
++            synchronized (this) {
++                if (setUserCookies) {
++                    int k = requests.getKey("Cookie");
++                    if ( k != -1)
++                        userCookies = requests.getValue(k);
++                    k = requests.getKey("Cookie2");
++                    if ( k != -1)
++                        userCookies2 = requests.getValue(k);
++                    setUserCookies = false;
++                }
+             }
+ 
+             // remove old Cookie header before setting new one.
+             requests.remove("Cookie");
++            requests.remove("Cookie2");
+ 
+             URI uri = ParseUtil.toURI(url);
+             if (uri != null) {
+@@ -966,6 +1080,13 @@ public class HttpURLConnection extends j
+                     requests.set("Cookie", requests.getValue(k) + ";" + userCookies);
+                 else
+                     requests.set("Cookie", userCookies);
++            }
++            if (userCookies2 != null) {
++                int k;
++                if ((k = requests.getKey("Cookie2")) != -1)
++                    requests.set("Cookie2", requests.getValue(k) + ";" + userCookies2);
++                else
++                    requests.set("Cookie2", userCookies2);
+             }
+ 
+         } // end of getting cookies
+@@ -2164,8 +2285,9 @@ public class HttpURLConnection extends j
+         if (key == null)
+             throw new NullPointerException ("key is null");
+ 
+-        checkMessageHeader(key, value);
+-        requests.set(key, value);
++        if (isExternalMessageHeaderAllowed(key, value)) {
++            requests.set(key, value);
++        }
+     }
+ 
+     /**
+@@ -2185,8 +2307,9 @@ public class HttpURLConnection extends j
+         if (key == null)
+             throw new NullPointerException ("key is null");
+ 
+-        checkMessageHeader(key, value);
+-        requests.add(key, value);
++        if (isExternalMessageHeaderAllowed(key, value)) {
++            requests.add(key, value);
++        }
+     }
+ 
+     //
+@@ -2199,14 +2322,24 @@ public class HttpURLConnection extends j
+     }
+ 
+     public String getRequestProperty (String key) {
++        if (key == null) {
++            return null;
++        }
+         // don't return headers containing security sensitive information
+-        if (key != null) {
+-            for (int i=0; i < EXCLUDE_HEADERS.length; i++) {
+-                if (key.equalsIgnoreCase(EXCLUDE_HEADERS[i])) {
+-                    return null;
+-                }
++        for (int i=0; i < EXCLUDE_HEADERS.length; i++) {
++	    if (key.equalsIgnoreCase(EXCLUDE_HEADERS[i])) {
++	        return null;
++	    }
++        }
++        if (!setUserCookies) {
++            if (key.equalsIgnoreCase("Cookie")) {
++                return userCookies;
++            }
++            if (key.equalsIgnoreCase("Cookie2")) {
++                return userCookies2;
+             }
+         }
++
+         return requests.findValue(key);
+     }
+ 
+@@ -2222,12 +2355,29 @@ public class HttpURLConnection extends j
+      * @throws IllegalStateException if already connected
+      * @since 1.4
+      */
+-    public Map getRequestProperties() {
++    public synchronized Map getRequestProperties() {
+         if (connected)
+             throw new IllegalStateException("Already connected");
+ 
+         // exclude headers containing security-sensitive info
+-        return requests.getHeaders(EXCLUDE_HEADERS);
++        if (setUserCookies) {
++            return requests.getHeaders(EXCLUDE_HEADERS);
++        }
++        /*
++         * The cookies in the requests message headers may have
++         * been modified. Use the saved user cookies instead.
++         */
++        Map userCookiesMap = null;
++        if (userCookies != null || userCookies2 != null) {
++            userCookiesMap = new HashMap();
++            if (userCookies != null) {
++                userCookiesMap.put("Cookie", userCookies);
++            }
++            if (userCookies2 != null) {
++                userCookiesMap.put("Cookie2", userCookies2);
++            }
++        }
++        return requests.filterAndAddHeaders(EXCLUDE_HEADERS2, userCookiesMap);
+     }
+ 
+     public void setConnectTimeout(int timeout) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20101012/6963285.patch	Mon Oct 11 21:52:05 2010 +0100
@@ -0,0 +1,20 @@
+# HG changeset patch
+# User prr
+# Date 1277403811 25200
+# Node ID 357bb3ba18c401c03ec1b85568df80130c3368d7
+# Parent  d77434402021cebc4c25b452db18bbfd2d7ccda1
+6963285: Crash in ICU Opentype layout engine due to mismatch in character counts
+Reviewed-by: bae, igor
+
+diff --git a/src/share/native/sun/font/layout/LayoutEngine.cpp b/src/share/native/sun/font/layout/LayoutEngine.cpp
+--- openjdk.orig/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp
++++ openjdk/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp
+@@ -292,7 +292,7 @@ le_int32 LayoutEngine::characterProcessi
+         outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag,
+             langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE);
+ 
+-        out = (rightToLeft? count - 1 : 0);
++        out = (rightToLeft? outCharCount - 1 : 0);
+ 
+         outChars = LE_NEW_ARRAY(LEUnicode, outCharCount);
+         for (i = 0; i < outCharCount; i += 1, out += dir) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20101012/6981426.patch	Mon Oct 11 21:52:05 2010 +0100
@@ -0,0 +1,24 @@
+# HG changeset patch
+# User michaelm
+# Date 1285257398 25200
+# Node ID c4573f15b0f8f304cf5fd5653e2c4d7cd8ccd61b
+# Parent  6e389e6349c94fd9576657adcd2656a6e868acb1
+6981426: limit use of TRACE method in HttpURLConnection
+Reviewed-by: chegar
+
+diff --git a/src/share/classes/java/net/HttpURLConnection.java b/src/share/classes/java/net/HttpURLConnection.java
+--- openjdk.orig/jdk/src/share/classes/java/net/HttpURLConnection.java
++++ openjdk/jdk/src/share/classes/java/net/HttpURLConnection.java
+@@ -344,6 +344,12 @@ abstract public class HttpURLConnection 
+ 
+         for (int i = 0; i < methods.length; i++) {
+             if (methods[i].equals(method)) {
++		if (method.equals("TRACE")) {
++		    SecurityManager s = System.getSecurityManager();
++		    if (s != null) {
++		        s.checkPermission(new NetPermission("allowHttpTrace"));
++		    }
++		}
+                 this.method = method;
+                 return;
+             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20101012/6990437.patch	Mon Oct 11 21:52:05 2010 +0100
@@ -0,0 +1,116 @@
+diff -Nru openjdk.orig/jdk/src/share/classes/java/io/SerialCallbackContext.java openjdk/jdk/src/share/classes/java/io/SerialCallbackContext.java
+--- openjdk.orig/jdk/src/share/classes/java/io/SerialCallbackContext.java	2010-10-11 20:07:49.000000000 +0100
++++ openjdk/jdk/src/share/classes/java/io/SerialCallbackContext.java	2010-10-11 20:13:57.045973207 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -22,55 +22,54 @@
+  * or visit www.oracle.com if you need additional information or have any
+  * questions.
+  */
+-  
+-  package java.io;
+-  
+-  /**
+-   * Context during upcalls from object stream to class-defined
+-   * readObject/writeObject methods. 
+-   * Holds object currently being deserialized and descriptor for current class. 
+-   *
+-   * This context keeps track of the thread it was constructed on, and allows
+-   * only a single call of defaultReadObject, readFields, defaultWriteObject 
+-   * or writeFields which must be invoked on the same thread before the class's
+-   * readObject/writeObject method has returned.
+-   * If not set to the current thread, the getObj method throws NotActiveException.
+-   */
+-  final class SerialCallbackContext {
+-      private final Object obj;
+-      private final ObjectStreamClass desc;
+-      /**
+-       * Thread this context is in use by.
+-       * As this only works in one thread, we do not need to worry about thread-safety.
+-       */
+-      private Thread thread;
+-  
+-      public SerialCallbackContext(Object obj, ObjectStreamClass desc) {
+-          this.obj = obj;
+-          this.desc = desc;
+-          this.thread = Thread.currentThread();
+-      }
+-  
+-      public Object getObj() throws NotActiveException {
+-          checkAndSetUsed();
+-          return obj;
+-      }
+-  
+-      public ObjectStreamClass getDesc() {
+-          return desc;
+-      }
+-  
+-      private void checkAndSetUsed() throws NotActiveException {
+-          if (thread != Thread.currentThread()) {
+-               throw new NotActiveException(
+-                "not in readObject invocation or fields already read");
+-          }
+-          thread = null;
+-      }
+-  
+-      public void setUsed() {
+-          thread = null;
+-      }
+-  }
+-  
++
++package java.io;
++
++/**
++ * Context during upcalls from object stream to class-defined
++ * readObject/writeObject methods.
++ * Holds object currently being deserialized and descriptor for current class.
++ *
++ * This context keeps track of the thread it was constructed on, and allows
++ * only a single call of defaultReadObject, readFields, defaultWriteObject
++ * or writeFields which must be invoked on the same thread before the class's
++ * readObject/writeObject method has returned.
++ * If not set to the current thread, the getObj method throws NotActiveException.
++ */
++final class SerialCallbackContext {
++    private final Object obj;
++    private final ObjectStreamClass desc;
++    /**
++     * Thread this context is in use by.
++     * As this only works in one thread, we do not need to worry about thread-safety.
++     */
++    private Thread thread;
++
++    public SerialCallbackContext(Object obj, ObjectStreamClass desc) {
++        this.obj = obj;
++        this.desc = desc;
++        this.thread = Thread.currentThread();
++    }
++
++    public Object getObj() throws NotActiveException {
++        checkAndSetUsed();
++        return obj;
++    }
++
++    public ObjectStreamClass getDesc() {
++        return desc;
++    }
++
++    private void checkAndSetUsed() throws NotActiveException {
++        if (thread != Thread.currentThread()) {
++             throw new NotActiveException(
++              "not in readObject invocation or fields already read");
++        }
++        thread = null;
++    }
++
++    public void setUsed() {
++        thread = null;
++    }
++}
+