Binder是Android上一种IPC机制,重要且较难理解。由于Linux上标准IPC在灵活和可靠性存在一定不足,Google基于OpenBinder的设计和构想实现了Binder。

本文只简单介绍其实现,并重点讨论Binder安全相关的内容。详细的Binder设计与实现分析,参考附录4篇文章。

一、Binder 实现

Android Binder由Client、Server、Service Manager和Binder驱动4个部件组成,下图引自网络。

在类UNIX系统中,进程是相互独立的,一个进程不能访问另一个进程的内存空间。然而内核控制着所有进程,因此可以暴露一个接口用作IPC。在Binder中这个接口就是/dev/binder设备,该设备由Binder内核驱动程序实现。

Binder驱动是整个Binder架构的核心,所有IPC都通过它来实现。

上图的Client与Server可以看作2个进程,其IPC通过对/dev/binder的ioctl实现。从Android源码可以看到,ioctl使用binder_write_read的结构体收发数据。

其中write_buffer包含驱动要执行的命令,read_buffer包含用户层需要执行的命令:

binder_write实现对bs->fd的ioctl()操作:

bs->fd是打开/dev/binder得到的文件描述符:

实际数据如何在进程间传输呢?

Binder驱动管理着每个进程的一部分地址空间。Binder管理的内存,对于进程是只读的,其写操作由内核模块实施。当一个进程向另一个进程发送消息时,内核在目标进程的内存空间申请一部分空间,接着直接将数据从发送进程复制进去。然后它将接收消息的具体位置,通过一个短消息通知给接收进程。因为消息在接收者的内存空间,接收者可以直接访问到消息。当进程不再需要这个数据时,它通知Binder驱动来释放这一内存块。

可以发现,数据经过了一次复制,所以Binder的效率不如共享内存。

Android中更高层次的IPC抽象,如Intent(跨进程组件间传递带有关联数据的命令),Messenger(支持跨进程消息通信的对象),ContentProvider(暴露跨进程数据管理接口的组件),均是基于Binder实现的。

二、Binder 安全

下图展示Binder IPC架构的一个简单例子。

每个通过Binder框架实现IBinder接口,允许被访问调用的对象都可被称作Binder对象。对Binder对象的调用在一个Binder事务处理(transaction)内部实现,其中包括一个对目标对象的引用、需执行方法的ID和一个数据缓冲区。

Binder驱动会将调用进程的ID(PID)和有效用户ID(EUID)自动添加到事务处理数据。被调用进程可以检查PID和EUID,然后基于内部实现逻辑来决定是否执行所请求的方法。

因为PID和EUID是由内核填写的,所以调用者进程不能通过伪造身份标识来获取超出系统允许的权限。这是Android安全模型的核心之一,所有更高层次抽象,比如权限,均是建立在它之上。调用者的PID和EUID通过类android.os.Binder的getCallingPid()和getCallingUid()来访问,他们是Android公开API的一部分。

三、Binder 令牌

Binder对象的一个重要属性是它具有跨进程、独一无二的身份标识。因此如果进程A创建了一个Binder对象,然后将之传递给进程B,进程B再将之传递给进程C,那么对这3个进程的调用,均由同一个Binder对象处理。实际上,进程A会通过内存地址直接引用Binder对象,而进程B和C使用Binder对象的句柄。

内核负责维护活动的Binder对象与它们在其他进程中的句柄之间的映射关系。因为一个Binder的标志符是独一无二的,并且由内核负责维护,所以用户空间进程除非通过IPC机制处理,否则不可能创建一个Binder对象的副本或获取相关引用(后面介绍如何获得Binder对象引用)。因此Binder对象是唯一的、不可伪造的、可通信的对象,可以作为安全令牌使用。

这也使得Android可以使用基于权能的安全模型(capability-based security)。

基于权能的安全模型中,通过赋予程序一个不可伪造的权能,授权程序对特定资源的访问权限。在Android中,Binder对象可以表示权能。

在这种使用方式下,Binder对象又被称作Binder令牌(Binder Token)。一个Binder令牌可以是一种权能,也可以是一个目标资源。一个进程拥有一个Binder令牌,授权该进程对Binder对象的完全访问控制权限,从而使其能够在目标对象上执行Binder事务处理操作。如果Binder对象实现了多个动作(基于Binder事务处理的code参数,选择要执行的动作),只要调用者拥有一个Binder对象的引用,就可以执行任意操作。如果需要更细粒度的访问控制,那么每个操作需要相应实现必要的权限检查,这通常利用调用者进程的PID和EUID来实现。

以上看到,获取了Binder对象引用(Binder令牌)后,就获取了目标Binder对象的完全访问权限,如果Binder事务处理操作涉及敏感动作,这是危险的。

在Android中,通常对于system(UID 10000)或root(UID 0)权限下运行的调用进程,允许执行所有操作,而对于其他进程要执行额外的权限检查。因此控制对一个重要Binder对象的访问,有2种方式:一是通过限制谁可以获得Binder对象的引用,另一个是执行该Binder对象动作前,检查调用者的身份标志(需要Binder对象自己实现)。

Binder对象可以没有其他功能实现,只被作为权能使用。这种模式下,多个协作进程可同时拥有同一个Binder对象,而作为服务端的进程(处理客户端请求)使用Binder令牌来验证它的客户端,就像Web服务器使用会话Cookie一样。

四、Binder 对象访问

出于安全考虑,Android控制着对Binder对象的访问,与Binder对象通信的唯一方法是使用该对象的引用。但很多Binder对象需要被全局访问的(尤其是系统服务)。分发所有Binder对象到每个进程是不切实际的,所以需要一种机制,来允许进程主动发现和获取这些Binder对象的引用。

Android使用servicemanger原生守护进程实现了这种发现机制。

servicemanger先于系统服务启动,因此系统服务在启动时,传递服务名和一个Binder对象引用到servicemanger进行注册。一旦注册成功,任何客户端都可以通过服务名获取它的Binder对象引用。然而大部分系统服务有额外的权限检查,所以获得引用不能自动确保对它所有功能的访问。

同时因为在servicemanger上注册后,任何人都可以访问该Binder对象引用,所以出于安全考虑,只有一部分在白名单内的系统进程才可以注册为系统服务。

可以通过service list命令查看已注册系统服务列表,该命令返回每个已注册服务的名称和实现的IBinder接口。

五、附录

Android进程间通信(IPC)机制Binder简要介绍和学习计划

Android深入浅出之Binder机制

Android Bander设计与实现 - 设计篇

Android Binder设计与实现 - 实现篇

ANDROID BINDER机制浅析的更多相关文章

  1. Android 进阶8:进程通信之 Binder 机制浅析

    读完本文你将了解: IBinder Binder Binder 通信机制 Binder 驱动 Service Manager Binder 机制跨进程通信流程 Binder 机制的优点 总结 Than ...

  2. 【转】Android - Binder机制

    以下几篇文章是分析binder机制里讲得还算清楚的 目录 1. Android - Binder机制 - ServiceManager 2. Android - Binder机制 - 普通servic ...

  3. Android Binder机制彻底梳理二

    根据AIDL了解整体调用流程[重点分析AIDL流程]: 在上一次https://www.cnblogs.com/webor2006/p/11741743.html中我们已经对Android Binde ...

  4. 浅谈android binder机制

    binder机制 是谷歌优化在android上更适合终端的IPC(多进程通信方式),满足系统对通信方式,传输性能和安全性的要求. 特性: 1. 用驱动程序来推进进程间的通信.2. 通过共享内存来提高性 ...

  5. Android Binder机制简单了解

    Binder -- 一种进程间通信(IPC)机制, 基于OpenBinder来实现 毫无疑问, 老罗的文章是不得不看的 Android进程间通信(IPC)机制Binder简要介绍和学习计划 浅谈Ser ...

  6. android binder机制之——(创建binder服务)

      Binder机制编程 前面的几篇文章具体介绍了android中binder机制的方方面面,相信你对binder机制已经有了较深刻的理解.俗话说得好"学以致用",以下我们就通过在 ...

  7. Android Binder机制详解:手写IPC通信

    想要掌握一样东西,最好的方式就是阅读理解它的源码.想要掌握Android Binder,最好的方式就是写一个AIDL文件,然后查看其生成的代码.本文的思路也是来自于此. 简介 Binder是Andro ...

  8. Android binder机制---概述

    1.进程间通讯的原因 目前操作系统都使用虚拟存储技术,管理内存. 假设是32位机器,0-3G是用户空间,3-4G是系统使用.虚拟内存和逻辑内存都按4K分页.这样虚拟内存和逻辑内存就存在对应关系. 一个 ...

  9. android binder机制详解

    摘要 Binder是android中一个很重要且很复杂的概念,它在系统的整体运作中发挥着极其重要的作用,不过本文并不打算从深层次分析Binder机制,有两点原因:1是目前网上已经有2篇很好的文章了,2 ...

随机推荐

  1. 按钮切换显示不同的内容(js控制)

    今天项目发现了一个jsp页面按钮切换,下面展示模块的不同显示问题,看到同事修改完之后的效果,js控制感觉特写好,所以想写把这个好的方法js记录下来,以便以后的参考. 一:先上图,了解大概的样子,如下图 ...

  2. 第2天【OS Linux发行版介绍、Linux系统基础使用入门、Linux命令帮助、Linux基础命令】

    Logout    退出系统 Gedit     文本编辑器工具 Uname –r 查看内核版本信息,uname –a 比较详细 Cat /proc/cpuinfo      查看CPU Cat /p ...

  3. leetcode Most Common Word——就是在考察自己实现split

    819. Most Common Word Given a paragraph and a list of banned words, return the most frequent word th ...

  4. utf8mb4与utf8的区别

    今天在测试小程序保存表情时,数据库插入数据时报错ER_TRUNCATED_WRONG_VALUE_FOR_FIELD: Incorrect string value: '\xF0\x9F\x98\x8 ...

  5. android studio maven 仓库的使用

    转自:http://www.cnblogs.com/sihaixuan/p/4852974.html 原文:How to distribute your own Android library thr ...

  6. Java逻辑

    1.开发简单Java应用程序 1-1:什么是程序 程序:为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合.1-2:为什么学习Java Java是现在的主流1-3:Java可以做什么 ...

  7. 0.5px的宽度的边框

    方法1:  .border {    position: relative;} .border:before {    content: "";/* 注意这里为双引号 */     ...

  8. Linux下使用systemctl命令

    systemctl命令是系统服务管理器指令,它实际上将 service 和 chkconfig 这两个命令组合到一起. 任务 旧指令 新指令 使某服务自动启动 chkconfig --level 3 ...

  9. day5-python数据类型

    数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需要定 ...

  10. SqlServer2008备份与还原(完整图示版)

    一.备份 1.在需要备份的数据库上,右键——任务——备份,如下: 2.选择备份到哪个路径和备份名字: 点击“添加”,如下, 3.上面点击“确定”后,回到第一个页面,选中刚才添加的路径和文件名 4.左上 ...