public inbox for mauve-patches@sourceware.org
 help / color / mirror / Atom feed
* FYI: AccessController.getContext() checks extended
@ 2006-07-28 13:39 Gary Benson
  0 siblings, 0 replies; only message in thread
From: Gary Benson @ 2006-07-28 13:39 UTC (permalink / raw)
  To: mauve-patches

[-- Attachment #1: Type: text/plain, Size: 591 bytes --]

Hi all,

This commit extends the AccessController.getContext() checks I wrote
on Tuesday.  The original test checked that the returned context
contained all protection domains in the call stack.  With this commit
it also checks that the returned context does not contain protection
domains masked by calls to AccessController.doPrivileged().  This is
actually what I was trying to achieve the other day before the lethal
cocktail of heat, reflection and the AccessController Javadoc overcame
me.

Cheers,
Gary

PS If there's a competition for the most insane testcase then this is
my entry.

[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 9981 bytes --]

Index: ChangeLog
===================================================================
RCS file: /cvs/mauve/mauve/ChangeLog,v
retrieving revision 1.1839
diff -u -r1.1839 ChangeLog
--- ChangeLog	28 Jul 2006 11:03:22 -0000	1.1839
+++ ChangeLog	28 Jul 2006 13:27:52 -0000
@@ -1,3 +1,10 @@
+2006-07-28  Gary Benson  <gbenson@redhat.com>
+
+	* gnu/testlet/java/security/AccessController/contexts.java
+	(copyClass): Copy inner classes too.
+	(callListJarsOf, callPrivilegedListJarsOf): New methods.
+	(test): Extend to test AccessController.doPrivileged().
+
 2006-07-28  Roman Kennke  <kennke@aicas.com>
 
 	* gnu/testlet/javax/swing/text/AbstractDocument/getDocumentProperties.java:
Index: gnu/testlet/java/security/AccessController/contexts.java
===================================================================
RCS file: /cvs/mauve/mauve/gnu/testlet/java/security/AccessController/contexts.java,v
retrieving revision 1.1
diff -u -r1.1 contexts.java
--- gnu/testlet/java/security/AccessController/contexts.java	25 Jul 2006 15:58:20 -0000	1.1
+++ gnu/testlet/java/security/AccessController/contexts.java	28 Jul 2006 13:27:52 -0000
@@ -22,6 +22,7 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileFilter;
 import java.io.FileOutputStream;
 import java.io.FilePermission;
 import java.lang.reflect.Constructor;
@@ -33,6 +34,7 @@
 import java.security.AccessControlContext;
 import java.security.Permission;
 import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
 import java.util.Enumeration;
 import java.util.LinkedList;
@@ -45,9 +47,9 @@
 // In this test we load three different instances of ourself from
 // three different jarfiles with three different classloaders.  Each
 // classloader has a different protection domain in which that
-// classloader's jarfile is readable.  Some context-hopping is done,
-// and we determine success by checking our protection domains to see
-// which jarfile read permissions we find.
+// classloader's jarfile is readable.  All kinds of context-hopping is
+// performed, and we infer which protection domains are in our stack
+// by seeing which jarfile read permissions we can see.
 
 public class contexts implements Testlet
 {
@@ -57,7 +59,7 @@
     if (System.getProperty("gnu.classpath.version") == null)
       return;
 
-    File jars[] = new File[] {null, null};
+    File jars[] = new File[] {null, null, null};
     try {
       harness.checkPoint("setup");
 
@@ -68,7 +70,6 @@
       JarOutputStream jos = new JarOutputStream(new FileOutputStream(jars[0]));
       copyClass(harness.getSourceDirectory(), jos, getClass());
       copyClass(harness.getSourceDirectory(), jos, TestHarness.class);
-      copyClass(harness.getSourceDirectory(), jos, TestObject.class);
       jos.close();
 
       for (int i = 1; i < jars.length; i++) {
@@ -88,7 +89,7 @@
       }
 
       // Run the tests
-      test(harness, testObjects[0], testObjects[1]);
+      test(harness, testObjects);
     }
     catch (Exception ex) {
       harness.debug(ex);
@@ -106,17 +107,34 @@
   private static void copyClass(String srcdir, JarOutputStream jos, Class cls)
     throws Exception
   {
-    String relpath = cls.getName().replace(".", File.separator) + ".class";
+    File root = new File(srcdir, cls.getName().replace(".", File.separator));
+    final String rootpath = root.getPath();
+    int chop = srcdir.length() + File.separator.length();
+
+    File dir = root.getParentFile();
+    if (dir.isDirectory()) {
+      File[] files = dir.listFiles(new FileFilter() {
+	public boolean accept(File file) {
+	  String path = file.getPath();
+	  if (path.endsWith(".class")) {
+	    path = path.substring(0, path.length() - 6);
+	    if (path.equals(rootpath))
+	      return true;
+	    if (path.startsWith(rootpath + "$"))
+	      return true;
+	  }
+	  return false;
+	}
+      });
+      for (int i = 0; i < files.length; i++) {
+	byte[] bytes = new byte[(int) files[i].length()];
+	FileInputStream fis = new FileInputStream(files[i]);
+	fis.read(bytes);
+	fis.close();
 
-    File file = new File(srcdir, relpath);
-    if (file.exists()) {
-      byte[] bytes = new byte[(int) file.length()];
-      FileInputStream fis = new FileInputStream(file);
-      fis.read(bytes);
-      fis.close();
-
-      jos.putNextEntry(new JarEntry(relpath));
-      jos.write(bytes, 0, bytes.length);
+	jos.putNextEntry(new JarEntry(files[i].getPath().substring(chop)));
+	jos.write(bytes, 0, bytes.length);
+      }
     }
 
     Class superclass = cls.getSuperclass();
@@ -168,6 +186,24 @@
 	"listJarsOf", new Class[] {Object.class});
       return (String[]) method.invoke(object, new Object[] {other.object});
     }
+
+    public String[] callListJarsOf(TestObject caller, TestObject callee)
+      throws Exception
+    {
+      Method method = object.getClass().getMethod(
+	"callListJarsOf", new Class[] {Object.class, Object.class});
+      return (String[]) method.invoke(
+	object, new Object[] {caller.object, callee.object});
+    }
+
+    public String[] callPrivilegedListJarsOf(
+      TestObject caller, TestObject callee) throws Exception
+    {
+      Method method = object.getClass().getMethod(
+	"callPrivilegedListJarsOf", new Class[] {Object.class, Object.class});
+      return (String[]) method.invoke(
+	object, new Object[] {caller.object, callee.object});
+    }
   }
 
   public String[] listJarsOf(Object object) throws Exception
@@ -176,6 +212,38 @@
     return (String[]) method.invoke(object, new Object[0]);
   }
 
+  public String[] callListJarsOf(Object caller, Object callee)
+    throws Exception
+  {
+    Method method = caller.getClass().getMethod(
+      "listJarsOf", new Class[] {Object.class});
+    return (String[]) method.invoke(caller, new Object[] {callee});
+  }
+
+  public String[] callPrivilegedListJarsOf(Object caller, Object callee)
+    throws Exception
+  {
+    Method method = caller.getClass().getMethod(
+      "privilegedListJarsOf", new Class[] {Object.class});
+    return (String[]) method.invoke(caller, new Object[] {callee});
+  }
+
+  public String[] privilegedListJarsOf(final Object object) throws Exception
+  {
+    final Method method = object.getClass().getMethod(
+      "listJars", new Class[0]);
+    return (String[]) AccessController.doPrivileged(new PrivilegedAction() {
+      public Object run() {
+	try {
+	  return method.invoke(object, new Object[0]);
+	}
+	catch (Exception e) {
+	  return e;
+	}
+      }
+    });
+  }
+
   public String[] listJars() throws Exception
   {
     AccessControlContext ctx = AccessController.getContext();
@@ -204,36 +272,74 @@
   }
   
   // Perform the tests
-  private static void test(
-    TestHarness harness, TestObject caller, TestObject callee)
+  private static void test(TestHarness harness, TestObject[] objects)
     throws Exception
   {
-    // Each object should see only its own jar when listing itself
+    // Each object should see only its own protection domain
     harness.checkPoint("self-listing");
 
-    String[] jars = caller.listJarsOf(caller);
-    harness.check(jars.length == 1);
-    String caller_jar = jars[0];
-
-    jars = callee.listJarsOf(callee);
-    harness.check(jars.length == 1);
-    String callee_jar = jars[0];
+    String[] jars = new String[objects.length];
+    for (int i = 0; i < objects.length; i++) {
+      String[] result = objects[i].listJarsOf(objects[i]);
+      harness.check(result.length == 1);
+      jars[i] = result[0];
+    }
+    for (int i = 0; i < objects.length; i++) {
+      for (int j = i + 1; j < objects.length; j++)
+	harness.check(!jars[i].equals(jars[j]));
+    }
+    
+    // When one object calls another both objects' protection domains
+    // should be present.
+    harness.checkPoint("straight other-listing");
 
-    harness.check(!caller_jar.equals(callee_jar));
+    boolean[] seen = new boolean[jars.length];
+    String[] result = objects[0].listJarsOf(objects[1]);
+    harness.check(result.length == 2);
+    for (int i = 0; i < seen.length; i++) {
+      seen[i] = false;
+      for (int j = 0; j < result.length; j++) {
+	if (result[j].equals(jars[i])) {
+	  harness.check(!seen[i]);
+	  seen[i] = true;
+	}
+      }
+    }
+    harness.check(seen[0] && seen[1] && !seen[2]);
 
-    // When one object calls another's lister both object's jars
-    // should be visible.
-    harness.checkPoint("straight other-listing");
+    // When one object calls another that calls another all three
+    // objects' protection domains should be present.
+    harness.checkPoint("straight other-other-listing");
+
+    result = objects[0].callListJarsOf(objects[1], objects[2]);
+    harness.check(result.length == 3);
+    for (int i = 0; i < seen.length; i++) {
+      seen[i] = false;
+      for (int j = 0; j < result.length; j++) {
+	if (result[j].equals(jars[i])) {
+	  harness.check(!seen[i]);
+	  seen[i] = true;
+	}
+      }
+    }
+    harness.check(seen[0] && seen[1] && seen[2]);
 
-    jars = caller.listJarsOf(callee);
-    boolean caller_seen = false;
-    boolean callee_seen = false;
-    for (int i = 0; i < jars.length; i++) {
-      if (jars[i].equals(caller_jar))
-	caller_seen = true;
-      else if (jars[i].equals(callee_jar))
-	callee_seen = true;
+    // When one object calls another that uses doPrivileged to call
+    // a third then the first object's protection domain should not
+    // be present.
+    harness.checkPoint("privileged other-other-listing");
+
+    result = objects[0].callPrivilegedListJarsOf(objects[1], objects[2]);
+    harness.check(result.length == 2);
+    for (int i = 0; i < seen.length; i++) {
+      seen[i] = false;
+      for (int j = 0; j < result.length; j++) {
+	if (result[j].equals(jars[i])) {
+	  harness.check(!seen[i]);
+	  seen[i] = true;
+	}
+      }
     }
-    harness.check(jars.length == 2 && caller_seen && callee_seen);
+    harness.check(!seen[0] && seen[1] && seen[2]);
   }
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-07-28 13:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-07-28 13:39 FYI: AccessController.getContext() checks extended Gary Benson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).