Re: [PATCH v5 08/13] selftests/sgx: Handle relocations in test enclave
From: Huang, Kai
Date: Thu Aug 31 2023 - 19:13:43 EST
On Thu, 2023-08-31 at 15:41 +0200, Jo Van Bulck wrote:
> Static-pie binaries normally include a startup routine to perform any ELF
> relocations from .rela.dyn. Since the enclave loading process is different
> and glibc is not included, do the necessary relocation for encl_op_array
> entries manually at runtime relative to the enclave base to ensure correct
> function pointers.
>
> When keeping encl_op_array as a local variable on the stack, gcc without
> optimizations generates code that explicitly gets the right function
> addresses and stores them to create the array on the stack:
>
> encl_body:
> /* snipped */
> lea do_encl_op_put_to_buf(%rip), %rax
> mov %rax, -0x50(%rbp)
> lea do_encl_op_get_from_buf(%rip), %rax
> mov %rax,-0x48(%rbp)
> lea do_encl_op_put_to_addr(%rip), %rax
> /* snipped */
>
> However, gcc -Os or clang generate more efficient code that initializes
> encl_op_array by copying a "prepared copy" containing the absolute
> addresses of the functions (i.e., relative to the image base starting from
> 0) generated by the compiler/linker:
>
> encl_body:
> /* snipped */
> lea prepared_copy(%rip), %rsi
> lea -0x48(%rsp), %rdi
> mov $0x10,%ecx
> rep movsl %ds:(%rsi),%es:(%rdi)
> /* snipped */
>
> When building the enclave with -static-pie, the compiler/linker includes
> relocation entries for the function symbols in the "prepared copy":
>
> Relocation section '.rela.dyn' at offset 0x4000 contains 12 entries:
> Offset Info Type Symbol
> /* snipped; "prepared_copy" starts at 0x6000 */
> 000000006000 000000000008 R_X86_64_RELATIVE <do_encl_emodpe>
> 000000006008 000000000008 R_X86_64_RELATIVE <do_encl_eaccept>
> 000000006010 000000000008 R_X86_64_RELATIVE <do_encl_op_put_to_buf>
> 000000006018 000000000008 R_X86_64_RELATIVE <do_encl_op_get_from_buf>
> 000000006020 000000000008 R_X86_64_RELATIVE <do_encl_op_put_to_addr>
> 000000006028 000000000008 R_X86_64_RELATIVE <do_encl_op_get_from_addr>
> 000000006030 000000000008 R_X86_64_RELATIVE <do_encl_op_nop>
> 000000006038 000000000008 R_X86_64_RELATIVE <do_encl_init_tcs_page>
>
> Static-pie binaries normally include a glibc "_dl_relocate_static_pie"
> routine that will perform these relocations as part of the startup.
> However, since the enclave loading process is different and glibc is not
> included, we cannot rely on these relocations to be performed. Without
> relocations, the code would erroneously jump to the _absolute_ function
> address loaded from the local copy.
>
> Thus, declare "encl_op_array" as global and manually relocate the loaded
> function-pointer entries relative to the enclave base at runtime. This
> generates the following code:
>
> encl_body:
> /* snipped */
> lea encl_op_array(%rip), %rcx
> lea __encl_base(%rip), %rax
> add (%rcx,%rdx,8),%rax
> jmp *%rax
call *%rax
?
> ret
>
> Link: https://lore.kernel.org/all/150d8ca8-2c66-60d1-f9fc-8e6279824e94@xxxxxxxxxxxxxx/
> Link: https://lore.kernel.org/all/5c22de5a-4b3b-1f38-9771-409b4ec7f96d@xxxxxxxxxxxxxx/#r
> Signed-off-by: Jo Van Bulck <jo.vanbulck@xxxxxxxxxxxxxx>
> Reviewed-by: Jarkko Sakkinen <jarkko@xxxxxxxxxx>
Acked-by: Kai Huang <kai.huang@xxxxxxxxx>