1/*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @bug 8136421
27 * @requires vm.jvmci
28 * @library /test/lib /
29 * @library common/patches
30 * @modules java.base/jdk.internal.misc
31 * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
32 * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
33 * @run main/othervm -XX:+UnlockExperimentalVMOptions
34 *      -XX:+EnableJVMCI
35 *      compiler.jvmci.SecurityRestrictionsTest
36 *      NO_SEC_MAN
37 * @run main/othervm -XX:+UnlockExperimentalVMOptions
38 *      -XX:+EnableJVMCI
39 *      compiler.jvmci.SecurityRestrictionsTest
40 *      NO_PERM
41 * @run main/othervm -XX:+UnlockExperimentalVMOptions
42 *      -XX:+EnableJVMCI
43 *      compiler.jvmci.SecurityRestrictionsTest
44 *      ALL_PERM
45 * @run main/othervm -XX:+UnlockExperimentalVMOptions
46 *      -XX:+EnableJVMCI -XX:-UseJVMCICompiler
47 *      compiler.jvmci.SecurityRestrictionsTest
48 *      NO_JVMCI_ACCESS_PERM
49 * @run main/othervm -XX:+UnlockExperimentalVMOptions
50 *      -XX:-EnableJVMCI -XX:-UseJVMCICompiler
51 *      compiler.jvmci.SecurityRestrictionsTest
52 *      NO_JVMCI
53 */
54
55package compiler.jvmci;
56
57import jdk.test.lib.Utils;
58
59import java.security.AccessControlException;
60import java.security.Permission;
61import java.util.PropertyPermission;
62import java.util.function.Consumer;
63
64public class SecurityRestrictionsTest {
65
66    public static void main(String[] args) {
67        try {
68            // to init Utils before call SecurityManager
69            Class.forName(Utils.class.getName(), true,
70                    Utils.class.getClassLoader());
71        } catch (ClassNotFoundException e) {
72            throw new Error("[TEST BUG]: jdk.test.lib.Utils not found", e);
73        }
74        try {
75            TestCase mode = TestCase.valueOf(args[0]);
76            mode.run();
77        } catch (IllegalArgumentException e) {
78            throw new Error("[TEST BUG]: Unknown mode " + args[0], e);
79        }
80    }
81
82    private enum TestCase {
83        NO_SEC_MAN,
84        NO_JVMCI {
85            @Override
86            public Class<? extends Throwable> getExpectedException() {
87                return InternalError.class;
88            }
89        },
90        ALL_PERM {
91            @Override
92            public SecurityManager getSecurityManager() {
93                return new SecurityManager() {
94                    @Override
95                    public void checkPermission(Permission perm) {
96                    }
97                };
98            }
99        },
100        NO_PERM {
101            @Override
102            public SecurityManager getSecurityManager() {
103                return new SecurityManager();
104            }
105
106            @Override
107            public Class<? extends Throwable> getExpectedException() {
108                return AccessControlException.class;
109            }
110        },
111        NO_JVMCI_ACCESS_PERM {
112            @Override
113            public SecurityManager getSecurityManager() {
114                return new SecurityManager() {
115                    @Override
116                    public void checkPermission(Permission perm) {
117                        if (isJvmciPermission(perm)) {
118                            super.checkPermission(perm);
119                        }
120                    }
121
122                    @Override
123                    public void checkPropertyAccess(String key) {
124                        if (key.startsWith(JVMCI_PROP_START)) {
125                            super.checkPropertyAccess(key);
126                        }
127                    }
128                };
129            }
130
131            private boolean isJvmciPermission(Permission perm) {
132                String name = perm.getName();
133                boolean isJvmciRuntime = perm instanceof RuntimePermission
134                        && (JVMCI_SERVICES.equals(name)
135                            || name.startsWith(JVMCI_RT_PERM_START));
136                boolean isJvmciProperty = perm instanceof PropertyPermission
137                        && name.startsWith(JVMCI_PROP_START);
138                return isJvmciRuntime || isJvmciProperty;
139            }
140
141            @Override
142            public Class<? extends Throwable> getExpectedException() {
143                return AccessControlException.class;
144            }
145        };
146
147        public void run() {
148            System.setSecurityManager(getSecurityManager());
149            Consumer<Throwable> exceptionCheck = e -> {
150                if (e == null) {
151                    if (getExpectedException() != null) {
152                        String message = name() + ": Didn't get expected exception "
153                                + getExpectedException();
154                        throw new AssertionError(message);
155                    }
156                } else {
157                    String message = name() + ": Got unexpected exception "
158                            + e.getClass().getSimpleName();
159                    if (getExpectedException() == null){
160                        throw new AssertionError(message, e);
161                    }
162
163                    Throwable t = e;
164                    while (t.getCause() != null) {
165                        t = t.getCause();
166                    }
167                    if (!getExpectedException().isAssignableFrom(t.getClass())) {
168                        message += " instead of " + getExpectedException()
169                                .getSimpleName();
170                        throw new AssertionError(message, e);
171                    }
172                }
173            };
174            Utils.runAndCheckException(() -> {
175                try {
176                    // CompilerToVM::<cinit> provokes CompilerToVM::<init>
177                    Class.forName("jdk.vm.ci.hotspot.CompilerToVMHelper");
178                } catch (ClassNotFoundException e) {
179                    throw new Error("TESTBUG : " + e, e);
180                }
181            }, exceptionCheck);
182        }
183
184        public SecurityManager getSecurityManager() {
185            return null;
186        }
187
188        public Class<? extends Throwable> getExpectedException() {
189            return null;
190        }
191
192        private static final String JVMCI_RT_PERM_START
193                = "accessClassInPackage.jdk.vm.ci";
194        private static final String JVMCI_SERVICES = "jvmciServices";
195        private static final String JVMCI_PROP_START = "jvmci.";
196
197    }
198}
199