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.cpp
     int main () {
         // [...]

         sp < ServiceManager > 管理器 = 新 ServiceManager();
         setRequestingSid(manager, true);
     }

启用此功能后,内核会增加extra_buffers_size的大小以在之后存储安全上下文。 收到的交易如下:

 

活页夹接收事务缓冲区

然后,接收者可以使用getCallingPid()检索事务中的安全上下文。

  pid_t IPCThreadState :: getCallingPid() 常量
     {
         返回 mCallingPid;
     }

     // /platform/system/libhwbinder/IPCThreadState.cpp
     status_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_sizetr->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旁路比以前的漏洞更容易!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值