SGXv2.8起Enclave内新增pthread库

SGX v2.8开始Enclave内部开始新增pthread库。在这之前,Enclave内部只能维护互斥量同步机制、读写锁同步机制、条件变量同步机制。如下图所示

SGX内部一开始不支持创建pthread线程的原因是因为线程的管理涉及到系统调用,这并不是用户态的Enclave能够完成的。

而现在SGXv2.8之后,为什么能支持SGX内部创建pthread线程呢?

简单来说tRTS pthread最终需要通过OCALL切换到uRTS进行线程管理,只是说tRTS内提供了一些API让SGX内部能够方便的使用pthread线程。

以【pthread_create(tRTS)】为主线来揭露tRTS pthread库的样貌

/*
 *: function: create a new thread
 *  limitation: Currently the "attr" is unused inside SGX pthread_create(). And the thread is created with "PTHREAD_CREATE_JOINABLE" attribute.
 *                      So user need to call pthread_join() to free pthread_create() created thread's resource.
 */
int pthread_create(pthread_t *threadp, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)

可以看到【pthread_create】和我们平时直接用的API接口完全一致。《pthread_create(3) — Linux manual page

不过目前【attr】这个属性参数暂不使用。

做法如下:

首先判断【start_routine】、【arg】均处于Enclave内部。

然后创建一个【pthread_t】变量。

对【pthread_t thread】初始化如下

pthread_t成员变量赋值说明

lock

SGX_SPINLOCK_INITIALIZER

 

tid

NULL

 

retval

NULL返回值

joiner_td

WAITER_TD_NULL

JOIN者的线程数据

creater_td

(sgx_thread_t)get_thread_data()

当前线程也就是创建者线程的线程数据

state

_STATE_PREPARING

 

start_routine

start_routine

Hook上入口函数
argarg传参

将【pthread_t->common_queue_elm】的地址挂到【g_work_queue】链表的尾部,期间用【g_work_queue_lock】来加锁。

创建者线程调用【pthread_create_ocall】切换上下文进入到uRST,创建新的pthread线程

extern "C" sgx_status_t pthread_create_ocall(unsigned long long self)

首先获取从传参的TCS(该线程还在tRTS时,从它的线程数据中找到)找到当前的Enclave。

然后获取一个空闲的TCS。

初始化一下属性,并将新线程设置为【PTHREAD_CREATE_DETACHED】,使用uRTS下标准的【pthread_create】函数创建线程。值得注意的是【pthread_create(uRTS)】创建的新线程的入口函数是【pthread_create_routine】,由【pthread_create_routine】到时候会去调用之前【pthread_create(tRTS)】中Hook好的真正的入口函数。

创建者线程回到tRTS,循环等待新线程,直到其状态从【_STATE_PREPARING】变成【_STATE_EXECUTION】。

新线程先开始执行【pthread_create_routine】,切换上下文进入tRTS

static void* pthread_create_routine(void* arg)

将当前Enclave的引用数加一。

将新线程的线程ID和创建者申请来给新线程的TCS进行绑定。

然后使用【CEnclave::ecall】一路切换上下文进入tRTS。可以参考《ECALL Switch模式

进入tRTS后,在查ECALL符号表时,常规ECALL回去查符号表,而此时我们这种创建tRTS pthread的情况下【ECMD_ECALL_PTHREAD】,我们会直接执行【_pthread_thread_run】

新线程执行真正的入口函数前,进行一些信息的维护,并通知创建者线程

/*
 * Note: This function is the entry point of sgx_pthread
 */
sgx_status_t _pthread_thread_run(void* ms)

先从【g_work_queue】链表头部获取当前会用到的【pthread_t】变量,里面包含了很多新线程的相关信息(之前设置过)。

更新当前线程的TLS信息【pthread_info_tls】

【__thread pthread_info pthread_info_tls】成员变量

赋值说明

m_pthread

【pthread_t thread】变量TLS所对应的线程句柄

m_local_storage

NULL

线程本地存储

更新线程句柄【pthread_t thread】

【pthread_t thread】成员变量赋值

tid

【__thread pthread_info pthread_info_tls】

state

状态赋值为【_STATE_EXECUTION】

然后唤醒创建者线程继续创建者线程自己的流程。

新线程执行当时Hook的入口函数,新线程创建完毕

//Execute the thread function
thread->start_routine(thread->arg);

新版《Intel_SGX_Developer_Reference_Linux_Open_Source》手册从2.8版本开始也有了SGX内pthread库的描述

截图来自《Intel_SGX_Developer_Reference_Linux_2.11_Open_Source》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值