文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

AndroidNativefdsan检测工具介绍

2023-02-10 12:00

关注

正文

本文分析基于Android T(13)

fdsan,全名为file descriptor sanitizer,是Android中的一种检测工具,用于检测fd的use-after-close和double-close错误。这两个错误会给设备留下安全漏洞,甚至造成数据泄露等安全问题。然而现实情况是这两种错误非常隐蔽,且难以排查。这才催生了fdsan的诞生。

fdsan由Google的工程师Josh Gao开发。最初在Android 10中引入,检测到错误时会打印log并继续运行。Android 11更改了运行模式,一旦检测到错误就立即abort,让问题暴露得更加醒目。

要让这些问题可以被检测,关键是要构建fd的所有权体系。

这套体系的建立有两个重要前提:

一个fd由生到死的所有者

基于这两个条件,fdsan使用一个64-bit的tag来表明一个fd由生到死的所有者。

tag组成

tag由两部分组成,最高位的8-bit构成type,后面的56-bit构成value。Type表示fd通过何种封装形式进行管理,譬如ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD就表示fd通过unique_fd进行管理。

对于应用工程师而言,他们接触到的大多为Java/Kotlin代码,因此Java中常用的FileInputStream/FileOutputStream/ParcelFileDescriptor等封装形式也有相应的type。

详细列表如下。

enum android_fdsan_owner_type {
  
  ANDROID_FDSAN_OWNER_TYPE_GENERIC_00 = 0,
  ANDROID_FDSAN_OWNER_TYPE_GENERIC_FF = 255,
  
  ANDROID_FDSAN_OWNER_TYPE_FILE = 1,
  
  ANDROID_FDSAN_OWNER_TYPE_DIR = 2,
  
  ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD = 3,
  
  ANDROID_FDSAN_OWNER_TYPE_SQLITE = 4,
  
  ANDROID_FDSAN_OWNER_TYPE_FILEINPUTSTREAM = 5,
  
  ANDROID_FDSAN_OWNER_TYPE_FILEOUTPUTSTREAM = 6,
  
  ANDROID_FDSAN_OWNER_TYPE_RANDOMACCESSFILE = 7,
  
  ANDROID_FDSAN_OWNER_TYPE_PARCELFILEDESCRIPTOR = 8,
  
  ANDROID_FDSAN_OWNER_TYPE_ART_FDFILE = 9,
  
  ANDROID_FDSAN_OWNER_TYPE_DATAGRAMSOCKETIMPL = 10,
  
  ANDROID_FDSAN_OWNER_TYPE_SOCKETIMPL = 11,
  
  ANDROID_FDSAN_OWNER_TYPE_ZIPARCHIVE = 12,
};

tag中的value主要用作唯一性标识。对于native层的封装(譬如unique_fd)而言,value为封装对象的指针值;对于Java层的封装(譬如FileInputStream)而言,value为封装对象的hash code。这两种值在同一个进程里都具有唯一性。

tag的创建和检验过程

了解完tag的构成后,接下来便是tag的创建和检验过程。

通过封装对象创建相应fd时(通常在对象的构造函数内),tag便会创建。而所有的close都会去进行tag检验,不论该close是通过封装对象的析构调用还是直接调用。举个例子,当一个fd通过FileInputStream创建时,对象回收期间便会close fd。可是如果我们不小心将此fd传到了JNI函数中,通过close函数直接去操作它,那么检测时我们就会发现:期望的tag是一个非零值(由type和value构成),实际的tag为0(通过原生close函数进行操作时tag为0),继而报错。

典型的报错log如下(与上述例子无关),一个通过opendir打开的fd,最终却直接通过close关闭,而不是closedir。

pid: 610, tid: 610, name: lmkd  >>> /system/bin/lmkd <<<
uid: 1069
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: 'fdsan: attempted to close file descriptor 15, expected to be unowned, actually owned by DIR* 0x745b003c00'
    x0  0000000000000000  x1  0000000000000262  x2  0000000000000006  x3  0000007fc8696f90
    x4  0000000000000000  x5  0000000000000000  x6  0000000000000000  x7  0000000000000010
    x8  00000000000000f0  x9  643eeef5a527dc04  x10 0000000000000001  x11 0000000000000000
    x12 0000000000000008  x13 0000000060345fc8  x14 000216096eb6f000  x15 000024dad07fc39e
    x16 000000745b715948  x17 000000745b6f4390  x18 000000745c0bc000  x19 0000000000000262
    x20 0000000000000262  x21 000000745bc34000  x22 000000745cfdeb5c  x23 0000000000000003
    x24 0000007fc8697080  x25 ffffff80ffffffc8  x26 0000007fc8696d00  x27 0000007fc8696cc0
    x28 0000000000000000  x29 0000007fc8697020
    lr  000000745b6abf4c  sp  0000007fc8696c40  pc  000000745b6abf6c  pst 0000000000001000
backtrace:
      #00 pc 000000000008df6c  /apex/com.android.runtime/lib64/bionic/libc.so (fdsan_error(char const*, ...)+588)
      #01 pc 000000000008dc68  /apex/com.android.runtime/lib64/bionic/libc.so (android_fdsan_close_with_tag+740)
      #02 pc 000000000008e3d0  /apex/com.android.runtime/lib64/bionic/libc.so (close+16)
      #03 pc 000000000000b110  /system/bin/lmkd (start_wait_for_proc_kill(int)+184)
      #04 pc 000000000000a45c  /system/bin/lmkd (find_and_kill_process(int, int, char const*, meminfo*, timespec*, bool)+744)
      #05 pc 00000000000098a0  /system/bin/lmkd (mp_event_common(int, unsigned int, polling_params*)+2140)
      #06 pc 000000000000ba1c  /system/bin/lmkd (call_handler(event_handler_info*, polling_params*, unsigned int)+64)
      #07 pc 00000000000053a8  /system/bin/lmkd (main+2440)
      #08 pc 000000000008506c  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108)

且慢,讨论了这么久的tag到底存在什么地方?可以肯定的是存在一个全局的table中,由于fd是一个32768以内的整数,因此可以将fd作为table的索引。此外,Josh将这个table设计成可扩容的,初始大小为128,扩容后可以存放下所有fd的tag。这样对于大多数fd创建数量较少的进程,便可以使用较小的table来节省内存。

fdsan自引入之际便全局打开,对于保障系统的安全至关重要。但受限于它的原理,仍然有一些fd的use-after-close和double-close错误无法被检出。它们是:

除了检测fd的错误外,存在全局table中的tag数据在生成tombstone时也会输出,表示每个fd的ownership。unowned表明该fd的创建未接入fdsan。

open files:
...
fd 47: /data/app/~~TPUHOtvHOT-iL2f4uUrFSg==/com.tencent.mm-FKuS1oTvzRpPMOXX-SE_ZQ==/base.apk (owned by ZipArchive 0xfffd2ae7dd90)
fd 48: /data/app/~~TPUHOtvHOT-iL2f4uUrFSg==/com.tencent.mm-FKuS1oTvzRpPMOXX-SE_ZQ==/split_config.arm64_v8a.apk (owned by ZipArchive 0xfffd2ae82390)
fd 49: /data/app/~~TPUHOtvHOT-iL2f4uUrFSg==/com.tencent.mm-FKuS1oTvzRpPMOXX-SE_ZQ==/split_config.en.apk (owned by ZipArchive 0xfffd2ae83ac0)
fd 50: /data/app/~~TPUHOtvHOT-iL2f4uUrFSg==/com.tencent.mm-FKuS1oTvzRpPMOXX-SE_ZQ==/split_config.hdpi.apk (owned by ZipArchive 0xfffd2ae84e00)
fd 51: /data/data/com.tencent.mm/files/splitcompat/2103/verified-splits/delivery.config.arm64_v8a.apk (owned by ZipArchive 0xfffd2ae80b10)
fd 52: /data/data/com.tencent.mm/files/splitcompat/2103/verified-splits/delivery.apk (owned by ZipArchive 0xfffd2ae803a0)
fd 53: anon_inode:[eventfd] (owned by unique_fd 0xfffd7ae85e84)
fd 54: anon_inode:[eventpoll] (owned by unique_fd 0xfffd7ae85edc)
fd 55: anon_inode:[eventfd] (owned by unique_fd 0xfffd7ae99ce4)
fd 56: anon_inode:[eventpoll] (owned by unique_fd 0xfffd7ae99d3c)
fd 57: /data/app/~~TPUHOtvHOT-iL2f4uUrFSg==/com.tencent.mm-FKuS1oTvzRpPMOXX-SE_ZQ==/base.apk (unowned)
fd 58: /data/app/~~TPUHOtvHOT-iL2f4uUrFSg==/com.tencent.mm-FKuS1oTvzRpPMOXX-SE_ZQ==/split_config.arm64_v8a.apk (unowned)

最后值得注意的一点是,fdsan在vfork得到的子进程里是不工作的。原因是vfork得到的子进程虽然会拷贝父进程的fd,但是使用的地址空间仍然属于父进程。因此fd和存储fd tag的内存产生了错配,在子进程中操作fd不会被父进程感知到,而tag的修改则会直接影响父进程的table。

【参考文档】 android.googlesource.com/platform/bi…

以上就是Android Native fdsan检测工具介绍的详细内容,更多关于Android Native fdsan检测工具的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯