mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 21:35:25 +00:00
6907662: System clipboard should ensure access restrictions
Reviewed-by: alexp
This commit is contained in:
parent
ed5bd3c06d
commit
a472ac15e8
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* <code>EventQueue</code> 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 <code>event</code> is <code>null</code>
|
||||
* @since 1.2
|
||||
*/
|
||||
protected void dispatchEvent(AWTEvent event) {
|
||||
protected void dispatchEvent(final AWTEvent event) {
|
||||
final Object src = event.getSource();
|
||||
final PrivilegedAction<Void> action = new PrivilegedAction<Void>() {
|
||||
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<Void>() {
|
||||
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);
|
||||
|
||||
@ -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 <code>MenuComponent</code> 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();
|
||||
|
||||
@ -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 <code>TrayIcon</code> 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()) {
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
@ -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> T doIntersectionPrivilege(
|
||||
PrivilegedAction<T> 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> T doIntersectionPrivilege(
|
||||
PrivilegedAction<T> action,
|
||||
AccessControlContext context)
|
||||
{
|
||||
return doIntersectionPrivilege(action,
|
||||
AccessController.getContext(), context);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/* CodeSource */
|
||||
private CodeSource codesource ;
|
||||
|
||||
|
||||
@ -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<Void>() {
|
||||
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
|
||||
|
||||
@ -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 <code>Transferable</code>
|
||||
* to and from Swing components. The <code>Transferable</code> 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<Void> action = new PrivilegedAction<Void>() {
|
||||
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<Void>() {
|
||||
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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
40
jdk/src/share/classes/sun/misc/JavaSecurityAccess.java
Normal file
40
jdk/src/share/classes/sun/misc/JavaSecurityAccess.java
Normal file
@ -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> T doIntersectionPrivilege(PrivilegedAction<T> action,
|
||||
AccessControlContext stack,
|
||||
AccessControlContext context);
|
||||
|
||||
<T> T doIntersectionPrivilege(PrivilegedAction<T> action,
|
||||
AccessControlContext context);
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user