# HG changeset patch # User dfuchs # Date 1381834888 -7200 # Node ID 8d5c16e4f64cbb3ba93c9cf52b4124b35b36ee41 # Parent eca8d93dd8fa6d4957a47e34c75130d87ac9db78 8026404: Logging in Applet can trigger ACE: access denied ("java.lang.RuntimePermission" "modifyThreadGroup") Summary: The test 'threadGroup.getParent() == null' can sometimes throw ACE and needs to be wrapped in doPrivileged. Reviewed-by: alanb, mchung, dholmes diff -r eca8d93dd8fa -r 8d5c16e4f64c jdk/src/share/classes/sun/awt/AppContext.java --- a/jdk/src/share/classes/sun/awt/AppContext.java Tue Oct 15 10:52:09 2013 +0100 +++ b/jdk/src/share/classes/sun/awt/AppContext.java Tue Oct 15 13:01:28 2013 +0200 @@ -839,6 +839,15 @@ return (numAppContexts.get() == 1 && mainAppContext != null); } + private boolean hasRootThreadGroup(final AppContext ecx) { + return AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Boolean run() { + return ecx.threadGroup.getParent() == null; + } + }); + } + /** * Returns the AppContext used for applet logging isolation, or null if * the default global context can be used. @@ -886,7 +895,7 @@ // See: JDK-8023258 final boolean isMainAppContext = ecx == null || mainAppContext == ecx - || mainAppContext == null && ecx.threadGroup.getParent() == null; + || mainAppContext == null && hasRootThreadGroup(ecx); return isMainAppContext ? null : ecx; } diff -r eca8d93dd8fa -r 8d5c16e4f64c jdk/test/TEST.groups --- a/jdk/test/TEST.groups Tue Oct 15 10:52:09 2013 +0100 +++ b/jdk/test/TEST.groups Tue Oct 15 13:01:28 2013 +0200 @@ -360,6 +360,7 @@ java/security/Security/ClassLoaderDeadlock/Deadlock.sh \ java/util/logging/Listeners.java \ java/util/logging/ListenersWithSM.java \ + java/util/logging/TestMainAppContext.java \ java/util/ResourceBundle/Control/Bug6530694.java \ java/text/Bidi/BidiConformance.java \ java/text/Bidi/BidiEmbeddingTest.java \ diff -r eca8d93dd8fa -r 8d5c16e4f64c jdk/test/java/util/logging/TestMainAppContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/logging/TestMainAppContext.java Tue Oct 15 13:01:28 2013 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.logging.Logger; +import sun.awt.AppContext; +import sun.awt.SunToolkit; + + +/** + * @test + * @bug 8026404 + * @summary checks that calling getLogger() from a Thread whose ThreadGroup is + * a child of the main root group doesn't throw an exception. + * @build TestMainAppContext + * @run main/othervm TestMainAppContext + * @author danielfuchs + */ +public class TestMainAppContext { + + static volatile Throwable thrown = null; + + public static void main(String... args) throws Exception { + ThreadGroup rootTG = Thread.currentThread().getThreadGroup(); + while (rootTG.getParent() != null) { + rootTG = rootTG.getParent(); + } + + ThreadGroup tg = new ThreadGroup(rootTG, "FakeApplet"); + final Thread t1 = new Thread(tg, "createNewAppContext") { + @Override + public void run() { + try { + AppContext context = SunToolkit.createNewAppContext(); + } catch(Throwable t) { + thrown = t; + } + } + }; + t1.start(); + t1.join(); + if (thrown != null) { + throw new RuntimeException("Unexpected exception: " + thrown, thrown); + } + Thread t2 = new Thread(tg, "BugDetector") { + + @Override + public void run() { + try { + Logger.getLogger("foo").info("Done"); + } catch (Throwable x) { + thrown = x; + } + } + + }; + + System.setSecurityManager(new SecurityManager()); + t2.start(); + t2.join(); + if (thrown != null) { + throw new RuntimeException("Test failed: " + thrown, thrown); + } + + } + +}