在启用 MTE 的 Pixel 8 上获取内核代码执行

在本文中,我将介绍CVE-2023-6241,这是我在 2023 年 11 月 15 日向 Arm 报告的 Arm Mali GPU 漏洞,该漏洞已在 2023 年 12 月 14 日公开发布的Arm Mali 驱动程序版本r47p0中得到修复。Android 已在3 月的安全更新中修复了该漏洞。此漏洞一旦被利用,可让恶意 Android 应用在设备上获得任意内核代码执行和 root 权限。该漏洞会影响使用命令流前端 (CSF)功能的较新 Arm Mali GPU 设备,例如 Google 的 Pixel 7 和 Pixel 8 手机。此漏洞的有趣之处在于,它是 Arm Mali GPU 内存管理单元中的一个逻辑错误,它能够绕过内存标记扩展 (MTE),这是 Pixel 8 中首次支持的一种新的、强大的内存损坏缓解措施。在这篇文章中,我将展示如何使用此错误从不受信任的用户应用程序在 Pixel 8 中获取任意内核代码执行。我已经确认,即使按照这些说明启用内核 MTE,该漏洞也能成功发挥作用。

Arm64 MTE MTE 是较新的 Arm 处理器上一个非常详尽的功能,它使用硬件实现来检查内存损坏。由于已经有很多关于 MTE 的优秀文章,我将仅简要介绍 MTE 的概念并解释其与其他内存损坏缓解措施相比的重要性。有兴趣了解更多细节的读者可以查阅这篇文章和Arm 发布的白皮书。

虽然 Arm64 架构使用 64 位指针来访问内存,但通常不需要使用这么大的地址空间。实际上,大多数应用程序使用的地址空间要小得多(通常为 52 位或更少)。这使得指针中的最高位未使用。内存标记的主要思想是使用地址中的这些较高位来存储“标记”,然后可以使用该标记来检查与该地址关联的内存块中存储的其他标记。这有助于缓解以下常见类型的内存损坏:

在线性溢出的情况下,指针用于取消引用相邻的内存块,该内存块的标记与指针中存储的标记不同。通过在取消引用时检查这些标记,可以检测到损坏的取消引用。对于释放后使用类型的内存损坏,只要每次释放内存块时清除内存块中的标记并在分配内存块时重新分配新标记,取消引用已释放和回收的对象也会导致指针标记与内存中的标记之间出现差异,从而可以检测到释放后使用。

(上图来自Arm发布的《Memory Tagging Extension:通过架构增强内存安全性》)

内存标记与之前的缓解措施(例如内核控制流完整性 (kCFI))不同的主要原因在于,与其他会破坏漏洞利用后期阶段的缓解措施不同,MTE 是一种非常早期的缓解措施,它会在内存损坏首次发生时尝试捕获它。因此,它能够在攻击者获得任何能力之前非常早期地阻止漏洞利用,因此很难绕过。它引入了检查,可以有效地将不安全的内存语言转变为内存安全的语言,尽管只是概率上的。

理论上,内存标记可以单独用软件实现,方法是让内存分配器在每次分配或释放内存时分配和删除标记,并在取消引用指针时添加标记检查逻辑。然而,这样做会导致性能成本,使其不适合生产使用。因此,需要硬件实现来降低性能成本并使内存标记可用于生产。硬件支持是在ARM 架构的v8.5a 版本中引入的,其中引入了额外的硬件指令(称为 MTE)来执行标记和检查。对于 Android 设备,大多数支持 MTE 的芯片组使用 Arm v9 处理器(而不是 Arm v8.5a),目前只有少数设备支持 MTE。

MTE 的一个限制是,与所有可能分配的内存块相比,可用的未使用位数很少。因此,标签冲突不可避免,许多内存块将具有相同的标签。这意味着损坏的内存访问仍可能偶然成功。实际上,即使仅使用 4 位标签,成功率也会降低到 1/16,这仍然是防止内存损坏的相当强大的保护。另一个限制是,通过使用 Spectre 等旁道攻击泄露指针和内存块值,攻击者可能能够确保损坏的内存访问是使用正确的标签进行的,从而绕过 MTE。然而,这种类型的泄露大多只对本地攻击者可用。Mark Brand 的系列文章《MTE 实施》深入研究了 MTE 对各种攻击场景的局限性和影响。

除了硬件使用实现 Arm v8.5a 或更高版本的处理器外,启用 MTE 还需要软件支持。目前,只有 Google 的 Pixel 8 允许用户在开发者选项中启用 MTE ,并且默认情况下 MTE 处于禁用状态。在内核中启用 MTE还需要额外的步骤。

Arm Mali GPU

Arm Mali GPU 可以集成到各种设备中(例如,请参阅Mali (GPU) Wikipedia 条目中的“实现” )。它一直是 Android 手机上一个有吸引力的目标,并且多次成为野外攻击的目标。当前的漏洞与我报告的另一个问题密切相关,是一种处理称为 JIT 内存的 GPU 内存类型的漏洞。现在我将简要介绍 JIT 内存并解释漏洞 CVE-2023-6241。

Arm Mali 中的 JIT 内存

使用 Mali GPU 驱动程序时,用户应用程序首先需要创建并初始化kbase_context内核对象。这涉及用户应用程序打开驱动程序文件并使用生成的文件描述符进行一系列ioctl调用。kbase_context对象负责管理打开的每个驱动程序文件的资源,并且对于每个文件句柄都是唯一的。

具体来说,kbase_context管理 GPU 设备和用户空间应用程序之间共享的不同类型的内存。用户应用程序可以将自己的内存映射到 GPU 的内存空间,以便 GPU 可以访问该内存,也可以从 GPU 分配内存。GPU 分配的内存由 管理,kbase_context可以映射到 GPU 内存空间,也可以映射到用户空间。用户应用程序还可以通过向 GPU 提交命令来使用 GPU 访问映射的内存。通常,内存需要由 GPU 分配和管理(本机内存),或者从用户空间导入到 GPU,然后映射到 GPU 地址空间,然后 GPU 才能访问。Mali GPU 中的内存区域由 表示kbase_va_region。与 CPU 中的虚拟内存类似,GPU 中的内存区域可能没有其整个范围由物理内存支持。nr_pages中的字段kbase_va_region指定内存区域的虚拟大小,而gpu_alloc->nents是支持该区域的实际物理页面数。从现在开始,我将把这些页面称为区域的支持页面。虽然内存区域的虚拟大小是固定的,但其物理大小可以改变。从现在开始,当我使用诸如调整大小、增大和收缩等与内存区域有关的术语时,我的意思是该区域的物理大小正在调整大小、增大或收缩。

JIT 内存是一种本机内存,其生命周期由内核驱动程序管理。用户应用程序通过向 GPU 发送相关命令来请求 GPU 分配和释放 JIT 内存。虽然大多数命令(例如使用 GPU 执行算术和内存访问的命令)都在 GPU 本身上执行,但也有一些命令(例如用于管理 JIT 内存的命令)在内核中实现并在 CPU 上执行。这些命令称为软件命令(与在 GPU(硬件)上执行的硬件命令相对)。在使用命令流前端 (CSF) 的 GPU 上,软件命令和硬件命令被放置在不同类型的命令队列中。要提交软件命令,kbase_kcpu_command_queue需要一个,可以使用 创建它。然后可以使用命令将软件命令排队。要分配或释放 JIT 内存,可以使用和类型的命令。KBASE_IOCTL_KCPU_QUEUE_CREATE ioctlKBASE_IOCTL_KCPU_QUEUE_ENQUEUEBASE_KCPU_COMMAND_TYPE_JIT_ALLOC``BASE_KCPU_COMMAND_TYPE_JIT_FREE

BASE_KCPU_COMMAND_TYPE_JIT_ALLOC命令用于

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值