kernel/slab: Fix potential memory leak in HashedObjectCache.
If the resize-needed amount changed while we were allocating memory, then we'd leak the new buffer. In testing, I added an ASSERT() to check if this case actually happened, and it didn't seem to fire when using the system (with a debug kernel though, admittedly.) Inspired by a change suggested on GitHub, but implemented in a completely different way (that cleans up the code at the same time.)
This commit is contained in:
@@ -173,22 +173,26 @@ void
|
|||||||
HashedObjectCache::_ResizeHashTableIfNeeded(uint32 flags)
|
HashedObjectCache::_ResizeHashTableIfNeeded(uint32 flags)
|
||||||
{
|
{
|
||||||
size_t hashSize = hash_table.ResizeNeeded();
|
size_t hashSize = hash_table.ResizeNeeded();
|
||||||
if (hashSize != 0) {
|
if (hashSize == 0)
|
||||||
Unlock();
|
return;
|
||||||
void* buffer = slab_internal_alloc(hashSize, flags);
|
|
||||||
Lock();
|
|
||||||
|
|
||||||
if (buffer != NULL) {
|
Unlock();
|
||||||
if (hash_table.ResizeNeeded() == hashSize) {
|
void* buffer = slab_internal_alloc(hashSize, flags);
|
||||||
void* oldHash;
|
Lock();
|
||||||
hash_table.Resize(buffer, hashSize, true, &oldHash);
|
|
||||||
if (oldHash != NULL) {
|
if (buffer == NULL)
|
||||||
Unlock();
|
return;
|
||||||
slab_internal_free(oldHash, flags);
|
|
||||||
Lock();
|
if (hash_table.ResizeNeeded() == hashSize) {
|
||||||
}
|
void* oldHash = NULL;
|
||||||
}
|
hash_table.Resize(buffer, hashSize, true, &oldHash);
|
||||||
}
|
buffer = oldHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != NULL) {
|
||||||
|
Unlock();
|
||||||
|
slab_internal_free(buffer, flags);
|
||||||
|
Lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user