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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [vm/] [reference/] [java/] [security/] [VMAccessController.java] - Blame information for rev 780

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 780 jeremybenn
/* VMAccessController.java -- VM-specific access controller methods.
2
   Copyright (C) 2004, 2005  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
   * This is a per-thread stack of AccessControlContext objects (which can
50
   * be null) for each call to AccessController.doPrivileged in each thread's
51
   * call stack. We use this to remember which context object corresponds to
52
   * which call.
53
   */
54
  private static final ThreadLocal contexts = new ThreadLocal();
55
 
56
  /**
57
   * This is a Boolean that, if set, tells getContext that it has already
58
   * been called once, allowing us to handle recursive permission checks
59
   * caused by methods getContext calls.
60
   */
61
  private static final ThreadLocal inGetContext = new ThreadLocal();
62
 
63
  /**
64
   * And we return this all-permissive context to ensure that privileged
65
   * methods called from getContext succeed.
66
   */
67
  private static final AccessControlContext DEFAULT_CONTEXT;
68
  static
69
  {
70
    CodeSource source = new CodeSource(null, null);
71
    Permissions permissions = new Permissions();
72
    permissions.add(new AllPermission());
73
    ProtectionDomain[] domain = new ProtectionDomain[] {
74
      new ProtectionDomain(source, permissions)
75
    };
76
    DEFAULT_CONTEXT = new AccessControlContext(domain);
77
  }
78
 
79
  private static final boolean DEBUG = gnu.classpath.Configuration.DEBUG;
80
  private static void debug(String msg)
81
  {
82
    System.err.print(">>> VMAccessController: ");
83
    System.err.println(msg);
84
  }
85
 
86
  // Constructors.
87
  // -------------------------------------------------------------------------
88
 
89
  private VMAccessController() { }
90
 
91
  // Class methods.
92
  // -------------------------------------------------------------------------
93
 
94
  /**
95
   * Relate a class (which should be an instance of {@link PrivilegedAction}
96
   * with an access control context. This method is used by {@link
97
   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
98
   * to set up the context that will be returned by {@link #getContext()}.
99
   * This method relates the class to the current thread, so contexts
100
   * pushed from one thread will not be available to another.
101
   *
102
   * @param acc The access control context.
103
   */
104
  static void pushContext (AccessControlContext acc)
105
  {
106
    if (DEBUG)
107
      debug("pushing " + acc);
108
    LinkedList stack = (LinkedList) contexts.get();
109
    if (stack == null)
110
      {
111
         if (DEBUG)
112
           debug("no stack... creating ");
113
        stack = new LinkedList();
114
        contexts.set(stack);
115
      }
116
    stack.addFirst(acc);
117
  }
118
 
119
  /**
120
   * Removes the relation of a class to an {@link AccessControlContext}.
121
   * This method is used by {@link AccessController} when exiting from a
122
   * call to {@link
123
   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
124
   */
125
  static void popContext()
126
  {
127
    if (DEBUG)
128
      debug("popping context");
129
 
130
    // Stack should never be null, nor should it be empty, if this method
131
    // and its counterpart has been called properly.
132
    LinkedList stack = (LinkedList) contexts.get();
133
    if (stack != null)
134
      {
135
        stack.removeFirst();
136
        if (stack.isEmpty())
137
          contexts.set(null);
138
      }
139
    else if (DEBUG)
140
      {
141
        debug("no stack during pop?????");
142
      }
143
  }
144
 
145
  /**
146
   * Examine the method stack of the currently running thread, and create
147
   * an {@link AccessControlContext} filled in with the appropriate {@link
148
   * ProtectionDomain} objects given this stack.
149
   *
150
   * @return The context.
151
   */
152
  static AccessControlContext getContext()
153
  {
154
    // If we are already in getContext, but called a method that needs
155
    // a permission check, return the all-permissive context so methods
156
    // called from here succeed.
157
    //
158
    // XXX is this necessary? We should verify if there are any calls in
159
    // the stack below this method that require permission checks.
160
    Boolean inCall = (Boolean) inGetContext.get();
161
    if (inCall != null && inCall.booleanValue())
162
      {
163
        if (DEBUG)
164
          debug("already in getContext");
165
        return DEFAULT_CONTEXT;
166
      }
167
 
168
    inGetContext.set(Boolean.TRUE);
169
 
170
    Object[][] stack = getStack();
171
    Class[] classes = (Class[]) stack[0];
172
    String[] methods = (String[]) stack[1];
173
 
174
    if (DEBUG)
175
      debug("got trace of length " + classes.length);
176
 
177
    HashSet domains = new HashSet();
178
    HashSet seenDomains = new HashSet();
179
    AccessControlContext context = null;
180
    int privileged = 0;
181
 
182
    // We walk down the stack, adding each ProtectionDomain for each
183
    // class in the call stack. If we reach a call to doPrivileged,
184
    // we don't add any more stack frames. We skip the first three stack
185
    // frames, since they comprise the calls to getStack, getContext,
186
    // and AccessController.getContext.
187
    for (int i = 3; i < classes.length && privileged < 2; i++)
188
      {
189
        Class clazz = classes[i];
190
        String method = methods[i];
191
 
192
        if (DEBUG)
193
          {
194
            debug("checking " + clazz + "." + method);
195
            // subject to getClassLoader RuntimePermission
196
            debug("loader = " + clazz.getClassLoader());
197
          }
198
 
199
        // If the previous frame was a call to doPrivileged, then this is
200
        // the last frame we look at.
201
        if (privileged == 1)
202
          privileged = 2;
203
 
204
        if (clazz.equals (AccessController.class)
205
            && method.equals ("doPrivileged"))
206
          {
207
            // If there was a call to doPrivileged with a supplied context,
208
            // return that context. If using JAAS doAs*, it should be
209
            // a context with a SubjectDomainCombiner
210
            LinkedList l = (LinkedList) contexts.get();
211
            if (l != null)
212
              context = (AccessControlContext) l.getFirst();
213
            privileged = 1;
214
          }
215
 
216
        // subject to getProtectionDomain RuntimePermission
217
        ProtectionDomain domain = clazz.getProtectionDomain();
218
 
219
        if (domain == null)
220
          continue;
221
        if (seenDomains.contains(domain))
222
          continue;
223
        seenDomains.add(domain);
224
 
225
        // Create a static snapshot of this domain, which may change over time
226
        // if the current policy changes.
227
        domains.add(new ProtectionDomain(domain.getCodeSource(),
228
                                         domain.getPermissions()));
229
      }
230
 
231
    if (DEBUG)
232
      debug("created domains: " + domains);
233
 
234
    ProtectionDomain[] result = (ProtectionDomain[])
235
      domains.toArray(new ProtectionDomain[domains.size()]);
236
 
237
    if (context != null)
238
      {
239
        DomainCombiner dc = context.getDomainCombiner ();
240
        // If the supplied context had no explicit DomainCombiner, use
241
        // our private version, which computes the intersection of the
242
        // context's domains with the derived set.
243
        if (dc == null)
244
          context = new AccessControlContext
245
            (IntersectingDomainCombiner.SINGLETON.combine
246
             (result, context.getProtectionDomains ()));
247
        // Use the supplied DomainCombiner. This should be secure,
248
        // because only trusted code may create an
249
        // AccessControlContext with a custom DomainCombiner.
250
        else
251
          context = new AccessControlContext (result, context, dc);
252
      }
253
    // No context was supplied. Return the derived one.
254
    else
255
      context = new AccessControlContext (result);
256
 
257
    inGetContext.set(Boolean.FALSE);
258
    return context;
259
  }
260
 
261
  /**
262
   * Returns a snapshot of the current call stack as a pair of arrays:
263
   * the first an array of classes in the call stack, the second an array
264
   * of strings containing the method names in the call stack. The two
265
   * arrays match up, meaning that method <i>i</i> is declared in class
266
   * <i>i</i>. The arrays are clean; it will only contain Java methods,
267
   * and no element of the list should be null.
268
   *
269
   * <p>The default implementation returns an empty stack, which will be
270
   * interpreted as having no permissions whatsoever.
271
   *
272
   * @return A pair of arrays describing the current call stack. The first
273
   *    element is an array of Class objects, and the second is an array
274
   *    of Strings comprising the method names.
275
   */
276
  private static Object[][] getStack()
277
  {
278
    return new Object[][] { new Class[0], new String[0] };
279
  }
280
}

powered by: WebSVN 2.1.0

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