From 44bc36797efb004b85bef4e540caae998ede7fc1 Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Sat, 25 Dec 2010 16:53:14 +0000 Subject: PR classpath/42390: Add security check to ObjectOutputStream(OutputStream) constructor. 2010-12-25 Andrew John Hughes PR classpath/42390 * java/io/ObjectOutputStream.java: (ObjectOutputStream(OutputStream)): Add required security check. (overridesMethods(Class)): Check whether the subclass overrides one of the methods which requires a security check. --- java/io/ObjectOutputStream.java | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'java') diff --git a/java/io/ObjectOutputStream.java b/java/io/ObjectOutputStream.java index 18890c02f..2717ac4aa 100644 --- a/java/io/ObjectOutputStream.java +++ b/java/io/ObjectOutputStream.java @@ -48,6 +48,8 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; /** * An ObjectOutputStream can be used to write objects @@ -136,6 +138,10 @@ public class ObjectOutputStream extends OutputStream */ public ObjectOutputStream (OutputStream out) throws IOException { + SecurityManager secMan = System.getSecurityManager(); + if (secMan != null && overridesMethods(getClass())) + secMan.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); + realOutput = new DataOutputStream(out); blockData = new byte[ BUFFER_SIZE ]; blockDataCount = 0; @@ -1481,4 +1487,44 @@ public class ObjectOutputStream extends OutputStream private boolean dump = false; private static final boolean DEBUG = false; + + /** + * Returns true if the given class overrides either of the + * methods putFields or writeUnshared. + * + * @param clazz the class to check. + * @return true if the class overrides one of the methods. + */ + private static boolean overridesMethods(final Class clazz) + { + if (clazz == ObjectOutputStream.class) + return false; + + return AccessController.doPrivileged(new PrivilegedAction() { + public Boolean run() + { + Method[] methods = clazz.getDeclaredMethods(); + for (int a = 0; a < methods.length; ++a) + { + String name = methods[a].getName(); + if (name.equals("writeUnshared")) + { + Class[] paramTypes = methods[a].getParameterTypes(); + if (paramTypes.length == 1 && + paramTypes[0] == Object.class && + methods[a].getReturnType() == Void.class) + return true; + } + else if (name.equals("putFields")) + { + if (methods[a].getParameterTypes().length == 0 && + methods[a].getReturnType() == PutField.class) + return true; + } + } + return false; + } + }); + } + } -- cgit v1.2.1