Skip to content

Commit

Permalink
fixup! [LibOS] Single-process-lifetime rollback protection for protec…
Browse files Browse the repository at this point in the history
…ted files (WIP)

Signed-off-by: g2flyer <michael.steiner@intel.com>
  • Loading branch information
g2flyer committed May 22, 2024
1 parent 11d4bb0 commit ee4c0c4
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 79 deletions.
20 changes: 8 additions & 12 deletions libos/include/libos_fs_encrypted.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ bool read_encrypted_files_key(struct libos_encrypted_files_key* key, pf_key_t* p
*/
void update_encrypted_files_key(struct libos_encrypted_files_key* key, const pf_key_t* pf_key);

/*
* \brief Register a volume.
*
* Registers passed volume -- assumed to be initialized, in particular with valid mount_point_path
* -- in global list of mounted volumes. Returns an error if a volume with identical
* mount_point_path already exists.
*/
int register_encrypted_volume(struct libos_encrypted_volume* volume);
/*
* \brief Retrieve a volume.
*
Expand All @@ -164,18 +172,6 @@ struct libos_encrypted_volume* get_encrypted_volume(const char* mount_point_path
int list_encrypted_volumes(int (*callback)(struct libos_encrypted_volume* volume, void* arg),
void* arg);

/*
* \brief Create a volume.
*
* Sets `*out_volume` to a volume with given mount_point_path. If the volume has not been created
* yet, creates a new one (with mount_point_path and list only fields initialized!).
* out_created is set to whether volume is newly created or not.
*
* Similar to `get_encrypted_volumes`, this does not pass ownership of `*out_volume`.
*/
int get_or_create_encrypted_volume(const char* mount_point_path,
struct libos_encrypted_volume** out_volume, bool* out_created);

/*
* \brief Open an existing encrypted file.
*
Expand Down
32 changes: 22 additions & 10 deletions libos/src/fs/chroot/encrypted.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,36 @@ static int chroot_encrypted_mount(struct libos_mount_params* params, void** moun
}

struct libos_encrypted_volume* volume;
bool created;
ret = get_or_create_encrypted_volume(params->path, &volume, &created);
if (ret < 0)
return ret;
if (!created) {
log_error("Volume '%s' is already mounted", params->path);
return -EEXIST;
volume = calloc(1, sizeof(*volume));
if (!volume)
return -ENOMEM;
volume->mount_point_path = strdup(params->path);
if (!volume->mount_point_path) {
ret = -ENOMEM;
goto err;
}
volume->protection_mode = protection_mode;
volume->key = key;
volume->key = key;
if (!create_lock(&volume->files_state_map_lock)) {
free(volume);
return -ENOMEM;
ret = -ENOMEM;
goto err;
}
volume->files_state_map = NULL;

ret = register_encrypted_volume(volume);
if (ret < 0)
goto err;

*mount_data = volume;
return 0;
err:
if (volume) {
if (lock_created(&volume->files_state_map_lock))
destroy_lock(&volume->files_state_map_lock);
free(volume->mount_point_path);
}
free(volume);
return ret;
}

static ssize_t chroot_encrypted_checkpoint(void** checkpoint, void* mount_data) {
Expand Down
104 changes: 47 additions & 57 deletions libos/src/fs/libos_fs_encrypted.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,43 +552,19 @@ static struct libos_encrypted_volume* get_volume(const char* mount_point_path) {
return NULL;
}

static struct libos_encrypted_volume* get_or_create_volume(const char* mount_point_path,
bool* out_created) {
assert(locked(&g_volumes_lock));

struct libos_encrypted_volume* volume = get_volume(mount_point_path);
if (volume) {
*out_created = false;
return volume;
}
int register_encrypted_volume(struct libos_encrypted_volume* volume) {
assert(volume && volume->mount_point_path);

volume = calloc(1, sizeof(*volume));
if (!volume)
return NULL;
volume->mount_point_path = strdup(mount_point_path);
if (!volume->mount_point_path) {
free(volume);
return NULL;
}
LISTP_ADD_TAIL(volume, &g_volumes, list);
*out_created = true;
return volume;
}

int get_or_create_encrypted_volume(const char* mount_point_path,
struct libos_encrypted_volume** out_volume, bool* out_created) {
lock(&g_volumes_lock);

int ret;
int ret = 0;

struct libos_encrypted_volume* volume = get_or_create_volume(mount_point_path, out_created);
if (!volume) {
ret = -ENOMEM;
struct libos_encrypted_volume* existing_volume = get_volume(volume->mount_point_path);
if (existing_volume) {
ret = -EEXIST;
goto out;
}

*out_volume = volume;
ret = 0;
LISTP_ADD_TAIL(volume, &g_volumes, list);
out:
unlock(&g_volumes_lock);
return ret;
Expand Down Expand Up @@ -983,7 +959,9 @@ BEGIN_RS_FUNC(encrypted_files_key) {
}
END_RS_FUNC(encrypted_files_key)

/* Checkpoint the `g_volumes` list. */
/* Checkpoint the `g_volumes` list. Note we only call this to checkpoint all volumes. The list
* itself is not checkpointed (and hence also no corresponding restore function). The list is
* reconstructed in the restore function of the volumes itself. */
BEGIN_CP_FUNC(all_encrypted_volumes) {
__UNUSED(size);
__UNUSED(obj);
Expand All @@ -1005,44 +983,56 @@ BEGIN_CP_FUNC(encrypted_volume) {
struct libos_encrypted_volume* volume = obj;
struct libos_encrypted_volume* new_volume = NULL;

size_t off = ADD_CP_OFFSET(sizeof(struct libos_encrypted_volume));

new_volume = (struct libos_encrypted_volume*)(base + off);

// TODO (MST): do something with remaining fields of struct
log_debug("CP(encrypted_volume): protection_mode=%d file_state_mape=%p",
volume->protection_mode, volume->files_state_map); // TODO (MST): DEBUG
// - protection_mode -> automatically copied
// - files_state_map
// - files_state_map_lock

lock(&g_keys_lock);
DO_CP_MEMBER(encrypted_files_key, volume, new_volume, key);
unlock(&g_keys_lock);

ADD_CP_FUNC_ENTRY(off);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) { /* We haven't already checkpointed this volume */
off = ADD_CP_OFFSET(sizeof(struct libos_encrypted_volume));
ADD_TO_CP_MAP(obj, off);
new_volume = (struct libos_encrypted_volume*)(base + off);

// TODO (MST): do something with remaining fields of struct
log_debug("CP(encrypted_volume): mount_point_path=%s protection_mode=%d file_state_mape=%p",
volume->mount_point_path, volume->protection_mode,
volume->files_state_map); // TODO (MST): DEBUG
DO_CP_MEMBER(str, volume, new_volume, mount_point_path);
new_volume->protection_mode = volume->protection_mode;
lock(&volume->files_state_map_lock);
// - files_state_map -> TODO, should be locked
unlock(&volume->files_state_map_lock);
// files_state_map_lock has no check point, it will be recreated in restore
lock(&g_keys_lock);
DO_CP_MEMBER(encrypted_files_key, volume, new_volume, key);
unlock(&g_keys_lock);
INIT_LIST_HEAD(new_volume, list);

ADD_CP_FUNC_ENTRY(off);
} else {
new_volume = (struct libos_encrypted_volume*)(base + off);
}
if (objp)
*objp = (void*)new_volume;
}
END_CP_FUNC(encrypted_volume)

// TODO (MST): revisit below, probably not correct?!
BEGIN_RS_FUNC(encrypted_volume) {
struct libos_encrypted_volume* volume = (void*)(base + GET_CP_FUNC_ENTRY());
__UNUSED(offset);
struct libos_encrypted_volume* migrated_volume = (void*)(base + GET_CP_FUNC_ENTRY());

CP_REBASE(migrated_volume->mount_point_path);

// TODO (MST): do something with remaining fields of struct
log_debug("RS(encrypted_volume): protection_mode=%d file_state_mape=%p",
volume->protection_mode, volume->files_state_map); // TODO (MST): DEBUG
// - protection_mode -> automatically copied
// - files_state_map
// - files_state_map_lock
if (!create_lock(&volume->files_state_map_lock)) {
// protection_mode needs no restore action
// files_state_map: TODO
if (!create_lock(&migrated_volume->files_state_map_lock)) {
return -ENOMEM;
}
CP_REBASE(migrated_volume->key);
log_debug("RS(encrypted_volume): mount_point_path=%s protection_mode=%d file_state_mape=%p",
migrated_volume->mount_point_path, migrated_volume->protection_mode,
migrated_volume->files_state_map); // TODO (MST): DEBUG

CP_REBASE(volume->key);
int ret = register_encrypted_volume(migrated_volume);
if (ret < 0)
return ret;
}
END_RS_FUNC(encrypted_volume)

Expand Down

0 comments on commit ee4c0c4

Please sign in to comment.