mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
tresor: check only the last secured superblock
Instead of iterating over all superblocks and checking each valid one, check only the one whose hash matches the hash stored in the trust anchor. I.e., the last one that was secured to the trust anchor. We must assume that the other superblocks were corrupted in the meantime by operating the Tresor container and, anyway, these Superblocks are not used anymore. Ref #5077
This commit is contained in:
parent
d2af024349
commit
016a769605
@ -43,18 +43,25 @@ class Tresor_check::Main : private Vfs::Env::User
|
||||
Vfs::Simple_env _vfs_env { _env, _heap, _config_rom.xml().sub_node("vfs"), *this };
|
||||
Signal_handler<Main> _sigh { _env.ep(), *this, &Main::_handle_signal };
|
||||
Tresor::Path const _block_io_path { _config_rom.xml().sub_node("block-io").attribute_value("path", Tresor::Path()) };
|
||||
Tresor::Path const _trust_anchor_path { _config_rom.xml().sub_node("trust-anchor").attribute_value("path", Tresor::Path()) };
|
||||
Vfs::Vfs_handle &_block_io_file { open_file(_vfs_env, _block_io_path, Vfs::Directory_service::OPEN_MODE_RDWR) };
|
||||
Vfs::Vfs_handle &_ta_decrypt_file { open_file(_vfs_env, { _trust_anchor_path, "/decrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
|
||||
Vfs::Vfs_handle &_ta_encrypt_file { open_file(_vfs_env, { _trust_anchor_path, "/encrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
|
||||
Vfs::Vfs_handle &_ta_generate_key_file { open_file(_vfs_env, { _trust_anchor_path, "/generate_key" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
|
||||
Vfs::Vfs_handle &_ta_initialize_file { open_file(_vfs_env, { _trust_anchor_path, "/initialize" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
|
||||
Vfs::Vfs_handle &_ta_hash_file { open_file(_vfs_env, { _trust_anchor_path, "/hash" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
|
||||
Block_io _block_io { _block_io_file };
|
||||
Vbd_check _vbd_check { };
|
||||
Ft_check _ft_check { };
|
||||
Sb_check _sb_check { };
|
||||
Trust_anchor _trust_anchor { { _ta_decrypt_file, _ta_encrypt_file, _ta_generate_key_file, _ta_initialize_file, _ta_hash_file } };
|
||||
Sb_check::Check _check_superblocks { };
|
||||
|
||||
void _wakeup_back_end_services() { _vfs_env.io().commit(); }
|
||||
|
||||
void _handle_signal()
|
||||
{
|
||||
while(_sb_check.execute(_check_superblocks, _vbd_check, _ft_check, _block_io));
|
||||
while(_sb_check.execute(_check_superblocks, _vbd_check, _ft_check, _block_io, _trust_anchor));
|
||||
if (_check_superblocks.complete())
|
||||
_env.parent().exit(_check_superblocks.success() ? 0 : -1);
|
||||
_wakeup_back_end_services();
|
||||
|
@ -868,7 +868,7 @@ class Tresor_tester::Main : Vfs::Env::User, Client_data_interface, Crypto_key_fi
|
||||
case Command::IN_PROGRESS:
|
||||
{
|
||||
Sb_check::Check &req = *cmd.check_superblocks_ptr;
|
||||
progress |= _sb_check.execute(req, _vbd_check, _ft_check, _block_io);
|
||||
progress |= _sb_check.execute(req, _vbd_check, _ft_check, _block_io, _trust_anchor);
|
||||
_try_complete_command(cmd, req, progress);
|
||||
break;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <tresor/vbd_check.h>
|
||||
#include <tresor/ft_check.h>
|
||||
#include <tresor/block_io.h>
|
||||
#include <tresor/trust_anchor.h>
|
||||
|
||||
namespace Tresor { class Sb_check; }
|
||||
|
||||
@ -34,23 +35,25 @@ struct Tresor::Sb_check : Noncopyable
|
||||
|
||||
enum State {
|
||||
INIT, COMPLETE, READ_BLK, READ_BLK_SUCCEEDED, CHECK_VBD, CHECK_VBD_SUCCEEDED, CHECK_FT, CHECK_FT_SUCCEEDED,
|
||||
CHECK_MT, CHECK_MT_SUCCEEDED};
|
||||
CHECK_MT, CHECK_MT_SUCCEEDED, READ_SB_HASH, READ_SB_HASH_SUCCEEDED };
|
||||
|
||||
using Helper = Request_helper<Check, State>;
|
||||
|
||||
Helper _helper;
|
||||
Generation _highest_gen { 0 };
|
||||
Superblock_index _highest_gen_sb_idx { 0 };
|
||||
Hash _hash { };
|
||||
bool _scan_for_highest_gen_sb_done { false };
|
||||
Superblock_index _sb_idx { 0 };
|
||||
Superblock_index _sb_idx { };
|
||||
Superblock _sb { };
|
||||
Snapshot_index _snap_idx { 0 };
|
||||
Constructible<Tree_root> _tree_root { };
|
||||
Block _blk { };
|
||||
Generatable_request<Helper, State, Trust_anchor::Read_hash> _read_sb_hash { };
|
||||
Generatable_request<Helper, State, Vbd_check::Check> _check_vbd { };
|
||||
Generatable_request<Helper, State, Ft_check::Check> _check_ft { };
|
||||
Generatable_request<Helper, State, Block_io::Read> _read_block { };
|
||||
|
||||
void _check_snap(bool &);
|
||||
|
||||
public:
|
||||
|
||||
Check() : _helper(*this) { }
|
||||
@ -59,7 +62,7 @@ struct Tresor::Sb_check : Noncopyable
|
||||
|
||||
void print(Output &out) const { Genode::print(out, "check"); }
|
||||
|
||||
bool execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io);
|
||||
bool execute(Vbd_check &, Ft_check &, Block_io &, Trust_anchor &);
|
||||
|
||||
bool complete() const { return _helper.complete(); }
|
||||
bool success() const { return _helper.success(); }
|
||||
@ -67,7 +70,7 @@ struct Tresor::Sb_check : Noncopyable
|
||||
|
||||
Sb_check() { }
|
||||
|
||||
bool execute(Check &check, Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io) { return check.execute(vbd_check, ft_check, block_io); };
|
||||
bool execute(Check &check, Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io, Trust_anchor &trust_anchor) { return check.execute(vbd_check, ft_check, block_io, trust_anchor); };
|
||||
|
||||
static constexpr char const *name() { return "sb_check"; }
|
||||
};
|
||||
|
@ -13,62 +13,62 @@
|
||||
|
||||
/* tresor includes */
|
||||
#include <tresor/sb_check.h>
|
||||
#include <tresor/hash.h>
|
||||
|
||||
using namespace Tresor;
|
||||
|
||||
bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io)
|
||||
void Sb_check::Check::_check_snap(bool &progress)
|
||||
{
|
||||
Snapshot &snap { _sb.snapshots.items[_snap_idx] };
|
||||
if (!snap.valid) {
|
||||
_helper.state = CHECK_VBD_SUCCEEDED;
|
||||
progress = true;
|
||||
if (VERBOSE_CHECK)
|
||||
log(" skip snap ", _snap_idx, " as it is unused");
|
||||
return;
|
||||
}
|
||||
_tree_root.construct(snap.pba, snap.gen, snap.hash, snap.max_level, _sb.degree, snap.nr_of_leaves);
|
||||
_check_vbd.generate(_helper, CHECK_VBD, CHECK_VBD_SUCCEEDED, progress, *_tree_root);
|
||||
if (VERBOSE_CHECK)
|
||||
log(" check snap ", _snap_idx, " (", snap, ")");
|
||||
}
|
||||
|
||||
|
||||
bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io &block_io, Trust_anchor &trust_anchor)
|
||||
{
|
||||
bool progress = false;
|
||||
switch (_helper.state) {
|
||||
case INIT:
|
||||
|
||||
_highest_gen = 0;
|
||||
_highest_gen_sb_idx = 0;
|
||||
_snap_idx = 0;
|
||||
_sb_idx = 0;
|
||||
_scan_for_highest_gen_sb_done = false;
|
||||
_read_sb_hash.generate(_helper, READ_SB_HASH, READ_SB_HASH_SUCCEEDED, progress, _hash);
|
||||
break;
|
||||
|
||||
case READ_SB_HASH: progress |= _read_sb_hash.execute(trust_anchor); break;
|
||||
case READ_SB_HASH_SUCCEEDED:
|
||||
|
||||
_read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, _sb_idx, _blk);
|
||||
break;
|
||||
|
||||
case READ_BLK: progress |= _read_block.execute(block_io); break;
|
||||
case READ_BLK_SUCCEEDED:
|
||||
|
||||
_sb.decode_from_blk(_blk);
|
||||
if (_scan_for_highest_gen_sb_done) {
|
||||
if (check_hash(_blk, _hash)) {
|
||||
_sb.decode_from_blk(_blk);
|
||||
if (VERBOSE_CHECK)
|
||||
log("check superblock ", _sb_idx, " hash ", _hash, "\n read superblock");
|
||||
|
||||
if (!_sb.valid()) {
|
||||
_helper.mark_failed(progress, "no valid superblock");;
|
||||
_helper.mark_failed(progress, "superblock marked invalid");;
|
||||
break;
|
||||
}
|
||||
Snapshot &snap { _sb.snapshots.items[_snap_idx] };
|
||||
if (snap.valid) {
|
||||
Snapshot &snap { _sb.snapshots.items[_snap_idx] };
|
||||
_tree_root.construct(snap.pba, snap.gen, snap.hash, snap.max_level, _sb.degree, snap.nr_of_leaves);
|
||||
_check_vbd.generate(_helper, CHECK_VBD, CHECK_VBD_SUCCEEDED, progress, *_tree_root);
|
||||
if (VERBOSE_CHECK)
|
||||
log(" check snap ", _snap_idx, " (", snap, ")");
|
||||
} else {
|
||||
_helper.state = CHECK_VBD_SUCCEEDED;
|
||||
progress = true;
|
||||
if (VERBOSE_CHECK)
|
||||
log(" skip snap ", _snap_idx, " as it is unused");
|
||||
}
|
||||
} else {
|
||||
Snapshot &snap { _sb.curr_snap() };
|
||||
if (_sb.valid() && snap.gen > _highest_gen) {
|
||||
_highest_gen = snap.gen;
|
||||
_highest_gen_sb_idx = _sb_idx;
|
||||
}
|
||||
_snap_idx = 0;
|
||||
_check_snap(progress);
|
||||
} else
|
||||
if (_sb_idx < MAX_SUPERBLOCK_INDEX) {
|
||||
_sb_idx++;
|
||||
_read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, _sb_idx, _blk);
|
||||
progress = true;
|
||||
} else {
|
||||
_scan_for_highest_gen_sb_done = true;
|
||||
_read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, _highest_gen_sb_idx, _blk);
|
||||
if (VERBOSE_CHECK)
|
||||
log("check superblock ", _highest_gen_sb_idx, "\n read superblock");
|
||||
}
|
||||
}
|
||||
} else
|
||||
_helper.mark_failed(progress, "superblock not found");
|
||||
break;
|
||||
|
||||
case CHECK_VBD: progress |= _check_vbd.execute(vbd_check, block_io); break;
|
||||
@ -76,10 +76,8 @@ bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io
|
||||
|
||||
if (_snap_idx < MAX_SNAP_IDX) {
|
||||
_snap_idx++;
|
||||
_helper.state = READ_BLK_SUCCEEDED;
|
||||
progress = true;
|
||||
_check_snap(progress);
|
||||
} else {
|
||||
_snap_idx = 0;
|
||||
_tree_root.construct(_sb.free_number, _sb.free_gen, _sb.free_hash, _sb.free_max_level, _sb.free_degree, _sb.free_leaves);
|
||||
_check_ft.generate(_helper, CHECK_FT, CHECK_FT_SUCCEEDED, progress, *_tree_root);
|
||||
if (VERBOSE_CHECK)
|
||||
|
Loading…
x
Reference in New Issue
Block a user