6734167: Calendar.readObject allows elevation of privileges
authorokutsu
Thu, 02 Oct 2008 16:49:33 +0900
changeset 2599 593d7b0502e2
parent 2598 6f980e1d6e31
child 2600 923ecc7ab342
6734167: Calendar.readObject allows elevation of privileges Reviewed-by: peytoia
jdk/src/share/classes/java/util/Calendar.java
--- a/jdk/src/share/classes/java/util/Calendar.java	Thu Sep 04 09:43:32 2008 -0700
+++ b/jdk/src/share/classes/java/util/Calendar.java	Thu Oct 02 16:49:33 2008 +0900
@@ -41,9 +41,14 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.io.OptionalDataException;
 import java.io.Serializable;
+import java.security.AccessControlContext;
 import java.security.AccessController;
+import java.security.PermissionCollection;
+import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
 import java.text.DateFormat;
 import java.text.DateFormatSymbols;
 import sun.util.BuddhistCalendar;
@@ -2626,6 +2631,18 @@
         }
     }
 
+    private static class CalendarAccessControlContext {
+        private static final AccessControlContext INSTANCE;
+        static {
+            RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar");
+            PermissionCollection perms = perm.newPermissionCollection();
+            perms.add(perm);
+            INSTANCE = new AccessControlContext(new ProtectionDomain[] {
+                                                    new ProtectionDomain(null, perms)
+                                                });
+        }
+    }
+
     /**
      * Reconstitutes this object from a stream (i.e., deserialize it).
      */
@@ -2655,17 +2672,30 @@
         serialVersionOnStream = currentSerialVersion;
 
         // If there's a ZoneInfo object, use it for zone.
+        ZoneInfo zi = null;
         try {
-            ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged(
-                new PrivilegedExceptionAction() {
-                    public Object run() throws Exception {
-                        return input.readObject();
-                    }
-                });
-            if (zi != null) {
-                zone = zi;
+            zi = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<ZoneInfo>() {
+                        public ZoneInfo run() throws Exception {
+                            return (ZoneInfo) input.readObject();
+                        }
+                    },
+                    CalendarAccessControlContext.INSTANCE);
+        } catch (PrivilegedActionException pae) {
+            Exception e = pae.getException();
+            if (!(e instanceof OptionalDataException)) {
+                if (e instanceof RuntimeException) {
+                    throw (RuntimeException) e;
+                } else if (e instanceof IOException) {
+                    throw (IOException) e;
+                } else if (e instanceof ClassNotFoundException) {
+                    throw (ClassNotFoundException) e;
+                }
+                throw new RuntimeException(e);
             }
-        } catch (Exception e) {
+        }
+        if (zi != null) {
+            zone = zi;
         }
 
         // If the deserialized object has a SimpleTimeZone, try to
@@ -2674,9 +2704,9 @@
         // implementation as much as possible.
         if (zone instanceof SimpleTimeZone) {
             String id = zone.getID();
-            TimeZone zi = TimeZone.getTimeZone(id);
-            if (zi != null && zi.hasSameRules(zone) && zi.getID().equals(id)) {
-                zone = zi;
+            TimeZone tz = TimeZone.getTimeZone(id);
+            if (tz != null && tz.hasSameRules(zone) && tz.getID().equals(id)) {
+                zone = tz;
             }
         }
     }