Java security: how to clear/zero-out memory associated with an object? (And/or ensure that is the only instance/copy of a particular variable)

Edit: Actually I just had three ideas that may indeed work – for different values of “work” at least.

The first that is more or less documented would be ByteBuffer.allocateDirect! As I understand it allocateDirect allocates the buffer outside the usual java heap so won’t be copied around. I can’t find any hard guarantees about it not getting copied in all situations though – but for the current Hotspot VM that is actually the case (ie it’s allocated in an extra heap) and I assume this will stay that way.

The second one is using the sun.misc.unsafe package – which as the name says has some rather obvious problems but at least that would be pretty much independent of the used VM – either it’s supported (and it works) or it’s not (and you get linking errors). The problem is, that the code to use that stuff will get horribly complicated pretty fast (alone getting an unsafe variable is non trivial).

The third one would be to allocate a much, much, MUCH larger size than is actually needed, so that the object gets allocated in the old generation heap to begin:

l-XX:PretenureSizeThreshold= that can be set to limit the
size of allocations in the young
generation. Any allocation larger than
this will not be attempted in the
young generation and so will be
allocated out of the old generation.

Well the drawback of THAT solution is obvious I think (default size seems to be about 64kb).

.
.

Anyways here the old answer:

Yep as I see it you pretty much cannot guarantee that the data stored on the heap is 100% removed without leaving a copy (that’s even true if you don’t want a general solution but one that’ll work with say the current Hotspot VM and its default garbage collectors).

As said in your linked post (here), the garbage collector pretty much makes this impossible to guarantee. Actually contrary to what the post says the problem here isn’t the generational GC, but the fact that the Hotspot VM (and now we’re implementation specific) is using some kind of Stop & Copy gc for its young generation per default.

This means that as soon as a garbage collection happens between storing the password in the char array and zeroing it out you’ll get a copy of the data that will be overwritten only as soon as the next GC happens. Note that tenuring an object will have exactly the same effect, but instead of copying it to to-space it’s copied to the old generation heap – we end up with a copy of the data in from space that isn’t overwritten.

To avoid this problem we’d pretty much need some way to guarantee that either NO garbage collection is happening between storing the password and zeroing it OR that the char array is stored from the get go in the old generation heap. Also note that this relies on the internas of the Hotspot VM which may very well change (actually there are different garbage collectors where many more copies can be generated; iirc the Hotspot VM supports a concurrent GC using a train algorithm). “luckily” it’s impossible to guarantee either one of those (afaik every method call/return introduces a safe point!), so you don’t even get tempted to try (especially considering that I don’t see any way to make sure the JIT doesn’t optimize the zeroing out away) 😉

Seems like the only way to guarantee that the data is stored only in one location is to use the JNI for it.

PS: Note that while the above is only true for the Heap, you can’t guarantee anything more for the stack (the JIT will likely optimize writes without reads to the stack away, so when you return from the function the data will still be on the stack)

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)