- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
In the Intel SGX user guide it mentions that pointers to structures may be returned from ECALLS. On page 43, "pointers returned by an ECALL or OCALL function are not checked by the edge-routines and must be verified by the enclave and application code."
I am not able to get pointers to return from an ECALL, however, and instead get functions that always return sgx_status_t.
Can you please explain how I can return a pointer from an ECALL? Is there an edger8r flag that I need to specify so that ECALLS are not assumed to return sgx_status_t?
Example:
enclave.edl
trusted{ public int* returns_int_ptr(void); }
enclave.c
int* returns_int_ptr(void) { /* do some stuff */ return int_ptr; }
enclave_u.h
/* I want int* as return type */ sgx_status_t returns_int_ptr(sgx_enclave_id_t eid, int* retval);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Nickolas.
The SGX Edger8r tool automatically converts your function to the one that you pasted here.
It means that you need to get the "returned" int pointer from the out pointer parameter.
To execute that eCall, your code should look like this:
app.cpp
sgx_enclave_id_t eid; /* create enclave.. */ sgx_status_t ret = SGX_SUCCESS; int myInt; ret = returns_int_ptr(eid, &myInt); /* use myInt */
Now, if you wanted to return several integers instead of only one, your code should look like this:
enclave.edl
enclave{ trusted{ public void returns_int_ptr([out, size=len] int *p_return_ptr, size_t len); }; };
enclave.cpp
void returns_int_ptr(int *p_return_ptr, size_t len) { int *p_ints = (int *) malloc(len*sizeof(int)); /* do some stuff */ memcpy(p_return_ptr, p_ints, len); free(p_ints); }
app.cpp
#define BUFFER_SIZE 100 sgx_enclave_id_t eid; /* create enclave */ int *p_ints = (int *) malloc(BUFFER_SIZE * sizeof(int)); sgx_status_t ret = SGX_SUCCESS; ret = returns_int_ptr(eid, p_ints, BUFFER_SIZE); /* do some stuff with p_ints */
Hope this is helpful.
Best regards,
Rodolfo
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Nickolas.
The SGX Edger8r tool automatically converts your function to the one that you pasted here.
It means that you need to get the "returned" int pointer from the out pointer parameter.
To execute that eCall, your code should look like this:
app.cpp
sgx_enclave_id_t eid; /* create enclave.. */ sgx_status_t ret = SGX_SUCCESS; int myInt; ret = returns_int_ptr(eid, &myInt); /* use myInt */
Now, if you wanted to return several integers instead of only one, your code should look like this:
enclave.edl
enclave{ trusted{ public void returns_int_ptr([out, size=len] int *p_return_ptr, size_t len); }; };
enclave.cpp
void returns_int_ptr(int *p_return_ptr, size_t len) { int *p_ints = (int *) malloc(len*sizeof(int)); /* do some stuff */ memcpy(p_return_ptr, p_ints, len); free(p_ints); }
app.cpp
#define BUFFER_SIZE 100 sgx_enclave_id_t eid; /* create enclave */ int *p_ints = (int *) malloc(BUFFER_SIZE * sizeof(int)); sgx_status_t ret = SGX_SUCCESS; ret = returns_int_ptr(eid, p_ints, BUFFER_SIZE); /* do some stuff with p_ints */
Hope this is helpful.
Best regards,
Rodolfo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When the trusted function returns "int
*
", the result is the following untrusted bridge:
sgx_status_t returns_int_ptr(sgx_enclave_id_t eid, int** retval);
and the untrusted app could then obtain the pointer as follows:
sgx_status_t ret = SGX_SUCCESS; int * myInt = NULL; ret = returns_int_ptr(eid, &myInt);
The documentation is saying that the such pointer is not marshalled, i.e., the untrusted application gets a pointer (address) but it doesn't get the content of the buffer. If you want to get the buffer you have to pass the pointer as a parameter as Rodolfo explained above.
static sgx_status_t SGX_CDECL sgx_returns_int_ptr(void* pms) { ms_returns_int_ptr_t* ms = SGX_CAST(ms_returns_int_ptr_t*, pms); sgx_status_t status = SGX_SUCCESS; CHECK_REF_POINTER(pms, sizeof(ms_returns_int_ptr_t)); ms->ms_retval = returns_int_ptr(); // We just get the pointer. No memcpy() below. return status; }
This is important when an OCALL returns a pointer, since the enclave has to check it as if it had the "user_check" attribute.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for both of your responses. They clear this up perfectly, and shows nicely where I was misunderstanding the SGX framework.
Nick

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page