Intel® Software Guard Extensions (Intel® SGX)
Use hardware-based isolation and memory encryption to provide more code protection in your solutions.

Reentrant ecalls

hyunsoo
New Contributor I
529 Views

Is there a reference that explains why reentrant ecalls are harmful from the perspective of security?

Thank you

0 Kudos
1 Solution
JesusG_Intel
Moderator
432 Views

Hello Hyunsoo,


You are correct. All sorts of things can go wrong on the untrusted side.


Have we answered all your questions on why nested calls are not allowed?


Sincerely,

Jesus G.

Intel Customer Support


View solution in original post

10 Replies
JesusG_Intel
Moderator
511 Views

Hello Hyunsoo,


By "reentrant" do you mean nested ecalls, where an ocall makes an ecall?


If so, the Intel® SGX Developer Guide addresses it:


"You should be aware that when an OCall is made, it opens the door for nested ECalls. Once outside the enclave, an attacker trying to find vulnerabilities may invoke any ISV interface function exposed as an ECall to recursively call into the enclave. When an OCall is needed, you may reduce the surface attack blocking ISV interface functions such that nested ECalls are not allowed. For instance, you may store the state information (corresponding to the OCall in progress) inside the enclave. However, an enclave cannot depend on nested ECalls occurring in certain order during an OCall. Initially, nested ECalls (ECalls during an OCall) are allowed and only limited by the amount of stack reserved inside the enclave. However, ISVs should be aware that such constructs complicates the security analysis on the enclave. When the need for nested ECalls arises, the enclave writer should try to partition the application in a different manner. If nested ECalls cannot be avoided, the enclave writer should limit the ISV interface functions that may be called recursively to only those strictly required."


Sincerely,

Jesus G.

Intel Customer Support




hyunsoo
New Contributor I
506 Views

Hi G, thanks for providing good reference, but I didn't fully understand what it says.

Your first statement is exactly right. Please consider a situation like below.

t0:     ecall_func1()  // ecall_func1() calls ocall(host_func1())
t1:             host_func1()   // host_func calls another ecall (ecall_func2)
t2:     ecall_func2()  


This scenario, ecall_func1() is terminated after ecall_func2() is terminated. Maybe this scenario is treated as vulnerable. Could you help me to understand why this scenario is vulnerable? 

JesusG_Intel
Moderator
491 Views

Hello Hyunsoo,

A primary goal when securing SGX enclaves is to reduce the attack surface, which means to limit the number of ways an attacker can compromise the system via an enclave.

Enclaves do not trust the untrusted domain. Ocalls go to the untrusted domain so, in general, it is a good idea to limit the number of ocalls and avoid them if possible.

When an enclave makes an ocall, the enclave cannot assume that the ocall was implemented as the enclave expects. To be safe, the enclave has to assume that the ocall is implemented in a malicious manner. Enclaves are blind to how ocalls are implemented. Therefore, the enclave must check the results of the ocall before using them.

In your scenario, from the perspective of ecall_func1, ecall_func1 cannot assume that the host_func1 calls ecall_func2 as it should because ecall_func1 is blind to the implementation of host_func1. An attacker can replace the original, good host_func1 implementation with an implementation that does not call ecall_func2. In fact, the host_func1 can call ecall_func1 again, causing a recursion, or any other enclave function! You can see how this can get messy very quickly.

This is why calling ecalls from ocalls has been disabled.

Sincerely,

Jesus G.

Intel Customer Support

 

hyunsoo
New Contributor I
476 Views

Thanks for the kind explanation. Let me put some things.

First, attacker can make a recursion to break a program using the ROP(bypass origin control flow) as you mentioned.

Second,  attacker can call so many ecalls that are not terminated by calling many other ecalls(if the target ecall is only one, then this is the first case above). Currently, there are many ecall threads and so many TCS(Thread Control Structure) and SSA(State Save Area) are being created and later, these may be exhausted or overflowed.

And your last sentence, I think calling another encalve function is benign if that host has corresponding enclave context.

 

So, maybe, the root cause is to prevent bypassing control flow because enclave function cannot expect that host functions works with our expectation.

 

Could you comment again?

Thank you

Vegan
New Contributor I
472 Views

In general any reentrant code needs to be completely stack oriented with local variables only

 

look at how to solve the factorial function using recursion which should give some idea as to the basis for reentrant code

 

JesusG_Intel
Moderator
457 Views

Hello Hyunsoo,


An ROP attack will not work with enclaves because of the memory protections. However, in the scenario where the ocall calls the same ecall that called it, an infinite recursion may be used as a denial of service attack because the ocall will never return to the original ecall.


Sincerely,

Jesus G.

Intel Customer Support


Vegan
New Contributor I
450 Views

An infinite recursion etc will cause a stack overflow bounds check, that is part of the design of C and C++ etc

hyunsoo
New Contributor I
437 Views

Hello G,

I meant that ROP attacks can be launched on host-side, not enclave-side, so ecall(enclave-side) cannot expect that function's behavior because they are open about the vulnerability of control flow integrity.

JesusG_Intel
Moderator
433 Views

Hello Hyunsoo,


You are correct. All sorts of things can go wrong on the untrusted side.


Have we answered all your questions on why nested calls are not allowed?


Sincerely,

Jesus G.

Intel Customer Support


JesusG_Intel
Moderator
420 Views

This thread has been marked as answered and Intel will no longer monitor this thread. If you want a response from Intel in a follow-up question, please open a new thread.


Reply