nashorn/src/jdk/internal/dynalink/beans/SandboxClassLoader.java
author sundar
Sat, 09 Mar 2013 21:49:32 +0530
changeset 16277 fd698c5ee684
permissions -rw-r--r--
8009559: clean up method handle lookup code. Reviewed-by: ahgross, jlaskey, attila, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16277
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     1
/*
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     4
 *
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    10
 *
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    15
 * accompanied this code).
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    16
 *
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    20
 *
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    23
 * questions.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    24
 */
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    25
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    26
/*
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    27
 * This file is available under and governed by the GNU General Public
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    28
 * License version 2 only, as published by the Free Software Foundation.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    29
 * However, the following notice accompanied the original version of this
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    30
 * file, and Oracle licenses the original version of this file under the BSD
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    31
 * license:
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    32
 */
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    33
/*
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    34
   Copyright 2009-2013 Attila Szegedi
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    35
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    36
   Licensed under both the Apache License, Version 2.0 (the "Apache License")
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    37
   and the BSD License (the "BSD License"), with licensee being free to
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    38
   choose either of the two at their discretion.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    39
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    40
   You may not use this file except in compliance with either the Apache
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    41
   License or the BSD License.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    42
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    43
   If you choose to use this file in compliance with the Apache License, the
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    44
   following notice applies to you:
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    45
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    46
       You may obtain a copy of the Apache License at
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    47
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    48
           http://www.apache.org/licenses/LICENSE-2.0
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    49
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    50
       Unless required by applicable law or agreed to in writing, software
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    51
       distributed under the License is distributed on an "AS IS" BASIS,
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    52
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    53
       implied. See the License for the specific language governing
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    54
       permissions and limitations under the License.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    55
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    56
   If you choose to use this file in compliance with the BSD License, the
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    57
   following notice applies to you:
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    58
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    59
       Redistribution and use in source and binary forms, with or without
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    60
       modification, are permitted provided that the following conditions are
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    61
       met:
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    62
       * Redistributions of source code must retain the above copyright
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    63
         notice, this list of conditions and the following disclaimer.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    64
       * Redistributions in binary form must reproduce the above copyright
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    65
         notice, this list of conditions and the following disclaimer in the
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    66
         documentation and/or other materials provided with the distribution.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    67
       * Neither the name of the copyright holder nor the names of
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    68
         contributors may be used to endorse or promote products derived from
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    69
         this software without specific prior written permission.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    70
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    71
       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    72
       IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    73
       TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    74
       PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    75
       BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    76
       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    77
       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    78
       BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    79
       WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    80
       OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    81
       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    82
*/
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    83
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    84
package jdk.internal.dynalink.beans;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    85
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    86
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    87
import static jdk.internal.org.objectweb.asm.Opcodes.ASM4;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    88
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    89
import java.io.IOException;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    90
import java.io.InputStream;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    91
import java.security.Permissions;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    92
import java.security.ProtectionDomain;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    93
import java.security.SecureClassLoader;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    94
import java.security.SecureRandom;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    95
import jdk.internal.org.objectweb.asm.ClassReader;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    96
import jdk.internal.org.objectweb.asm.ClassVisitor;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    97
import jdk.internal.org.objectweb.asm.ClassWriter;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    98
import jdk.internal.org.objectweb.asm.MethodVisitor;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
    99
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   100
/**
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   101
 * A utility class that can load a class with specified name into an isolated zero-permissions protection domain. It can
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   102
 * be used to load classes that perform security-sensitive operations with no privileges at all, therefore ensuring such
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   103
 * operations will only succeed if they would require no permissions, as well as to make sure that if these operations
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   104
 * bind some part of the security execution context to their results, the bound security context is completely
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   105
 * unprivileged. Such measures serve as firebreaks against accidental privilege escalation.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   106
 */
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   107
final class SandboxClassLoader {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   108
    private final String className;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   109
    private final String randomizedClassName;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   110
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   111
    private SandboxClassLoader(String className) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   112
        this.className = className;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   113
        final String simpleClassName = className.substring(className.lastIndexOf('.') + 1);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   114
        this.randomizedClassName = "randomPackage" + Long.toHexString(new SecureRandom().nextLong()) + "." + simpleClassName;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   115
    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   116
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   117
    /**
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   118
     * Load the named class into a zero-permissions protection domain. Even if the class is already loaded into the
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   119
     * Dynalink's class loader, an independent class is created from the same bytecode, thus the returned class will
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   120
     * never be identical with the one that might already be loaded. The class to be loaded is supposed to be package
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   121
     * private and have no public constructors. This is not a functional requirement, but it is enforced to ensure that
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   122
     * the original class was made adequately inaccessible. The returned class will be public and its constructors will
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   123
     * be changed to public. The only permission given to the returned class will be
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   124
     * {@code accessClassInPackage.jdk.internal.dynalink.beans.sandbox}. That package should be used solely to define
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   125
     * SPI interfaces implemented by the loaded class.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   126
     * @param className the fully qualified name of the class to load
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   127
     * @return the loaded class, renamed to a random package, made public, its constructors made public, and lacking any
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   128
     * permissions except access to the sandbox package.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   129
     * @throws SecurityException if the calling code lacks the {@code createClassLoader} runtime permission. This
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   130
     * normally means that Dynalink itself is running as untrusted code, and whatever functionality was meant to be
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   131
     * isolated into an unprivileged class is likely okay to be used directly too.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   132
     */
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   133
    static Class<?> loadClass(String className) throws SecurityException {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   134
        return new SandboxClassLoader(className).loadClass();
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   135
    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   136
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   137
    private Class<?> loadClass() throws SecurityException {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   138
        final ClassLoader loader = createClassLoader();
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   139
        try {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   140
            final Class<?> clazz = Class.forName(randomizedClassName, true, loader);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   141
            // Sanity check to ensure we didn't accidentally pick up the class from elsewhere
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   142
            if(clazz.getClassLoader() != loader) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   143
                throw new AssertionError(randomizedClassName + " was loaded from a different class loader");
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   144
            }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   145
            return clazz;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   146
        } catch(ClassNotFoundException e) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   147
            throw new AssertionError(e);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   148
        }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   149
    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   150
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   151
    private ClassLoader createClassLoader() throws SecurityException {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   152
        final String lclassName = this.randomizedClassName;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   153
        // We deliberately override loadClass instead of findClass so that we don't give a chance to finding this
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   154
        // class already loaded anywhere else. We use this class' loader as the parent class loader as the loaded class
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   155
        // needs to be able to access implemented interfaces from the sandbox package.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   156
        return new SecureClassLoader(getClass().getClassLoader()) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   157
            @Override
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   158
            protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   159
                if(name.equals(lclassName)) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   160
                    final byte[] bytes = getClassBytes();
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   161
                    // Define the class with a protection domain that grants (almost) no permissions.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   162
                    Class<?> clazz = defineClass(name, bytes, 0, bytes.length, createMinimalPermissionsDomain());
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   163
                    if(resolve) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   164
                        resolveClass(clazz);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   165
                    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   166
                    return clazz;
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   167
                }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   168
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   169
                final int i = name.lastIndexOf('.');
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   170
                if (i != -1) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   171
                    final SecurityManager sm = System.getSecurityManager();
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   172
                    if (sm != null) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   173
                        sm.checkPackageAccess(name.substring(0, i));
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   174
                    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   175
                }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   176
                return super.loadClass(name, resolve);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   177
            }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   178
        };
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   179
    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   180
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   181
    /**
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   182
     * Create a no-permissions protection domain. Except, it's not really a no-permissions protection domain, since we
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   183
     * need to give the protection domain the permission to access the sandbox package where the interop interfaces are
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   184
     * defined.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   185
     * @return a new (almost) no-permission protection domain.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   186
     */
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   187
    private static ProtectionDomain createMinimalPermissionsDomain() {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   188
        final Permissions p = new Permissions();
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   189
        p.add(new RuntimePermission("accessClassInPackage.jdk.internal.dynalink.beans.sandbox"));
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   190
        return new ProtectionDomain(null, p);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   191
    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   192
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   193
    private byte[] getClassBytes() {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   194
        try(final InputStream in = getClass().getResourceAsStream("/" + className.replace('.', '/') + ".class")) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   195
            final ClassReader cr = new ClassReader(in);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   196
            final ClassWriter cw = new ClassWriter(cr, 0);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   197
            cr.accept(new ClassVisitor(ASM4, cw) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   198
                @Override
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   199
                public void visit(int version, int access, String name, String signature, String superName,
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   200
                        String[] interfaces) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   201
                    // Rename the class to its random name, and make it public (otherwise we won't be able to
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   202
                    // instantiate it). The privileged template class is package-private.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   203
                    if((access & ACC_PUBLIC) != 0) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   204
                        throw new IllegalArgumentException("Class " + className + " must be package-private");
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   205
                    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   206
                    super.visit(version, access | ACC_PUBLIC, randomizedClassName.replace('.', '/'),
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   207
                            signature, superName, interfaces);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   208
                }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   209
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   210
                @Override
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   211
                public MethodVisitor visitMethod(int access, String name, String desc, String signature,
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   212
                        String[] exceptions) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   213
                    // Make the constructor(s) public (otherwise we won't be able to instantiate the class). The
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   214
                    // privileged template's constructor(s) should not be public.
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   215
                    final boolean isCtor = "<init>".equals(name);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   216
                    if(isCtor && ((access & ACC_PUBLIC) != 0)) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   217
                        throw new IllegalArgumentException("Class " + className + " must have no public constructors");
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   218
                    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   219
                    return super.visitMethod(isCtor ? (access | ACC_PUBLIC) : access, name, desc, signature,
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   220
                            exceptions);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   221
                }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   222
            }, 0);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   223
            return cw.toByteArray();
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   224
        } catch(IOException e) {
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   225
            throw new RuntimeException(e);
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   226
        }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   227
    }
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents:
diff changeset
   228
}