-
Bug
-
Resolution: Fixed
-
P4
-
1.4.1, 1.4.2, 1.4.2_05
-
b28
-
generic, x86
-
generic, linux, windows_2000, windows_xp
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2130692 | 1.4.2_11 | Mala Bankal | P3 | Resolved | Fixed | b01 |
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.
======================================================================
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.
======================================================================
- backported by
-
JDK-2130692 Cannot deserialize a Calendar with Security on
-
- Resolved
-
- duplicates
-
JDK-6367956 GregorianCalendar deserialization error
-
- Closed
-
-
JDK-4950874 Deserialization of multiple Calendar objects fails under applet security manager
-
- Closed
-