genode/ports/src/noux/rom_session_component.h
Norman Feske 956cab5fdb noux: Keep track of how dataspaces are used
This patch eliminates the "no attachment at..." warnings, which
were caused by a use-after-free problem of dataspaces. When a
dataspace was destroyed, the users of the dataspace were not
informed and therefore could not revert possible attachments to
RM sessions. The fix introduces a callback mechanism that allows
dataspace users (i.e., RM regions) to register for the event that
a dataspace vanishes.

The following types of dataspaces are handled:
* RAM dataspaces
* ROM dataspaces
* The process binary
* The binary of the dynamic linker
* Args dataspace
* Sysio dataspace
* Env dataspace
* managed RM dataspaces

The handling of ROM dataspaces is still not complete. When forking,
the ROM dataspace of the parent process gets just reused without
creating proper meta data ('Dataspace_info') for the forked process.
Similar issues might arise from other special dataspaces (e.g.,
args, env, sysio).

This patch removes all "no attachment at..." warnings except for
one (an attachment at 0).

Issue #485
2013-08-06 17:40:10 +02:00

98 lines
2.0 KiB
C++

/*
* \brief ROM session implementation used by Noux processes
* \author Norman Feske
* \date 2013-07-18
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _NOUX__ROM_SESSION_COMPONENT_H_
#define _NOUX__ROM_SESSION_COMPONENT_H_
/* Genode includes */
#include <rom_session/connection.h>
#include <base/rpc_server.h>
namespace Noux {
struct Rom_dataspace_info : Dataspace_info
{
Rom_dataspace_info(Dataspace_capability ds) : Dataspace_info(ds) { }
~Rom_dataspace_info() { }
Dataspace_capability fork(Ram_session_capability,
Dataspace_registry &ds_registry,
Rpc_entrypoint &)
{
return ds_cap();
}
void poke(addr_t dst_offset, void const *src, size_t len)
{
PERR("Attempt to poke onto a ROM dataspace");
}
};
class Rom_session_component : public Rpc_object<Rom_session>
{
private:
/**
* Wrapped ROM session at core
*/
Rom_connection _rom;
Dataspace_registry &_ds_registry;
Rom_dataspace_info _ds_info;
public:
Rom_session_component(Dataspace_registry &ds_registry,
char const *name)
:
_rom(name), _ds_registry(ds_registry), _ds_info(_rom.dataspace())
{
_ds_registry.insert(&_ds_info);
}
~Rom_session_component()
{
/*
* Lookup and lock ds info instead of directly acccessing
* the '_ds_info' member.
*/
Object_pool<Dataspace_info>::Guard
info(_ds_registry.lookup_info(_ds_info.ds_cap()));
if (info)
info->dissolve_users();
else
PERR("~Rom_session_component: unexpected !info");
_ds_registry.remove(&_ds_info);
}
/***************************
** ROM session interface **
***************************/
Rom_dataspace_capability dataspace()
{
return static_cap_cast<Rom_dataspace>(_ds_info.ds_cap());
}
void sigh(Signal_context_capability) { }
};
}
#endif /* _NOUX__ROM_SESSION_COMPONENT_H_ */