optee patch --- Trusted OS欣赏

我准备改写它, 它在这
https://github.com/leesagacious/optee_os_patch-x64

本文将发 100 个patch,让你明白
1 : Linaro 那些“乌合之众”(????)的作者用意何在,
2 : 该patch对 Trusted OS 的影响
3 : 对 Rich OS (Linux Kernel )的影响
4 : 更好的实现方法
5 : 攻击方法 (专业Attack destroyer ????,努力尝试让TEE也挂????)

帮你彻底明白 OP-TEE Latest version changes

好,那就开始吧… 哈哈 ???? ???? (看完烦请点个赞哦, 不足之处还请下面留评论,thanks .定回复)

1:core: fix the reopen session condition for single instance TA
optee patch --- Trusted OS欣赏
首先必须要明白的是
1 : 它的调用流程
2 : Trusted Application instance types

1:调用流程

/*
	该函数是它的直接调用者, 
	该函数名字如意思 就是想初始化一个tee_ta_session
	该tee_ta_session在本函数中是一个局部变量,最后本函数执行成功后会通过第4个
	参数传出.
	
	我们先看看它的caller传递给它哪些 resources, 
	下面A-0流程图显示该函数的"领导梯队"

    *err : 返回值
           看,上面的patch 重要性可见一斑了,如果 if 有失误(或者通过其他的方法destroy,就像patch fault一样),
           session别想打开了,后面的一切都别想了,
           
    *open_sessions : 一个全局的链表 tee_open_sessions ,
           链表的作用无需多说,session都往上挂接吧, 
           什么时候用到了,直接find_session()取出
           这里是一个可以改进的点,要找一个session,需要把链表全部查询一次,难道hash表做不到吗
    
    *uuid : 这个重要了,身份证号, 
            Each Trusted Application is identified by a Universally Unique Identifier
            好吧,以后会经常提到它的,这里先放放  

    **sess : out 参数,既有传出 又有传入 你家是开高速公路吧 ?  

   该函数的参数就决定了该函数能做什么, 就给你这么多资源,你自己玩吧 
   
   看到了吧,其实就是一个 UUID 在孤军深入, 其余的都是 no value !     
*/
static TEE_Result tee_ta_init_session(TEE_ErrorOrigin *err,
				    struct tee_ta_session_head *open_sessions,
				    const TEE_UUID *uuid,
				    struct tee_ta_session **sess)
{
    /*
        上来你就弄一个返回值 嘿嘿????
     */
    TEE_Result res;
	
    /*
	    好了,下面会调用 tee_ta_context_find() 查找tee_ta_ctx 了
	    查找的依据就是那个 UUID,关键的是 找到了 tee_ta_ctx 它做了什么
        就是本PATH的意思
	    tee_ta_ctx  : Context of a loaded TA, 这里和 Linux Kernel 中的 Task Context 大一不样
    */
    struct tee_ta_ctx *ctx;
    
    /*
    	分配内存空间->赋值->挂接全局链表, 
    	挂接链表方便以后find, remove,insert,地球人都知道了
    */
    struct tee_ta_session *s = calloc(1, sizeof(struct tee_ta_session));
    *err = TEE_ORIGIN_TEE;
    if (!s)
	return TEE_ERROR_OUT_OF_MEMORY;
		
    /*
       mask ? 却是一个 bool 
       client 可以随时取消打开一个session 
       关于这个 MaskCancellation 的问题有一大堆干货,这里不是重点
    */		
    s->cancel_mask = true;	
    /*
	    造了两把锁,
        TA_FLAG_MULTI_SESSION 会造成并发的现象? 显然不是,
	    只是多个session, 最终还是串行调用,就像 Uart 独占性一样
	*/
    condvar_init(&s->refc_cv);
    condvar_init(&s->lock_cv);
    /*
	    这个lock_thread 在 debug page fault 的时候 没少跟你打交道
	    在创建session的时候就初始化为 -1*/
    s->lock_thread = THREAD_ID_INVALID;
    /*
	    好了,重点来了 !
	    看 引用计数在这里 + 1 了
	    什么时机++ ,什么时机 -- ,为什么要++--
	    是理解该patch的一个重要的地方
    */
    s->ref_count = 1;
    /*
	    加锁了, 非重点 略过
    */
    mutex_lock(&tee_ta_mutex);
    /*
	    挂接到链表上去吧. 
    */
    TAILQ_INSERT_TAIL(open_sessions, s, link);
    /*
        根据UUID到 全局链表 tee_ctxes 链表上 查找 已经 load 的 TA 
        好,
        1 : 那么是在什么时机将 tee_ta_ctx 添加到全局链表 tee_ctxes 上的 ?
        2 : 显然这里如果找不到,我们上面的那个patch 将不会起作用了 ,????
             作者将继续 Look static TA 、user TA, 
             如果都找不到,那么就 销毁分配给的资源无奈 return 从哪儿来还会到哪里去了   

        好,下面就是本patch了 先回答上面的几个问题,在往下看吧
    */
    ctx = tee_ta_context_find(uuid);
    if (ctx) {
        res = tee_ta_init_session_with_context(ctx, s);
        if (res == TEE_SUCCESS || res != TEE_ERROR_ITEM_NOT_FOUND)
		    goto out;
    }
}								

这里只考虑运行在Rich Execution Environment 中的 Client
不考虑TA 通过内部客户端API 来担当另一个TA的 client 的场景
optee patch --- Trusted OS欣赏

optee patch --- Trusted OS欣赏

TEE_Result tee_ta_close_session (...)
{
	/*
		下面会为它们赋值
	*/
	struct tee_ta_session *sess;
	struct tee_ta_ctx *ctx;
	....
	/*
		从open_sessions 链表上查找 获取session
	*/
	sess = tee_ta_get_session((vaddr_t)csess, true, open_sessions);
	....
	/*
		获取session维护的 context TA
	*/
	ctx = sess->ctx;
	....
	/*close_session() 中将引用计数减少
		是否能顺利的减少引用计数,上面还判断了该TA是否busy
		什么样的TA是busy的,如何判断的,往下看吧
	*/
	ctx->ref_count--;
}

2 : Trusted Application instance types

1 : Multi Instance Trusted Application
2 : Single Instance Trusted Application

新增加了一个test_case ,创建了两个thread,每个thread都去open session
如下 :optee patch --- Trusted OS欣赏

对与 single instance TA ,客户端打开的所有的 session 都定向到该instance of the TA,  
所有的session 共享该TA拥有的内存空间资源,

那么single instance TA 一定支持 多会话(TA_FLAG_MULTI_SESSION)了,看下面的macro 
如果不支持TA_FLAG_MULTI_SESSION,那么一个TA 实例只支持一个 session

所以,本patch 478行,判断该TA实例是否支持多会话,
如果 不支持多会话且上一个会话还没有结束,那么就返回 TEE_ERROR_BUSY 了
它使用一个变量来标志会话是否结束在以后的patch中改变了这样的判断手法
#define PTA_MANDATORY_FLAGS	(TA_FLAG_SINGLE_INSTANCE | \
				TA_FLAG_MULTI_SESSION | \
				TA_FLAG_INSTANCE_KEEP_ALIVE)

optee patch --- Trusted OS欣赏