Skip to content

Commit 6f71463

Browse files
committed
[LibOS] Updates to encrypted files
* make corruption status for encrypted files sticky * update filemap state for any corruption also encountered during operations other than open, close, unlink and rename
1 parent cd03cef commit 6f71463

File tree

4 files changed

+122
-62
lines changed

4 files changed

+122
-62
lines changed

common/src/protected_files/protected_files.c

+17
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,9 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) {
791791
if (PF_FAILURE(status)) {
792792
pf->last_error = status;
793793
DEBUG_PF("failed to decrypt metadata: %d", status);
794+
if (status == PF_STATUS_MAC_MISMATCH)
795+
// MAC could also mismatch if wrong key was provided but we err on side of safety ...
796+
pf->file_status = PF_STATUS_CORRUPTED;
794797
return false;
795798
}
796799

@@ -818,6 +821,8 @@ static bool ipf_init_existing_file(pf_context_t* pf, const char* path) {
818821
&pf->metadata_decrypted.root_mht_node_mac);
819822
if (PF_FAILURE(status)) {
820823
pf->last_error = status;
824+
if (status == PF_STATUS_MAC_MISMATCH)
825+
pf->file_status = PF_STATUS_CORRUPTED;
821826
return false;
822827
}
823828
}
@@ -1162,6 +1167,9 @@ pf_status_t pf_get_size(pf_context_t* pf, uint64_t* size) {
11621167
if (!g_initialized)
11631168
return PF_STATUS_UNINITIALIZED;
11641169

1170+
if (pf->file_status == PF_STATUS_CORRUPTED)
1171+
return pf->file_status; // Make corruption "sticky"
1172+
11651173
*size = pf->metadata_decrypted.file_size;
11661174
return PF_STATUS_SUCCESS;
11671175
}
@@ -1173,6 +1181,9 @@ pf_status_t pf_set_size(pf_context_t* pf, uint64_t size) {
11731181
if (!(pf->mode & PF_FILE_MODE_WRITE))
11741182
return PF_STATUS_INVALID_MODE;
11751183

1184+
if (pf->file_status == PF_STATUS_CORRUPTED)
1185+
return pf->file_status; // Make corruption "sticky"
1186+
11761187
if (size == pf->metadata_decrypted.file_size)
11771188
return PF_STATUS_SUCCESS;
11781189

@@ -1221,6 +1232,9 @@ pf_status_t pf_rename(pf_context_t* pf, const char* new_path, pf_mac_t* new_root
12211232
if (!g_initialized)
12221233
return PF_STATUS_UNINITIALIZED;
12231234

1235+
if (pf->file_status == PF_STATUS_CORRUPTED)
1236+
return pf->file_status; // Make corruption "sticky"
1237+
12241238
if (!(pf->mode & PF_FILE_MODE_WRITE))
12251239
return PF_STATUS_INVALID_MODE;
12261240

@@ -1293,6 +1307,9 @@ pf_status_t pf_flush(pf_context_t* pf) {
12931307
if (!g_initialized)
12941308
return PF_STATUS_UNINITIALIZED;
12951309

1310+
if (pf->file_status == PF_STATUS_CORRUPTED)
1311+
return pf->file_status; // Make corruption "sticky"
1312+
12961313
if (!ipf_internal_flush(pf))
12971314
return pf->last_error;
12981315

libos/include/libos_fs_encrypted.h

+12-6
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,19 @@ typedef enum {
4141
PF_FILE_STATE_DELETED = 2, // file was previously seen but then either unlinked or renamed
4242
} libos_encrypted_file_state_t;
4343

44+
inline static const char* file_state_to_string(libos_encrypted_file_state_t state) {
45+
return (state == PF_FILE_STATE_ERROR ? "error"
46+
: (state == PF_FILE_STATE_ACTIVE ? "active" : "deleted"));
47+
}
48+
4449
/*
4550
* Map mapping file URIs to state providing information on files, in particular whether we have seen
4651
* them before and what the last seen root-hash is. This is necessary to provide rollback
4752
*/
4853
struct libos_encrypted_volume_state_map {
4954
char* norm_path; // assumptions: all paths canonicalized, symlinks are resolved & no hard links
5055
libos_encrypted_file_state_t state;
51-
pf_mac_t last_seen_root_mac;
56+
pf_mac_t last_seen_root_mac; // valid only if state == PF_FILE_STATE_ACTIVE
5257
UT_hash_handle hh;
5358
};
5459

@@ -224,16 +229,17 @@ void encrypted_file_put(struct libos_encrypted_file* enc, bool fs_reachable);
224229
/*
225230
* \brief Flush pending writes to an encrypted file.
226231
*/
227-
int encrypted_file_flush(struct libos_encrypted_file* enc);
232+
int encrypted_file_flush(struct libos_encrypted_file* enc, bool fs_reachable);
228233

229234
int encrypted_file_read(struct libos_encrypted_file* enc, void* buf, size_t buf_size,
230-
file_off_t offset, size_t* out_count);
235+
file_off_t offset, size_t* out_count, bool fs_reachable);
231236
int encrypted_file_write(struct libos_encrypted_file* enc, const void* buf, size_t buf_size,
232-
file_off_t offset, size_t* out_count);
237+
file_off_t offset, size_t* out_count, bool fs_reachable);
233238
int encrypted_file_rename(struct libos_encrypted_file* enc, const char* new_uri);
234239
int encrypted_file_unlink(struct libos_encrypted_file* enc);
235240

236-
int encrypted_file_get_size(struct libos_encrypted_file* enc, file_off_t* out_size);
237-
int encrypted_file_set_size(struct libos_encrypted_file* enc, file_off_t size);
241+
int encrypted_file_get_size(struct libos_encrypted_file* enc, file_off_t* out_size,
242+
bool fs_reachable);
243+
int encrypted_file_set_size(struct libos_encrypted_file* enc, file_off_t size, bool fs_reachable);
238244

239245
int parse_pf_key(const char* key_str, pf_key_t* pf_key);

libos/src/fs/chroot/encrypted.c

+7-5
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ static int chroot_encrypted_lookup(struct libos_dentry* dent) {
207207
goto out;
208208
}
209209
} else {
210-
ret = encrypted_file_get_size(enc, &size);
210+
ret = encrypted_file_get_size(enc, &size, true);
211211
encrypted_file_put(enc, true);
212212

213213
if (ret < 0) {
@@ -468,7 +468,7 @@ static int chroot_encrypted_flush(struct libos_handle* hdl) {
468468

469469
/* This will write changes from `enc` to host file */
470470
lock(&hdl->inode->lock);
471-
ret = encrypted_file_flush(enc);
471+
ret = encrypted_file_flush(enc, hdl->inode == hdl->dentry->inode);
472472
unlock(&hdl->inode->lock);
473473
return ret;
474474
}
@@ -502,7 +502,8 @@ static ssize_t chroot_encrypted_read(struct libos_handle* hdl, void* buf, size_t
502502
size_t actual_count;
503503

504504
lock(&hdl->inode->lock);
505-
int ret = encrypted_file_read(enc, buf, count, *pos, &actual_count);
505+
int ret =
506+
encrypted_file_read(enc, buf, count, *pos, &actual_count, hdl->inode == hdl->dentry->inode);
506507
unlock(&hdl->inode->lock);
507508

508509
if (ret < 0)
@@ -527,7 +528,8 @@ static ssize_t chroot_encrypted_write(struct libos_handle* hdl, const void* buf,
527528

528529
lock(&hdl->inode->lock);
529530

530-
int ret = encrypted_file_write(enc, buf, count, *pos, &actual_count);
531+
int ret = encrypted_file_write(enc, buf, count, *pos, &actual_count,
532+
hdl->inode == hdl->dentry->inode);
531533
if (ret < 0) {
532534
unlock(&hdl->inode->lock);
533535
return ret;
@@ -557,7 +559,7 @@ static int chroot_encrypted_truncate(struct libos_handle* hdl, file_off_t size)
557559
assert(enc);
558560

559561
lock(&hdl->inode->lock);
560-
ret = encrypted_file_set_size(enc, size);
562+
ret = encrypted_file_set_size(enc, size, hdl->inode == hdl->dentry->inode);
561563
if (ret < 0) {
562564
unlock(&hdl->inode->lock);
563565
return ret;

0 commit comments

Comments
 (0)