mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 07:08:18 +00:00
slab: detect corrupted slab and invalid frees
and report about that. Fixes #2350
This commit is contained in:
committed by
Christian Helmuth
parent
62c59a56d1
commit
1c79ba4182
@ -23,6 +23,8 @@ using namespace Genode;
|
||||
*/
|
||||
class Genode::Slab::Block
|
||||
{
|
||||
friend struct Genode::Slab::Entry;
|
||||
|
||||
public:
|
||||
|
||||
Block *next = this; /* next block in ring */
|
||||
@ -71,6 +73,12 @@ class Genode::Slab::Block
|
||||
*/
|
||||
int _slab_entry_idx(Entry *e);
|
||||
|
||||
/**
|
||||
* These functions are called by Slab::Entry.
|
||||
*/
|
||||
void inc_avail(Entry &e);
|
||||
void dec_avail() { _avail--; }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -96,12 +104,6 @@ class Genode::Slab::Block
|
||||
* Return a used slab block entry
|
||||
*/
|
||||
Entry *any_used_entry();
|
||||
|
||||
/**
|
||||
* These functions are called by Slab::Entry.
|
||||
*/
|
||||
void inc_avail(Entry &e);
|
||||
void dec_avail() { _avail--; }
|
||||
};
|
||||
|
||||
|
||||
@ -124,6 +126,9 @@ struct Genode::Slab::Entry
|
||||
block.inc_avail(*this);
|
||||
}
|
||||
|
||||
bool used() {
|
||||
return block._state(block._slab_entry_idx(this)) == Block::USED; }
|
||||
|
||||
/**
|
||||
* Lookup Entry by given address
|
||||
*
|
||||
@ -317,8 +322,8 @@ bool Slab::alloc(size_t size, void **out_addr)
|
||||
|
||||
/* too large for us ? */
|
||||
if (size > _slab_size) {
|
||||
Genode::error("requested size ", size, " is larger then slab size ",
|
||||
_slab_size);
|
||||
error("requested size ", size, " is larger then slab size ",
|
||||
_slab_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -370,8 +375,20 @@ void Slab::_free(void *addr)
|
||||
if (!e)
|
||||
return;
|
||||
|
||||
if (addr < (void *)((addr_t)&e->block + sizeof(e->block)) ||
|
||||
addr >= (void *)((addr_t)&e->block + _block_size)) {
|
||||
error("slab block ", Hex_range<addr_t>((addr_t)&e->block, _block_size),
|
||||
" is corrupt - slab address ", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
Block &block = e->block;
|
||||
|
||||
if (!e->used()) {
|
||||
error("slab address ", addr, " freed which is unused");
|
||||
return;
|
||||
}
|
||||
|
||||
e->~Entry();
|
||||
_total_avail++;
|
||||
|
||||
|
Reference in New Issue
Block a user