United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4921945 : Cannot deserialize a Calendar with Security on

Details
Type:
Bug
Submit Date:
2003-09-12
Status:
Resolved
Updated Date:
2003-11-05
Project Name:
JDK
Resolved Date:
2003-11-05
Component:
core-libs
OS:
linux,generic,windows_xp,windows_2000
Sub-Component:
java.util:i18n
CPU:
x86,generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.4.1,1.4.2,1.4.2_05
Fixed Versions:
5.0 (b28)

Related Reports
Backport:
Duplicate:
Duplicate:

Sub Tasks

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
EVALUATION

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

BugTraq+ Release Management Values

COMMIT TO FIX:
tiger
tiger-beta

FIXED IN:
tiger-beta

INTEGRATED IN:
tiger-b28
tiger-beta


                                     
2004-09-03
WORK AROUND

Name: dk106046			Date: 09/12/2003

Grant accessClassInPackage.sun.util.calendar to the application. This is undesirable.
======================================================================
                                     
2004-09-03



Hardware and Software, Engineered to Work Together