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

User-space separation #815

Closed
wants to merge 6 commits into from
Closed

User-space separation #815

wants to merge 6 commits into from

Conversation

mikbras
Copy link
Collaborator

@mikbras mikbras commented Aug 21, 2020

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

Comment on lines +94 to +101
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;
}

Copy link
Contributor

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.

Suggested change
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;
Copy link
Contributor

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.

Suggested change
args.ua_lkl_syscall = _lkl_syscall_wrapper;
args.ua_lkl_syscall = lkl_syscall;

return ret;
}

static void _enter_user_space(
Copy link
Contributor

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.

Comment on lines +18 to +23
long lkl_syscall(long no, long* params)
{
long ret = __sgxlkl_userargs->ua_lkl_syscall(no, params);

return ret;
}
Copy link
Contributor

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)
Copy link
Contributor

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");
Copy link
Contributor

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.

Comment on lines +45 to +61
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);
}
Copy link
Contributor

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?

Comment on lines +75 to +76
return __sgxlkl_userargs->ua_enclave_mmap(addr, length, mmap_fixed,
prot, zero_pages);
Copy link
Contributor

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.

Suggested change
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);

Copy link
Contributor

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:

Suggested change
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.

@davidchisnall davidchisnall mentioned this pull request Aug 24, 2020
2 tasks
@davidchisnall
Copy link
Contributor

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.

@mikbras
Copy link
Collaborator Author

mikbras commented Aug 24, 2020

Thank you David for your review. I'm sorry I created the PR without much background. Here are a few follow-up issues:

  1. There are still some syscall bypasses that are beyond the scope of this PR to remove (see userargs.h).
  2. This PR breaks syscall logging. We need to implement syslog as soon as possible.
  3. A few builtin math functions are stubbed out (see stubs.c).

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.

@davidchisnall
Copy link
Contributor

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()
{
Copy link
Contributor

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.

@bodzhang bodzhang requested a review from vtikoo August 25, 2020 17:35
/* Determines path of libsgxlkl-user */
void get_libsgxlkl_user_path(char* path_buf, size_t len)
{
find_lib("libsgxlkl-user.so", path_buf, len);
Copy link
Contributor

@vtikoo vtikoo Aug 25, 2020

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>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// 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)
Copy link
Contributor

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.

Copy link
Contributor

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;
Copy link
Contributor

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?

Copy link
Contributor

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;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
enclave_image_provided = true;
isolated_image_provided = true;

Copy link
Contributor

@vtikoo vtikoo left a 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 use libsgxlkl-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.

@prp
Copy link
Member

prp commented Sep 4, 2020

Merged as PR #818.

@prp prp closed this Sep 4, 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.

5 participants