kernel/slab: Add checks to object_cache_alloc for 0xdeadbeef.
We should always find it if PARANOID_KERNEL_FREE is enabled and the object size is at least 2 pointers.
This commit is contained in:
@@ -159,6 +159,7 @@ ObjectCache::InitSlab(slab* slab, void* pages, size_t byteCount, uint32 flags)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fill_freed_block(data, object_size);
|
||||||
slab->free.Push(object_to_link(data, object_size));
|
slab->free.Push(object_to_link(data, object_size));
|
||||||
|
|
||||||
ADD_PARANOIA_CHECK(PARANOIA_SUSPICIOUS, slab,
|
ADD_PARANOIA_CHECK(PARANOIA_SUSPICIOUS, slab,
|
||||||
|
|||||||
@@ -1240,59 +1240,63 @@ object_cache_set_minimum_reserve(object_cache* cache, size_t objectCount)
|
|||||||
void*
|
void*
|
||||||
object_cache_alloc(object_cache* cache, uint32 flags)
|
object_cache_alloc(object_cache* cache, uint32 flags)
|
||||||
{
|
{
|
||||||
if (!(cache->flags & CACHE_NO_DEPOT)) {
|
void* object = NULL;
|
||||||
void* object = object_depot_obtain(&cache->depot);
|
if ((cache->flags & CACHE_NO_DEPOT) == 0)
|
||||||
if (object) {
|
object = object_depot_obtain(&cache->depot);
|
||||||
add_alloc_tracing_entry(cache, flags, object);
|
|
||||||
return fill_allocated_block(object, cache->object_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MutexLocker locker(cache->lock);
|
if (object == NULL) {
|
||||||
slab* source = NULL;
|
MutexLocker locker(cache->lock);
|
||||||
|
slab* source = NULL;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
source = cache->partial.Head();
|
source = cache->partial.Head();
|
||||||
if (source != NULL)
|
if (source != NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
source = cache->empty.RemoveHead();
|
source = cache->empty.RemoveHead();
|
||||||
if (source != NULL) {
|
if (source != NULL) {
|
||||||
cache->empty_count--;
|
cache->empty_count--;
|
||||||
cache->partial.Add(source);
|
cache->partial.Add(source);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object_cache_reserve_internal(cache, 1, flags) != B_OK) {
|
||||||
|
T(Alloc(cache, flags, NULL));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->pressure++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object_cache_reserve_internal(cache, 1, flags) != B_OK) {
|
ParanoiaChecker _2(source);
|
||||||
T(Alloc(cache, flags, NULL));
|
|
||||||
return NULL;
|
slab_queue_link* link = source->free.Pop();
|
||||||
|
source->count--;
|
||||||
|
cache->used_count++;
|
||||||
|
|
||||||
|
if (cache->total_objects - cache->used_count < cache->min_object_reserve)
|
||||||
|
increase_object_reserve(cache);
|
||||||
|
|
||||||
|
REMOVE_PARANOIA_CHECK(PARANOIA_SUSPICIOUS, source, &link->next,
|
||||||
|
sizeof(void*));
|
||||||
|
|
||||||
|
TRACE_CACHE(cache, "allocate %p (%p) from %p, %lu remaining.",
|
||||||
|
link_to_object(link, cache->object_size), link, source, source->count);
|
||||||
|
|
||||||
|
if (source->count == 0) {
|
||||||
|
cache->partial.Remove(source);
|
||||||
|
cache->full.Add(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->pressure++;
|
object = link_to_object(link, cache->object_size);
|
||||||
|
locker.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
ParanoiaChecker _2(source);
|
#if PARANOID_KERNEL_FREE
|
||||||
|
if (cache->object_size >= (sizeof(void*) * 2)) {
|
||||||
slab_queue_link* link = source->free.Pop();
|
ASSERT_ALWAYS(*(uint32*)object == 0xdeadbeef);
|
||||||
source->count--;
|
|
||||||
cache->used_count++;
|
|
||||||
|
|
||||||
if (cache->total_objects - cache->used_count < cache->min_object_reserve)
|
|
||||||
increase_object_reserve(cache);
|
|
||||||
|
|
||||||
REMOVE_PARANOIA_CHECK(PARANOIA_SUSPICIOUS, source, &link->next,
|
|
||||||
sizeof(void*));
|
|
||||||
|
|
||||||
TRACE_CACHE(cache, "allocate %p (%p) from %p, %lu remaining.",
|
|
||||||
link_to_object(link, cache->object_size), link, source, source->count);
|
|
||||||
|
|
||||||
if (source->count == 0) {
|
|
||||||
cache->partial.Remove(source);
|
|
||||||
cache->full.Add(source);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
void* object = link_to_object(link, cache->object_size);
|
|
||||||
locker.Unlock();
|
|
||||||
|
|
||||||
add_alloc_tracing_entry(cache, flags, object);
|
add_alloc_tracing_entry(cache, flags, object);
|
||||||
return fill_allocated_block(object, cache->object_size);
|
return fill_allocated_block(object, cache->object_size);
|
||||||
|
|||||||
Reference in New Issue
Block a user