I am trying to put part of the code of the program into the enclave. The code in enclave needs to access external global variables. Because there are so many extern global variables inside enclave. It's not scalable to pass their address through ECALL functions.
The code in the dynamic library can access the variables defined in the host application. Can the code in enclave also be like this?
I try to build enclave as a dynamic library by adding '-shared' to Enclave_Link_Flags. And Delete the '--no-undefined' flag in Enclave_Link_Flags. In addition, I explore the symbol table of host application by adding '--export-dynamic' to App_Link_Flags.
The application can run normally, but the address of external global variables inside encalve is wrong.
Here is the expriment result(ASLR turn off. The global variable address inside enclave is fixed.)
global variable address outside: 0x60e2a0 value:10
global variable address inside: 0x7ffff5000000 value:1179403647
It is not possible to access global variables from inside an enclave. This would break the trust boundary between the enclave and external app. The only way to pass data between the host app and the enclave is through the ecalls and ocalls.
Hi, i hope the week has gone well for everyone.
I'm not sure that it would be correct to assert that code running in enclave context cannot access variables outside the address space of the enclave, ie. global program address space. If this were the case the EDL generated code would not be able to marshal the data supplied by the untrusted function call that translates, via an ECALL, into the trusted implementation of the function.
If one looks into the code that is generated by the sgx_edger8 utility, you will see that the untrusted function call converts the arguments to the function call into a data structure and then passes a pointer to that structure, which is in untrusted address space, into the enclave via the ENCLU[EENTER] instruction. The ECALL entry/marshaling code that is called uses the structure pointer to copy data from untrusted space in order to create arguments in enclave address space that are passed to the trusted implementation of the function call.
A second counter-example to this notion would seem to be the 'switchless' code that is designed to implement a low latency replacement for OCALL's. The switchless architecture is based on a model where supplier threads running in untrusted space populate buffers in global address space for consumption by consumer threads running in enclave context. The entire architecture is predicated on the ability of a context of execution, running in trusted/enclave space, being able to access the supplier buffers in untrusted space without the latency costs imposed by an OCALL exit and re-entry.
This architecture was the subject of a lively debate between myself and the young Intel engineer that wrote the code. I would provide a reference to that link but it was accidentally removed. We were debating whether or not this strategy was playing a bit fast and loose with respect to the notion that SGX applications should be cautious with respect to data transitions that occur across the enclave boundary.
Unless we misunderstand the SGX architecture, the trust guarantee of SGX is that any context of execution running in non-enclave mode cannot access virtual addresses that are within an initialized ELRANGE of an enclave, regardless of the privilege level that the context of execution is running with. While running in enclave mode a context of execution has free access to any address that is in the virtual address space of the process that initialized the enclave.
There may be an open question of whether or not the EDL/sgx_edger8 architecture makes it easy for an enclave to generically access the global address space of its supporting application, but I do not believe the case can be made that this is an SGX hardware imposed limitation.
Corrections to this notion fully embraced however.
Have a good week.