JDK-4921945 : Cannot deserialize a Calendar with Security on
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.4.1,1.4.2,1.4.2_05
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    generic,linux,windows_2000,windows_xp generic,linux,windows_2000,windows_xp
  • CPU: generic,x86
  • Submitted: 2003-09-12
  • Updated: 2003-11-05
  • Resolved: 2003-11-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2_11Fixed
Related Reports
Duplicate :  
Duplicate :  
Description
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.

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

Comments
WORK AROUND Name: dk106046 Date: 09/12/2003 Grant accessClassInPackage.sun.util.calendar to the application. This is undesirable. ======================================================================
03-09-2004

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger tiger-beta FIXED IN: tiger-beta INTEGRATED IN: tiger-b28 tiger-beta
03-09-2004

EVALUATION Should be fixed in Tiger. ###@###.### 2003-10-03
03-10-2003