Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Free enclave state when last ethread exits. #759

Closed
wants to merge 1 commit into from

Conversation

vtikoo
Copy link
Contributor

@vtikoo vtikoo commented Aug 10, 2020

Summary

sgxlkl_enclave_state state is being cleaned up during lkl_termination_thread. This is too early for the lthread scheduler which relies on state->config.mode for context switches. According to @prp this is a cause of other failures as well.

This PR moves sgxlkl_free_enclave_state to run later, when the last ethread exits.

@@ -216,6 +218,14 @@ static void _sgxlkl_enclave_show_attribute(const void* sgxlkl_enclave_base)
}
#endif

static inline void dec_ethread_counter() {
if (a_fetch_add(&ethreads_minus_1, -1) == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In new code, please use C11 atomic instead of the musl functions. Since we want sequential consistency, just declare the variable with the _Atomic qualifier as _Atomic(int).

@@ -12,6 +13,7 @@
#include "shared/env.h"
#include "shared/timer_dev.h"

int ethreads_minus_1 = -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment explaining why this need the minus one bit.

@@ -379,7 +391,10 @@ int sgxlkl_enclave_init(const sgxlkl_shared_memory_t* shared_memory)
SGXLKL_VERBOSE("calling _dlstart_c()\n");
_dlstart_c((size_t)sgxlkl_enclave_base);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels as if this should be earlier. Since this is the first ethread, why not skip it entirely and initialise the global assuming the initial ethread exists (if it doesn’t, nothing happens).

@@ -234,9 +244,11 @@ void sgxlkl_ethread_init(void)
}

/* Initialization completed, now run the scheduler */
a_inc(&ethreads_minus_1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there’s a race here. What happens if we call this just after another ethread has exited and deleted the enclave state? This won’t happen in normal operation, but an attacker can trigger it.

I think we want to add a second atomic counter on the number of exited threads and increment it before decrementing this counter on thread exit. At this point, we want to check if the exited threads counter is >0 and, if so, exit.

Copy link
Contributor

@wintersteiger wintersteiger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right, we definitely need to run this later. I think there is in deed a data race where @davidchisnall suspects one and his suggested fix should work.

On the general subject of cleanup: since we don't clean up the thread state, we might as well not clean up the config and drop sgxlkl_free_enclave_state entirely.

@davidchisnall
Copy link
Contributor

On the general subject of cleanup: since we don't clean up the thread state, we might as well not clean up the config and drop sgxlkl_free_enclave_state entirely.

I agree. There is no real benefit in trying to do this: the enclave will be destroyed on exit and all state will be cleaned up. The main thing I think we need is a guard on entry to the ecalls to make sure the host can't try to launch new ethreads when we are shutting down. We probably also need a guard here to make sure that we only ever get one initial thread:

SGXLKL_ASSERT(shared_memory);

@vtikoo
Copy link
Contributor Author

vtikoo commented Aug 11, 2020

Closing this PR, as there is consensus on not freeing enclave state. I 'll create a new one with the sgxlkl_free_enclave_state() removed and additional asserts.

@vtikoo vtikoo closed this Aug 11, 2020
@prp prp mentioned this pull request Aug 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants