The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
If possible, we should not be using this method to get around security.
Comments
CONVERTED DATA
BugTraq+ Release Management Values
COMMIT TO FIX:
tiger
FIXED IN:
tiger
INTEGRATED IN:
tiger
tiger-b03
14-06-2004
EVALUATION
Will be filed by ###@###.###
Name: ssR10077 Date: 04/25/2003
Reflection is used instead of JNI to access private constructor of another class
======================================================================
11-06-2004
SUGGESTED FIX
Name: ssR10077 Date: 04/25/2003
------- AWTKeyStroke.java -------
*** /tmp/d.caaSw Fri Apr 25 16:29:00 2003
--- AWTKeyStroke.java Thu Feb 13 18:17:45 2003
***************
*** 13,18 ****
--- 13,22 ----
import java.util.Map;
import java.util.StringTokenizer;
import java.io.Serializable;
+ import java.security.AccessController;
+ import java.security.PrivilegedAction;
+ import java.lang.reflect.Constructor;
+ import java.lang.reflect.InvocationTargetException;
/**
* An <code>AWTKeyStroke</code> represents a key action on the
***************
*** 43,49 ****
public class AWTKeyStroke implements Serializable {
private static Map cache;
private static AWTKeyStroke cacheKey;
! private static Class subclass = AWTKeyStroke.class;
private static Map modifierKeywords;
/**
* Maps from VK_XXX (as a String) to an Integer. This is done to
--- 47,53 ----
public class AWTKeyStroke implements Serializable {
private static Map cache;
private static AWTKeyStroke cacheKey;
! private static Constructor ctor = getCtor(AWTKeyStroke.class);
private static Map modifierKeywords;
/**
* Maps from VK_XXX (as a String) to an Integer. This is done to
***************
*** 145,151 ****
if (subclass == null) {
throw new IllegalArgumentException("subclass cannot be null");
}
! if (AWTKeyStroke.subclass.equals(subclass)) {
// Already registered
return;
}
--- 149,155 ----
if (subclass == null) {
throw new IllegalArgumentException("subclass cannot be null");
}
! if (AWTKeyStroke.ctor.getDeclaringClass().equals(subclass)) {
// Already registered
return;
}
***************
*** 153,161 ****
throw new ClassCastException("subclass is not derived from AWTKeyStroke");
}
String couldNotInstantiate = "subclass could not be instantiated";
try {
! AWTKeyStroke stroke = allocateNewInstance(subclass);
if (stroke == null) {
throw new IllegalArgumentException(couldNotInstantiate);
}
--- 157,171 ----
throw new ClassCastException("subclass is not derived from AWTKeyStroke");
}
+ Constructor ctor = getCtor(subclass);
+
String couldNotInstantiate = "subclass could not be instantiated";
+
+ if (ctor == null) {
+ throw new IllegalArgumentException(couldNotInstantiate);
+ }
try {
! AWTKeyStroke stroke = (AWTKeyStroke)ctor.newInstance(null);
if (stroke == null) {
throw new IllegalArgumentException(couldNotInstantiate);
}
***************
*** 165,185 ****
throw new IllegalArgumentException(couldNotInstantiate);
} catch (InstantiationException e) {
throw new IllegalArgumentException(couldNotInstantiate);
}
synchronized (AWTKeyStroke.class) {
! AWTKeyStroke.subclass = subclass;
cache = null;
cacheKey = null;
}
}
! // Native function allows us to bypass all security and access
! // restrictions. This allows us to define javax.swing.KeyStroke with only
! // a private no-arg constructor, yet still instantiate it from AWT without
! // special knowledge of Swing.
! private static native AWTKeyStroke allocateNewInstance(Class clazz)
! throws InstantiationException;
private static synchronized AWTKeyStroke getCachedStroke
(char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
--- 175,217 ----
throw new IllegalArgumentException(couldNotInstantiate);
} catch (InstantiationException e) {
throw new IllegalArgumentException(couldNotInstantiate);
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException(couldNotInstantiate);
+ } catch (InvocationTargetException e) {
+ throw new IllegalArgumentException(couldNotInstantiate);
}
synchronized (AWTKeyStroke.class) {
! AWTKeyStroke.ctor = ctor;
cache = null;
cacheKey = null;
}
}
! /* returns noarg Constructor for class with accessible flag. No security
! threat as accessible flag is set only for this Constructor object,
! not for Class constructor.
! */
! private static Constructor getCtor(final Class clazz)
! {
! Object ctor = AccessController.doPrivileged(new PrivilegedAction() {
! public Object run() {
! try {
! Constructor ctor = clazz.getDeclaredConstructor(null);
! if (ctor != null) {
! ctor.setAccessible(true);
! }
! return ctor;
! } catch (SecurityException e) {
! assert(false);
! } catch (NoSuchMethodException e) {
! assert(false);
! }
! return null;
! }
! });
! return (Constructor)ctor;
! }
private static synchronized AWTKeyStroke getCachedStroke
(char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
***************
*** 190,197 ****
if (cacheKey == null) {
try {
! cacheKey = allocateNewInstance(subclass);
} catch (InstantiationException e) {
}
}
cacheKey.keyChar = keyChar;
--- 222,234 ----
if (cacheKey == null) {
try {
! cacheKey = (AWTKeyStroke)ctor.newInstance(null);
} catch (InstantiationException e) {
+ assert(false);
+ } catch (IllegalAccessException e) {
+ assert(false);
+ } catch (InvocationTargetException e) {
+ assert(false);
}
}
cacheKey.keyChar = keyChar;
***************
*** 664,670 ****
protected Object readResolve() throws java.io.ObjectStreamException {
synchronized (AWTKeyStroke.class) {
Class newClass = getClass();
! if (!newClass.equals(subclass)) {
registerSubclass(newClass);
}
return getCachedStroke(keyChar, keyCode, modifiers, onKeyRelease);
--- 701,707 ----
protected Object readResolve() throws java.io.ObjectStreamException {
synchronized (AWTKeyStroke.class) {
Class newClass = getClass();
! if (!newClass.equals(ctor.getDeclaringClass())) {
registerSubclass(newClass);
}
return getCachedStroke(keyChar, keyCode, modifiers, onKeyRelease);
======================================================================