Skip to content
This repository has been archived by the owner on Apr 23, 2019. It is now read-only.

Fixes memory leak when decrypting scuttlebutt incoming messages #209

Merged
merged 5 commits into from
Apr 7, 2019

Conversation

Happy0
Copy link
Contributor

@Happy0 Happy0 commented Apr 5, 2019

I believe this changes fixes #205 .

I think this was happening because the underlying JNI Pointer for the header and body nonces weren't being freed until the garbage collector destroyed the objects which no longer had any references. Until the garbage collector destroyed them, the lib sodium malloc would periodically fail because there wasn't enough memory available to malloc - but once the garbage collector called destroy on the objects memory became free to allocate again, and the decryption would start succeeding again.

Note: this is just a theory from reading the code (i'm not sure how I'd test it empirically) but the changes appear to stop the error happening.

This change also means that if the decryption fails due to a lib sodium error, a StreamException will be thrown and the underlying socket (scuttlebutt connection) will be closed.

@@ -271,6 +271,7 @@ static Pointer dup(byte[] bytes) {

static <T> T dup(byte[] bytes, BiFunction<Pointer, Integer, T> ctr) {
Pointer ptr = Sodium.dup(bytes);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra blank line


}
} catch (Exception e) {
throw new StreamException(e.getMessage());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be more specific - Exception is very broad.
Also can we throw StreamException(e) so we get the whole stacktrace?

@Happy0
Copy link
Contributor Author

Happy0 commented Apr 5, 2019

thanks @atoulme - done :)

@@ -193,7 +193,7 @@ public Bytes bytes() {
/**
* A SecretBox nonce.
*/
public static final class Nonce {
public static final class Nonce implements AutoCloseable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I agree with making a Nonce "auto closeable". It's not a resource, so it feels odd to treat it like one. We could certainly make it implement Destroyable, just like the secret keys.

However, whatever we do, it must be applied consistently across all cava-sodium types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cleishm - I see where you're coming from. I've pushed a new commit to this PR to implement Destroyable instead.

There's currently a couple of other classes (below) that implement AutoCloseable that aren't 'resources' (like sockets) but on searching, it looks like the majority implement Destroyable like you suggested so I'll follow that convention.

public final class AES256GCM implements AutoCloseable {
public final class Box implements AutoCloseable {

Perhaps these can be made to implement 'destroyable' also in a separate PR instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a different flow. You open a secret box and close it - you don't destroy it. It's more the pointers of the keys and nonces generated along the way we need to clean up.

….Nonce class to be more consistent with the rest of cava.
@atoulme atoulme merged commit b67ae4f into ConsenSysMesh:master Apr 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Periodic sodium OutOfMemory exception when consuming scuttlebutt streams
3 participants