gramineproject / gramine

A library OS for Linux multi-process applications, with Intel SGX support
GNU Lesser General Public License v3.0
606 stars 201 forks source link

Code segment assertion in IRET instruction #2067

Open hermann-o opened 4 days ago

hermann-o commented 4 days ago

Description of the problem

In debug builds of gramine, IRET crashes the app. In my case, this looks like:

trce:  GramineApplicationSecretsProvider[0]
2024-11-21T08:52:04.752618776Z       KE IV written to [...].iv
2024-11-21T08:52:04.769629498Z assert failed ../pal/src/host/linux-sgx/pal_exception.c:157 cs == cur_cs

Here's some more debug info (adding not much insight though..)

(fs.c:409:is_open_allowed) [P1:T1:de.odiga.frontendli...] warning: Allowing access to unknown file 'System.Numerics.Vectors.dll' due to file_check_policy.
(libos_init.c:583:create_pipe) [P1:T1:de.odiga.frontendli...] debug: Creating pipe: pipe.srv:5650856448057221650/fca578a0d2ecf9a7b4d8315042a0747bd120eae7e2f7b324216bc526db3d0f13
(pal_exception.c:143:emulate_iret_and_print_warning) warning: Emulating a raw iret instruction. This degrades performance.
(pal_exception.c:157:emulate_iret_and_print_warning) assert failed ../pal/src/host/linux-sgx/pal_exception.c:157 cs == cur_cs
(pal_process.c:248:_PalProcessExit) debug: PalProcessExit: Returning exit code 1

Here's the assertion:

uc->rip = *(uint64_t*)(intptr_t)uc->rsp;
uc->rsp += 8;

/* Assume that cs register doesn't change. */
#ifdef DEBUG
    uint64_t cs = *(uint64_t*)(intptr_t)uc->rsp;
    uint64_t cur_cs = 0;
    __asm__ volatile (
        "movq %%cs, %0\n"
        : "=r"(cur_cs)
    );
    assert(cs == cur_cs);
#endif

It appears that IRET is not emulated entirely i wonder if this can have implications for my code running in release build. I tried to create little console app to showcase the issue, but wasn't able to reproduce it: Same source code, no IRET

Steps to reproduce

Expected results

app does not crash

Actual results

app crashes with assert failed ../pal/src/host/linux-sgx/pal_exception.c:157 cs == cur_cs

Gramine commit hash

93be2c23164f89def3afdc3d049bf6dd3e872401

kailun-qin commented 12 hours ago

Yeah, we assume that cs can't change while implementing IRET -- this is a known limitation that Gramine would't support otherwise. Pls see some original discussions here: https://github.com/gramineproject/gramine/pull/1166.