intel / linux-sgx

Intel SGX for Linux*
https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/linux-overview.html
Other
1.32k stars 543 forks source link

Segfault While passing a big data through an Ocall #376

Open elichai opened 5 years ago

elichai commented 5 years ago

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

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?

ghost commented 5 years ago

Can you please check your stack size? https://unix.stackexchange.com/questions/127602/default-stack-size-for-pthreads

elichai commented 5 years ago

It says 8192 but I'll try increasing it while compiling. why isn't this allocated on the heap? and is this the same case in ecalls?

ghost commented 5 years ago

Inside enclave, the malloc is only able to be used to malloc trusted memory. Ecall is using trusted stack, you need to configure the stack size in the enclave configuration file.

andyzyb commented 5 years ago

This is to make the implementation simpler. Allocating on the heap will need another ocall to do the malloc in untrusted memory before current ocall.

arefasvadi commented 4 years ago

I'm having the same issue after I updated to 2.7 version! sgx_ocalloc throws a segfault when it tries to allocate a buffer around 790KB. I did try increasing stack size through ulimit -S -s x to 16MB, 128MB, and 256MB, but it kept throwing the segfault. I really wanted to see where the abort() happens! I recompiled the SDK in debug mode and it did not happen again?

Does anyone have any suggestions on what can cause this? I really need to benchmark the code, so it would be best if it is linked against optimized libraries with no debug symbols in them.

ghost commented 4 years ago

@arefasvadi Do you tried sgx-gdb to stop the application when it crashed? If you did it, can you please attach the call trace at that time?

taserghar commented 4 years ago

Does anyone have any solution to that? I am having same issue. I tried to increase both the stack size to 128 MB and the heap size to 6 GB. It successfully allocates the buffer in the enclave. But causing segmentation fault for only 10 MB buffer when writing to the outside enclave via ocall.

taserghar commented 4 years ago

I am attaching the stack-trace using sgx-gdb.

`#0 0x00007ffef59779c1 in sgx_ocalloc_switchless ()

1 0x00007ffef593a293 in ocall_WriteFile (fileId=1, pos=0, pBuf=0x7ffef5bdb340 "",

pSize=10480000, ret_status=0x7fff651be1c8) at Enclave/Enclave_t.c:1873

2 0x00007ffef593f854 in BlockFile::writeBlock (this=0x7fff651be310, pBlock=0x7ffef5bdb340 "",

pos=0) at Enclave/BlockFile.cpp:68

3 0x00007ffef5973500 in convTextToRecord (outputFile=...) at Enclave/synthetic_data.cpp:49

4 0x00007ffef5973945 in gen_synthetic (p_nob=1, p_blockSize=10480000, p_recordSize=52428800,

p_recordLimit=2) at Enclave/synthetic_data.cpp:110

5 0x00007ffef593c208 in gen_data (p_nob=1, p_blockSize=10480000, p_recordSize=52428800,

p_recordLimit=2) at Enclave/Enclave.cpp:193

6 0x00007ffef59385e8 in sgx_gen_data (pms=0x7fffffffd570) at Enclave/Enclave_t.c:467

7 0x00007ffef5978016 in do_ecall ()

8 0x00007ffef59b0941 in enter_enclave ()

9 0x00007ffef59b0cee in enclave_entry ()

10 0x00007ffff7bc015c in __morestack () from /app/sgxsdk/sdk_libs/libsgx_urts_sim.so

11 0x00007ffff7bb571f in CEnclave::ecall(int, void const, void, bool) ()

from /app/sgxsdk/sdk_libs/libsgx_urts_sim.so

12 0x00007ffff7bb95af in _sgx_ecall(unsigned long, int, void const, void, bool) [clone .part.0] () from /app/sgxsdk/sdk_libs/libsgx_urts_sim.so

13 0x0000555555557ca1 in gen_data (eid=52639119179778, p_nob=1, p_blockSize=10480000,

p_recordSize=52428800, p_recordLimit=2) at App/Enclave_u.c:535

14 0x0000555555559331 in start_analyze (NOB=1, blockSize=10480000, isInEnclaveMemory=0)

at App/App.cpp:287

15 0x000055555555a5d8 in main (argc=4, argv=0x7fffffffd8d8) at App/App.cpp:439

`

doubley318 commented 2 years ago

I have same issue too.

doubley318 commented 2 years ago

I find the solution by setting system stack size!