Skip to content

Commit 17d0062

Browse files
committed
fixup! [LibOS] Single-process-lifetime rollback protection for protected files (WIP)
Signed-off-by: g2flyer <[email protected]>
1 parent 11d4bb0 commit 17d0062

File tree

4 files changed

+77
-79
lines changed

4 files changed

+77
-79
lines changed

libos/include/libos_fs_encrypted.h

+8-12
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ bool read_encrypted_files_key(struct libos_encrypted_files_key* key, pf_key_t* p
146146
*/
147147
void update_encrypted_files_key(struct libos_encrypted_files_key* key, const pf_key_t* pf_key);
148148

149+
/*
150+
* \brief Register a volume.
151+
*
152+
* Registers passed volume -- assumed to be initialized, in particular with valid mount_point_path
153+
* -- in global list of mounted volumes. Returns an error if a volume with identical
154+
* mount_point_path already exists.
155+
*/
156+
int register_encrypted_volume(struct libos_encrypted_volume* volume);
149157
/*
150158
* \brief Retrieve a volume.
151159
*
@@ -164,18 +172,6 @@ struct libos_encrypted_volume* get_encrypted_volume(const char* mount_point_path
164172
int list_encrypted_volumes(int (*callback)(struct libos_encrypted_volume* volume, void* arg),
165173
void* arg);
166174

167-
/*
168-
* \brief Create a volume.
169-
*
170-
* Sets `*out_volume` to a volume with given mount_point_path. If the volume has not been created
171-
* yet, creates a new one (with mount_point_path and list only fields initialized!).
172-
* out_created is set to whether volume is newly created or not.
173-
*
174-
* Similar to `get_encrypted_volumes`, this does not pass ownership of `*out_volume`.
175-
*/
176-
int get_or_create_encrypted_volume(const char* mount_point_path,
177-
struct libos_encrypted_volume** out_volume, bool* out_created);
178-
179175
/*
180176
* \brief Open an existing encrypted file.
181177
*

libos/src/fs/chroot/encrypted.c

+22-10
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,36 @@ static int chroot_encrypted_mount(struct libos_mount_params* params, void** moun
8585
}
8686

8787
struct libos_encrypted_volume* volume;
88-
bool created;
89-
ret = get_or_create_encrypted_volume(params->path, &volume, &created);
90-
if (ret < 0)
91-
return ret;
92-
if (!created) {
93-
log_error("Volume '%s' is already mounted", params->path);
94-
return -EEXIST;
88+
volume = calloc(1, sizeof(*volume));
89+
if (!volume)
90+
return -ENOMEM;
91+
volume->mount_point_path = strdup(params->path);
92+
if (!volume->mount_point_path) {
93+
ret = -ENOMEM;
94+
goto err;
9595
}
9696
volume->protection_mode = protection_mode;
97-
volume->key = key;
97+
volume->key = key;
9898
if (!create_lock(&volume->files_state_map_lock)) {
99-
free(volume);
100-
return -ENOMEM;
99+
ret = -ENOMEM;
100+
goto err;
101101
}
102102
volume->files_state_map = NULL;
103103

104+
ret = register_encrypted_volume(volume);
105+
if (ret < 0)
106+
goto err;
107+
104108
*mount_data = volume;
105109
return 0;
110+
err:
111+
if (volume) {
112+
if (lock_created(&volume->files_state_map_lock))
113+
destroy_lock(&volume->files_state_map_lock);
114+
free(volume->mount_point_path);
115+
}
116+
free(volume);
117+
return ret;
106118
}
107119

108120
static ssize_t chroot_encrypted_checkpoint(void** checkpoint, void* mount_data) {

libos/src/fs/libos_fs_encrypted.c

+46-57
Original file line numberDiff line numberDiff line change
@@ -552,43 +552,19 @@ static struct libos_encrypted_volume* get_volume(const char* mount_point_path) {
552552
return NULL;
553553
}
554554

555-
static struct libos_encrypted_volume* get_or_create_volume(const char* mount_point_path,
556-
bool* out_created) {
557-
assert(locked(&g_volumes_lock));
558-
559-
struct libos_encrypted_volume* volume = get_volume(mount_point_path);
560-
if (volume) {
561-
*out_created = false;
562-
return volume;
563-
}
555+
int register_encrypted_volume(struct libos_encrypted_volume* volume) {
556+
assert(volume && volume->mount_point_path);
564557

565-
volume = calloc(1, sizeof(*volume));
566-
if (!volume)
567-
return NULL;
568-
volume->mount_point_path = strdup(mount_point_path);
569-
if (!volume->mount_point_path) {
570-
free(volume);
571-
return NULL;
572-
}
573-
LISTP_ADD_TAIL(volume, &g_volumes, list);
574-
*out_created = true;
575-
return volume;
576-
}
577-
578-
int get_or_create_encrypted_volume(const char* mount_point_path,
579-
struct libos_encrypted_volume** out_volume, bool* out_created) {
580558
lock(&g_volumes_lock);
581559

582-
int ret;
560+
int ret = 0;
583561

584-
struct libos_encrypted_volume* volume = get_or_create_volume(mount_point_path, out_created);
585-
if (!volume) {
586-
ret = -ENOMEM;
562+
struct libos_encrypted_volume* existing_volume = get_volume(volume->mount_point_path);
563+
if (existing_volume) {
564+
ret = -EEXIST;
587565
goto out;
588566
}
589-
590-
*out_volume = volume;
591-
ret = 0;
567+
LISTP_ADD_TAIL(volume, &g_volumes, list);
592568
out:
593569
unlock(&g_volumes_lock);
594570
return ret;
@@ -983,7 +959,9 @@ BEGIN_RS_FUNC(encrypted_files_key) {
983959
}
984960
END_RS_FUNC(encrypted_files_key)
985961

986-
/* Checkpoint the `g_volumes` list. */
962+
/* Checkpoint the `g_volumes` list. Note we only call this to checkpoint all volumes. The list
963+
* itself is not checkpointed (and hence also no corresponding restore function). The list is
964+
* reconstructed in the restore function of the volumes itself. */
987965
BEGIN_CP_FUNC(all_encrypted_volumes) {
988966
__UNUSED(size);
989967
__UNUSED(obj);
@@ -1005,44 +983,55 @@ BEGIN_CP_FUNC(encrypted_volume) {
1005983
struct libos_encrypted_volume* volume = obj;
1006984
struct libos_encrypted_volume* new_volume = NULL;
1007985

1008-
size_t off = ADD_CP_OFFSET(sizeof(struct libos_encrypted_volume));
1009-
1010-
new_volume = (struct libos_encrypted_volume*)(base + off);
1011-
1012-
// TODO (MST): do something with remaining fields of struct
1013-
log_debug("CP(encrypted_volume): protection_mode=%d file_state_mape=%p",
1014-
volume->protection_mode, volume->files_state_map); // TODO (MST): DEBUG
1015-
// - protection_mode -> automatically copied
1016-
// - files_state_map
1017-
// - files_state_map_lock
1018-
1019-
lock(&g_keys_lock);
1020-
DO_CP_MEMBER(encrypted_files_key, volume, new_volume, key);
1021-
unlock(&g_keys_lock);
1022-
1023-
ADD_CP_FUNC_ENTRY(off);
986+
size_t off = GET_FROM_CP_MAP(obj);
987+
if (!off) { /* We haven't already checkpointed this volume */
988+
off = ADD_CP_OFFSET(sizeof(struct libos_encrypted_volume));
989+
ADD_TO_CP_MAP(obj, off);
990+
new_volume = (struct libos_encrypted_volume*)(base + off);
991+
992+
log_debug("CP(encrypted_volume): mount_point_path=%s protection_mode=%d file_state_mape=%p",
993+
volume->mount_point_path, volume->protection_mode,
994+
volume->files_state_map); // TODO (MST): DEBUG
995+
DO_CP_MEMBER(str, volume, new_volume, mount_point_path);
996+
new_volume->protection_mode = volume->protection_mode;
997+
lock(&volume->files_state_map_lock);
998+
// - files_state_map -> TODO (MST): Serialize me
999+
unlock(&volume->files_state_map_lock);
1000+
// files_state_map_lock has no check point, it will be recreated in restore
1001+
lock(&g_keys_lock);
1002+
DO_CP_MEMBER(encrypted_files_key, volume, new_volume, key);
1003+
unlock(&g_keys_lock);
1004+
INIT_LIST_HEAD(new_volume, list);
10241005

1006+
ADD_CP_FUNC_ENTRY(off);
1007+
} else {
1008+
new_volume = (struct libos_encrypted_volume*)(base + off);
1009+
}
10251010
if (objp)
10261011
*objp = (void*)new_volume;
10271012
}
10281013
END_CP_FUNC(encrypted_volume)
10291014

10301015
// TODO (MST): revisit below, probably not correct?!
10311016
BEGIN_RS_FUNC(encrypted_volume) {
1032-
struct libos_encrypted_volume* volume = (void*)(base + GET_CP_FUNC_ENTRY());
10331017
__UNUSED(offset);
1018+
struct libos_encrypted_volume* migrated_volume = (void*)(base + GET_CP_FUNC_ENTRY());
1019+
1020+
CP_REBASE(migrated_volume->mount_point_path);
10341021

1035-
// TODO (MST): do something with remaining fields of struct
1036-
log_debug("RS(encrypted_volume): protection_mode=%d file_state_mape=%p",
1037-
volume->protection_mode, volume->files_state_map); // TODO (MST): DEBUG
1038-
// - protection_mode -> automatically copied
1039-
// - files_state_map
1040-
// - files_state_map_lock
1041-
if (!create_lock(&volume->files_state_map_lock)) {
1022+
/* protection_mode needs no restore action */
1023+
// files_state_map: TODO (MST): deserialize me
1024+
if (!create_lock(&migrated_volume->files_state_map_lock)) {
10421025
return -ENOMEM;
10431026
}
1027+
CP_REBASE(migrated_volume->key);
1028+
log_debug("RS(encrypted_volume): mount_point_path=%s protection_mode=%d file_state_mape=%p",
1029+
migrated_volume->mount_point_path, migrated_volume->protection_mode,
1030+
migrated_volume->files_state_map); // TODO (MST): DEBUG
10441031

1045-
CP_REBASE(volume->key);
1032+
int ret = register_encrypted_volume(migrated_volume);
1033+
if (ret < 0)
1034+
return ret;
10461035
}
10471036
END_RS_FUNC(encrypted_volume)
10481037

python/graminelibos/manifest_check.py

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
Required('type'): 'encrypted',
3131
Required('uri'): _uri,
3232
'key_name': str,
33+
'protection_mode': str,
3334
},
3435
{
3536
Required('type'): 'tmpfs',

0 commit comments

Comments
 (0)