# HG changeset patch # User denis # Date 1300407395 25200 # Node ID 29f983feda95b74ca14cba61148e193524c21042 # Parent 9a3f042d307e8918625471d91a4b29c5daf52f77 6907662: System clipboard should ensure access restrictions Reviewed-by: alexp diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/java/awt/AWTEvent.java --- a/jdk/src/share/classes/java/awt/AWTEvent.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/java/awt/AWTEvent.java Thu Mar 17 17:16:35 2011 -0700 @@ -33,6 +33,11 @@ import sun.awt.AWTAccessor; import sun.util.logging.PlatformLogger; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.io.ObjectInputStream; +import java.io.IOException; + /** * The root event class for all AWT events. * This class and its subclasses supercede the original @@ -97,6 +102,22 @@ */ protected boolean consumed = false; + /* + * The event's AccessControlContext. + */ + private transient volatile AccessControlContext acc = + AccessController.getContext(); + + /* + * Returns the acc this event was constructed with. + */ + final AccessControlContext getAccessControlContext() { + if (acc == null) { + throw new SecurityException("AWTEvent is missing AccessControlContext"); + } + return acc; + } + transient boolean focusManagerIsDispatching = false; transient boolean isPosted; @@ -247,6 +268,10 @@ public boolean isSystemGenerated(AWTEvent ev) { return ev.isSystemGenerated; } + + public AccessControlContext getAccessControlContext(AWTEvent ev) { + return ev.getAccessControlContext(); + } }); } diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/java/awt/Component.java --- a/jdk/src/share/classes/java/awt/Component.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/java/awt/Component.java Thu Mar 17 17:16:35 2011 -0700 @@ -59,6 +59,7 @@ import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.AccessControlContext; import javax.accessibility.*; import java.applet.Applet; @@ -471,6 +472,12 @@ static final Object LOCK = new AWTTreeLock(); static class AWTTreeLock {} + /* + * The component's AccessControlContext. + */ + private transient volatile AccessControlContext acc = + AccessController.getContext(); + /** * Minimum size. * (This field perhaps should have been transient). @@ -671,6 +678,16 @@ return objectLock; } + /* + * Returns the acc this component was constructed with. + */ + final AccessControlContext getAccessControlContext() { + if (acc == null) { + throw new SecurityException("Component is missing AccessControlContext"); + } + return acc; + } + boolean isPacked = false; /** @@ -950,6 +967,10 @@ public void processEvent(Component comp, AWTEvent e) { comp.processEvent(e); } + + public AccessControlContext getAccessControlContext(Component comp) { + return comp.getAccessControlContext(); + } }); } @@ -8608,6 +8629,8 @@ { objectLock = new Object(); + acc = AccessController.getContext(); + s.defaultReadObject(); appContext = AppContext.getAppContext(); diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/java/awt/EventQueue.java --- a/jdk/src/share/classes/java/awt/EventQueue.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/java/awt/EventQueue.java Thu Mar 17 17:16:35 2011 -0700 @@ -48,6 +48,12 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; +import java.security.AccessControlContext; +import java.security.ProtectionDomain; + +import sun.misc.SharedSecrets; +import sun.misc.JavaSecurityAccess; + /** * EventQueue is a platform-independent class * that queues events, both from the underlying peer classes @@ -612,6 +618,9 @@ return null; } + private static final JavaSecurityAccess javaSecurityAccess = + SharedSecrets.getJavaSecurityAccess(); + /** * Dispatches an event. The manner in which the event is * dispatched depends upon the type of the event and the @@ -650,13 +659,49 @@ * @throws NullPointerException if event is null * @since 1.2 */ - protected void dispatchEvent(AWTEvent event) { + protected void dispatchEvent(final AWTEvent event) { + final Object src = event.getSource(); + final PrivilegedAction action = new PrivilegedAction() { + public Void run() { + dispatchEventImpl(event, src); + return null; + } + }; + + final AccessControlContext stack = AccessController.getContext(); + final AccessControlContext srcAcc = getAccessControlContextFrom(src); + final AccessControlContext eventAcc = event.getAccessControlContext(); + if (srcAcc == null) { + javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc); + } else { + javaSecurityAccess.doIntersectionPrivilege( + new PrivilegedAction() { + public Void run() { + javaSecurityAccess.doIntersectionPrivilege(action, eventAcc); + return null; + } + }, stack, srcAcc); + } + } + + private static AccessControlContext getAccessControlContextFrom(Object src) { + return src instanceof Component ? + ((Component)src).getAccessControlContext() : + src instanceof MenuComponent ? + ((MenuComponent)src).getAccessControlContext() : + src instanceof TrayIcon ? + ((TrayIcon)src).getAccessControlContext() : + null; + } + + /** + * Called from dispatchEvent() under a correct AccessControlContext + */ + private void dispatchEventImpl(final AWTEvent event, final Object src) { event.isPosted = true; - Object src = event.getSource(); if (event instanceof ActiveEvent) { // This could become the sole method of dispatching in time. setCurrentEventAndMostRecentTimeImpl(event); - ((ActiveEvent)event).dispatch(); } else if (src instanceof Component) { ((Component)src).dispatchEvent(event); diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/java/awt/MenuComponent.java --- a/jdk/src/share/classes/java/awt/MenuComponent.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/java/awt/MenuComponent.java Thu Mar 17 17:16:35 2011 -0700 @@ -33,6 +33,9 @@ import sun.awt.AWTAccessor; import javax.accessibility.*; +import java.security.AccessControlContext; +import java.security.AccessController; + /** * The abstract class MenuComponent is the superclass * of all menu-related components. In this respect, the class @@ -100,6 +103,23 @@ boolean newEventsOnly = false; /* + * The menu's AccessControlContext. + */ + private transient volatile AccessControlContext acc = + AccessController.getContext(); + + /* + * Returns the acc this menu component was constructed with. + */ + final AccessControlContext getAccessControlContext() { + if (acc == null) { + throw new SecurityException( + "MenuComponent is missing AccessControlContext"); + } + return acc; + } + + /* * Internal constants for serialization. */ final static String actionListenerK = Component.actionListenerK; @@ -402,6 +422,9 @@ throws ClassNotFoundException, IOException, HeadlessException { GraphicsEnvironment.checkHeadless(); + + acc = AccessController.getContext(); + s.defaultReadObject(); appContext = AppContext.getAppContext(); diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/java/awt/TrayIcon.java --- a/jdk/src/share/classes/java/awt/TrayIcon.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/java/awt/TrayIcon.java Thu Mar 17 17:16:35 2011 -0700 @@ -40,6 +40,8 @@ import sun.awt.SunToolkit; import sun.awt.HeadlessToolkit; import java.util.EventObject; +import java.security.AccessControlContext; +import java.security.AccessController; /** * A TrayIcon object represents a tray icon that can be @@ -90,6 +92,7 @@ * @author Anton Tarasov */ public class TrayIcon { + private Image image; private String tooltip; private PopupMenu popup; @@ -103,6 +106,24 @@ transient MouseMotionListener mouseMotionListener; transient ActionListener actionListener; + /* + * The tray icon's AccessControlContext. + * + * Unlike the acc in Component, this field is made final + * because TrayIcon is not serializable. + */ + private final AccessControlContext acc = AccessController.getContext(); + + /* + * Returns the acc this tray icon was constructed with. + */ + final AccessControlContext getAccessControlContext() { + if (acc == null) { + throw new SecurityException("TrayIcon is missing AccessControlContext"); + } + return acc; + } + static { Toolkit.loadLibraries(); if (!GraphicsEnvironment.isHeadless()) { diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/java/security/AccessControlContext.java --- a/jdk/src/share/classes/java/security/AccessControlContext.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/java/security/AccessControlContext.java Thu Mar 17 17:16:35 2011 -0700 @@ -29,6 +29,9 @@ import java.util.List; import sun.security.util.Debug; import sun.security.util.SecurityConstants; +import sun.misc.JavaSecurityAccess; +import sun.misc.SharedSecrets; + /** * An AccessControlContext is used to make system resource access decisions @@ -197,6 +200,24 @@ } /** + * Constructor for JavaSecurityAccess.doIntersectionPrivilege() + */ + AccessControlContext(ProtectionDomain[] context, + AccessControlContext privilegedContext) + { + this.context = context; + this.privilegedContext = privilegedContext; + this.isPrivileged = true; + } + + /** + * Returns this context's context. + */ + ProtectionDomain[] getContext() { + return context; + } + + /** * Returns true if this context is privileged. */ boolean isPrivileged() diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/java/security/ProtectionDomain.java --- a/jdk/src/share/classes/java/security/ProtectionDomain.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/java/security/ProtectionDomain.java Thu Mar 17 17:16:35 2011 -0700 @@ -36,6 +36,8 @@ import sun.misc.SharedSecrets; import sun.security.util.Debug; import sun.security.util.SecurityConstants; +import sun.misc.JavaSecurityAccess; +import sun.misc.SharedSecrets; /** * @@ -59,6 +61,36 @@ public class ProtectionDomain { + static { + // Set up JavaSecurityAccess in SharedSecrets + SharedSecrets.setJavaSecurityAccess( + new JavaSecurityAccess() { + public T doIntersectionPrivilege( + PrivilegedAction action, + final AccessControlContext stack, + final AccessControlContext context) + { + if (action == null) { + throw new NullPointerException(); + } + return AccessController.doPrivileged( + action, + new AccessControlContext( + stack.getContext(), context).optimize() + ); + } + + public T doIntersectionPrivilege( + PrivilegedAction action, + AccessControlContext context) + { + return doIntersectionPrivilege(action, + AccessController.getContext(), context); + } + } + ); + } + /* CodeSource */ private CodeSource codesource ; diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/javax/swing/Timer.java --- a/jdk/src/share/classes/javax/swing/Timer.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/javax/swing/Timer.java Thu Mar 17 17:16:35 2011 -0700 @@ -35,6 +35,10 @@ import java.awt.*; import java.awt.event.*; import java.io.Serializable; +import java.io.*; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.PrivilegedAction; import javax.swing.event.EventListenerList; @@ -208,6 +212,22 @@ } } + /* + * The timer's AccessControlContext. + */ + private transient volatile AccessControlContext acc = + AccessController.getContext(); + + /** + * Returns the acc this timer was constructed with. + */ + final AccessControlContext getAccessControlContext() { + if (acc == null) { + throw new SecurityException( + "Timer is missing AccessControlContext"); + } + return acc; + } /** * DoPostEvent is a runnable class that fires actionEvents to @@ -587,8 +607,13 @@ void post() { - if (notify.compareAndSet(false, true) || !coalesce) { - SwingUtilities.invokeLater(doPostEvent); + if (notify.compareAndSet(false, true) || !coalesce) { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + SwingUtilities.invokeLater(doPostEvent); + return null; + } + }, getAccessControlContext()); } } @@ -596,6 +621,13 @@ return lock; } + private void readObject(ObjectInputStream in) + throws ClassNotFoundException, IOException + { + this.acc = AccessController.getContext(); + in.defaultReadObject(); + } + /* * We have to use readResolve because we can not initialize final * fields for deserialized object otherwise diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/javax/swing/TransferHandler.java --- a/jdk/src/share/classes/javax/swing/TransferHandler.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/javax/swing/TransferHandler.java Thu Mar 17 17:16:35 2011 -0700 @@ -42,6 +42,16 @@ import sun.swing.*; import sun.awt.SunToolkit; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import java.security.AccessControlContext; +import java.security.ProtectionDomain; +import sun.misc.SharedSecrets; +import sun.misc.JavaSecurityAccess; + +import sun.awt.AWTAccessor; + /** * This class is used to handle the transfer of a Transferable * to and from Swing components. The Transferable is used to @@ -1686,7 +1696,37 @@ return true; } - public void actionPerformed(ActionEvent e) { + private static final JavaSecurityAccess javaSecurityAccess = + SharedSecrets.getJavaSecurityAccess(); + + public void actionPerformed(final ActionEvent e) { + final Object src = e.getSource(); + + final PrivilegedAction action = new PrivilegedAction() { + public Void run() { + actionPerformedImpl(e); + return null; + } + }; + + final AccessControlContext stack = AccessController.getContext(); + final AccessControlContext srcAcc = AWTAccessor.getComponentAccessor().getAccessControlContext((Component)src); + final AccessControlContext eventAcc = AWTAccessor.getAWTEventAccessor().getAccessControlContext(e); + + if (srcAcc == null) { + javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc); + } else { + javaSecurityAccess.doIntersectionPrivilege( + new PrivilegedAction() { + public Void run() { + javaSecurityAccess.doIntersectionPrivilege(action, eventAcc); + return null; + } + }, stack, srcAcc); + } + } + + private void actionPerformedImpl(ActionEvent e) { Object src = e.getSource(); if (src instanceof JComponent) { JComponent c = (JComponent) src; diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/sun/awt/AWTAccessor.java --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java Thu Mar 17 17:16:35 2011 -0700 @@ -33,6 +33,9 @@ import sun.misc.Unsafe; import java.awt.peer.ComponentPeer; +import java.security.AccessController; +import java.security.AccessControlContext; + /** * The AWTAccessor utility class. * The main purpose of this class is to enable accessing @@ -221,6 +224,13 @@ * Processes events occurring on this component. */ void processEvent(Component comp, AWTEvent e); + + + /* + * Returns the acc this component was constructed with. + */ + AccessControlContext getAccessControlContext(Component comp); + } /* @@ -323,6 +333,13 @@ * Indicates whether this AWTEvent was generated by the system. */ boolean isSystemGenerated(AWTEvent ev); + + + /* + * Returns the acc this event was constructed with. + */ + AccessControlContext getAccessControlContext(AWTEvent ev); + } public interface InputEventAccessor { diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/sun/misc/JavaSecurityAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/misc/JavaSecurityAccess.java Thu Mar 17 17:16:35 2011 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.misc; + +import java.security.AccessControlContext; +import java.security.PrivilegedAction; + +public interface JavaSecurityAccess { + + T doIntersectionPrivilege(PrivilegedAction action, + AccessControlContext stack, + AccessControlContext context); + + T doIntersectionPrivilege(PrivilegedAction action, + AccessControlContext context); + +} diff -r 9a3f042d307e -r 29f983feda95 jdk/src/share/classes/sun/misc/SharedSecrets.java --- a/jdk/src/share/classes/sun/misc/SharedSecrets.java Mon Jan 10 18:12:43 2011 +0000 +++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java Thu Mar 17 17:16:35 2011 -0700 @@ -30,6 +30,8 @@ import java.io.FileDescriptor; import java.security.ProtectionDomain; +import java.security.AccessController; + /** A repository of "shared secrets", which are a mechanism for calling implementation-private methods in another package without using reflection. A package-private class implements a public @@ -48,6 +50,7 @@ private static JavaNioAccess javaNioAccess; private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess; private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess; + private static JavaSecurityAccess javaSecurityAccess; public static JavaUtilJarAccess javaUtilJarAccess() { if (javaUtilJarAccess == null) { @@ -125,4 +128,15 @@ unsafe.ensureClassInitialized(ProtectionDomain.class); return javaSecurityProtectionDomainAccess; } + + public static void setJavaSecurityAccess(JavaSecurityAccess jsa) { + javaSecurityAccess = jsa; + } + + public static JavaSecurityAccess getJavaSecurityAccess() { + if (javaSecurityAccess == null) { + unsafe.ensureClassInitialized(AccessController.class); + } + return javaSecurityAccess; + } }