Skip to content
Permalink
Browse files

fix(debug): untrack memory allocation before free call

This fixes an ISE that can happen when:

- the memory address of the freed allocation is reused by a malloc in another thread
- the track call in the allocating thread happens before the untrack call in the freeing thread
  • Loading branch information...
Spasi committed Aug 10, 2017
1 parent f21c4e7 commit c8cd8b51f66a9c8287dd2b8b0236575c32da06fb
Showing with 24 additions and 12 deletions.
  1. +24 −12 modules/core/src/main/java/org/lwjgl/system/MemoryManage.java
@@ -121,26 +121,36 @@ public long calloc(long num, long size) {

@Override
public long realloc(long ptr, long size) {
/*
realloc semantics:
a) if size == 0 and ptr != NULL => free(ptr), return NULL
b) if size != 0 and ptr == NULL => malloc(size), return new address
c) if ptr != NULL and size < oldSize =>
1) reduce size, return ptr
2) malloc new address, memcpy, free(ptr), return new address
d) if ptr != NULL and oldSize < size =>
1) expand size, return ptr
2) malloc new address, memcpy, free(ptr), return new address
3) malloc fails, return NULL
*/

long oldSize = untrack(ptr);

long address = allocator.realloc(ptr, size);

if (size == 0L) {
if (ptr != NULL) {
untrack(ptr);
}
} else if (address != NULL) {
if (ptr != NULL) {
untrack(ptr);
}
if (address != NULL) {
track(address, size);
} else if (size != 0L) {
track(ptr, oldSize); // d3
}

return address;
}

@Override
public void free(long ptr) {
allocator.free(ptr);
untrack(ptr);
allocator.free(ptr);
}

@Override
@@ -150,8 +160,8 @@ public long aligned_alloc(long alignment, long size) {

@Override
public void aligned_free(long ptr) {
allocator.aligned_free(ptr);
untrack(ptr);
allocator.aligned_free(ptr);
}

static long track(long address, long size) {
@@ -171,15 +181,17 @@ static long track(long address, long size) {
return address;
}

static void untrack(long address) {
static long untrack(long address) {
if (address == NULL) {
return;
return 0L;
}

Allocation allocation = ALLOCATIONS.remove(address);
if (allocation == null) {
throw new IllegalStateException("The memory address specified is not being tracked");
}

return allocation.size;
}

private static class Allocation {

0 comments on commit c8cd8b5

Please sign in to comment.
You can’t perform that action at this time.