file_vault: clean up

Ref #5190
This commit is contained in:
Martin Stein 2024-04-17 01:17:21 +02:00 committed by Christian Helmuth
parent a7ef2319f6
commit 969469edef
15 changed files with 1070 additions and 2285 deletions

View File

@ -60,12 +60,12 @@ append config {
<resource name="CPU" quantum="5"/>
<provides> <service name="Timer"/> </provides>
<route>
<service name="PD"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="IO_PORT"> <parent/> </service>
<service name="IRQ"> <parent/> </service>
<service name="IRQ"> <parent/> </service>
</route>
</start>
@ -148,9 +148,7 @@ append_if [have_board linux] config {
<service name="File_system"/>
</provides>
<config>
<policy label="file_vault -> data"
root="/file_vault_dir/data"
writeable="yes"/>
<policy label="file_vault -> data" root="/file_vault_dir/data" writeable="yes"/>
</config>
<route>
<service name="Timer"> <child name="timer"/> </service>
@ -168,9 +166,7 @@ append_if [have_board linux] config {
<service name="File_system"/>
</provides>
<config>
<policy label="file_vault -> trust_anchor"
root="/file_vault_dir/trust_anchor"
writeable="yes"/>
<policy label="file_vault -> trust_anchor" root="/file_vault_dir/trust_anchor" writeable="yes"/>
</config>
<route>
<service name="Timer"> <child name="timer"/> </service>
@ -216,7 +212,7 @@ append_if [expr ![have_board linux]] config {
<policy label="file_vault -> trust_anchor" root="/trust_anchor" writeable="yes"/>
</config>
<route>
<service name="PD"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="CPU"> <parent/> </service>
@ -235,21 +231,21 @@ append config {
</vfs>
</config>
<route>
<service name="ROM" label="ui_config"> <child name="dynamic_rom" label="file_vault_ui_config"/> </service>
<service name="Report" label="ui_report"> <child name="report_rom"/> </service>
<service name="ROM" label="ui_config"> <child name="dynamic_rom" label="file_vault_ui_config"/> </service>
<service name="Report" label="ui_report"> <child name="report_rom"/> </service>
<service name="File_system" label="tresor_trust_anchor_vfs -> storage_dir"> <child name="trust_anchor_fs" label="file_vault -> trust_anchor"/> </service>
<service name="File_system" label="tresor_init -> "> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="tresor"> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="fs_query -> "> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="image_fs_query -> "> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="tresor_vfs -> tresor_fs"> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="truncate_file -> tresor"> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="PD"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="RM"> <parent/> </service>
<service name="File_system" label="tresor_init -> "> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="tresor"> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="fs_query -> "> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="image_fs_query -> "> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="tresor_vfs -> tresor_fs"> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="File_system" label="truncate_file -> tresor"> <child name="data_fs" label="file_vault -> data"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="PD"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="RM"> <parent/> </service>
</route>
</start>

View File

@ -1,70 +0,0 @@
/*
* \brief Utility for querying the child-exit state from init's state report
* \author Norman Feske
* \author Martin Stein
* \date 2021-03-05
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CHILD_EXIT_STATE_H_
#define _CHILD_EXIT_STATE_H_
/* Genode includes */
#include <util/xml_node.h>
/* local includes */
#include <types.h>
namespace File_vault {
class Child_exit_state;
}
class File_vault::Child_exit_state
{
public:
typedef String<128> Name;
typedef String<16> Version;
private:
bool _exists = false;
bool _exited = false;
bool _responsive = true;
int _code = 0;
Version _version { };
public:
Child_exit_state(Xml_node init_state, Name const &name)
{
init_state.for_each_sub_node("child", [&] (Xml_node child) {
if (child.attribute_value("name", Name()) == name) {
_exists = true;
_version = child.attribute_value("version", Version());
if (child.has_attribute("exited")) {
_exited = true;
_code = (int)child.attribute_value("exited", 0L);
}
_responsive = (child.attribute_value("skipped_heartbeats", 0U) <= 2);
}
});
}
bool exists() const { return _exists ; }
bool exited() const { return _exited ; }
bool responsive() const { return _responsive ; }
int code() const { return _code ; }
Version version() const { return _version ; }
};
#endif /* _CHILD_EXIT_STATE_H_ */

View File

@ -23,94 +23,46 @@
#include <base/quota_guard.h>
/* local includes */
#include <types.h>
#include <file_vault/types.h>
namespace File_vault {
class Child_state;
}
namespace File_vault { class Child_state; }
class File_vault::Child_state : Noncopyable
{
private:
using Start_name = String<128>;
using Binary_name = String<128>;
using Registry_element = Registry<Child_state>::Element;
struct Version
{
unsigned value;
};
Registry_element _registry_element;
Start_name const _start_name;
Binary_name const _binary_name;
Ram_quota const _initial_ram_quota;
Cap_quota const _initial_cap_quota;
Ram_quota _ram_quota { _initial_ram_quota };
Cap_quota _cap_quota { _initial_cap_quota };
Version _version { 0 };
Registry_element _registry_element;
Child_name const _start_name;
Child_name const _binary_name;
Ram_quota const _initial_ram_quota;
Cap_quota const _initial_cap_quota;
Ram_quota _ram_quota { _initial_ram_quota };
Cap_quota _cap_quota { _initial_cap_quota };
public:
Child_state(Registry<Child_state> &registry,
Start_name const &start_name,
Binary_name const &binary_name,
Ram_quota ram_quota,
Cap_quota cap_quota)
Child_state(Registry<Child_state> &registry, Child_name const &start_name,
Child_name const &binary_name, Ram_quota ram_quota, Cap_quota cap_quota)
:
_registry_element { registry, *this },
_start_name { start_name },
_binary_name { binary_name },
_initial_ram_quota { ram_quota },
_registry_element { registry, *this }, _start_name { start_name },
_binary_name { binary_name }, _initial_ram_quota { ram_quota },
_initial_cap_quota { cap_quota }
{ }
Child_state(Registry<Child_state> &registry,
Start_name const &start_name,
Ram_quota ram_quota,
Cap_quota cap_quota)
:
_registry_element { registry, *this },
_start_name { start_name },
_binary_name { start_name },
_initial_ram_quota { ram_quota },
_initial_cap_quota { cap_quota }
{ }
Child_state(Registry<Child_state> &registry, Child_name const &name, Ram_quota ram_quota, Cap_quota cap_quota)
: Child_state(registry, name, name, ram_quota, cap_quota) { }
void trigger_restart()
void gen_start_node(Xml_generator &xml, auto const &gen_content) const
{
_version.value++;
_ram_quota = _initial_ram_quota;
_cap_quota = _initial_cap_quota;
}
void gen_start_node_version(Xml_generator &xml) const
{
if (_version.value)
xml.attribute("version", _version.value);
}
template <typename GEN_CONTENT>
void gen_start_node(Xml_generator &xml,
GEN_CONTENT const &gen_content) const
{
xml.node("start", [&] () {
xml.attribute("name", _start_name);
gen_named_node(xml, "start", _start_name, [&] {
xml.attribute("caps", _cap_quota.value);
gen_start_node_version(xml);
if (_start_name != _binary_name) {
xml.node("binary", [&] () {
xml.attribute("name", _binary_name);
});
}
xml.node("resource", [&] () {
xml.attribute("name", "RAM");
Number_of_bytes const bytes(_ram_quota.value);
xml.attribute("quantum", String<64>(bytes)); });
if (_start_name != _binary_name)
gen_named_node(xml, "binary", _binary_name, [] { });
gen_named_node(xml, "resource", "RAM", [&] {
xml.attribute("quantum", Number_of_bytes(_ram_quota.value)); });
gen_content();
});
}
@ -118,8 +70,7 @@ class File_vault::Child_state : Noncopyable
bool apply_child_state_report(Xml_node const &child)
{
bool result = false;
if (child.attribute_value("name", Start_name()) != _start_name)
if (child.attribute_value("name", Child_name()) != _start_name)
return false;
if (child.has_sub_node("ram") &&
@ -128,20 +79,18 @@ class File_vault::Child_state : Noncopyable
_ram_quota.value *= 2;
result = true;
}
if (child.has_sub_node("caps") &&
child.sub_node("caps").has_attribute("requested"))
{
_cap_quota.value += 100;
result = true;
}
return result;
}
Ram_quota ram_quota() const { return _ram_quota; }
Start_name start_name() const { return _start_name; }
Child_name start_name() const { return _start_name; }
};
#endif /* _CHILD_STATE_H_ */

View File

@ -1,64 +0,0 @@
/*
* \brief Pointer of const object safe against null dereferencing
* \author Martin Stein
* \date 2021-04-02
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CONST_POINTER_H_
#define _CONST_POINTER_H_
/* local includes */
#include <types.h>
namespace File_vault {
template <typename T>
class Const_pointer;
}
template <typename OBJECT_TYPE>
class File_vault::Const_pointer
{
private:
OBJECT_TYPE const *_object;
public:
struct Invalid : Genode::Exception { };
Const_pointer() : _object { nullptr } { }
Const_pointer(OBJECT_TYPE const &object) : _object { &object } { }
OBJECT_TYPE const &object() const
{
if (_object == nullptr)
throw Invalid();
return *_object;
}
bool valid() const { return _object != nullptr; }
bool operator != (Const_pointer const &other) const
{
if (valid() != other.valid()) {
return true;
}
if (valid()) {
return _object != other._object;
}
return false;
}
};
#endif /* _CONST_POINTER_H_ */

View File

@ -28,18 +28,31 @@ namespace File_vault {
static constexpr Tree_level_index TRESOR_FREE_TREE_MAX_LVL = 5;
static constexpr size_t MIN_CLIENT_FS_SIZE = 100 * 1024;
static constexpr size_t MIN_PASSPHRASE_LENGTH = 8;
static constexpr size_t MIN_CAPACITY = 100 * 1024;
using Node_name = String<32>;
using File_path = String<32>;
using Child_name = String<128>;
struct Number_of_clients { uint64_t value; };
struct Operation_id { uint64_t value; };
void gen_named_node(Xml_generator &xml, char const *type, auto name, auto const &fn)
{
xml.node(type, [&] {
xml.attribute("name", name);
fn(); });
}
using Version_string = String<80>;
template <typename T>
static void read_optional_attr(Xml_node const &node, char const *attr, Constructible<T> &dst)
inline size_t min_journal_buf(Number_of_bytes capacity)
{
if (node.has_attribute(attr))
dst.construct(node.attribute_value(attr, T { }));
size_t result { (size_t)capacity >> 8 };
if (result < MIN_CAPACITY)
result = MIN_CAPACITY;
return result;
}
struct Ui_report

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +0,0 @@
/*
* \brief Report session provided by the Tresor manager
* \author Martin Stein
* \author Norman Feske
* \date 2021-02-25
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _REPORT_SESSION_COMPONENT_H_
#define _REPORT_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/attached_ram_dataspace.h>
#include <base/session_object.h>
#include <report_session/report_session.h>
namespace Report {
using namespace Genode;
class Session_component;
}
class Report::Session_component : public Session_object<Report::Session>
{
public:
struct Handler_base : Interface, Genode::Noncopyable
{
virtual void handle_report(char const *, size_t) = 0;
};
template <typename T>
struct Xml_handler : Handler_base
{
T &_obj;
void (T::*_member) (Xml_node const &);
Xml_handler(T &obj, void (T::*member)(Xml_node const &))
: _obj(obj), _member(member) { }
void handle_report(char const *start, size_t length) override
{
(_obj.*_member)(Xml_node(start, length));
}
};
private:
Attached_ram_dataspace _ds;
Handler_base &_handler;
/*******************************
** Report::Session interface **
*******************************/
Dataspace_capability dataspace() override { return _ds.cap(); }
void submit(size_t length) override
{
_handler.handle_report(_ds.local_addr<char const>(),
min(_ds.size(), length));
}
void response_sigh(Signal_context_capability) override { }
size_t obtain_response() override { return 0; }
public:
template <typename... ARGS>
Session_component(Env &env, Handler_base &handler,
Entrypoint &ep, Resources const &resources,
ARGS &&... args)
:
Session_object(ep, resources, args...),
_ds(env.ram(), env.rm(), resources.ram_quota.value),
_handler(handler)
{ }
};
#endif /* _REPORT_SESSION_COMPONENT_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +0,0 @@
/*
* \brief Pointer of const object safe against null dereferencing
* \author Martin Stein
* \date 2021-04-02
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SNAPSHOT_H_
#define _SNAPSHOT_H_
namespace File_vault {
class Snapshot;
}
class File_vault::Snapshot
{
private:
Generation const _generation;
public:
Snapshot(Generation const &generation)
:
_generation { generation }
{ }
virtual ~Snapshot() { }
/***************
** Accessors **
***************/
Generation const &generation() const { return _generation; }
};
#endif /* _SNAPSHOT_H_ */

View File

@ -11,8 +11,6 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/attached_rom_dataspace.h>
#include <base/component.h>
#include <base/heap.h>
@ -20,31 +18,21 @@
using namespace Genode;
struct Main : private Vfs::Env::User
struct Main : Vfs::Env::User
{
Env &_env;
Heap _heap { _env.ram(), _env.rm() };
Attached_rom_dataspace _config_rom { _env, "config" };
Vfs::Simple_env _vfs_env { _env, _heap,
_config_rom.xml().sub_node("vfs"), *this };
Directory _root_dir { _vfs_env };
Env &env;
Heap heap { env.ram(), env.rm() };
Attached_rom_dataspace config_rom { env, "config" };
Vfs::Simple_env vfs_env { env, heap, config_rom.xml().sub_node("vfs"), *this };
Directory root { vfs_env };
void wakeup_vfs_user() override { }
Main(Env &env) : _env { env }
Main(Env &env) : env(env)
{
{
Append_file { _root_dir,
Directory::Path("/tresor/tresor/current/data") };
}
_env.parent().exit(0);
{ Append_file { root, Directory::Path("/tresor/tresor/current/data") }; }
env.parent().exit(0);
}
};
void Component::construct(Env &env)
{
static Main main(env);
}
void Component::construct(Env &env) { static Main main(env); }

View File

@ -1,10 +1,5 @@
TARGET := file_vault
SRC_CC += main.cc
INC_DIR += $(PRG_DIR)
INC_DIR += $(PRG_DIR) $(PRG_DIR)/include
INC_DIR += $(call select_from_repositories,/src/lib/tresor/include)
LIBS += base sandbox vfs
CC_OPT += -Os

View File

@ -11,75 +11,40 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <base/heap.h>
#include <os/vfs.h>
namespace Truncate_file {
class Main;
}
using namespace Truncate_file;
using namespace Genode;
class Truncate_file::Main
struct Main
{
private:
Env &env;
Heap heap { env.ram(), env.rm() };
Attached_rom_dataspace config { env, "config" };
Root_directory vfs { env, heap, config.xml().sub_node("vfs") };
Vfs::File_system &fs { vfs.root_dir() };
Directory::Path path { config.xml().attribute_value("path", Directory::Path { }) };
Number_of_bytes size { config.xml().attribute_value("size", Number_of_bytes { }) };
Env &_env;
Heap _heap { _env.ram(), _env.rm() };
Attached_rom_dataspace _config { _env, "config" };
Root_directory _vfs { _env, _heap, _config.xml().sub_node("vfs") };
Vfs::File_system &_fs { _vfs.root_dir() };
Directory::Path const _path { _config.xml().attribute_value("path", Directory::Path { }) };
Number_of_bytes const _size { _config.xml().attribute_value("size", Number_of_bytes { }) };
Main(Env &env) : env(env)
{
unsigned mode = Vfs::Directory_service::OPEN_MODE_WRONLY;
Vfs::Directory_service::Stat stat { };
if (fs.stat(path.string(), stat) != Vfs::Directory_service::STAT_OK)
mode |= Vfs::Directory_service::OPEN_MODE_CREATE;
public:
Main(Env &env);
Vfs::Vfs_handle *handle_ptr = nullptr;
auto res = fs.open(path.string(), mode, &handle_ptr, heap);
if (res != Vfs::Directory_service::OPEN_OK || (handle_ptr == nullptr)) {
error("failed to create file '", path, "'");
env.parent().exit(-1);
}
handle_ptr->fs().ftruncate(handle_ptr, size);
handle_ptr->ds().close(handle_ptr);
env.parent().exit(0);
}
};
/*************************
** Truncate_file::Main **
*************************/
Main::Main(Env &env)
:
_env { env }
{
unsigned mode = Vfs::Directory_service::OPEN_MODE_WRONLY;
Vfs::Directory_service::Stat stat { };
if (_fs.stat(_path.string(), stat) != Vfs::Directory_service::STAT_OK) {
mode |= Vfs::Directory_service::OPEN_MODE_CREATE;
}
Vfs::Vfs_handle *handle_ptr = nullptr;
Vfs::Directory_service::Open_result const res =
_fs.open(_path.string(), mode, &handle_ptr, _heap);
if (res != Vfs::Directory_service::OPEN_OK || (handle_ptr == nullptr)) {
error("failed to create file '", _path, "'");
class Create_failed { };
throw Create_failed { };
}
handle_ptr->fs().ftruncate(handle_ptr, _size);
handle_ptr->ds().close(handle_ptr);
_env.parent().exit(0);
}
/***********************
** Genode::Component **
***********************/
void Component::construct(Genode::Env &env)
{
static Truncate_file::Main main { env };
}
void Component::construct(Env &env) { static Main main(env); }

View File

@ -1,4 +1,3 @@
TARGET := file_vault-truncate_file
SRC_CC += main.cc
INC_DIR += $(PRG_DIR)/..
LIBS += base vfs

View File

@ -1,51 +0,0 @@
/*
* \brief Common types
* \author Martin Stein
* \date 2021-02-25
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _TYPES_H_
#define _TYPES_H_
/* Genode includes */
#include <include/file_vault/types.h>
namespace File_vault {
using Node_name = String<32>;
using File_path = String<32>;
class Tree_geometry
{
private:
uint64_t const _nr_of_levels;
uint64_t const _nr_of_children;
uint64_t const _nr_of_leaves;
public:
Tree_geometry(
uint64_t nr_of_levels,
uint64_t nr_of_children,
uint64_t nr_of_leaves)
:
_nr_of_levels { nr_of_levels },
_nr_of_children { nr_of_children },
_nr_of_leaves { nr_of_leaves }
{ }
uint64_t nr_of_levels() const { return _nr_of_levels ; }
uint64_t nr_of_children() const { return _nr_of_children; }
uint64_t nr_of_leaves() const { return _nr_of_leaves ; }
};
}
#endif /* _TYPES_H_ */

View File

@ -221,8 +221,6 @@ struct Main : Prompt::Action
struct Setup_frame : Widget<Frame>
{
enum { MIN_CAPACITY = 100 * 1024 };
enum Prompt_type { PASSPHRASE, CAPACITY, JOURNALING_BUFFER };
Main &main;
@ -235,20 +233,11 @@ struct Main : Prompt::Action
Setup_frame(Main &main) : main(main) { }
size_t min_journal_buf() const
{
size_t result { (size_t)capacity.as_num_bytes() >> 8 };
if (result < MIN_CAPACITY)
result = MIN_CAPACITY;
return result;
}
bool passphrase_long_enough() const { return passphrase.text.length() >= MIN_PASSPHRASE_LENGTH + 1; }
bool capacity_sufficient() const { return capacity.as_num_bytes() >= MIN_CAPACITY; }
bool journal_buf_sufficient() const { return journal_buf.as_num_bytes() >= min_journal_buf(); }
bool journal_buf_sufficient() const { return journal_buf.as_num_bytes() >= min_journal_buf(capacity.as_num_bytes()); }
bool ready_to_setup() const { return passphrase_long_enough() && capacity_sufficient() && journal_buf_sufficient(); }
@ -281,7 +270,7 @@ struct Main : Prompt::Action
s.sub_scope<Left_align>(" Journaling buffer: ");
s.widget(journal_buf, selected == JOURNALING_BUFFER);
if (!journal_buf_sufficient())
s.sub_scope<Left_align>(Text(" Minimum: ", min_journal_buf(), " "));
s.sub_scope<Left_align>(Text(" Minimum: ", min_journal_buf(capacity.as_num_bytes()), " "));
if (capacity_sufficient() && journal_buf_sufficient()) {
s.sub_scope<Left_align>("");
@ -664,7 +653,7 @@ struct Main : Prompt::Action
Expanding_reporter ui_config_reporter { env, "ui_config", "ui_config" };
Attached_rom_dataspace ui_report_rom { env, "ui_report" };
Signal_handler<Main> signal_handler { env.ep(), *this, &Main::handle_signal };
Constructible<Ui_report> ui_report { };
Reconstructible<Ui_report> ui_report { };
void handle_event(Dialog::Event const &event)
{