-
Notifications
You must be signed in to change notification settings - Fork 89
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
User-space separation #815
Conversation
static long _lkl_syscall_wrapper(long no, long* params) | ||
{ | ||
//sgxlkl_warn("syscall begin: no=%u\n", no); | ||
long ret = lkl_syscall(no, params); | ||
//sgxlkl_warn("syscall end: ret=%u\n", ret); | ||
return ret; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like dead code that was left in during debugging.
static long _lkl_syscall_wrapper(long no, long* params) | |
{ | |
//sgxlkl_warn("syscall begin: no=%u\n", no); | |
long ret = lkl_syscall(no, params); | |
//sgxlkl_warn("syscall end: ret=%u\n", ret); | |
return ret; | |
} |
if (!(proc = __oe_get_isolated_image_entry_point())) | ||
sgxlkl_fail("failed to obtain user space entry point"); | ||
|
||
args.ua_lkl_syscall = _lkl_syscall_wrapper; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above comment about dead code.
args.ua_lkl_syscall = _lkl_syscall_wrapper; | |
args.ua_lkl_syscall = lkl_syscall; |
return ret; | ||
} | ||
|
||
static void _enter_user_space( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for now, but we should be setting up the stack in the kernel and using a clone syscall to launch the thread on a pre-prepared stack using the libc entry point.
long lkl_syscall(long no, long* params) | ||
{ | ||
long ret = __sgxlkl_userargs->ua_lkl_syscall(no, params); | ||
|
||
return ret; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine for now, but please open an issue to track the fact that we should be always referencing lkl_syscall
via a function pointer (or, ideally, an ifunc).
**============================================================================== | ||
*/ | ||
|
||
long lkl_syscall(long no, long* params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need a hidden-visibility attribute, or is the build system still hiding this from userspace?
int params_len, | ||
...) | ||
{ | ||
sgxlkl_warn("__sgxlkl_log_syscall() unimplemented in user space"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still called for dup2
and epoll_wait
(redirected system calls). I think we should just remove the caller here, since we're removing the behaviour.
void sgxlkl_warn(const char* msg, ...) | ||
{ | ||
/* ATTN: ignore variadic arguments */ | ||
return __sgxlkl_userargs->ua_sgxlkl_warn(msg); | ||
} | ||
|
||
void sgxlkl_error(const char* msg, ...) | ||
{ | ||
/* ATTN: ignore variadic arguments */ | ||
return __sgxlkl_userargs->ua_sgxlkl_error(msg); | ||
} | ||
|
||
void sgxlkl_fail(const char* msg, ...) | ||
{ | ||
/* ATTN: ignore variadic arguments */ | ||
return __sgxlkl_userargs->ua_sgxlkl_fail(msg); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't be calling any kernel code other than the syscall interface in userspace. Please can you conditionally compile these so that they appear only in debug builds?
return __sgxlkl_userargs->ua_enclave_mmap(addr, length, mmap_fixed, | ||
prot, zero_pages); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Userspace's libc shouldn't issue this call directly. We probably need to still call enclave_mmap
because the kernel libc tries to mmap things before LKL is running, but this one should just do an mmap syscall.
return __sgxlkl_userargs->ua_enclave_mmap(addr, length, mmap_fixed, | |
prot, zero_pages); | |
return mmap(addr, length, prot, MAP_PRIVATE | MAP_ANONYMOUS | (mmap_fixed ? MAP_FIXED : 0, -1, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is called in two places in malloc, neither sets map_fixed
, so we don't actually need to handle this case. It might be worth adding an assertion, something like:
return __sgxlkl_userargs->ua_enclave_mmap(addr, length, mmap_fixed, | |
prot, zero_pages); | |
assert(prot == PROT_READ | PROT_WRITE); | |
assert(!mmap_fixed); | |
return mmap(addr, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
This can then be removed once we are no longer linking a copy of libc into the kernel.
This PR contains some calls to functions that shouldn't exist. I've opened #816 to track this - I don't believe the fix should block this PR landing. |
Thank you David for your review. I'm sorry I created the PR without much background. Here are a few follow-up issues:
Also, the tests are broken since I forgot to add an install rule for libsgxlkl-user.so. I will update the PR in a couple of hours. |
We moved syscall logging into the kernel already, the only thing that's broken is locking for translated syscalls (ones where we implement a legacy x86 syscall by calling its legacy version). I don't think we actually need that. |
#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" | ||
|
||
void __muldc3() | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would call abort()
here, just in case they actually get called.
/* Determines path of libsgxlkl-user */ | ||
void get_libsgxlkl_user_path(char* path_buf, size_t len) | ||
{ | ||
find_lib("libsgxlkl-user.so", path_buf, len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my understanding, is this shared object not signed like the kernel counterpart?
@@ -1391,8 +1405,15 @@ void _create_enclave( | |||
|
|||
setting.u.eeid = eeid; | |||
|
|||
// Format the follwing path <libsgxlkl>:<libsgxlkl_user> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Format the follwing path <libsgxlkl>:<libsgxlkl_user> | |
// Format the following path <libsgxlkl>:<libsgxlkl_user> |
@@ -1863,6 +1891,13 @@ int main(int argc, char* argv[], char* envp[]) | |||
} | |||
sgxlkl_host_verbose_raw("result=%s\n", libsgxlkl); | |||
|
|||
sgxlkl_host_verbose("get_libsgxlkl_user_path... "); | |||
if (!isolated_image_provided) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will always evaluate to true, I don't see where isolated_image_provided
is being set again after initialization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe should happen on L1774?
{ | ||
sgxlkl_fail("Failed to create lthread for startmain()\n"); | ||
static startmain_args_t args; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my understanding, is this(creating code blocks with parantheses) a standard C feature or a gcc extension?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also wondering if this was intentional, and if yes what was the rationale behind it.
@@ -1746,6 +1770,10 @@ int main(int argc, char* argv[], char* envp[]) | |||
enclave_image_provided = true; | |||
strcpy(libsgxlkl, optarg); | |||
break; | |||
case 'i': | |||
enclave_image_provided = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enclave_image_provided = true; | |
isolated_image_provided = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Really appreciate the README, it helped a lot to understand the design!
Had two minor concerns, which should not be PR blocking -
- Passing a custom isolated image to
sgx-lkl-run-oe
seems to be broken. Right now, it will always uselibsgxlkl-user.so
even if the user specifies an override. - Its not clear to me whether the userspace shared object is signed and whether we are using the signed version.
Merged as PR #818. |
This PR, separates the C runtime (libc and ldso) into its own ELF memory region, effectively isolating it from the kernel. The resulting library is called libsgxlkl-user.so (built under the ./user directory).
This PR depends on two other PRs:
- lsds/sgx-lkl-musl#37
- openenclave/openenclave#3425
For more information see the README below.
https://github.com/lsds/sgx-lkl/pull/815/files?short_path=9e7b9bd#diff-9e7b9bdf8e7469060b7afdf451e7e430