aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/security
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/security')
-rw-r--r--libjava/java/security/VMAccessControlState.java103
-rw-r--r--libjava/java/security/VMAccessController.java55
-rw-r--r--libjava/java/security/natVMAccessControlState.cc32
3 files changed, 153 insertions, 37 deletions
diff --git a/libjava/java/security/VMAccessControlState.java b/libjava/java/security/VMAccessControlState.java
new file mode 100644
index 0000000..360f08a
--- /dev/null
+++ b/libjava/java/security/VMAccessControlState.java
@@ -0,0 +1,103 @@
+/* VMAccessControlState.java -- per-thread state for the access controller.
+ Copyright (C) 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.LinkedList;
+
+class VMAccessControlState
+{
+ /**
+ * A list of {@link AccessControlContext} objects (which can be
+ * null) for each call to {@link AccessController#doPrivileged()} in
+ * the thread's call stack.
+ */
+ private LinkedList contexts = new LinkedList();
+
+ /**
+ * A flag indicating that we are within a call to {@link
+ * VMAccessController#getContext()}.
+ */
+ private boolean inGetContext = false;
+
+ /**
+ * Not directly instantiable: use getThreadState() instead.
+ */
+ private VMAccessControlState() {}
+
+ /**
+ * Return an object representing the access control state of this
+ * thread.
+ *
+ * @return The access control state of this thread, or
+ * <code>null</code> if the VM is not initialized to the point of
+ * being able to return this.
+ */
+ static native VMAccessControlState getThreadState();
+
+ /**
+ * Indicate whether this thread is within a call to {@link
+ * VMAccessController#getContext()}.
+ *
+ * @return <code>true</code> if this thread is within a call to
+ * {@link VMAccessController#getContext()}.
+ */
+ boolean isInGetContext()
+ {
+ return inGetContext;
+ }
+
+ /**
+ * Specify whether this thread is within a call to {@link
+ * VMAccessController#getContext()}.
+ */
+ void setInGetContext(boolean inGetContext)
+ {
+ this.inGetContext = inGetContext;
+ }
+
+ /**
+ * Return a list of {@link AccessControlContext} objects (which can
+ * be null) for each call to {@link AccessController#doPrivileged()}
+ * in the thread's call stack.
+ *
+ * @return a list of {@link AccessControlContext} objects.
+ */
+ LinkedList getContexts()
+ {
+ return contexts;
+ }
+}
diff --git a/libjava/java/security/VMAccessController.java b/libjava/java/security/VMAccessController.java
index 85d0313..8436c9c 100644
--- a/libjava/java/security/VMAccessController.java
+++ b/libjava/java/security/VMAccessController.java
@@ -46,21 +46,6 @@ final class VMAccessController
// -------------------------------------------------------------------------
/**
- * 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.
*/
@@ -103,19 +88,15 @@ final class VMAccessController
*/
static void pushContext (AccessControlContext acc)
{
- if (Thread.currentThread() == null)
+ // Can't really do anything while the VM is initializing.
+ VMAccessControlState state = VMAccessControlState.getThreadState();
+ if (state == null)
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);
- }
+
+ LinkedList stack = state.getContexts();
stack.addFirst(acc);
}
@@ -127,7 +108,9 @@ final class VMAccessController
*/
static void popContext()
{
- if (Thread.currentThread() == null)
+ // Can't really do anything while the VM is initializing.
+ VMAccessControlState state = VMAccessControlState.getThreadState();
+ if (state == null)
return;
if (DEBUG)
@@ -135,12 +118,10 @@ final class VMAccessController
// 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)
+ LinkedList stack = state.getContexts();
+ if (!stack.isEmpty())
{
- stack.removeFirst();
- if (stack.isEmpty())
- contexts.set(null);
+ stack.removeFirst();
}
else if (DEBUG)
{
@@ -159,7 +140,8 @@ final class VMAccessController
{
// If the VM is initializing return the all-permissive context
// so that any security checks succeed.
- if (Thread.currentThread() == null)
+ VMAccessControlState state = VMAccessControlState.getThreadState();
+ if (state == null)
return DEFAULT_CONTEXT;
// If we are already in getContext, but called a method that needs
@@ -168,15 +150,14 @@ final class VMAccessController
//
// 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 (state.isInGetContext())
{
if (DEBUG)
debug("already in getContext");
return DEFAULT_CONTEXT;
}
- inGetContext.set(Boolean.TRUE);
+ state.setInGetContext(true);
Object[] stack = getStack();
Class[] classes = (Class[]) stack[0];
@@ -210,8 +191,8 @@ final class VMAccessController
// 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)
+ LinkedList l = state.getContexts();
+ if (!l.isEmpty())
context = (AccessControlContext) l.getFirst();
}
@@ -256,7 +237,7 @@ final class VMAccessController
else
context = new AccessControlContext (result);
- inGetContext.set(Boolean.FALSE);
+ state.setInGetContext(false);
return context;
}
diff --git a/libjava/java/security/natVMAccessControlState.cc b/libjava/java/security/natVMAccessControlState.cc
new file mode 100644
index 0000000..a4c14cd
--- /dev/null
+++ b/libjava/java/security/natVMAccessControlState.cc
@@ -0,0 +1,32 @@
+// natVMAccessControlState.cc -- Native part of the VMAccessControlState 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/lang/Thread.h>
+#include <java/security/VMAccessControlState.h>
+
+java::security::VMAccessControlState *
+java::security::VMAccessControlState::getThreadState ()
+{
+ java::lang::Thread *thread = java::lang::Thread::currentThread ();
+ if (thread == NULL)
+ return NULL;
+
+ VMAccessControlState *state =
+ reinterpret_cast<VMAccessControlState *> (thread->accessControlState);
+ if (state == NULL)
+ thread->accessControlState = state = new VMAccessControlState ();
+
+ return state;
+}