为什么在SGX enclave字符串参数必须与[in]属性配合使用

问题描述:

使用OCALL,我想获得一个在非信任内存中动态创建的C字符串副本到我的飞地。因此,我必须使用[out, string]属性。为什么在SGX enclave字符串参数必须与[in]属性配合使用

但是,我不能那样做,因为我还必须添加[in]属性。问题是我真的不知道字符串的大小,并且我不希望每次制作OCALL时都会从字符串不必要地复制字符串到不受信任的内存,从而导致开销([in]附带)。

我EDL文件:

enclave { 
    trusted { 
     public void ecall_open(void); 
    }; 
    untrusted { 
     void ocall_get_string([out, string] char* str); 
    }; 
}; 

error: string/wstring/sizefunc should be used with an 'in' attribute

为什么我要补充[in]属性?

出于性能的原因,有没有办法避免这种开销?

+0

开发者手册上说 “'string'和'wstring'不能 用'单独out'使用。”也许你可以让你的OCALL使用自己的ECALL把数据发送到飞地,像这样:'ocall_get_string()允许ecall_to_pass_string([in,string] char * str)''。在手册中,这是写在第59页的标题*授予访问ECALLs *。 – Daniel

我想,一个解决办法是将指针传递给char*[out]属性和长度:

void ocall_get_string([out] char** str, [out] size_t* length);

,然后手动从不可信的存储器复制C字符串使用memcpy()信赖。

内飞地:

char* untrusted_str; // pointer to string in untrusted memory that we would get form OCALL 
size_t length; // length of string 

ocall_get_string(&untrusted_str, &length); 

char *trusted_str = new char[length]; // pointer to string in trusted memory 
memcpy(trusted_str, untrusted_str, length); 

// delete it later 
delete[] trusted_str; 
+0

似乎是一个非常糟糕的做法。你相信一个不可信的长度和不可信的指针。如果攻击者会通过你一个指向你在飞地内的秘密的指针呢? – Tal

+0

@Tal,同意,但我可以调用'sgx_is_outside_enclave()'来检查我的字符串是否严格在飞地之外,对吗? – yerzhan7

+0

不要重新发明*,决定你想要的性能或安全性。 – Tal