1246 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1247 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1248 Boolean result = Caches.subclassAudits.get(key);
1249 if (result == null) {
1250 result = Boolean.valueOf(auditSubclass(cl));
1251 Caches.subclassAudits.putIfAbsent(key, result);
1252 }
1253 if (result.booleanValue()) {
1254 return;
1255 }
1256 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1257 }
1258
1259 /**
1260 * Performs reflective checks on given subclass to verify that it doesn't
1261 * override security-sensitive non-final methods. Returns true if subclass
1262 * is "safe", false otherwise.
1263 */
1264 private static boolean auditSubclass(final Class<?> subcl) {
1265 Boolean result = AccessController.doPrivileged(
1266 new PrivilegedAction<Boolean>() {
1267 public Boolean run() {
1268 for (Class<?> cl = subcl;
1269 cl != ObjectInputStream.class;
1270 cl = cl.getSuperclass())
1271 {
1272 try {
1273 cl.getDeclaredMethod(
1274 "readUnshared", (Class[]) null);
1275 return Boolean.FALSE;
1276 } catch (NoSuchMethodException ex) {
1277 }
1278 try {
1279 cl.getDeclaredMethod("readFields", (Class[]) null);
1280 return Boolean.FALSE;
1281 } catch (NoSuchMethodException ex) {
1282 }
1283 }
1284 return Boolean.TRUE;
1285 }
1286 }
2238 }
2239 AccessControlContext acc = AccessController.getContext();
2240 if (prev != null) {
2241 prev.next = new Callback(obj, priority, cur, acc);
2242 } else {
2243 list = new Callback(obj, priority, list, acc);
2244 }
2245 }
2246
2247 /**
2248 * Invokes all registered callbacks and clears the callback list.
2249 * Callbacks with higher priorities are called first; those with equal
2250 * priorities may be called in any order. If any of the callbacks
2251 * throws an InvalidObjectException, the callback process is terminated
2252 * and the exception propagated upwards.
2253 */
2254 void doCallbacks() throws InvalidObjectException {
2255 try {
2256 while (list != null) {
2257 AccessController.doPrivileged(
2258 new PrivilegedExceptionAction<Void>()
2259 {
2260 public Void run() throws InvalidObjectException {
2261 list.obj.validateObject();
2262 return null;
2263 }
2264 }, list.acc);
2265 list = list.next;
2266 }
2267 } catch (PrivilegedActionException ex) {
2268 list = null;
2269 throw (InvalidObjectException) ex.getException();
2270 }
2271 }
2272
2273 /**
2274 * Resets the callback list to its initial (empty) state.
2275 */
2276 public void clear() {
2277 list = null;
2278 }
|
1246 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1247 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1248 Boolean result = Caches.subclassAudits.get(key);
1249 if (result == null) {
1250 result = Boolean.valueOf(auditSubclass(cl));
1251 Caches.subclassAudits.putIfAbsent(key, result);
1252 }
1253 if (result.booleanValue()) {
1254 return;
1255 }
1256 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1257 }
1258
1259 /**
1260 * Performs reflective checks on given subclass to verify that it doesn't
1261 * override security-sensitive non-final methods. Returns true if subclass
1262 * is "safe", false otherwise.
1263 */
1264 private static boolean auditSubclass(final Class<?> subcl) {
1265 Boolean result = AccessController.doPrivileged(
1266 new PrivilegedAction<>() {
1267 public Boolean run() {
1268 for (Class<?> cl = subcl;
1269 cl != ObjectInputStream.class;
1270 cl = cl.getSuperclass())
1271 {
1272 try {
1273 cl.getDeclaredMethod(
1274 "readUnshared", (Class[]) null);
1275 return Boolean.FALSE;
1276 } catch (NoSuchMethodException ex) {
1277 }
1278 try {
1279 cl.getDeclaredMethod("readFields", (Class[]) null);
1280 return Boolean.FALSE;
1281 } catch (NoSuchMethodException ex) {
1282 }
1283 }
1284 return Boolean.TRUE;
1285 }
1286 }
2238 }
2239 AccessControlContext acc = AccessController.getContext();
2240 if (prev != null) {
2241 prev.next = new Callback(obj, priority, cur, acc);
2242 } else {
2243 list = new Callback(obj, priority, list, acc);
2244 }
2245 }
2246
2247 /**
2248 * Invokes all registered callbacks and clears the callback list.
2249 * Callbacks with higher priorities are called first; those with equal
2250 * priorities may be called in any order. If any of the callbacks
2251 * throws an InvalidObjectException, the callback process is terminated
2252 * and the exception propagated upwards.
2253 */
2254 void doCallbacks() throws InvalidObjectException {
2255 try {
2256 while (list != null) {
2257 AccessController.doPrivileged(
2258 new PrivilegedExceptionAction<>()
2259 {
2260 public Void run() throws InvalidObjectException {
2261 list.obj.validateObject();
2262 return null;
2263 }
2264 }, list.acc);
2265 list = list.next;
2266 }
2267 } catch (PrivilegedActionException ex) {
2268 list = null;
2269 throw (InvalidObjectException) ex.getException();
2270 }
2271 }
2272
2273 /**
2274 * Resets the callback list to its initial (empty) state.
2275 */
2276 public void clear() {
2277 list = null;
2278 }
|