Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4921945

Cannot deserialize a Calendar with Security on

XMLWordPrintable

    • b28
    • generic, x86
    • generic, linux, windows_2000, windows_xp

        Name: dk106046 Date: 09/12/2003

        Cannot fully reconstitute a Calendar if Security is on and the caller does not have the permission accessClassInPackage.sun.util.calendar. This is because the Calendar.readObject() method needs access to the class sun.util.calendar.ZoneInfo.

        In the simple testcase supplied, a SimpleTimeZone object gets substituted, but in a more complex environment with IIOP, a ClassCastException is thrown and the application fails.

        - Exact steps to reproduce
        Run the supplied testcase, SerialRoundTrip. With security off, you'll see:

        $ java SerialRoundTrip
        SecurityManager=null
        objects are equal: true

        but with security on:
        $java -Djava.security.manager SerialRoundTrip
        SecurityManager=java.lang.SecurityManager@xxxxxxxx
        package access = false
        objects are equal: false

        Note if you see "package access = true", then you have some non-default permissions granted somewhere, look for $HOME/.java.policy or similar.

        - Minimal source code that demonstrates the problem

        import java.util.GregorianCalendar;
        import java.io.ByteArrayInputStream;
        import java.io.ByteArrayOutputStream;
        import java.io.IOException;
        import java.io.ObjectInputStream;
        import java.io.ObjectOutputStream;

        public class SerialRoundTrip {

            public byte[] write (Object o) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject (o);
        return baos.toByteArray();
            }

            public Object read (byte[] serialized) throws IOException,ClassNotFoundException {
        ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
        ObjectInputStream ois = new ObjectInputStream(bais);
        return ois.readObject();
            }

            public static void main(String[] args) throws ClassNotFoundException,IOException {
        SecurityManager sm = System.getSecurityManager();
        System.out.println ("SecurityManager=" + sm);
        boolean accessPackagePermission;
        if (sm != null) {
        try {
        sm.checkPackageAccess ("sun.util.calendar");
        accessPackagePermission = true;
        } catch (SecurityException e) {
        accessPackagePermission = false;
        }
        System.out.println ("package access = " + accessPackagePermission);
        }

        GregorianCalendar gc1 = new GregorianCalendar();
        SerialRoundTrip s = new SerialRoundTrip();
        byte[] serialized = s.write (gc1);
        // System.out.println ("wrote:" + gc1);
        GregorianCalendar gc2 = (GregorianCalendar)s.read (serialized);
        // System.out.println ("read: " + gc2);
        System.out.println ("objects are equal: " + gc1.equals(gc2));
            }
        }

        If you turn on security debug:
        $java -Djava.security.manager -Djava.security.debug=access,failure SerialRoundTrip

        you can see the internal exception:
        access: access denied (java.lang.RuntimePermission accessClassInPackage.sun.util.calendar)
        java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Thread.java:1071)
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java:259)
        at java.security.AccessController.checkPermission(AccessController.java:401)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:542)
        at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1513)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:262)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:255)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:315)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:217)
        at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:558)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1513)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1435)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1626)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
        at java.util.Calendar.readObject(Calendar.java:1690)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:324)
        at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:824)
        at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1746)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
        at SerialRoundTrip.read(SerialRoundTrip.java:21)
        at SerialRoundTrip.main(SerialRoundTrip.java:42)
        access: access allowed (java.util.PropertyPermission java.security.debug read)
        access: access allowed (java.io.FilePermission /export/home/cem/defects/s63741 read)
        access: domain that failed ProtectionDomain (file:/export/home/cem/defects/s63741/ <no certificates>)
         sun.misc.Launcher$AppClassLoader@169e11
         <no principals>
         java.security.Permissions@7bd9f2 (
         (java.io.FilePermission /export/home/cem/defects/s63741/- read)
         (java.net.SocketPermission localhost:1024- listen,resolve)
         (java.util.PropertyPermission java.specification.vendor read)
         (java.util.PropertyPermission java.vm.specification.vendor read)
         (java.util.PropertyPermission path.separator read)
         (java.util.PropertyPermission java.vm.name read)
         (java.util.PropertyPermission java.class.version read)
         (java.util.PropertyPermission os.name read)
         (java.util.PropertyPermission java.vendor.url read)
         (java.util.PropertyPermission java.vendor read)
         (java.util.PropertyPermission java.vm.vendor read)
         (java.util.PropertyPermission file.separator read)
         (java.util.PropertyPermission os.version read)
         (java.util.PropertyPermission java.vm.version read)
         (java.util.PropertyPermission java.version read)
         (java.util.PropertyPermission line.separator read)
         (java.util.PropertyPermission java.vm.specification.version read)
         (java.util.PropertyPermission java.specification.name read)
         (java.util.PropertyPermission java.vm.specification.name read)
         (java.util.PropertyPermission java.specification.version read)
         (java.util.PropertyPermission os.arch read)
         (java.lang.RuntimePermission exitVM)
         (java.lang.RuntimePermission stopThread)
        )

        A suggested fix is to wrap the failing code in the Calendar.readObject() method in a privileged block.

        ======================================================================

              okutsu Masayoshi Okutsu
              dkorbel David Korbel (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: