Intel® Software Guard Extensions (Intel® SGX)
Discussion board focused on hardware-based isolation and memory encryption to provide extended code protection in solutions.

Reentrant ecalls

hyunsoo
New Contributor I
1,140 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
1,043 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

0 Kudos
10 Replies
JesusG_Intel
Moderator
1,122 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




0 Kudos
hyunsoo
New Contributor I
1,117 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? 

0 Kudos
JesusG_Intel
Moderator
1,102 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

 

0 Kudos
hyunsoo
New Contributor I
1,087 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

0 Kudos
Vegan
New Contributor I
1,083 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

 

0 Kudos
JesusG_Intel
Moderator
1,068 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


0 Kudos
Vegan
New Contributor I
1,061 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
1,048 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
1,044 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


0 Kudos
JesusG_Intel
Moderator
1,031 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.


0 Kudos
Reply