On 2010-09-28 11:15, Wendy Feng (JIRA) wrote: > Synchonrize on mutable field in Permissions.java > ------------------------------------------------ > > Key: HARMONY-6661 > URL: https://issues.apache.org/jira/browse/HARMONY-6661 > Project: Harmony > Issue Type: Bug > Components: Classlib > Affects Versions: 6.0M1 > Environment: Windows XP > Reporter: Wendy Feng > > > I found a unsafe synchronization in modules/security/src/main/java/common/java/security/Permissions.java > public final class Permissions extends PermissionCollection implements Serializable { > ... > private void readObject(java.io.ObjectInputStream in) throws IOException, > ClassNotFoundException { > ... > klasses = new HashMap(); > synchronized (klasses) { > for (Iterator iter = perms.entrySet().iterator(); iter.hasNext();) { > Map.Entry entry = (Map.Entry) iter.next(); > Class key = (Class) entry.getKey(); > PermissionCollection pc = (PermissionCollection) entry.getValue(); > if (key != pc.elements().nextElement().getClass()) { > throw new InvalidObjectException(Messages.getString("security.22")); //$NON-NLS-1$ > } > klasses.put(key, pc); > } > } > ... > } > ... > } > > In the above code , a block is synchronized on klasses field. Before the synchronized block, klasses is assigned to a new value. > > Consequence: > Different threads will synchronize on different klasses objects because it has been assigned to a new value. It breaks the mutual exclusion and update on klasses would be lost. > > I suggest to rewrite it as follow: > public final class Permissions extends PermissionCollection implements Serializable { > private static final Object monitor = new Object(); > ... > private void readObject(java.io.ObjectInputStream in) throws IOException, > ClassNotFoundException { > ... > klasses = new HashMap(); > synchronized (monitor ) { > for (Iterator iter = perms.entrySet().iterator(); iter.hasNext();) { > Map.Entry entry = (Map.Entry) iter.next(); > Class key = (Class) entry.getKey(); > PermissionCollection pc = (PermissionCollection) entry.getValue(); > if (key != pc.elements().nextElement().getClass()) { > throw new InvalidObjectException(Messages.getString("security.22")); //$NON-NLS-1$ > } > klasses.put(key, pc); > } > } > ... > } > ... > } > > In this case, readObject play a role like constructor, initialize the object, so I guess it could be safe here without "synchornized" block. But serialization may be different, is there any chance that someone could hold a reference to a incompletely deserialized object and then invoke methods on it? -- Best Regards, Regis.