genode/ports/src/noux/local_rom_service.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

79 lines
1.8 KiB
C++

/*
* \brief ROM service provided to Noux processes
* \author Norman Feske
* \date 2013-07-18
*
* The local ROM service has the sole purpose of tracking ROM dataspaces
* so that they are properly detached from RM sessions when the corresponding
* ROM sessions are closed.
*/
/*
* 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__LOCAL_ROM_SERVICE_H_
#define _NOUX__LOCAL_ROM_SERVICE_H_
/* Genode includes */
#include <base/service.h>
/* Noux includes */
#include <dataspace_registry.h>
#include <rom_session_component.h>
namespace Noux {
class Local_rom_service : public Service
{
private:
Rpc_entrypoint &_ep;
Dataspace_registry &_ds_registry;
public:
Local_rom_service(Rpc_entrypoint &ep, Dataspace_registry &ds_registry)
:
Service(Rom_session::service_name()), _ep(ep),
_ds_registry(ds_registry)
{ }
Genode::Session_capability session(const char *args)
{
enum { NAME_MAX_LEN = 128 };
char name[NAME_MAX_LEN];
Arg_string::find_arg(args, "filename").string(name, sizeof(name), "<noname>");
Rom_session_component *rom = new (env()->heap())
Rom_session_component(_ds_registry, name);
return _ep.manage(rom);
}
void upgrade(Genode::Session_capability, const char *args) { }
void close(Genode::Session_capability session)
{
/* acquire locked session object */
Rom_session_component *rom_session =
dynamic_cast<Rom_session_component *>(_ep.lookup_and_lock(session));
if (!rom_session) {
PWRN("Unexpected call of close with non-ROM-session argument");
return;
}
_ep.dissolve(rom_session);
destroy(env()->heap(), rom_session);
}
};
}
#endif /* _NOUX__LOCAL_ROM_SERVICE_H_ */