OSDN Git Service

2006-07-28 Gary Benson <gbenson@redhat.com>
authorgary <gary@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 Jul 2006 10:54:11 +0000 (10:54 +0000)
committergary <gary@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 Jul 2006 10:54:11 +0000 (10:54 +0000)
    Casey Marshall <csm@gnu.org>

PR libgcj/13604:
* include/java-stack.h (GetClassMethodStack): Declare.
* stacktrace.cc (GetClassMethodStack): New method.
* java/security/AccessController.java: Removed.
* java/security/VMAccessController.java: New file.
* java/security/natVMAccessController.cc: Likewise.
* Makefile.am (nat_source_files): Added the above.
* sources.am, Makefile.in: Rebuilt.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115793 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/include/java-stack.h
libjava/java/security/AccessController.java [deleted file]
libjava/java/security/VMAccessController.java [new file with mode: 0644]
libjava/java/security/natVMAccessController.cc [new file with mode: 0644]
libjava/sources.am
libjava/stacktrace.cc

index 3e4e0f5..e73c3e5 100644 (file)
@@ -1,4 +1,16 @@
 2006-07-28  Gary Benson  <gbenson@redhat.com>
+           Casey Marshall <csm@gnu.org>
+
+       PR libgcj/13604:
+       * include/java-stack.h (GetClassMethodStack): Declare.
+       * stacktrace.cc (GetClassMethodStack): New method.
+       * java/security/AccessController.java: Removed.
+       * java/security/VMAccessController.java: New file.
+       * java/security/natVMAccessController.cc: Likewise.
+       * Makefile.am (nat_source_files): Added the above.
+       * sources.am, Makefile.in: Rebuilt.
+
+2006-07-28  Gary Benson  <gbenson@redhat.com>
 
        * java/lang/SecurityManager.java (currentClassLoader,
        currentLoadedClass, classLoaderDepth, checkAccess, checkRead,
index f4f5d15..45a4930 100644 (file)
@@ -826,6 +826,7 @@ java/net/natVMNetworkInterface.cc \
 java/net/natInetAddress.cc \
 java/nio/channels/natVMChannels.cc \
 java/nio/natDirectByteBufferImpl.cc \
+java/security/natVMAccessController.cc \
 java/text/natCollator.cc \
 java/util/natResourceBundle.cc \
 java/util/natVMTimeZone.cc \
index e50c1e6..631ebb8 100644 (file)
@@ -287,12 +287,13 @@ am__libgcj_la_SOURCES_DIST = prims.cc jni.cc jvmti.cc exception.cc \
        java/lang/reflect/natField.cc java/lang/reflect/natMethod.cc \
        java/net/natVMNetworkInterface.cc java/net/natInetAddress.cc \
        java/nio/channels/natVMChannels.cc \
-       java/nio/natDirectByteBufferImpl.cc java/text/natCollator.cc \
-       java/util/natResourceBundle.cc java/util/natVMTimeZone.cc \
-       java/util/logging/natLogger.cc java/util/zip/natDeflater.cc \
-       java/util/zip/natInflater.cc boehm.cc nogc.cc posix.cc \
-       win32.cc darwin.cc posix-threads.cc win32-threads.cc \
-       no-threads.cc
+       java/nio/natDirectByteBufferImpl.cc \
+       java/security/natVMAccessController.cc \
+       java/text/natCollator.cc java/util/natResourceBundle.cc \
+       java/util/natVMTimeZone.cc java/util/logging/natLogger.cc \
+       java/util/zip/natDeflater.cc java/util/zip/natInflater.cc \
+       boehm.cc nogc.cc posix.cc win32.cc darwin.cc posix-threads.cc \
+       win32-threads.cc no-threads.cc
 am__objects_2 = gnu/classpath/natSystemProperties.lo \
        gnu/gcj/natCore.lo gnu/gcj/convert/JIS0208_to_Unicode.lo \
        gnu/gcj/convert/JIS0212_to_Unicode.lo \
@@ -328,10 +329,11 @@ am__objects_2 = gnu/classpath/natSystemProperties.lo \
        java/lang/reflect/natField.lo java/lang/reflect/natMethod.lo \
        java/net/natVMNetworkInterface.lo java/net/natInetAddress.lo \
        java/nio/channels/natVMChannels.lo \
-       java/nio/natDirectByteBufferImpl.lo java/text/natCollator.lo \
-       java/util/natResourceBundle.lo java/util/natVMTimeZone.lo \
-       java/util/logging/natLogger.lo java/util/zip/natDeflater.lo \
-       java/util/zip/natInflater.lo
+       java/nio/natDirectByteBufferImpl.lo \
+       java/security/natVMAccessController.lo \
+       java/text/natCollator.lo java/util/natResourceBundle.lo \
+       java/util/natVMTimeZone.lo java/util/logging/natLogger.lo \
+       java/util/zip/natDeflater.lo java/util/zip/natInflater.lo
 @USING_BOEHMGC_TRUE@am__objects_3 = boehm.lo
 @USING_NOGC_TRUE@am__objects_4 = nogc.lo
 @USING_POSIX_PLATFORM_TRUE@am__objects_5 = posix.lo
@@ -616,6 +618,7 @@ bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
 build_cpu = @build_cpu@
+build_libsubdir = @build_libsubdir@
 build_os = @build_os@
 build_subdir = @build_subdir@
 build_vendor = @build_vendor@
@@ -4158,7 +4161,7 @@ java_rmi_server_header_files = $(patsubst classpath/%,%,$(patsubst %.java,%.h,$(
 java_security_source_files = \
 classpath/java/security/AccessControlContext.java \
 classpath/java/security/AccessControlException.java \
-java/security/AccessController.java \
+classpath/java/security/AccessController.java \
 classpath/java/security/AlgorithmParameterGenerator.java \
 classpath/java/security/AlgorithmParameterGeneratorSpi.java \
 classpath/java/security/AlgorithmParameters.java \
@@ -4223,6 +4226,7 @@ classpath/java/security/SignedObject.java \
 classpath/java/security/Signer.java \
 classpath/java/security/UnrecoverableKeyException.java \
 classpath/java/security/UnresolvedPermission.java \
+java/security/VMAccessController.java \
 java/security/VMSecureRandom.java
 
 java_security_header_files = $(patsubst classpath/%,%,$(patsubst %.java,%.h,$(java_security_source_files)))
@@ -7136,6 +7140,7 @@ java/net/natVMNetworkInterface.cc \
 java/net/natInetAddress.cc \
 java/nio/channels/natVMChannels.cc \
 java/nio/natDirectByteBufferImpl.cc \
+java/security/natVMAccessController.cc \
 java/text/natCollator.cc \
 java/util/natResourceBundle.cc \
 java/util/natVMTimeZone.cc \
@@ -7625,6 +7630,14 @@ java/nio/$(DEPDIR)/$(am__dirstamp):
        @: > java/nio/$(DEPDIR)/$(am__dirstamp)
 java/nio/natDirectByteBufferImpl.lo: java/nio/$(am__dirstamp) \
        java/nio/$(DEPDIR)/$(am__dirstamp)
+java/security/$(am__dirstamp):
+       @$(mkdir_p) java/security
+       @: > java/security/$(am__dirstamp)
+java/security/$(DEPDIR)/$(am__dirstamp):
+       @$(mkdir_p) java/security/$(DEPDIR)
+       @: > java/security/$(DEPDIR)/$(am__dirstamp)
+java/security/natVMAccessController.lo: java/security/$(am__dirstamp) \
+       java/security/$(DEPDIR)/$(am__dirstamp)
 java/text/$(am__dirstamp):
        @$(mkdir_p) java/text
        @: > java/text/$(am__dirstamp)
@@ -7926,6 +7939,8 @@ mostlyclean-compile:
        -rm -f java/nio/channels/natVMChannels.lo
        -rm -f java/nio/natDirectByteBufferImpl.$(OBJEXT)
        -rm -f java/nio/natDirectByteBufferImpl.lo
+       -rm -f java/security/natVMAccessController.$(OBJEXT)
+       -rm -f java/security/natVMAccessController.lo
        -rm -f java/text/natCollator.$(OBJEXT)
        -rm -f java/text/natCollator.lo
        -rm -f java/util/logging/natLogger.$(OBJEXT)
@@ -8042,6 +8057,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@java/net/$(DEPDIR)/natVMNetworkInterface.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@java/nio/$(DEPDIR)/natDirectByteBufferImpl.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@java/nio/channels/$(DEPDIR)/natVMChannels.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@java/security/$(DEPDIR)/natVMAccessController.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@java/text/$(DEPDIR)/natCollator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@java/util/$(DEPDIR)/natResourceBundle.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@java/util/$(DEPDIR)/natVMTimeZone.Plo@am__quote@
@@ -8317,6 +8333,7 @@ clean-libtool:
        -rm -rf java/net/.libs java/net/_libs
        -rm -rf java/nio/.libs java/nio/_libs
        -rm -rf java/nio/channels/.libs java/nio/channels/_libs
+       -rm -rf java/security/.libs java/security/_libs
        -rm -rf java/text/.libs java/text/_libs
        -rm -rf java/util/.libs java/util/_libs
        -rm -rf java/util/logging/.libs java/util/logging/_libs
@@ -8739,6 +8756,8 @@ distclean-generic:
        -rm -f java/nio/$(am__dirstamp)
        -rm -f java/nio/channels/$(DEPDIR)/$(am__dirstamp)
        -rm -f java/nio/channels/$(am__dirstamp)
+       -rm -f java/security/$(DEPDIR)/$(am__dirstamp)
+       -rm -f java/security/$(am__dirstamp)
        -rm -f java/text/$(DEPDIR)/$(am__dirstamp)
        -rm -f java/text/$(am__dirstamp)
        -rm -f java/util/$(DEPDIR)/$(am__dirstamp)
@@ -8760,7 +8779,7 @@ clean-am: clean-binPROGRAMS clean-dbexecLTLIBRARIES clean-generic \
 
 distclean: distclean-recursive
        -rm -f $(am__CONFIG_DISTCLEAN_FILES)
-       -rm -rf ./$(DEPDIR) classpath/tools/$(DEPDIR) gnu/classpath/$(DEPDIR) gnu/gcj/$(DEPDIR) gnu/gcj/convert/$(DEPDIR) gnu/gcj/io/$(DEPDIR) gnu/gcj/runtime/$(DEPDIR) gnu/gcj/tools/gcj_dbtool/$(DEPDIR) gnu/gcj/util/$(DEPDIR) gnu/gcj/xlib/$(DEPDIR) gnu/java/lang/$(DEPDIR) gnu/java/net/$(DEPDIR) gnu/java/net/protocol/core/$(DEPDIR) gnu/java/nio/$(DEPDIR) gnu/java/nio/channels/$(DEPDIR) java/io/$(DEPDIR) java/lang/$(DEPDIR) java/lang/ref/$(DEPDIR) java/lang/reflect/$(DEPDIR) java/net/$(DEPDIR) java/nio/$(DEPDIR) java/nio/channels/$(DEPDIR) java/text/$(DEPDIR) java/util/$(DEPDIR) java/util/logging/$(DEPDIR) java/util/zip/$(DEPDIR)
+       -rm -rf ./$(DEPDIR) classpath/tools/$(DEPDIR) gnu/classpath/$(DEPDIR) gnu/gcj/$(DEPDIR) gnu/gcj/convert/$(DEPDIR) gnu/gcj/io/$(DEPDIR) gnu/gcj/runtime/$(DEPDIR) gnu/gcj/tools/gcj_dbtool/$(DEPDIR) gnu/gcj/util/$(DEPDIR) gnu/gcj/xlib/$(DEPDIR) gnu/java/lang/$(DEPDIR) gnu/java/net/$(DEPDIR) gnu/java/net/protocol/core/$(DEPDIR) gnu/java/nio/$(DEPDIR) gnu/java/nio/channels/$(DEPDIR) java/io/$(DEPDIR) java/lang/$(DEPDIR) java/lang/ref/$(DEPDIR) java/lang/reflect/$(DEPDIR) java/net/$(DEPDIR) java/nio/$(DEPDIR) java/nio/channels/$(DEPDIR) java/security/$(DEPDIR) java/text/$(DEPDIR) java/util/$(DEPDIR) java/util/logging/$(DEPDIR) java/util/zip/$(DEPDIR)
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-libtool distclean-local distclean-tags
@@ -8791,7 +8810,7 @@ installcheck-am:
 maintainer-clean: maintainer-clean-recursive
        -rm -f $(am__CONFIG_DISTCLEAN_FILES)
        -rm -rf $(top_srcdir)/autom4te.cache
-       -rm -rf ./$(DEPDIR) classpath/tools/$(DEPDIR) gnu/classpath/$(DEPDIR) gnu/gcj/$(DEPDIR) gnu/gcj/convert/$(DEPDIR) gnu/gcj/io/$(DEPDIR) gnu/gcj/runtime/$(DEPDIR) gnu/gcj/tools/gcj_dbtool/$(DEPDIR) gnu/gcj/util/$(DEPDIR) gnu/gcj/xlib/$(DEPDIR) gnu/java/lang/$(DEPDIR) gnu/java/net/$(DEPDIR) gnu/java/net/protocol/core/$(DEPDIR) gnu/java/nio/$(DEPDIR) gnu/java/nio/channels/$(DEPDIR) java/io/$(DEPDIR) java/lang/$(DEPDIR) java/lang/ref/$(DEPDIR) java/lang/reflect/$(DEPDIR) java/net/$(DEPDIR) java/nio/$(DEPDIR) java/nio/channels/$(DEPDIR) java/text/$(DEPDIR) java/util/$(DEPDIR) java/util/logging/$(DEPDIR) java/util/zip/$(DEPDIR)
+       -rm -rf ./$(DEPDIR) classpath/tools/$(DEPDIR) gnu/classpath/$(DEPDIR) gnu/gcj/$(DEPDIR) gnu/gcj/convert/$(DEPDIR) gnu/gcj/io/$(DEPDIR) gnu/gcj/runtime/$(DEPDIR) gnu/gcj/tools/gcj_dbtool/$(DEPDIR) gnu/gcj/util/$(DEPDIR) gnu/gcj/xlib/$(DEPDIR) gnu/java/lang/$(DEPDIR) gnu/java/net/$(DEPDIR) gnu/java/net/protocol/core/$(DEPDIR) gnu/java/nio/$(DEPDIR) gnu/java/nio/channels/$(DEPDIR) java/io/$(DEPDIR) java/lang/$(DEPDIR) java/lang/ref/$(DEPDIR) java/lang/reflect/$(DEPDIR) java/net/$(DEPDIR) java/nio/$(DEPDIR) java/nio/channels/$(DEPDIR) java/security/$(DEPDIR) java/text/$(DEPDIR) java/util/$(DEPDIR) java/util/logging/$(DEPDIR) java/util/zip/$(DEPDIR)
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
index eb1ddcc..a1b0db6 100644 (file)
@@ -124,6 +124,7 @@ public:
   static void GetCallerInfo (jclass checkClass, jclass *, _Jv_Method **);
   static JArray<jclass> *GetClassContext (jclass checkClass);
   static ClassLoader *GetFirstNonSystemClassLoader (void);
+  static JArray<jobjectArray> *GetClassMethodStack (_Jv_StackTrace *trace);
   
 };
 
diff --git a/libjava/java/security/AccessController.java b/libjava/java/security/AccessController.java
deleted file mode 100644 (file)
index 4f40edb..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* AccessController.java --- Access control context and permission checker
-   Copyright (C) 2001, 2004  Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath 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.
-
-GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package java.security;
-
-/**
- * Access control context and permission checker.
- * Can check permissions in the access control context of the current thread
- * through the <code>checkPermission()</code> method.
- * Manipulates the access control context for code that needs to be executed
- * the protection domain of the calling class (by explicitly ignoring the
- * context of the calling code) in the <code>doPrivileged()</code> methods.
- * And provides a <code>getContext()</code> method which gives the access
- * control context of the current thread that can be used for checking
- * permissions at a later time and/or in another thread.
- * <p>
- * XXX - Mostly a stub implementation at the moment. Needs native support
- * from the VM to function correctly. XXX - Do not forget to think about
- * how to handle <code>java.lang.reflect.Method.invoke()</code> on the
- * <code>doPrivileged()</code> methods.
- *
- * @author Mark Wielaard (mark@klomp.org)
- * @since 1.2
- */
-public final class AccessController
-{
-  /**
-   * This class only has static methods so there is no public contructor.
-   */
-  private AccessController()
-  {
-  }
-
-  /**
-   * Checks wether the access control context of the current thread allows
-   * the given Permission. Throws an <code>AccessControlException</code>
-   * when the permission is not allowed in the current context. Otherwise
-   * returns silently without throwing an exception.
-   *
-   * @param perm the permission to be checked.
-   * @exception AccessControlException thrown if the current context does not
-   * allow the given permission.
-   */
-  public static void checkPermission(Permission perm)
-    throws AccessControlException
-  {
-    getContext().checkPermission(perm);
-  }
-
-  /**
-   * Calls the <code>run()</code> method of the given action with as
-   * (initial) access control context only the protection domain of the
-   * calling class. Calls to <code>checkPermission()</code> in the
-   * <code>run()</code> method ignore all earlier protection domains of
-   * classes in the call chain. Note that the protection domains of classes
-   * called by the code in the <code>run()</code> method are not ignored.
-   *
-   * @param action the <code>PrivilegedAction</code> whose <code>run()</code>
-   * should be be called.
-   * @return the result of the <code>action.run()</code> method.
-   */
-  public static Object doPrivileged(PrivilegedAction action)
-  {
-    return action.run();
-  }
-
-  /**
-   * Calls the <code>run()</code> method of the given action with as
-   * (initial) access control context the given context combined with the
-   * protection domain of the calling class. Calls to
-   * <code>checkPermission()</code> in the <code>run()</code> method ignore
-   * all earlier protection domains of classes in the call chain, but add
-   * checks for the protection domains given in the supplied context.
-   *
-   * @param action the <code>PrivilegedAction</code> whose <code>run()</code>
-   * should be be called.
-   * @param context the <code>AccessControlContext</code> whose protection
-   * domains should be added to the protection domain of the calling class.
-   * @return the result of the <code>action.run()</code> method.
-   */
-  public static Object doPrivileged(PrivilegedAction action,
-                                    AccessControlContext context)
-  {
-    return action.run();
-  }
-
-  /**
-   * Calls the <code>run()</code> method of the given action with as
-   * (initial) access control context only the protection domain of the
-   * calling class. Calls to <code>checkPermission()</code> in the
-   * <code>run()</code> method ignore all earlier protection domains of
-   * classes in the call chain. Note that the protection domains of classes
-   * called by the code in the <code>run()</code> method are not ignored.
-   * If the <code>run()</code> method throws an exception then this method
-   * will wrap that exception in an <code>PrivilegedActionException</code>.
-   *
-   * @param action the <code>PrivilegedExceptionAction</code> whose
-   * <code>run()</code> should be be called.
-   * @return the result of the <code>action.run()</code> method.
-   * @exception PrivilegedActionException wrapped around any exception that
-   * is thrown in the <code>run()</code> method.
-   */
-  public static Object doPrivileged(PrivilegedExceptionAction action)
-    throws PrivilegedActionException
-  {
-    try
-      {
-        return action.run();
-      }
-    catch (Exception e)
-      {
-        throw new PrivilegedActionException(e);
-      }
-  }
-
-  /**
-   * Calls the <code>run()</code> method of the given action with as
-   * (initial) access control context the given context combined with the
-   * protection domain of the calling class. Calls to
-   * <code>checkPermission()</code> in the <code>run()</code> method ignore
-   * all earlier protection domains of classes in the call chain, but add
-   * checks for the protection domains given in the supplied context.
-   * If the <code>run()</code> method throws an exception then this method
-   * will wrap that exception in an <code>PrivilegedActionException</code>.
-   *
-   * @param action the <code>PrivilegedExceptionAction</code> whose
-   * <code>run()</code> should be be called.
-   * @param context the <code>AccessControlContext</code> whose protection
-   * domains should be added to the protection domain of the calling class.
-   * @return the result of the <code>action.run()</code> method.
-   * @exception PrivilegedActionException wrapped around any exception that
-   * is thrown in the <code>run()</code> method.
-   */
-  public static Object doPrivileged(PrivilegedExceptionAction action,
-                                    AccessControlContext context)
-    throws PrivilegedActionException
-  {
-    try
-      {
-        return action.run();
-      }
-    catch (Exception e)
-      {
-        throw new PrivilegedActionException(e);
-      }
-  }
-
-  /**
-   * Returns the complete access control context of the current thread.
-   * <p>
-   * XXX - Should this include all the protection domains in the call chain
-   * or only the domains till the last <code>doPrivileged()</code> call?
-   * <p>
-   * XXX - needs native support. Currently returns an empty context.
-   */
-  public static AccessControlContext getContext()
-  {
-    // For now just return an new empty context
-    return new AccessControlContext(new ProtectionDomain[0]);
-  }
-}
diff --git a/libjava/java/security/VMAccessController.java b/libjava/java/security/VMAccessController.java
new file mode 100644 (file)
index 0000000..dfbd16f
--- /dev/null
@@ -0,0 +1,294 @@
+/* VMAccessController.java -- VM-specific access controller methods.
+   Copyright (C) 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This program 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.
+
+This program 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 this program; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.security;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+
+final class VMAccessController
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /**
+   * This is a per-thread stack of AccessControlContext objects (which can
+   * be null) for each call to AccessController.doPrivileged in each thread's
+   * call stack. We use this to remember which context object corresponds to
+   * which call.
+   */
+  private static final ThreadLocal contexts = new ThreadLocal();
+
+  /**
+   * This is a Boolean that, if set, tells getContext that it has already
+   * been called once, allowing us to handle recursive permission checks
+   * caused by methods getContext calls.
+   */
+  private static final ThreadLocal inGetContext = new ThreadLocal();
+
+  /**
+   * And we return this all-permissive context to ensure that privileged
+   * methods called from getContext succeed.
+   */
+  private static final AccessControlContext DEFAULT_CONTEXT;
+  static
+  {
+    CodeSource source = new CodeSource(null, null);
+    Permissions permissions = new Permissions();
+    permissions.add(new AllPermission());
+    ProtectionDomain[] domain = new ProtectionDomain[] {
+      new ProtectionDomain(source, permissions)
+    };
+    DEFAULT_CONTEXT = new AccessControlContext(domain);
+  }
+
+  private static final boolean DEBUG = gnu.classpath.Configuration.DEBUG;
+  private static void debug(String msg)
+  {
+    System.err.print(">>> VMAccessController: ");
+    System.err.println(msg);
+  }
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  private VMAccessController() { }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Relate a class (which should be an instance of {@link PrivilegedAction}
+   * with an access control context. This method is used by {@link
+   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
+   * to set up the context that will be returned by {@link #getContext()}.
+   * This method relates the class to the current thread, so contexts
+   * pushed from one thread will not be available to another.
+   *
+   * @param acc The access control context.
+   */
+  static void pushContext (AccessControlContext acc)
+  {
+    if (!runtimeInitialized())
+      return;
+
+    if (DEBUG)
+      debug("pushing " + acc);
+    LinkedList stack = (LinkedList) contexts.get();
+    if (stack == null)
+      {
+         if (DEBUG)
+           debug("no stack... creating ");
+        stack = new LinkedList();
+        contexts.set(stack);
+      }
+    stack.addFirst(acc);
+  }
+
+  /**
+   * Removes the relation of a class to an {@link AccessControlContext}.
+   * This method is used by {@link AccessController} when exiting from a
+   * call to {@link
+   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
+   */
+  static void popContext()
+  {
+    if (!runtimeInitialized())
+      return;
+
+    if (DEBUG)
+      debug("popping context");
+
+    // Stack should never be null, nor should it be empty, if this method
+    // and its counterpart has been called properly.
+    LinkedList stack = (LinkedList) contexts.get();
+    if (stack != null)
+      {
+        stack.removeFirst();
+        if (stack.isEmpty())
+          contexts.set(null);
+      }
+    else if (DEBUG)
+      {
+        debug("no stack during pop?????");
+      }
+  }
+
+  /**
+   * Examine the method stack of the currently running thread, and create
+   * an {@link AccessControlContext} filled in with the appropriate {@link
+   * ProtectionDomain} objects given this stack.
+   *
+   * @return The context.
+   */
+  static AccessControlContext getContext()
+  {
+    // If the VM is initializing return the all-permissive context
+    // so that any security checks succeed.
+    //
+    // XXX this might not be necessary, but it seems prudent.
+    if (!runtimeInitialized())
+      return DEFAULT_CONTEXT;
+
+    // If we are already in getContext, but called a method that needs
+    // a permission check, return the all-permissive context so methods
+    // called from here succeed.
+    //
+    // XXX is this necessary? We should verify if there are any calls in
+    // the stack below this method that require permission checks.
+    Boolean inCall = (Boolean) inGetContext.get();
+    if (inCall != null && inCall.booleanValue())
+      {
+        if (DEBUG)
+          debug("already in getContext");
+        return DEFAULT_CONTEXT;
+      }
+
+    inGetContext.set(Boolean.TRUE);
+
+    Object[][] stack = getStack();
+    Class[] classes = (Class[]) stack[0];
+    String[] methods = (String[]) stack[1];
+
+    if (DEBUG)
+      debug("got trace of length " + classes.length);
+
+    HashSet domains = new HashSet();
+    HashSet seenDomains = new HashSet();
+    AccessControlContext context = null;
+    int privileged = 0;
+
+    // We walk down the stack, adding each ProtectionDomain for each
+    // class in the call stack. If we reach a call to doPrivileged,
+    // we don't add any more stack frames. We skip the first three stack
+    // frames, since they comprise the calls to getStack, getContext,
+    // and AccessController.getContext.
+    for (int i = 3; i < classes.length && privileged < 2; i++)
+      {
+        Class clazz = classes[i];
+        String method = methods[i];
+
+        if (DEBUG)
+          {
+            debug("checking " + clazz + "." + method);
+            // subject to getClassLoader RuntimePermission
+            debug("loader = " + clazz.getClassLoader());
+          }
+
+        // If the previous frame was a call to doPrivileged, then this is
+        // the last frame we look at.
+        if (privileged == 1)
+          privileged = 2;
+
+        if (clazz.equals (AccessController.class)
+            && method.equals ("doPrivileged"))
+          {
+            // If there was a call to doPrivileged with a supplied context,
+            // return that context. If using JAAS doAs*, it should be 
+           // a context with a SubjectDomainCombiner
+            LinkedList l = (LinkedList) contexts.get();
+            if (l != null)
+              context = (AccessControlContext) l.getFirst();
+            privileged = 1;
+          }
+
+        // subject to getProtectionDomain RuntimePermission
+       ProtectionDomain domain = clazz.getProtectionDomain();
+
+        if (domain == null)
+          continue;
+        if (seenDomains.contains(domain))
+          continue;
+        seenDomains.add(domain);
+
+        // Create a static snapshot of this domain, which may change over time
+        // if the current policy changes.
+        domains.add(new ProtectionDomain(domain.getCodeSource(),
+                                         domain.getPermissions()));
+      }
+
+    if (DEBUG)
+      debug("created domains: " + domains);
+
+    ProtectionDomain[] result = (ProtectionDomain[])
+      domains.toArray(new ProtectionDomain[domains.size()]);
+
+    if (context != null)
+      {
+        DomainCombiner dc = context.getDomainCombiner ();
+        // If the supplied context had no explicit DomainCombiner, use
+        // our private version, which computes the intersection of the
+        // context's domains with the derived set.
+        if (dc == null)
+          context = new AccessControlContext
+            (IntersectingDomainCombiner.SINGLETON.combine
+             (result, context.getProtectionDomains ()));
+        // Use the supplied DomainCombiner. This should be secure,
+        // because only trusted code may create an
+        // AccessControlContext with a custom DomainCombiner.
+        else
+          context = new AccessControlContext (result, context, dc);
+      }
+    // No context was supplied. Return the derived one.
+    else
+      context = new AccessControlContext (result);
+
+    inGetContext.set(Boolean.FALSE);
+    return context;
+  }
+
+  /**
+   * Returns a snapshot of the current call stack as a pair of arrays:
+   * the first an array of classes in the call stack, the second an array
+   * of strings containing the method names in the call stack. The two
+   * arrays match up, meaning that method <i>i</i> is declared in class
+   * <i>i</i>. The arrays are clean; it will only contain Java methods,
+   * and no element of the list should be null.
+   *
+   * @return A pair of arrays describing the current call stack. The first
+   *    element is an array of Class objects, and the second is an array
+   *    of Strings comprising the method names.
+   */
+  private static native Object[][] getStack();
+
+  /**
+   * Tell whether runtime initialization is complete.
+   *
+   * @return whether runtime initialization is complete.
+   */
+  private static native boolean runtimeInitialized();
+}
diff --git a/libjava/java/security/natVMAccessController.cc b/libjava/java/security/natVMAccessController.cc
new file mode 100644 (file)
index 0000000..2550345
--- /dev/null
@@ -0,0 +1,30 @@
+// natVMAccessController.cc -- Native part of the VMAccessController class.
+
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/security/VMAccessController.h>
+
+JArray<jobjectArray> *
+java::security::VMAccessController::getStack ()
+{
+  _Jv_StackTrace *trace = _Jv_StackTrace::GetStackTrace ();
+  return _Jv_StackTrace::GetClassMethodStack (trace);
+}
+
+jboolean
+java::security::VMAccessController::runtimeInitialized ()
+{
+  return gcj::runtimeInitialized;
+}
index cbb7fa0..1b1ed62 100644 (file)
@@ -5265,7 +5265,7 @@ java/rmi/server.list: $(java_rmi_server_source_files)
 java_security_source_files = \
 classpath/java/security/AccessControlContext.java \
 classpath/java/security/AccessControlException.java \
-java/security/AccessController.java \
+classpath/java/security/AccessController.java \
 classpath/java/security/AlgorithmParameterGenerator.java \
 classpath/java/security/AlgorithmParameterGeneratorSpi.java \
 classpath/java/security/AlgorithmParameters.java \
@@ -5330,6 +5330,7 @@ classpath/java/security/SignedObject.java \
 classpath/java/security/Signer.java \
 classpath/java/security/UnrecoverableKeyException.java \
 classpath/java/security/UnresolvedPermission.java \
+java/security/VMAccessController.java \
 java/security/VMSecureRandom.java
 
 java_security_header_files = $(patsubst classpath/%,%,$(patsubst %.java,%.h,$(java_security_source_files)))
index ba971dd..843c512 100644 (file)
@@ -534,3 +534,45 @@ _Jv_StackTrace::GetFirstNonSystemClassLoader ()
   
   return NULL;
 }
+
+JArray<jobjectArray> *
+_Jv_StackTrace::GetClassMethodStack (_Jv_StackTrace *trace)
+{
+  jint length = 0;
+
+  UpdateNCodeMap();
+  for (int i = 0; i < trace->length; i++)
+    {
+      _Jv_StackFrame *frame = &trace->frames[i];
+      FillInFrameInfo (frame);
+
+      if (frame->klass && frame->meth)
+       length++;
+    }
+
+  jclass array_class = _Jv_GetArrayClass (&::java::lang::Object::class$, NULL);
+  JArray<jobjectArray> *result =
+    (JArray<jobjectArray> *) _Jv_NewObjectArray (2, array_class, NULL);
+  JArray<jclass> *classes = (JArray<jclass> *)
+    _Jv_NewObjectArray (length, &::java::lang::Class::class$, NULL);
+  JArray<jstring> *methods = (JArray<jstring> *)
+    _Jv_NewObjectArray (length, &::java::lang::String::class$, NULL);
+  jclass  *c = elements (classes);
+  jstring *m = elements (methods);
+
+  for (int i = 0, j = 0; i < trace->length; i++)
+    {
+      _Jv_StackFrame *frame = &trace->frames[i];
+      if (!frame->klass || !frame->meth)
+       continue;
+      c[j] = frame->klass;
+      m[j] = JvNewStringUTF (frame->meth->name->chars());
+      j++;
+    }
+
+  jobjectArray *elems = elements (result);
+  elems[0] = (jobjectArray) classes;
+  elems[1] = (jobjectArray) methods;
+
+  return result;
+}