1248
1249 /**
1250 * Verifies that this (possibly subclass) instance can be constructed
1251 * without violating security constraints: the subclass must not override
1252 * security-sensitive non-final methods, or else the
1253 * "enableSubclassImplementation" SerializablePermission is checked.
1254 */
1255 private void verifySubclass() {
1256 Class<?> cl = getClass();
1257 if (cl == ObjectInputStream.class) {
1258 return;
1259 }
1260 SecurityManager sm = System.getSecurityManager();
1261 if (sm == null) {
1262 return;
1263 }
1264 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1265 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1266 Boolean result = Caches.subclassAudits.get(key);
1267 if (result == null) {
1268 result = Boolean.valueOf(auditSubclass(cl));
1269 Caches.subclassAudits.putIfAbsent(key, result);
1270 }
1271 if (result.booleanValue()) {
1272 return;
1273 }
1274 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1275 }
1276
1277 /**
1278 * Performs reflective checks on given subclass to verify that it doesn't
1279 * override security-sensitive non-final methods. Returns true if subclass
1280 * is "safe", false otherwise.
1281 */
1282 private static boolean auditSubclass(final Class<?> subcl) {
1283 Boolean result = AccessController.doPrivileged(
1284 new PrivilegedAction<>() {
1285 public Boolean run() {
1286 for (Class<?> cl = subcl;
1287 cl != ObjectInputStream.class;
1288 cl = cl.getSuperclass())
1289 {
1290 try {
1291 cl.getDeclaredMethod(
1292 "readUnshared", (Class[]) null);
1293 return Boolean.FALSE;
1294 } catch (NoSuchMethodException ex) {
1295 }
1296 try {
1297 cl.getDeclaredMethod("readFields", (Class[]) null);
1298 return Boolean.FALSE;
1299 } catch (NoSuchMethodException ex) {
1300 }
1301 }
1302 return Boolean.TRUE;
1303 }
1304 }
1305 );
1306 return result.booleanValue();
1307 }
1308
1309 /**
1310 * Clears internal data structures.
1311 */
1312 private void clear() {
1313 handles.clear();
1314 vlist.clear();
1315 }
1316
1317 /**
1318 * Underlying readObject implementation.
1319 */
1320 private Object readObject0(boolean unshared) throws IOException {
1321 boolean oldMode = bin.getBlockDataMode();
1322 if (oldMode) {
1323 int remain = bin.currentBlockRemaining();
1324 if (remain > 0) {
1325 throw new OptionalDataException(remain);
1326 } else if (defaultDataEnd) {
|
1248
1249 /**
1250 * Verifies that this (possibly subclass) instance can be constructed
1251 * without violating security constraints: the subclass must not override
1252 * security-sensitive non-final methods, or else the
1253 * "enableSubclassImplementation" SerializablePermission is checked.
1254 */
1255 private void verifySubclass() {
1256 Class<?> cl = getClass();
1257 if (cl == ObjectInputStream.class) {
1258 return;
1259 }
1260 SecurityManager sm = System.getSecurityManager();
1261 if (sm == null) {
1262 return;
1263 }
1264 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1265 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1266 Boolean result = Caches.subclassAudits.get(key);
1267 if (result == null) {
1268 result = auditSubclass(cl);
1269 Caches.subclassAudits.putIfAbsent(key, result);
1270 }
1271 if (!result) {
1272 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1273 }
1274 }
1275
1276 /**
1277 * Performs reflective checks on given subclass to verify that it doesn't
1278 * override security-sensitive non-final methods. Returns TRUE if subclass
1279 * is "safe", FALSE otherwise.
1280 */
1281 private static Boolean auditSubclass(Class<?> subcl) {
1282 return AccessController.doPrivileged(
1283 new PrivilegedAction<>() {
1284 public Boolean run() {
1285 for (Class<?> cl = subcl;
1286 cl != ObjectInputStream.class;
1287 cl = cl.getSuperclass())
1288 {
1289 try {
1290 cl.getDeclaredMethod(
1291 "readUnshared", (Class[]) null);
1292 return Boolean.FALSE;
1293 } catch (NoSuchMethodException ex) {
1294 }
1295 try {
1296 cl.getDeclaredMethod("readFields", (Class[]) null);
1297 return Boolean.FALSE;
1298 } catch (NoSuchMethodException ex) {
1299 }
1300 }
1301 return Boolean.TRUE;
1302 }
1303 }
1304 );
1305 }
1306
1307 /**
1308 * Clears internal data structures.
1309 */
1310 private void clear() {
1311 handles.clear();
1312 vlist.clear();
1313 }
1314
1315 /**
1316 * Underlying readObject implementation.
1317 */
1318 private Object readObject0(boolean unshared) throws IOException {
1319 boolean oldMode = bin.getBlockDataMode();
1320 if (oldMode) {
1321 int remain = bin.currentBlockRemaining();
1322 if (remain > 0) {
1323 throw new OptionalDataException(remain);
1324 } else if (defaultDataEnd) {
|