jboss / openjdk-orb-jdk9

JDK9 parts of https://github.com/jboss/openjdk-orb
GNU General Public License v2.0
0 stars 3 forks source link

ObjectStreamClass use of bridge.getXXX static fields does not confirm Unsafe API #2

Open pavel-vyssotski opened 5 years ago

pavel-vyssotski commented 5 years ago

ObjectStreamClass must use staticFieldBase object instead of class object to get a field value, see for example the code https://github.com/jboss/openjdk-orb-jdk9/blob/f8e9580f439ce51071c0452d57a49ec02014e860/src/main/java/com/sun/corba/se/impl/io/ObjectStreamClass.java#L547-L552

Here are excerpts from sun.misc.Unsafe doc:

public native Object staticFieldBase(Field f) Report the location of a given static field, in conjunction with #staticFieldOffset. ... public int getInt(Object o, int offset) // getLong, etc. ... The results are undefined unless one of the following cases is true: ... The offset and object reference o (either null or non-null) were both obtained via #staticFieldOffset and #staticFieldBase (respectively) from the reflective Field representation of some Java field.

With OpenJDK VMs using the class object incidentally works but with other VMs (Azul Zing for example) this fails.

pavel-vyssotski commented 5 years ago

Proposing change:

diff --git a/src/main/java/com/sun/corba/se/impl/io/ObjectStreamClass.java b/src/main/java/com/sun/corba/se/impl/io/ObjectStreamClass.java
index b875d25..7f081c2 100644
--- a/src/main/java/com/sun/corba/se/impl/io/ObjectStreamClass.java
+++ b/src/main/java/com/sun/corba/se/impl/io/ObjectStreamClass.java
@@ -416,8 +416,9 @@ public class ObjectStreamClass implements java.io.Serializable {
                 if (Modifier.isPrivate(mods) && Modifier.isStatic(mods) &&
                         Modifier.isFinal(mods)) {
                     long offset = bridge.staticFieldOffset(pf);
+                    Object base = bridge.staticFieldBase(pf);
                     java.io.ObjectStreamField[] fields =
-                            (java.io.ObjectStreamField[])bridge.getObject(type, offset);
+                            (java.io.ObjectStreamField[])bridge.getObject(base, offset);
                     return translateFields(fields);
                 }
             } catch (NoSuchFieldException |
@@ -549,7 +550,8 @@ public class ObjectStreamClass implements java.io.Serializable {
                         // SerialBug 5:  static final SUID should be read
                         if (Modifier.isStatic(mods) && Modifier.isFinal(mods) ) {
                             long offset = bridge.staticFieldOffset(f);
-                            suid = bridge.getLong(cl, offset);
+                            Object base = bridge.staticFieldBase(f);
+                            suid = bridge.getLong(base, offset);
                             // SerialBug 2: should be computed after writeObject
                             // actualSuid = computeStructuralUID(cl);
                         } else {
diff --git a/src/main/java/sun/corba/Bridge.java b/src/main/java/sun/corba/Bridge.java
index e22240e..f4fe8ae 100644
--- a/src/main/java/sun/corba/Bridge.java
+++ b/src/main/java/sun/corba/Bridge.java
@@ -309,6 +309,14 @@ public final class Bridge
     }

     /**
+     * Returns the location of a given static field.
+     */
+    public final Object staticFieldBase(Field f)
+    {
+        return unsafe.staticFieldBase( f ) ;
+    }
+
+    /**
      * Ensure that the class has been initalized.
      * @param cl the class to ensure is initialized
      */
tadamski commented 5 years ago

@pavel-vyssotski thanks for creating the issue; I will prepare the relevant PR