// Tags: JDK1.2
// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
// Written by Jeroen Frijters <jeroen@frijters.net>
// This file is part of Mauve.
// Mauve is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// Mauve is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Mauve; see the file COPYING. If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA. */
package gnu.testlet.wonka.lang.ClassLoader;
import gnu.testlet.TestHarness;
import gnu.testlet.Testlet;
/**
* This test simulates a security attack dealing with the registering of a rogue
* ClassLoader when it is not allowed. The detail of the potentiel problem is
* described
* <a href="http://www.securingjava.com/chapter-five/chapter-five-8.html">here</a>.
* Basically, it creates an incomplete ClassLoader (by throwing an exception
* during the construction) and later uses the finalizer to retrieve the
* instance and try to use this rogue instance. This test makes sure that any
* method call then throws a SecurityException.
* Running finalizers being not an exact science, some jvm will not run them
* when System.runFinalization() is called hence not allowing the security
* breach to be checked.
*
* @author Jeroen Frijters <jeroen@frijters.net>
*/
public class initialize implements Testlet
{
static class TestLoader extends ClassLoader
{
// The holder for the rogue TestLoader instance
static TestLoader ref;
// The method which simulates an exception to be thrown at construction time
static ClassLoader throwException() { throw new Error(); }
// The constructor which will fail to create a complete instance
TestLoader() { super(throwException()); }
// The finalizer which retrieves the partly created instance
protected void finalize() { ref = this; }
static void runTests(TestHarness harness) throws Exception
{
harness.checkPoint("loadClass");
try
{
ref.loadClass("java.lang.Object");
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
try
{
ref.loadClass("java.lang.Object", false);
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
harness.checkPoint("findClass");
try
{
ref.findClass("java.lang.Object");
harness.check(false);
}
catch(ClassNotFoundException _)
{
harness.check(true);
}
harness.checkPoint("defineClass");
try
{
ref.defineClass(new byte[0], 0, 0);
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
try
{
ref.defineClass("Foo", new byte[0], 0, 0);
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
try
{
ref.defineClass("Foo", new byte[0], 0, 0, null);
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
harness.checkPoint("resolveClass");
try
{
ref.resolveClass(String.class);
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
harness.checkPoint("findSystemClass");
try
{
ref.findSystemClass("java.lang.Object");
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
harness.checkPoint("setSigners");
try
{
ref.setSigners(String.class, new Object[0]);
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
harness.checkPoint("findLoadedClass");
try
{
ref.findLoadedClass("java.lang.Object");
harness.check(false);
}
catch(SecurityException _)
{
harness.check(true);
}
harness.checkPoint("definePackage");
try
{
ref.definePackage("Foo", "", "", "", "", "", "", null);
harness.check(false);
}
catch(NullPointerException _)
{
harness.check(true);
}
try
{
ref.getPackage("Foo");
harness.check(false);
}
catch(NullPointerException _)
{
harness.check(true);
}
try
{
ref.getPackages();
harness.check(false);
}
catch(NullPointerException _)
{
harness.check(true);
}
}
}
public void test(TestHarness harness)
{
// Creates a garbage collectable rogue TestLoader instance
try { new TestLoader(); } catch(Error x) {}
// Hints at the vm that running finalizers now would be a good idea
System.gc();
System.runFinalization();
// Checks that TestLoader.finalize retrieved the partly created instance,
// and if so, tests it
if (TestLoader.ref == null)
harness.debug("Unable to obtain finalized ClassLoader instance");
else
{
try
{
TestLoader.runTests(harness);
}
catch(Exception x)
{
harness.debug(x);
harness.check(false);
}
}
}
}