Creating Dangling Pointers in Java

Overview

Since Java uses a Garbage Collector it is not possoble to create a dangling reference in pure Java See here for more details However using the Java Library it is possible to create a dangling pointer if you go out of your way to create one. You still cannot create one by accident AFAIK.

Creating a dangling pointer deliberately

A DirectByteBuffer has the address to a direct area of memory. In C terminology this could be called a pointer. This area of memory is not managed by the GC and must be explicity freed. The DirectByteBuffer manages the creation and cleanup for you so that when the DirectByteBuffer's Cleaner/Deallocator is GC'ed, the memory is freed. This means that indirectly the area of memory is freed when it is no longer used, however it is not directly managed meaning you can pervert this process and create a dangling references like so

ByteBuffer bb1 = ByteBuffer.allocateDirect(4096);
ByteBuffer bb2 = ByteBuffer.allocateDirect(4096);
useReflectionsToCopyTheAddressFieldFrom(bb1, /* to */ bb2);
// now both byte buffers use the same address.
bb1.put(0, 5);
assert bb2.get(0) == 5;
// clean up bb1
bb1= null;
System.gc(); // etc.
// bb1 is gone and so is its memory, but bb2 lives on.

bb2.get(0); // can return 5 or kill the JVM.

Comments

  1. I don't think the JVM allows mapped byte buffers to ever be garbage collected for security reasons. And GC only frees Java objects (heap memory), not things like this that live off the heap.

    ReplyDelete
  2. Articles are created to express different body of knowledge. That is why I admire writers who are passionate of doing such incredible job. By the way, I like you post for it is specifically talk about current issues and technicalities in life. I look forward for your subsequent post.I look forward for your next article.Thanks Marks Liferay Blog

    ReplyDelete
  3. @Min, these direct byte buffers are freed when the GC removes the Cleaner associated with it.

    When a mapped ByteBuffer is cleaned up the area is un mapped using FileChannelImpl.Unmapper.

    The fact the GC doesn't clean up the direct memory area is part of my point. It only causes the memory to be freed when it Cleaner collected, however you cna retain a reference to a "freed" area of memory if you mess with its internals.

    ReplyDelete

Post a Comment

Popular posts from this blog

Low Latency Microservices, A Retrospective

Unusual Java: StackTrace Extends Throwable

System wide unique nanosecond timestamps