Linux-Sgx Archive on lore.kernel.org
 help / color / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Cc: Nathaniel McCallum <npmccallum@redhat.com>,
	Cedric Xing <cedric.xing@intel.com>,
	Jethro Beekman <jethro@fortanix.com>,
	Andy Lutomirski <luto@amacapital.net>,
	linux-sgx@vger.kernel.org
Subject: [PATCH for_v29 0/8] x86/sgx: Make vDSO callable from C
Date: Wed, 18 Mar 2020 18:11:22 -0700
Message-ID: <20200319011130.8556-1-sean.j.christopherson@intel.com> (raw)

Nathaniel pointed out that __vdso_sgx_enter_enclave() is tantalizingly
close to being callable from C (with caveats and a cooperative enclave).
The missing pieces are preserving %rbx and taking @leaf as a standard
paramter (hey look, %rcx is available!).

As requested, update the selftest to invoke the vDSO from C, and fix
bugs along the way.  Don't suppose you've changed your mind about waiting
until after upstreaming to add a proper framework?

I also did a lot more testing on my internal code base to verify the
%rsp tweaks play nice with the exit handler, and to prove that an exit
handler can even cleanly handle exceptions in the enclave.

Here's the relevant code from my internal test suite, might want to have
eye bleach ready ;-).  I tested the exception handling by overwriting
@ms in enter_enclave() with a bogus value, e.g. 0xdeadull << 0x48.  The
nested call to the vDSO (in the exit handler) with EMCD_EXCEPTION has the
enclave dump its register.  The host (this runs as cgo in a Golang process)
dumps the exception info.

I also verified the relative %rsp fixup by corrupting %rsp in the enclave,
verifying it exploded as expected (I added extra consumption in the vDSO to
force this) and then adding code to undo the damage in the exit handler and
verifying things got back to normal.

Last thread of thought, IMO taking a context param (as suggested by
Nathaniel) is unnecessary.  As shown below, the runtime effectively has a
context param in the form of "struct sgx_enclave_exception *e", the handler
just needs to be willing to cast (or use container_of()).  There are a
multitude of other ways to pass info as well.

vdso_sgx_enter_enclave_t __enter_enclave;

vDSO::vDSO()
{
    if (__enter_enclave)
        abort();

    uintptr_t vdso = (uintptr_t)getauxval(AT_SYSINFO_EHDR);
    vdso_init_from_sysinfo_ehdr(vdso);

    __enter_enclave = (vdso_sgx_enter_enclave_t)vdso_sym("LINUX_2.6", "__vdso_sgx_enter_enclave");
    if (!__enter_enclave)
        abort();
}

struct sgx_vdso_ctxt {
    sgx_exception_t e;
    long            ret;
    Enclave *       enclave;
    jmp_buf         buf;
};

static int exit_handler(long rdi, long rsi, long rdx, long ursp, long r8, long r9,
                        void *tcs, int ret, struct sgx_enclave_exception *e)
{
    struct sgx_vdso_ctxt *ctxt = (struct sgx_vdso_ctxt *)e;
    int r;

    if (!ret) {
        if (ctxt)
            ctxt->ret = rdi;
        return 0;
    }

    if (!ctxt)
        exit(EFAULT);

    r = __enter_enclave(ECMD_EXCEPTION, (unsigned long)&ctxt->e.regs, 0, EENTER,
                        0, 0, tcs, NULL, exit_handler);
    if (r)
        exit(-r);

    ctxt->enclave->set_exception(ctxt->e);

    longjmp(ctxt->buf, ret);
}

sgx_status_t vDSO::enter_enclave(Enclave &enclave, const long fn, void *ms, tcs_t *tcs)
{
    struct sgx_vdso_ctxt ctxt;
    ctxt.enclave = &enclave;

    int ret = setjmp(ctxt.buf);
    if (ret) {
        if (ret != -EFAULT)
            return SGX_ERROR_INVALID_PARAMETER;

        SE_URTS_ERROR("\nEnclave exception, base = %lx, size = %lx",
                      enclave.get_base(), enclave.get_size());

        return SGX_ERROR_UNHANDLED_EXCEPTION;
    }

    ret = __enter_enclave(fn, (unsigned long)ms, 0, EENTER, 0, 0, tcs,
                          &ctxt.e.fault, exit_handler);
    if (ret == -EINVAL)
        return SGX_ERROR_INVALID_PARAMETER;

    return (sgx_status_t)ctxt.ret;
}

Sean Christopherson (8):
  x86/sgx: vdso: Remove an incorrect statement the enter enclave comment
  x86/sgx: vdso: Make the %rsp fixup on return from handler relative
  x86/sgx: vdso: Make __vdso_sgx_enter_enclave() callable from C code
  x86/sgx: vdso: Define a typedef for __vdso_sgx_enter_enclave
  selftests/x86: sgx: Zero out @result before invoking vDSO sub-test
  selftests/x86: sgx: Pass EENTER to vDSO wrapper instead of hardcoding
  selftests/x86: sgx: Stop clobbering non-volatile registers
  selftests/x86: Add selftest to invoke __vsgx_enter_enclave() from C

 arch/x86/entry/vdso/vsgx_enter_enclave.S      | 72 ++-----------------
 arch/x86/include/uapi/asm/sgx.h               | 61 ++++++++++++++++
 .../selftests/x86/sgx/encl_bootstrap.S        |  6 +-
 tools/testing/selftests/x86/sgx/main.c        | 17 ++++-
 tools/testing/selftests/x86/sgx/sgx_call.S    |  1 -
 tools/testing/selftests/x86/sgx/sgx_call.h    |  2 +-
 6 files changed, 85 insertions(+), 74 deletions(-)

-- 
2.24.1


             reply index

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-19  1:11 Sean Christopherson [this message]
2020-03-19  1:11 ` [PATCH for_v29 1/8] x86/sgx: vdso: Remove an incorrect statement the enter enclave comment Sean Christopherson
2020-03-19 20:49   ` Jarkko Sakkinen
2020-03-19  1:11 ` [PATCH for_v29 2/8] x86/sgx: vdso: Make the %rsp fixup on return from handler relative Sean Christopherson
2020-03-20  2:39   ` Jarkko Sakkinen
2020-03-20  2:42     ` Jarkko Sakkinen
2020-03-19  1:11 ` [PATCH for_v29 3/8] x86/sgx: vdso: Make __vdso_sgx_enter_enclave() callable from C code Sean Christopherson
2020-03-19 20:03   ` Xing, Cedric
2020-03-19 20:11     ` Sean Christopherson
2020-03-20  3:07       ` Jarkko Sakkinen
2020-03-20 23:26         ` Sean Christopherson
2020-03-21  0:57           ` Jarkko Sakkinen
2020-03-19  1:11 ` [PATCH for_v29 4/8] x86/sgx: vdso: Define a typedef for __vdso_sgx_enter_enclave Sean Christopherson
2020-03-19  1:11 ` [PATCH for_v29 5/8] selftests/x86: sgx: Zero out @result before invoking vDSO sub-test Sean Christopherson
2020-03-19  1:11 ` [PATCH for_v29 6/8] selftests/x86: sgx: Pass EENTER to vDSO wrapper instead of hardcoding Sean Christopherson
2020-03-19  1:11 ` [PATCH for_v29 7/8] selftests/x86: sgx: Stop clobbering non-volatile registers Sean Christopherson
2020-03-19  1:11 ` [PATCH for_v29 8/8] selftests/x86: Add selftest to invoke __vsgx_enter_enclave() from C Sean Christopherson
2020-03-20  0:57 ` [PATCH for_v29 0/8] x86/sgx: Make vDSO callable " Jarkko Sakkinen
2020-03-20 23:25   ` Sean Christopherson
2020-03-21  0:55     ` Jarkko Sakkinen
2020-03-21 20:11       ` Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200319011130.8556-1-sean.j.christopherson@intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=cedric.xing@intel.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=jethro@fortanix.com \
    --cc=linux-sgx@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=npmccallum@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Sgx Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-sgx/0 linux-sgx/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-sgx linux-sgx/ https://lore.kernel.org/linux-sgx \
		linux-sgx@vger.kernel.org
	public-inbox-index linux-sgx

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-sgx


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git