8020637: Permissions.readObject doesn't enforce proper Class to PermissionCollection mappings
Reviewed-by: weijun
This commit is contained in:
parent
9a97b54211
commit
8b8759de8d
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
@ -25,21 +25,20 @@
|
||||
|
||||
package java.security;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.io.Serializable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* This class represents a heterogeneous collection of Permissions. That is,
|
||||
@ -392,6 +391,22 @@ implements Serializable
|
||||
permsMap = new ConcurrentHashMap<>(perms.size()*2);
|
||||
permsMap.putAll(perms);
|
||||
|
||||
// Check that Class is mapped to PermissionCollection containing
|
||||
// Permissions of the same class
|
||||
for (Map.Entry<Class<?>, PermissionCollection> e : perms.entrySet()) {
|
||||
Class<?> k = e.getKey();
|
||||
PermissionCollection v = e.getValue();
|
||||
Enumeration<Permission> en = v.elements();
|
||||
while (en.hasMoreElements()) {
|
||||
Permission p = en.nextElement();
|
||||
if (!k.equals(p.getClass())) {
|
||||
throw new InvalidObjectException("Permission with class " +
|
||||
k + " incorrectly mapped to PermissionCollection " +
|
||||
"containing Permission with " + p.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set hasUnresolved
|
||||
UnresolvedPermissionCollection uc =
|
||||
(UnresolvedPermissionCollection) permsMap.get(UnresolvedPermission.class);
|
||||
@ -584,5 +599,15 @@ implements Serializable
|
||||
(Hashtable<Permission, Permission>)gfields.get("perms", null);
|
||||
permsMap = new ConcurrentHashMap<>(perms.size()*2);
|
||||
permsMap.putAll(perms);
|
||||
|
||||
// check that the Permission key and value are the same object
|
||||
for (Map.Entry<Permission, Permission> e : perms.entrySet()) {
|
||||
Permission k = e.getKey();
|
||||
Permission v = e.getValue();
|
||||
if (k != v) {
|
||||
throw new InvalidObjectException("Permission (" + k +
|
||||
") incorrectly mapped to Permission (" + v + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8020637
|
||||
* @summary Deserialize a serialized Permissions object with incorrect Class to
|
||||
* Permission mappings
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.security.Permissions;
|
||||
import java.util.Base64;
|
||||
|
||||
public class DeserializeInvalidPermissions {
|
||||
|
||||
private static final String BASE = System.getProperty("test.src", ".");
|
||||
|
||||
/**
|
||||
* A base64 encoded serialized Permissions object. This contains two
|
||||
* Permissions, SecurityPermission("foo") and FilePermission("bar", "read").
|
||||
* However, the Hashtable mappings have been switched, such that
|
||||
* FilePermission.class maps to BasicPermissionCollection (which contains
|
||||
* the SecurityPermission) and SecurityPermission.class maps to
|
||||
* FilePermissionCollection.
|
||||
*/
|
||||
private static String INVALID_PERMISSIONS =
|
||||
"rO0ABXNyABlqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb25zQ21LTdLID1ADAAJMAA1hbGxQ" +
|
||||
"ZXJtaXNzaW9udAAkTGphdmEvc2VjdXJpdHkvUGVybWlzc2lvbkNvbGxlY3Rpb247TAAF" +
|
||||
"cGVybXN0ABVMamF2YS91dGlsL0hhc2h0YWJsZTt4cgAiamF2YS5zZWN1cml0eS5QZXJt" +
|
||||
"aXNzaW9uQ29sbGVjdGlvbqKk2tZqGAkpAgABWgAIcmVhZE9ubHl4cABwc3IAE2phdmEu" +
|
||||
"dXRpbC5IYXNodGFibGUTuw8lIUrkuAMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4" +
|
||||
"cD9AAAAAAAADdwgAAAAEAAAAAnZyABZqYXZhLmlvLkZpbGVQZXJtaXNzaW9ubg+fk/TA" +
|
||||
"qbsDAAFMAAdhY3Rpb25zdAASTGphdmEvbGFuZy9TdHJpbmc7eHIAGGphdmEuc2VjdXJp" +
|
||||
"dHkuUGVybWlzc2lvbrHG4T8oV1F+AgABTAAEbmFtZXEAfgAIeHBzcgAnamF2YS5zZWN1" +
|
||||
"cml0eS5CYXNpY1Blcm1pc3Npb25Db2xsZWN0aW9uCkKHBI3t48cDAANaAAthbGxfYWxs" +
|
||||
"b3dlZEwACXBlcm1DbGFzc3QAEUxqYXZhL2xhbmcvQ2xhc3M7TAALcGVybWlzc2lvbnNx" +
|
||||
"AH4AAnhxAH4AAwAAdnIAIGphdmEuc2VjdXJpdHkuU2VjdXJpdHlQZXJtaXNzaW9uSKpm" +
|
||||
"PrGHHSYCAAB4cgAdamF2YS5zZWN1cml0eS5CYXNpY1Blcm1pc3Npb25XJQvcz06megIA" +
|
||||
"AHhxAH4ACXNxAH4ABT9AAAAAAAABdwgAAAACAAAAAXQAA2Zvb3NxAH4ADnEAfgASeHhx" +
|
||||
"AH4AEHNyACBqYXZhLmlvLkZpbGVQZXJtaXNzaW9uQ29sbGVjdGlvbh6SeX3UjlWpAwAB" +
|
||||
"TAALcGVybWlzc2lvbnN0ABJMamF2YS91dGlsL1ZlY3Rvcjt4cQB+AAMAc3IAEGphdmEu" +
|
||||
"dXRpbC5WZWN0b3LZl31bgDuvAQMAA0kAEWNhcGFjaXR5SW5jcmVtZW50SQAMZWxlbWVu" +
|
||||
"dENvdW50WwALZWxlbWVudERhdGF0ABNbTGphdmEvbGFuZy9PYmplY3Q7eHAAAAAAAAAA" +
|
||||
"AXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAFzcQB+AAd0AANi" +
|
||||
"YXJ0AARyZWFkeHh4eHg=";
|
||||
|
||||
/**
|
||||
* A base64 encoded serialized PermissionsHash object, which is an internal
|
||||
* class used to store Permissions that do not implement their own
|
||||
* PermissionCollection. This contains one Permission,
|
||||
* PrivateCredentialPermission("a.b.PrivateCredential a.b.Principal
|
||||
* \"duke\"", "read")
|
||||
* However, the Hashtable entry has been modified to map the
|
||||
* PrivateCredentialPermission to SecurityPermission("foo") instead of
|
||||
* itself.
|
||||
*/
|
||||
private static String INVALID_PERMISSIONS_HASH =
|
||||
"rO0ABXNyABlqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb25zQ21LTdLID1ADAAJMAA1hbGxQ" +
|
||||
"ZXJtaXNzaW9udAAkTGphdmEvc2VjdXJpdHkvUGVybWlzc2lvbkNvbGxlY3Rpb247TAAF" +
|
||||
"cGVybXN0ABVMamF2YS91dGlsL0hhc2h0YWJsZTt4cgAiamF2YS5zZWN1cml0eS5QZXJt" +
|
||||
"aXNzaW9uQ29sbGVjdGlvbqKk2tZqGAkpAgABWgAIcmVhZE9ubHl4cAFwc3IAE2phdmEu" +
|
||||
"dXRpbC5IYXNodGFibGUTuw8lIUrkuAMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4" +
|
||||
"cD9AAAAAAAAEdwgAAAAGAAAAA3ZyABZqYXZhLmlvLkZpbGVQZXJtaXNzaW9ubg+fk/TA" +
|
||||
"qbsDAAFMAAdhY3Rpb25zdAASTGphdmEvbGFuZy9TdHJpbmc7eHIAGGphdmEuc2VjdXJp" +
|
||||
"dHkuUGVybWlzc2lvbrHG4T8oV1F+AgABTAAEbmFtZXEAfgAIeHBzcgAgamF2YS5pby5G" +
|
||||
"aWxlUGVybWlzc2lvbkNvbGxlY3Rpb24eknl91I5VqQMAAUwAC3Blcm1pc3Npb25zdAAS" +
|
||||
"TGphdmEvdXRpbC9WZWN0b3I7eHEAfgADAHNyABBqYXZhLnV0aWwuVmVjdG9y2Zd9W4A7" +
|
||||
"rwEDAANJABFjYXBhY2l0eUluY3JlbWVudEkADGVsZW1lbnRDb3VudFsAC2VsZW1lbnRE" +
|
||||
"YXRhdAATW0xqYXZhL2xhbmcvT2JqZWN0O3hwAAAAAAAAAAF1cgATW0xqYXZhLmxhbmcu" +
|
||||
"T2JqZWN0O5DOWJ8QcylsAgAAeHAAAAABc3EAfgAHdAADYmFydAAEcmVhZHh4eHZyAC9q" +
|
||||
"YXZheC5zZWN1cml0eS5hdXRoLlByaXZhdGVDcmVkZW50aWFsUGVybWlzc2lvbklV3Hd7" +
|
||||
"UH9MAgADWgAHdGVzdGluZ0wAD2NyZWRlbnRpYWxDbGFzc3EAfgAITAAKcHJpbmNpcGFs" +
|
||||
"c3QAD0xqYXZhL3V0aWwvU2V0O3hxAH4ACXNyAB1qYXZhLnNlY3VyaXR5LlBlcm1pc3Np" +
|
||||
"b25zSGFzaIomZbSmPV1AAwABTAAFcGVybXNxAH4AAnhxAH4AAwBzcQB+AAU/QAAAAAAA" +
|
||||
"AXcIAAAAAgAAAAFzcQB+ABZ0ACphLmIuUHJpdmF0ZUNyZWRlbnRpYWwgYS5iLlByaW5j" +
|
||||
"aXBhbCAiZHVrZSIAdAAVYS5iLlByaXZhdGVDcmVkZW50aWFscHNyACBqYXZhLnNlY3Vy" +
|
||||
"aXR5LlNlY3VyaXR5UGVybWlzc2lvbkiqZj6xhx0mAgAAeHIAHWphdmEuc2VjdXJpdHku" +
|
||||
"QmFzaWNQZXJtaXNzaW9uVyUL3M9OpnoCAAB4cQB+AAl0AANmb294eHZxAH4AH3NyACdq" +
|
||||
"YXZhLnNlY3VyaXR5LkJhc2ljUGVybWlzc2lvbkNvbGxlY3Rpb24KQocEje3jxwMAA1oA" +
|
||||
"C2FsbF9hbGxvd2VkTAAJcGVybUNsYXNzdAARTGphdmEvbGFuZy9DbGFzcztMAAtwZXJt" +
|
||||
"aXNzaW9uc3EAfgACeHEAfgADAABxAH4AI3NxAH4ABT9AAAAAAAABdwgAAAACAAAAAXEA" +
|
||||
"fgAic3EAfgAfcQB+ACJ4eHh4";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Base64.Decoder decoder = Base64.getDecoder();
|
||||
deserialize(decoder.decode(INVALID_PERMISSIONS));
|
||||
deserialize(decoder.decode(INVALID_PERMISSIONS_HASH));
|
||||
}
|
||||
|
||||
private static void deserialize(byte[] serialBytes) throws Exception {
|
||||
try (ObjectInputStream ois =
|
||||
new ObjectInputStream(new ByteArrayInputStream(serialBytes))) {
|
||||
try {
|
||||
Permissions p = (Permissions) ois.readObject();
|
||||
throw new Exception("expected InvalidObjectException");
|
||||
} catch (InvalidObjectException ioe) {
|
||||
// test passed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user