Check ownership when freeing RAM dataspaces

This commit is contained in:
Martin Stein 2012-04-20 10:59:41 +02:00 committed by Norman Feske
parent d6f956e37e
commit 3236395e6a
4 changed files with 47 additions and 12 deletions

View File

@ -27,6 +27,11 @@
namespace Genode {
/**
* Deriving classes can own a dataspace to implement conditional behavior
*/
class Dataspace_owner { };
class Dataspace_component : public Rpc_object<Linux_dataspace>
{
private:
@ -36,18 +41,25 @@ namespace Genode {
Filename _fname; /* filename for mmap */
bool _writable; /* false if read-only */
/* Holds the dataspace owner if a distinction between owner and
* others is necessary on the dataspace, otherwise it is 0 */
Dataspace_owner * _owner;
public:
/**
* Constructor
*/
Dataspace_component(size_t size, addr_t addr, bool writable)
: _size(size), _addr(addr), _writable(writable) { }
Dataspace_component(size_t size, addr_t addr, bool writable,
Dataspace_owner * owner = 0)
: _size(size), _addr(addr), _writable(writable),
_owner(owner) { }
/**
* Default constructor returns invalid dataspace
*/
Dataspace_component() : _size(0), _addr(0), _writable(false) { }
Dataspace_component() : _size(0), _addr(0), _writable(false),
_owner(0) { }
/**
* This constructor is only provided for compatibility
@ -55,8 +67,8 @@ namespace Genode {
*/
Dataspace_component(size_t size, addr_t core_local_addr,
addr_t phys_addr, bool write_combined,
bool writable)
: _size(size), _addr(phys_addr)
bool writable, Dataspace_owner * _owner = 0)
: _size(size), _addr(phys_addr), _owner(_owner)
{
PWRN("Should only be used for IOMEM and not within Linux.");
}
@ -70,6 +82,10 @@ namespace Genode {
*/
void fname(const char *fname) { strncpy(_fname.buf, fname, sizeof(_fname.buf)); }
/**
* Check if dataspace is owned by a specified object
*/
bool owner(Dataspace_owner * const o) const { return _owner == o; }
/*************************
** Dataspace interface **

View File

@ -29,6 +29,11 @@ namespace Genode {
class Rm_region;
class Rm_session_component;
/**
* Deriving classes can own a dataspace to implement conditional behavior
*/
class Dataspace_owner { };
class Dataspace_component : public Rpc_object<Dataspace>
{
private:
@ -43,6 +48,10 @@ namespace Genode {
List<Rm_region> _regions; /* regions this is attached to */
Lock _lock;
/* Holds the dataspace owner if a distinction between owner and
* others is necessary on the dataspace, otherwise it is 0 */
Dataspace_owner * _owner;
protected:
bool _managed; /* true if this is a managed dataspace */
@ -62,17 +71,19 @@ namespace Genode {
Dataspace_component()
: _phys_addr(0), _core_local_addr(0), _size(0),
_is_io_mem(false), _write_combined(false), _writable(false),
_managed(false) { }
_owner(0), _managed(false) { }
/**
* Constructor for non-I/O dataspaces
*
* This constructor is used by RAM and ROM dataspaces.
*/
Dataspace_component(size_t size, addr_t core_local_addr, bool writable)
Dataspace_component(size_t size, addr_t core_local_addr,
bool writable,
Dataspace_owner * owner = 0)
: _phys_addr(core_local_addr), _core_local_addr(core_local_addr),
_size(round_page(size)), _is_io_mem(false), _write_combined(false),
_writable(writable), _managed(false) { }
_writable(writable), _owner(owner), _managed(false) { }
/**
* Constructor for dataspaces with different core-local and
@ -86,10 +97,11 @@ namespace Genode {
*/
Dataspace_component(size_t size, addr_t core_local_addr,
addr_t phys_addr, bool write_combined,
bool writable)
bool writable,
Dataspace_owner * owner = 0)
: _phys_addr(phys_addr), _core_local_addr(core_local_addr),
_size(size), _is_io_mem(true), _write_combined(write_combined),
_writable(writable), _managed(false) { }
_writable(writable), _owner(owner), _managed(false) { }
/**
* Destructor
@ -123,6 +135,11 @@ namespace Genode {
void attached_to(Rm_region *region);
void detached_from(Rm_region *region);
/**
* Check if dataspace is owned by a specific owner
*/
bool owner(Dataspace_owner * const o) const { return _owner == o; }
List<Rm_region> *regions() { return &_regions; }
/*************************

View File

@ -29,7 +29,8 @@ namespace Genode {
typedef List<Ram_session_component> Ram_ref_account_members;
class Ram_session_component : public Rpc_object<Ram_session>,
public Ram_ref_account_members::Element
public Ram_ref_account_members::Element,
public Dataspace_owner
{
private:

View File

@ -27,6 +27,7 @@ static const bool verbose = false;
void Ram_session_component::_free_ds(Dataspace_component *ds)
{
if (!ds) return;
if (!ds->owner(this)) return;
size_t ds_size = ds->size();
@ -153,7 +154,7 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size)
Dataspace_component *ds;
try {
ds = new (&_ds_slab) Dataspace_component(ds_size, (addr_t)ds_addr, true);
ds = new (&_ds_slab) Dataspace_component(ds_size, (addr_t)ds_addr, true, this);
} catch (Allocator::Out_of_memory) {
PWRN("Could not allocate metadata");
throw Out_of_metadata();