BINDER SECCTX PATCH ANALYSIS
在2019年初,Binder內核模塊中添加了一項新功能。?此修補程序允許在Binder事務中發送調用方SElinux上下文。?該功能實際上是CVE-2019-2023的修復程序。?此漏洞與不正確使用getpidcon函數有關,從而導致ACL繞過。
本文研究此修補程序的詳細信息及其對安全性的影響。
getpidcon ACL繞過
關于getpidcon()使用的問題在Android中由來已久。?Jann Horn的問題報告詳細說明了硬件服務管理器容易受到攻擊,并且由于使用了不安全的getpidcon()?,已經報告了幾個類似的錯誤。?正如Jann Horn在其問題之一中所解釋的,此功能不是獲取調用過程的SELinux上下文的安全方法:
這是有問題的,因為只有在調用者知道$ pid最初引用的進程不能從僵尸過渡到死進程(通常是因為它是$ pid的父級或ptracer?getpidcon($pid)才可以安全使用。調用者可以根據$ pid指向getpidcon()之后指向的進程的年齡,驗證$ pid引用的進程在$ pid引用正確的進程之前是否已經生成。?(同一件事幾乎適用于所有引用使用PID的進程的API。)
換句話說,存在競爭條件:給定pid引用的過程可以在接收到事務的時間與對getpidcon的調用之間進行更改。
解決此設計問題的一種干凈方法是將SELinux上下文與活頁夾事務一起發送。?這就是我們今天將分析的補丁的目的。
補丁概述
補丁詳細信息可在lore.kernel.org上找到?。?提交標題為“創建節點標志以請求發送者的安全上下文”。
讓我們分析此補丁的主要部分:
// @@ -3020,6 +3027,20 @@靜態空值bind_transaction(struct bind_proc * proc,t- > 標志 = tr- > 標志;t- > 優先級 = task_nice(當前);+ if (target_node && target_node- > txn_security_ctx) {+ u32 secid;++ security_task_getsecid( proc- > tsk 和 secid);+ ret = security_secid_to_secctx(secid, & secctx, & secctx_sz);+ if (ret) {+ return_error = BR_FAILED_REPLY;+ return_error_param = ret;+ return_error_line = __LINE__;+ 轉到 err_get_secctx_failed;+ }+ extra_buffers_size + = ALIGN(secctx_sz, sizeof (u64));+ }+ if (secctx) {+ size_t buf_offset = ALIGN( tr- > data_size, sizeof ( void * )) ++ ALIGN( tr- > offsets_size, sizeof ( void * )) ++ ALIGN(extra_buffers_size, sizeof ( void * )) -+ ALIGN(secctx_sz, sizeof (u64));+ char * kptr = t- > 緩沖區 -> 數據 + buf_offset;++ t- > security_ctx = ( uintptr_t )kptr ++ binder_alloc_get_user_buffer_offset( & target_proc- > 分配 );+ memcpy(kptr, secctx, secctx_sz);+ security_release_secctx(secctx, secctx_sz);+ secctx = NULL;+ }發送綁定程序事務時,內核會檢查目標進程是否需要SELinux上下文(?target_node->txn_security_ctx?)。?可以在綁定器對象初始化上使用標志FLAT_BINDER_FLAG_TXN_SECURITY_CTX來指定此選項。
例如,硬件服務管理器啟用此功能:
//platform/system/hwservicemanager/service.cppint main () {// [...]sp < ServiceManager > 管理器 = 新 ServiceManager();setRequestingSid(manager, true);}啟用此功能后,內核會增加extra_buffers_size的大小以在之后存儲安全上下文。?收到的交易如下:
?
活頁夾接收事務緩沖區
然后,接收者可以使用getCallingPid()檢索事務中的安全上下文。
pid_t IPCThreadState :: getCallingPid() 常量{返回 mCallingPid;}// /platform/system/libhwbinder/IPCThreadState.cppstatus_t IPCThreadState :: executeCommand( int32_t cmd){// [...]structinder_transaction_data_secctx {struct binder_transaction_data transaction_data;binding_uintptr_t secctx;};binding_transaction_data_secctx tr_secctx;活頁夾數據 & tr = tr_secctx.transaction_data;如果 (cmd == ( int ) BR_TRANSACTION_SEC_CTX) {結果 = mIn.read( & tr_secctx, sizeof (tr_secctx));} 其他 {結果 = mIn.read( & tr, sizeof (tr));tr_secctx.secctx = 0 ;}// ...mCallingSid = reinterpret_cast < const char *> (tr_secctx.secctx);漏洞1:整數溢出
快速瀏覽可以確定整數溢出。
extra_buffers_size + = ALIGN(secctx_sz, sizeof (u64));用戶通過BC_TRANSACTION_SG事務完全控制BC_TRANSACTION_SG?。?如果extra_buffers_size?,?tr->data_size和tr->offsets_size等于零,則以下指令將在t->buffer->data?buf_offset?t->buffer->data之前復制安全上下文(?buf_offset為負)。
size_t buf_offset = ALIGN( tr- > data_size, sizeof ( void * )) +ALIGN( tr- > offsets_size, sizeof ( void * )) +ALIGN(extra_buffers_size, sizeof ( void * )) -ALIGN(secctx_sz, sizeof (u64));char * kptr = t- > 緩沖區 -> 數據 + buf_offset;t- > security_ctx = (binder_uintptr_t)kptr +binding_alloc_get_user_buffer_offset( & target_proc- > alloc);memcpy(kptr, secctx, secctx_sz);此漏洞被標識為CVE-2019-2181并在提交0b0509508beff65c1d50541861bc0d4973487dc5中進行了修補?。
它已在2019年9月的Android安全公告中發布.https:?//source.android.com/security/bulletin/2019-09-01.html#kernel-components
漏洞2:安全上下文覆蓋
當綁定程序事務包含BINDER_TYPE_PTR對象時,內核會在extra部分復制發送方進程的緩沖區。?我們可以在上面看到,為了存儲安全上下文,增加了extra_buffers_size?。?但是,內核不會在額外緩沖區中區分標準數據和安全上下文。?用戶可以制作一個綁定交易,該交易會覆蓋安全上下文。
BINDER_TYPE_PTR覆蓋安全上下文
這比getpidcon()競爭條件更容易繞過ACL!
此漏洞已通過名為的提交進行了修補:?活頁夾:正確設置SG緩沖區的結尾
結論
Binder內核補丁的目的是提高安全性,并提供另一種方法來檢索調用進程的上下文,以避免使用getpidcon()?。
矛盾的是,最初的補丁程序版本增加了更多的安全漏洞,并使ACL旁路比以前的漏洞更容易!
總結
以上是生活随笔為你收集整理的BINDER SECCTX PATCH ANALYSIS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 链表队列初始化
- 下一篇: 【译】Android中的安全数据— An