Android MTE技术详解

这篇具有很好参考价值的文章主要介绍了Android MTE技术详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.MTE概念

        MTE(内存标记扩展)是ARM v8.5-A新增的一项缓解内存安全的机制。在Android Linux现有的安全机制中,类似的机制有ASAN、HWSAN。但两者因为性能开销代价昂,不适用于广泛部署(仅调试使用)。MTE当前带来了一种高性能、可扩展的硬件解决方案,可降低以不安全语言编写的代码中可能存在的内存安全违规风险。

注:MTE不仅可用在研发自测、内存问题调试,也可以用于Fuzz。

2.MTE支持条件

ARM解释: v8.5及以上

Qcom平台解释:ARM v9(MSM8450)以上

Android解释:Android对MTE的支持将在2021年/2022年初发布带有MTE的芯片时完成。截至于2023年底,最新的旗舰设备(Pixel、OPPO)开发者选项中已具备MTE功能。

3.MTE的开关

        内核层CONFIG_ARM64_MTE=y时开启,此Kconfig由平台根据环境自行控制,无需工程师手动开关。依赖情况如下:

1687config ARM64_MTE

1688 bool "Memory Tagging Extension support"

1689 default y

1690 depends on ARM64_AS_HAS_MTE && ARM64_TAGGED_ADDR_ABI

1691 depends on AS_HAS_ARMV8_5

1692 # Required for tag checking in the uaccess routines

1693 depends on ARM64_PAN

1694 depends on AS_HAS_LSE_ATOMICS

1695 select ARCH_USES_HIGH_VMA_FLAGS

1696 help

        Google Play中也提供了APP(Sanitizer Test APP[外网,需要科学上网])可用于测试MTE,例如:

Android MTE技术详解,Security,android,漏洞缓解,内存安全

4.MTE检测目标

MTE认为内存安全违规主要分2种:空间安全、时间安全。

  • 空间安全:

对象在真实边界之外被访问,例如溢出、越界等。可被利用来改变函数指针、保存寄存器等目标地址。

  • 时间安全:

在对象引用的内存释放、过期后使用。例如UAF等,攻击者可以放置一个新的恶意对象来代替预期目标。

下图是两类内存违规的代码表视图:

Android MTE技术详解,Security,android,漏洞缓解,内存安全

5.MTE的检测原理

  • 总体思路

        MTE实现了对内存的锁和密钥的验证关系,通过在指针上增加密钥,在内存中加入锁。在指针访问内存时,密钥与锁进行验证。如果匹配,则允许内存访问;否则访问会被记录、拦截。通过这种方式来检测、捕捉内存安全问题。整体逻辑如下图:

Android MTE技术详解,Security,android,漏洞缓解,内存安全

  • 技术实现

        ARM64 架构使用64位指针来寻址内存。其中通常有48~52位被硬件实际使用(如果由开启large-address-space,则是52位)。所以理论上有12-16位是预留的。ARM架构一直有“TOP BYTE IGNORE”高字节忽略的功能,允许软件在虚拟地址的最高字节中存储任意数据,但直到MTE前,这些位依然是没有使用。

        MTE允许在虚拟地址的59-56位(即最上层字节的低4位)存储一个key作为密钥。也会将这个密钥与一个或多个16字节的内存范围关联(单独存储作为“锁”)。当一个指针简介访问此内存区域时,存储在指针中的密钥会与指针引用内存的关联密钥进行校验。

  • 密钥来源

        密钥可以由应用程序管理(keymaster)产生,也可以由CPU随机生成。

6.MTE的实际效果

        以2020年修复libjpeg-trubo库漏洞CVE-2020-13790为例。此漏洞是JPEG图像编解码器,在加载格式错误的img文件时导致的堆缓冲区溢出。以下是MTE开启时,漏洞触发的情景:

可以看到,在漏洞复现时,MTE轻松的捕获到,进程会因为分段错误导致中止。故障的存储会通过logcat打印。从图中可以看到:

Android MTE技术详解,Security,android,漏洞缓解,内存安全

  • 奔溃的原因:MTE
  • 崩溃的类型:Buffer Overflow
  • 堆的大小以及溢出的大小:104 bytes right of a 16151-byte
  • 问题地址:pc指针(00000056d2240ddc)
  • 进程id:pid=187,tid=187
  • CPU寄存器信息
  • 堆栈的回溯信息

通过addr2line解析pc指针,可以找到问题出现的地址:

Android MTE技术详解,Security,android,漏洞缓解,内存安全

7.MTE的处理措施

        当PROT_MTE(相关特性:页表允许MTE分配标签)已开启,并且检测出异常时,有三种不同的选项:

  • Ignore模式(PR_MTE_TCF_NONE):这是默认模式。CPU和内核将忽略MTE检测错误;如果未设置,也默认此选项。
  • 同步模式(PR_MTE_TCF_SYNC):内核引发SIGSEGV同步,并且引发SEGV_MTESERR和si_code=fauly-address。并且内存访问会被拦截,如果SIGSEGV被阻塞或忽略,则包含的进程将通过coredump中止。
  • 异步模式(PR_MTE_TCF_ASYNC):在一个或多个线程检测错误后内核引发SIGSEGV,并设置SEGV_MTAERR和si_code=0;

8.MTE的性能开销

Android MTE技术详解,Security,android,漏洞缓解,内存安全

以上是官方给出的性能开销结论:

同步模式:能够识别精确指令和地址,但对性能开销较大;

异步模式:成本更低,再测试工作负载和基准测试中,性能开销估计为:1%~2%,但异步检测提供是失败信息可能不太准确,但它可以提供一些缓解错误信息并用于分析,以便缩小排查范围

9.上手实效

        据2023年8月,Google Project Zero发布的一篇博文《Fitst handset with MTE on market》呈现,博主在Pixel 8上开启了MTE,正常日常使用中未发现任何异常,也没有感受到性能受到影响。

        作为世界顶级安全团队的Zero,自然也编写了一个具备OOB的Poc进行测试,源码如下:

extern "C" JNIEXPORT jstring JNICALL

Java_com_example_mtetestapplication_MainActivity_stringFromJNI(

        JNIEnv* env,

        jobject /* this */) {

    char* ptr = strdup("test string");

  free(ptr);

  // Use-after-free when ptr is accessed below.

    return env->NewStringUTF(ptr);

}

测试的结果如下(视频请参考原始地址),以下仅为logcat打印,可以明显看到崩溃原因是testapplication程序发生了UAF。

EBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

DEBUG   : Build fingerprint: 'google/shiba/shiba:14/UD1A.230803.041/10808477:user/release-keys'

DEBUG   : Revision: 'MP1.0'

DEBUG   : ABI: 'arm64'

DEBUG   : Timestamp: 2023-10-24 16:56:32.092532886+0200

DEBUG   : Process uptime: 2s

DEBUG   : Cmdline: com.example.mtetestapplication

DEBUG   : pid: 24147, tid: 24147, name: testapplication  >>> com.example.mtetestapplication <<<

DEBUG   : uid: 10292

DEBUG   : tagged_addr_ctrl: 000000000007fff3 (PR_TAGGED_ADDR_ENABLE, PR_MTE_TCF_SYNC, mask 0xfffe)

DEBUG   : pac_enabled_keys: 000000000000000f (PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY)

DEBUG   : signal 11 (SIGSEGV), code 9 (SEGV_MTESERR), fault addr 0x0b000072afa9f790

DEBUG   :     x0  0000000000000001  x1  0000007fe384c2e0  x2  0000000000000075  x3  00000072aae969ac

DEBUG   :     x4  0000007fe384c308  x5  0000000000000004  x6  7274732074736574  x7  00676e6972747320

DEBUG   :     x8  0000000000000020  x9  00000072ab1867e0  x10 000000000000050c  x11 00000072aaed0af4

DEBUG   :     x12 00000072aaed0ca8  x13 31106e3dee7fb177  x14 ffffffffffffffff  x15 00000000ebad6a89

DEBUG   :     x16 0000000000000001  x17 000000722ff047b8  x18 00000075740fe000  x19 0000007fe384c2d0

DEBUG   :     x20 0000007fe384c308  x21 00000072aae969ac  x22 0000007fe384c2e0  x23 070000741fa897b0

DEBUG   :     x24 0b000072afa9f790  x25 00000072aaed0c18  x26 0000000000000001  x27 000000754a5fae40

DEBUG   :     x28 0000007573c00000  x29 0000007fe384c260

DEBUG   :     lr  00000072ab35e7ac  sp  0000007fe384be30  pc  00000072ab1867ec  pst 0000000080001000

DEBUG   : 98 total frames

DEBUG   : backtrace:

DEBUG   :       #00 pc 00000000003867ec  /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::ScopedCheck::Check(art::ScopedObjectAccess&, bool, char const*, art::(anonymous namespace)::JniValueType*) (.__uniq.99033978352804627313491551960229047428)+1636) (BuildId: a5fcf27f4a71b07dff05c648ad58e3cd)

DEBUG   :       #01 pc 000000000055e7a8  /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::CheckJNI::NewStringUTF(_JNIEnv*, char const*) (.__uniq.99033978352804627313491551960229047428.llvm.6178811259984417487)+160) (BuildId: a5fcf27f4a71b07dff05c648ad58e3cd)

DEBUG   :       #02 pc 00000000000017dc  /data/app/~~lgGoAt3gB6oojf3IWXi-KQ==/com.example.mtetestapplication-k4Yl4oMx9PEbfuvTEkjqFg==/base.apk!libmtetestapplication.so (offset 0x1000) (_JNIEnv::NewStringUTF(char const*)+36) (BuildId: f60a9970a8a46ff7949a5c8e41d0ece51e47d82c)

...

DEBUG   : Note: multiple potential causes for this crash were detected, listing them in decreasing order of likelihood.

DEBUG   : Cause: [MTE]: Use After Free, 0 bytes into a 12-byte allocation at 0x72afa9f790

DEBUG   : deallocated by thread 24147:

DEBUG   :       #00 pc 000000000005e800  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::Allocator<scudo::AndroidConfig, &(scudo_malloc_postinit)>::quarantineOrDeallocateChunk(scudo::Options, void*, scudo::Chunk::UnpackedHeader*, unsigned long)+496) (BuildId: a017f07431ff6692304a0cae225962fb)

DEBUG   :       #01 pc 0000000000057ba4  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::Allocator<scudo::AndroidConfig, &(scudo_malloc_postinit)>::deallocate(void*, scudo::Chunk::Origin, unsigned long, unsigned long)+212) (BuildId: a017f07431ff6692304a0cae225962fb)

DEBUG   :       #02 pc 000000000000179c  /data/app/~~lgGoAt3gB6oojf3IWXi-KQ==/com.example.mtetestapplication-k4Yl4oMx9PEbfuvTEkjqFg==/base.apk!libmtetestapplication.so (offset 0x1000) (Java_com_example_mtetestapplication_MainActivity_stringFromJNI+40) (BuildId: f60a9970a8a46ff7949a5c8e41d0ece51e47d82c)

  10.结论

        从目前看来,启用MTE在性能、续航上的削弱并不明显,但在安全上的提升十分显著。是这些年来继CFI后最重要的商用安全特性(小编自己评的,如果不准确,请不要喷我)。许多0-click的攻击面都会涉及大量C/C++的安全问题。当前MTE也不是内存安全的最终答案,开启后能够提高安全性,但不意味着安全万无一失,文章来源地址https://www.toymoban.com/news/detail-829052.html

11.参考资料

参考资料 链接
Kernel 5.15.0-rcl MTE https://www.kernel.org/doc/html/latest/arm64/memory-tagging-extension.html
Tools and Software Tools and Software
ARM Developer MTE LWN:Arm64的内存标记扩展功能!-CSDN博客
CSDN LWN:ARM64的内存标记扩展功能 https://developer.arm.com/architectures/cpu-architecture/a-profile?&_ga=2.256687755.1292256680.1566735535-2019613222.1563850500#mte
ARM MTE白皮书 https://www.wwwbuild.net/androidperf/74222.html

到了这里,关于Android MTE技术详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android网络安全配置network_security_config

    Android开发中如果采用的okhttp作为网络请求框架,则可以使用Chucker实现手机网络请求日志打印: 但是上面的方式有局限性,所以测试经常会用到网络抓包来查看网络请求错误。 在Android6.0 及以下系统可以抓包,而 Android7.0 及以上系统不能再抓包了,因为Android7.0及以上系统版本

    2024年02月12日
    浏览(38)
  • 【Android】Mobile-Security-Framework-MobSF Manifest 静态扫描规则

    移动安全框架(MobSF)是一个自动化的一体化移动应用程序(Android/iOS/Windows)测试、恶意软件分析和安全评估框架,能够执行静态和动态分析。MobSF支持移动应用程序二进制文件(APK、XAPK、IPA和APPX)以及压缩源代码,并提供REST API,可与您的CI/CD或DevSecOps管道无缝集成。动态

    2024年02月12日
    浏览(36)
  • Android网络安全配置network-security-config区分正式服和测试服

    在Android开发中,为了帮助测试人员进行抓包,一般都会在Android的AndroidManifest.xml文件中配置network_security_config。不过,这也带来了一些安全性的问题,所以我们通常的策略是:线上的版本不支持抓包,测试版本支持抓包即可。为此,我们需要单独为正式服和测试服单独的进行

    2024年02月17日
    浏览(40)
  • Android之内存泄漏与内存溢出

    内存泄漏(memory leak):是指程序在申请内存后,无法释放已申请的内存空间,导致系统无法及时回收内存并且分配给其他进程使用。通常少次数的内存无法及时回收并不会到程序造成什么影响,但是如果在内存本身就比较少获取多次导致内存无法正常回收时,就会导致内存

    2024年02月13日
    浏览(48)
  • Android内存泄漏分析及检测工具LeakCanary简介,Android进阶

    @Synchronized override fun expectWeaklyReachable( watchedObject: Any, description: String ) { if (!isEnabled()) { return } removeWeaklyReachableObjects() val key = UUID.randomUUID() .toString() val watchUptimeMillis = clock.uptimeMillis() val reference = KeyedWeakReference(watchedObject, key, description, watchUptimeMillis, queue) SharkLog.d { \\\"Watching \\\" +

    2024年04月25日
    浏览(39)
  • 【Android 性能优化:内存篇】——WebView 内存泄露治理

    背景:笔者在公司项目中优化内存泄露时发现WebView 相关的内存泄露问题非常经典,一个 Fragment 页面使用的 WebView 有多条泄露路径,故记录下。 项目中一个Fragment 使用 Webview,在 Fragment onDestroyView 时候却没有释放,释放 WebView 还不简单嘛,于是笔者在 Fragment 的 onDestroyView 补充

    2024年02月04日
    浏览(44)
  • android 如何分析应用的内存(十七)——使用MAT查看Android堆

    前一篇文章,介绍了使用Android profiler中的memory profiler来查看Android的堆情况。 如Android 堆中有哪些对象,这些对象的引用情况是什么样子的。 可是我们依然面临一个比较严峻的挑战:不管是app开发者,还是内存分析者而言,堆中的对象,非常之多,不仅有Android 原生的类,还

    2024年02月13日
    浏览(69)
  • Android MemoryFile 共享内存

    应用场景: 跨进程传输大数据,如文件、图片等; 技术选型: 共享内存–MemoryFile; 优点: 1. 共享内存没有传输大小限制,所以和应用总的分配内存一样(512MB); 2. MemoryFile 是对 SharedMemory 的包装,使用简单便于管理; 实现步骤: (以A进程共享文件a.txt给B进程为例) A进程

    2024年02月20日
    浏览(17)
  • Android中的内存管理

    1.内存管理机制概述 1.分配机制: 安卓系统会为每个进程合理的分配内存,从而保证每个进程能正常运行。而不至于内存不够使用或者每个进程占用太多的内存。 2.回收机制 操作系统在内存不足的时候,它会有一个合理的回收和再分配的机制。 从而保证新的进程能够正常运

    2024年02月07日
    浏览(32)
  • Android 内存管理

            我司存在内存为1G RAM的设备,属于低内存设备,经常会出现内存很紧张的场景,也容易因此导致一系列七七八八的边际问题,故有必要了解Android系统的内存相关知识: 了解内存的分配、回收方式 了解OOM、LMK的相关机制 了解Android系统内存相关调试方式 了解Andro

    2024年02月11日
    浏览(18)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包