diff --git a/src/share/classes/java/awt/AWTEvent.java b/src/share/classes/java/awt/AWTEvent.java
index 60ab93e1dc6a091ae11b22051e8090fa94c37644..5afd14afa23aae3625b1cec3be77b025103912ab 100644
--- a/src/share/classes/java/awt/AWTEvent.java
+++ b/src/share/classes/java/awt/AWTEvent.java
@@ -33,6 +33,11 @@ import java.lang.reflect.Field;
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 @@ public abstract class AWTEvent extends EventObject {
*/
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 abstract class AWTEvent extends EventObject {
public boolean isSystemGenerated(AWTEvent ev) {
return ev.isSystemGenerated;
}
+
+ public AccessControlContext getAccessControlContext(AWTEvent ev) {
+ return ev.getAccessControlContext();
+ }
});
}
diff --git a/src/share/classes/java/awt/Component.java b/src/share/classes/java/awt/Component.java
index d0eda994f1bd3dc2f8d79ad5bf479b6c51c06173..adabdbccca78178401eb6f489d866f877b045233 100644
--- a/src/share/classes/java/awt/Component.java
+++ b/src/share/classes/java/awt/Component.java
@@ -59,6 +59,7 @@ import java.lang.reflect.InvocationTargetException;
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 @@ public abstract class Component implements ImageObserver, MenuContainer,
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 @@ public abstract class Component implements ImageObserver, MenuContainer,
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 abstract class Component implements ImageObserver, MenuContainer,
public void processEvent(Component comp, AWTEvent e) {
comp.processEvent(e);
}
+
+ public AccessControlContext getAccessControlContext(Component comp) {
+ return comp.getAccessControlContext();
+ }
});
}
@@ -8608,6 +8629,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
{
objectLock = new Object();
+ acc = AccessController.getContext();
+
s.defaultReadObject();
appContext = AppContext.getAppContext();
diff --git a/src/share/classes/java/awt/EventQueue.java b/src/share/classes/java/awt/EventQueue.java
index d4c763b4f3fa911da515cfe1b632dd128b84668c..8aab49f075a16951ff9b63351951eb930dea8768 100644
--- a/src/share/classes/java/awt/EventQueue.java
+++ b/src/share/classes/java/awt/EventQueue.java
@@ -48,6 +48,12 @@ import sun.awt.AWTAccessor;
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 @@ public class EventQueue {
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 @@ public class EventQueue {
* @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 --git a/src/share/classes/java/awt/MenuComponent.java b/src/share/classes/java/awt/MenuComponent.java
index 19d57394a23b9e7fef3c1c6eee4993a0a735a100..d1a5a2577b415971797cea06be4cde23e102cdb9 100644
--- a/src/share/classes/java/awt/MenuComponent.java
+++ b/src/share/classes/java/awt/MenuComponent.java
@@ -33,6 +33,9 @@ import sun.awt.SunToolkit;
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
@@ -99,6 +102,23 @@ public abstract class MenuComponent implements java.io.Serializable {
*/
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.
*/
@@ -402,6 +422,9 @@ public abstract class MenuComponent implements java.io.Serializable {
throws ClassNotFoundException, IOException, HeadlessException
{
GraphicsEnvironment.checkHeadless();
+
+ acc = AccessController.getContext();
+
s.defaultReadObject();
appContext = AppContext.getAppContext();
diff --git a/src/share/classes/java/awt/TrayIcon.java b/src/share/classes/java/awt/TrayIcon.java
index 35a98706e7f442d39c1704504ea06c45bd65c87d..13185bf92fd9c25868f921abdcf45b0256e3d7b0 100644
--- a/src/share/classes/java/awt/TrayIcon.java
+++ b/src/share/classes/java/awt/TrayIcon.java
@@ -40,6 +40,8 @@ import sun.awt.AppContext;
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 @@ import java.util.EventObject;
* @author Anton Tarasov
*/
public class TrayIcon {
+
private Image image;
private String tooltip;
private PopupMenu popup;
@@ -103,6 +106,24 @@ public class TrayIcon {
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 --git a/src/share/classes/java/security/AccessControlContext.java b/src/share/classes/java/security/AccessControlContext.java
index e80953b66963e300945ad3853b0a332ca470b059..940aff6377041d17856d5eab05012a3827db8517 100644
--- a/src/share/classes/java/security/AccessControlContext.java
+++ b/src/share/classes/java/security/AccessControlContext.java
@@ -29,6 +29,9 @@ import java.util.ArrayList;
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
@@ -196,6 +199,24 @@ public final class AccessControlContext {
this.isPrivileged = isPrivileged;
}
+ /**
+ * 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.
*/
diff --git a/src/share/classes/java/security/ProtectionDomain.java b/src/share/classes/java/security/ProtectionDomain.java
index 43a39028e3df5cc0f2df2a2153095c783ada5113..9025e81b5dcb215747a216bd5da16d9d7c66f365 100644
--- a/src/share/classes/java/security/ProtectionDomain.java
+++ b/src/share/classes/java/security/ProtectionDomain.java
@@ -36,6 +36,8 @@ import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
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 @@ import sun.security.util.SecurityConstants;
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 --git a/src/share/classes/javax/swing/Timer.java b/src/share/classes/javax/swing/Timer.java
index 9e98d5f920e87490c687939f4c8e63bd4878de8c..c6c80baeda9299708dec103a64900e0cad40084e 100644
--- a/src/share/classes/javax/swing/Timer.java
+++ b/src/share/classes/javax/swing/Timer.java
@@ -35,6 +35,10 @@ import java.util.concurrent.locks.*;
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 @@ public class Timer implements Serializable
}
}
+ /*
+ * 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 @@ public class Timer implements Serializable
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 @@ public class Timer implements Serializable
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 --git a/src/share/classes/javax/swing/TransferHandler.java b/src/share/classes/javax/swing/TransferHandler.java
index eb7f8d1a644a3678d3bb7e5374d2b92e780f8619..dd54b259eef06c386d986e838bdf7ba148401f65 100644
--- a/src/share/classes/javax/swing/TransferHandler.java
+++ b/src/share/classes/javax/swing/TransferHandler.java
@@ -42,6 +42,16 @@ import sun.awt.AppContext;
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 @@ public class TransferHandler implements Serializable {
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 --git a/src/share/classes/sun/awt/AWTAccessor.java b/src/share/classes/sun/awt/AWTAccessor.java
index 0e38de6df6fdfb26d2dfeaed02caafe0c5c42258..b88531dfcd21efb09ed08403ec81497acb130947 100644
--- a/src/share/classes/sun/awt/AWTAccessor.java
+++ b/src/share/classes/sun/awt/AWTAccessor.java
@@ -33,6 +33,9 @@ import java.awt.image.BufferedImage;
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 @@ public final class AWTAccessor {
* 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 @@ public final class AWTAccessor {
* 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 --git a/src/share/classes/sun/misc/JavaSecurityAccess.java b/src/share/classes/sun/misc/JavaSecurityAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a3aa513fb80521b0bba11aed6a2841da82615e9
--- /dev/null
+++ b/src/share/classes/sun/misc/JavaSecurityAccess.java
@@ -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 --git a/src/share/classes/sun/misc/SharedSecrets.java b/src/share/classes/sun/misc/SharedSecrets.java
index 2335b2d68b58b97e12734d4971e4b07f6d9055c3..0bd39b4a5d42f0b12478143bad17dce21db3ba11 100644
--- a/src/share/classes/sun/misc/SharedSecrets.java
+++ b/src/share/classes/sun/misc/SharedSecrets.java
@@ -30,6 +30,8 @@ import java.io.Console;
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 @@ public class SharedSecrets {
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 @@ public class SharedSecrets {
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;
+ }
}