apache / apache/teaclave-sgx-sdk

maximum size of ocall

Open
#77 10 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
1.2k
Forks
268
PR merge metrics
No merged PRs in 30d

Description

Hi, I'm trying to pass a big chunk of data through an ocall, and I get a segmentation fault when I pass around ~2MB.
is a known thing?
Trying to debug where exactly the SIGSEGV comes from leds me to it coming from the line:
`__tmp = sgx_ocalloc(ocalloc_size);` in `Enclave_t.c` with `ocalloc_size = 2196985`.

The C code in Enclave_t looks as follow:
```
sgx_status_t SGX_CDECL ocall_save_to_memory(uint64_t* retval, const uint8_t* data_ptr, size_t data_len)
{
sgx_status_t status = SGX_SUCCESS;
size_t _len_data_ptr = data_len * sizeof(uint8_t);

ms_ocall_save_to_memory_t* ms = NULL;
size_t ocalloc_size = sizeof(ms_ocall_save_to_memory_t);
void *__tmp = NULL;

CHECK_ENCLAVE_POINTER(data_ptr, _len_data_ptr);

ocalloc_size += (data_ptr != NULL) ? _len_data_ptr : 0;

__tmp = sgx_ocalloc(ocalloc_size);
if (__tmp == NULL) {
sgx_ocfree();
return SGX_ERROR_UNEXPECTED;
}
ms = (ms_ocall_save_to_memory_t*)__tmp;
__tmp = (void *)((size_t)__tmp + sizeof(ms_ocall_save_to_memory_t));
ocalloc_size -= sizeof(ms_ocall_save_to_memory_t);

if (data_ptr != NULL) {
ms->ms_data_ptr = (const uint8_t*)__tmp;
if (memcpy_s(__tmp, ocalloc_size, data_ptr, _len_data_ptr)) {
sgx_ocfree();
return SGX_ERROR_UNEXPECTED;
}
__tmp = (void *)((size_t)__tmp + _len_data_ptr);
ocalloc_size -= _len_data_ptr;
} else {
ms->ms_data_ptr = NULL;
}

ms->ms_data_len = data_len;
status = sgx_ocall(3, ms);

if (status == SGX_SUCCESS) {
if (retval) *retval = ms->ms_retval;
}
sgx_ocfree();
return status;
}
```
In the SIGSEGV instance it is called with these parameters:
`#1 0x00007fff0002ae1d in ocall_save_to_memory (retval=0x7fff50c250b8, data_ptr=0x7fff02b2d718 "", data_len=2196961) at enclave/Enclave_t.c:1742`

The Rust headers of the ocall is: `pub unsafe extern "C" fn ocall_save_to_memory(data_ptr: *const u8, data_len: usize) -> u64`
and in the EDL: `uint64_t ocall_save_to_memory( [in, count=data_len] const uint8_t* data_ptr, size_t data_len);`

Any ideas if there's a cap on how much data can be passed through an ocall or is it something else that I'm missing?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reproducing the SIGSEGV at enclave/Enclave_t.c:1742 with data_len=2196961, then inspect the generated ocall_save_to_memory wrapper and its EDL declaration. Compare the ocalloc_size calculation with the [in, count=data_len] parameter handling and determine whether the failure is an allocation limit or another mismatch. Done means the cause and supported handling for large ocall buffers are established.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, rust
Domain
security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.