diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2010-12-25 16:53:14 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2010-12-25 16:53:14 +0000 |
commit | 44bc36797efb004b85bef4e540caae998ede7fc1 (patch) | |
tree | 86633ff5dae77371a2ecc46ebf0536eb2920ee37 | |
parent | e2d3135056d61448313e413b201697b3808f06ba (diff) | |
download | classpath-44bc36797efb004b85bef4e540caae998ede7fc1.tar.gz |
PR classpath/42390: Add security check to ObjectOutputStream(OutputStream) constructor.
2010-12-25 Andrew John Hughes <ahughes@redhat.com>
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.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | java/io/ObjectOutputStream.java | 46 |
2 files changed, 56 insertions, 0 deletions
@@ -1,3 +1,13 @@ +2010-12-25 Andrew John Hughes <ahughes@redhat.com> + + 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. + 2010-12-24 Andrew John Hughes <ahughes@redhat.com> * java/security/ProtectionDomain.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 <code>ObjectOutputStream</code> 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 <code>putFields</code> or <code>writeUnshared</code>. + * + * @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<Boolean>() { + 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; + } + }); + } + } |