OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [java/] [security/] [VMAccessController.java] - Blame information for rev 758

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 758 jeremybenn
/* VMAccessController.java -- VM-specific access controller methods.
2
   Copyright (C) 2004, 2005, 2006, 2010  Free Software Foundation, Inc.
3
 
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2, or (at your option)
7
any later version.
8
 
9
This program is distributed in the hope that it will be useful, but
10
WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
General Public License for more details.
13
 
14
You should have received a copy of the GNU General Public License
15
along with this program; see the file COPYING.  If not, write to the
16
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
02110-1301 USA.
18
 
19
Linking this library statically or dynamically with other modules is
20
making a combined work based on this library.  Thus, the terms and
21
conditions of the GNU General Public License cover the whole
22
combination.
23
 
24
As a special exception, the copyright holders of this library give you
25
permission to link this library with independent modules to produce an
26
executable, regardless of the license terms of these independent
27
modules, and to copy and distribute the resulting executable under
28
terms of your choice, provided that you also meet, for each linked
29
independent module, the terms and conditions of the license of that
30
module.  An independent module is a module which is not derived from
31
or based on this library.  If you modify this library, you may extend
32
this exception to your version of the library, but you are not
33
obligated to do so.  If you do not wish to do so, delete this
34
exception statement from your version. */
35
 
36
 
37
package java.security;
38
 
39
import java.util.HashSet;
40
import java.util.LinkedList;
41
 
42
final class VMAccessController
43
{
44
 
45
  // Fields.
46
  // -------------------------------------------------------------------------
47
 
48
  /**
49
   * And we return this all-permissive context to ensure that privileged
50
   * methods called from getContext succeed.
51
   */
52
  private static final AccessControlContext DEFAULT_CONTEXT;
53
  static
54
  {
55
    CodeSource source = new CodeSource(null, null);
56
    Permissions permissions = new Permissions();
57
    permissions.add(new AllPermission());
58
    ProtectionDomain[] domain = new ProtectionDomain[] {
59
      new ProtectionDomain(source, permissions, null, null)
60
    };
61
    DEFAULT_CONTEXT = new AccessControlContext(domain);
62
  }
63
 
64
  private static final boolean DEBUG = gnu.classpath.Configuration.DEBUG;
65
  private static void debug(String msg)
66
  {
67
    System.err.print(">>> VMAccessController: ");
68
    System.err.println(msg);
69
  }
70
 
71
  // Constructors.
72
  // -------------------------------------------------------------------------
73
 
74
  private VMAccessController() { }
75
 
76
  // Class methods.
77
  // -------------------------------------------------------------------------
78
 
79
  /**
80
   * Relate a class (which should be an instance of {@link PrivilegedAction}
81
   * with an access control context. This method is used by {@link
82
   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
83
   * to set up the context that will be returned by {@link #getContext()}.
84
   * This method relates the class to the current thread, so contexts
85
   * pushed from one thread will not be available to another.
86
   *
87
   * @param acc The access control context.
88
   */
89
  static void pushContext (AccessControlContext acc)
90
  {
91
    // Can't really do anything while the VM is initializing.
92
    VMAccessControlState state = VMAccessControlState.getThreadState();
93
    if (state == null)
94
      return;
95
 
96
    if (DEBUG)
97
      debug("pushing " + acc);
98
 
99
    LinkedList stack = state.getContexts();
100
    stack.addFirst(acc);
101
  }
102
 
103
  /**
104
   * Removes the relation of a class to an {@link AccessControlContext}.
105
   * This method is used by {@link AccessController} when exiting from a
106
   * call to {@link
107
   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
108
   */
109
  static void popContext()
110
  {
111
    // Can't really do anything while the VM is initializing.
112
    VMAccessControlState state = VMAccessControlState.getThreadState();
113
    if (state == null)
114
      return;
115
 
116
    if (DEBUG)
117
      debug("popping context");
118
 
119
    // Stack should never be null, nor should it be empty, if this method
120
    // and its counterpart has been called properly.
121
    LinkedList stack = state.getContexts();
122
    if (!stack.isEmpty())
123
      {
124
        stack.removeFirst();
125
      }
126
    else if (DEBUG)
127
      {
128
        debug("no stack during pop?????");
129
      }
130
  }
131
 
132
  /**
133
   * Examine the method stack of the currently running thread, and create
134
   * an {@link AccessControlContext} filled in with the appropriate {@link
135
   * ProtectionDomain} objects given this stack.
136
   *
137
   * @return The context.
138
   */
139
  static AccessControlContext getContext()
140
  {
141
    // If the VM is initializing return the all-permissive context
142
    // so that any security checks succeed.
143
    VMAccessControlState state = VMAccessControlState.getThreadState();
144
    if (state == null)
145
      return DEFAULT_CONTEXT;
146
 
147
    // If we are already in getContext, but called a method that needs
148
    // a permission check, return the all-permissive context so methods
149
    // called from here succeed.
150
    //
151
    // XXX is this necessary? We should verify if there are any calls in
152
    // the stack below this method that require permission checks.
153
    if (state.isInGetContext())
154
      {
155
        if (DEBUG)
156
          debug("already in getContext");
157
        return DEFAULT_CONTEXT;
158
      }
159
 
160
    state.setInGetContext(true);
161
 
162
    Object[] stack = getStack();
163
    Class[] classes = (Class[]) stack[0];
164
    boolean privileged = ((Boolean) stack[1]).booleanValue();
165
 
166
    if (DEBUG)
167
      debug("got trace of length " + classes.length);
168
 
169
    HashSet domains = new HashSet();
170
    HashSet seenDomains = new HashSet();
171
    AccessControlContext context = null;
172
 
173
    // We walk down the stack, adding each ProtectionDomain for each
174
    // class in the call stack. If we reach a call to doPrivileged,
175
    // we don't add any more stack frames. We skip the first three stack
176
    // frames, since they comprise the calls to getStack, getContext,
177
    // and AccessController.getContext.
178
    for (int i = 3; i < classes.length; i++)
179
      {
180
        Class clazz = classes[i];
181
        ClassLoader loader = clazz.getClassLoader();
182
 
183
        if (DEBUG)
184
          {
185
            debug("checking " + clazz);
186
            // subject to getClassLoader RuntimePermission
187
            debug("loader = " + loader);
188
          }
189
 
190
        if (privileged && i == classes.length - 2)
191
          {
192
            // If there was a call to doPrivileged with a supplied context,
193
            // return that context. If using JAAS doAs*, it should be
194
            // a context with a SubjectDomainCombiner
195
            LinkedList l = state.getContexts();
196
            if (!l.isEmpty())
197
              context = (AccessControlContext) l.getFirst();
198
          }
199
 
200
        // subject to getProtectionDomain RuntimePermission
201
        ProtectionDomain domain = clazz.getProtectionDomain();
202
 
203
        if (domain == null)
204
          continue;
205
        if (seenDomains.contains(domain))
206
          continue;
207
        seenDomains.add(domain);
208
 
209
        // Create a static snapshot of this domain, which may change over time
210
        // if the current policy changes.
211
        domains.add(new ProtectionDomain(domain.getCodeSource(),
212
                                         domain.getPermissions(),
213
                                         loader, null));
214
      }
215
 
216
    if (DEBUG)
217
      debug("created domains: " + domains);
218
 
219
    ProtectionDomain[] result = (ProtectionDomain[])
220
      domains.toArray(new ProtectionDomain[domains.size()]);
221
 
222
    if (context != null)
223
      {
224
        DomainCombiner dc = context.getDomainCombiner ();
225
        // If the supplied context had no explicit DomainCombiner, use
226
        // our private version, which computes the intersection of the
227
        // context's domains with the derived set.
228
        if (dc == null)
229
          context = new AccessControlContext
230
            (IntersectingDomainCombiner.SINGLETON.combine
231
             (result, context.getProtectionDomains ()));
232
        // Use the supplied DomainCombiner. This should be secure,
233
        // because only trusted code may create an
234
        // AccessControlContext with a custom DomainCombiner.
235
        else
236
          context = new AccessControlContext (result, context, dc);
237
      }
238
    // No context was supplied. Return the derived one.
239
    else
240
      context = new AccessControlContext (result);
241
 
242
    state.setInGetContext(false);
243
    return context;
244
  }
245
 
246
  /**
247
   * Returns a snapshot of the current call stack as a two-element
248
   * array. The first element is an array of classes in the call
249
   * stack, and the second element is a boolean value indicating
250
   * whether the trace stopped early because a call to doPrivileged
251
   * was encountered.  If this boolean value is true then the call to
252
   * doPrivileged will be the second-last frame in the returned trace.
253
   *
254
   * @return A snapshot of the current call stack.
255
   */
256
  private static native Object[] getStack();
257
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.