导语:最近在 Linux 内核 TEE 子系统中发现了一个释放后重引用(UAF)漏洞,影响版本小于等于 5.15.11,分配了CVE编号 CVE-2021-44733。
最近在 Linux 内核 TEE 子系统中发现了一个释放后重引用(UAF)漏洞,影响版本小于等于 5.15.11,分配了CVE编号 CVE-2021-44733。
简单的UAF无法进一步利用,在对漏洞代码路径做了进一步分析,简单写了个PoC测试后发现是可以覆盖Linux内核中的函数指针的,本文没有提供权限提升的漏洞利用代码,但是在环境设置部分提供了运行OPTTE和漏洞利用的测试环境。
0x01 背景信息
TEE是Trusted Execution Environment,也就是可信执行环境,通常用于数字版权保护(Digital Rights Management)、移动支付保护、敏感数据保护。TEE的实现是基于ARM TrustZone。
需要介绍的另一个概念是REE,也就是Rich Execution Environment,被称为通用执行环境,这是所有移动设备的通用运行环境,运行Android、iOS 系统。OS的代码量庞杂很容易出现漏洞,OS可以读写APP软件中的所有数据,存在大量针对REE的高级攻击技术和漏洞利用代码。
TEE受硬件机制的保护,TEE隔离于REE,只能通过特定入口和TEE进行通信;TEE可以访问REE的内存,可以抵御某些硬件攻击。
TEE实质上是一个可信子操作系统,比如最常见的ARM CPU上的TrustZone,运行在CPU芯片中的子OS,TEE驱动程序会处理TEE OS和上层操作之间的通信。
TEE 子系统会对TEE驱动程序进行注册初始化、会管理Linux 和 TEE的共享内存、会为TEE提供通用API。
驱动程序注册初始化步骤: 1. 根据设备类型,构造所需描述驱动的结构体。该结构体需要继承struct device_driver结构,并给几个重要的成员初始化。 2. 通过module_init宏调用驱动程序的初始化函数xx_init_module,在初始化函数中注册驱动程序。 3.驱动程序会遍历总线上的struct device和struct device_driver两条链表,调用总线的match函数,对设备与驱动程序进行匹配。 4.如果设备与驱动程序匹配成功,则调用驱动程序的probe函数。 什么是注册驱动程序: 初始化函数中调用的xx_register_driver函数就是注册驱动程序,初始化函数执行其实非常简单,执行一下xx_register_driver函数就会返回,这也是Linux驱动程序的标准注册流程:module_init-->xx_init_module-->xx_register_driver。
TEE接口
include/uapi/linux/tee.h中的结构体和宏定义提供了TEE的通用使用接口,用户空间和客户端可通过打开/dev/tee[0-9] 或 /dev/teepriv[0-9] 连接TEE驱动程序。
下面是在include/uapi/linux/tee.h中定义的结构体接口:
TEE_IOC_SHM_ALLOC 分配共享内存并返回用户空间可以映射的文件描述符。当用户空间不再需要文件描述符时,它应该被关闭。当不再需要共享内存时,应该使用 munmap() 取消映射以允许重用内存。
TEE_IOC_VERSION 让用户空间知道此驱动程序处理哪个 TEE 及其功能。
TEE_IOC_OPEN_SESSION 打开一个到可信应用程序的新会话。
TEE_IOC_INVOKE 调用可信应用程序中的函数。
TEE_IOC_CANCEL 可以取消正在进行的 TEE_IOC_OPEN_SESSION 或 TEE_IOC_INVOKE。
TEE_IOC_CLOSE_SESSION 关闭与可信应用程序的会话。
mmap会将一个文件和其他对象映射到内存空间中。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定地址区域的对象映射。
TEE有两种客户端:普通客户端和请求者客户端,请求者客户端是TEE在Linux OS中的辅助进程,用于访问资源,比如文件系统访问等。普通客户端会打开 /dev/tee[0-9]*,请求者kehu客户端会打开 /dev/teepriv[0-9]。
/dev/目录下是Linux的外部设备文件,注意不是驱动文件,Linux会将所有设备认为是文件。
客户端和 TEE 之间的大部分通信对驱动程序来说是不透明的。驱动程序的主要工作是接收来自客户端的请求,将它们转发到 TEE 并将结果发回。在请求方的情况下,通信在另一个方向进行,TEE 向请求方发送请求,然后请求方将结果发回。
TEE是在安全环境中运行的可信操作系统,例如 ARM CPU 上的 TrustZone。TEE 驱动程序会处理与 TEE 通信所需的细节,驱动程序更重要的职责是为基于 Globalplatform TEE 客户端 API 规范的 TEE 提供通用 API,而且还管理 Linux 和 TEE 之间的共享内存。该子系统可以通过CONFIG_OPTEE在 ARM 架构的内核配置中进行配置来启用。
The secure world包含表示为 OP-TEE OS 的可信操作系统。在此操作系统之上,可以运行受信任应用程序 (TA),这些应用程序可以在隔离环境中执行某些操作,参见图 1。
图 1:TEE 概述
The normal world 包括Linux 用户空间和内核空间,可以使用客户端应用程序 (CA) 和 TEE 子系统公开的 API 与这些应用程序交互。CA 可以向特定 TA 打开会话并调用 TA 实现的功能。在 TA 和 CA 之间来回传递任何参数都是使用共享内存完成的。接下来描述使用所有相关系统调用的 CA 和 TA 之间的交互。
1、CA 打开/dev/tee[0-9]以与驱动程序通信。对于使用这些 API 的传统方式,这是使用 libteec 隐式完成的。
2、CA 可以使用IOCTL TEE_IOC_SHM_ALLOC。这将分配共享内存并返回一个文件描述符,用户空间可以将其用作 mmap 的一部分。
3、下一步是使用IOCTL TEE_IOC_OPEN_SESSION和指定特定 TA 的 uuid建立会话。这个 uuid 在 TA 的编译过程中是硬编码的。
4、为了调用 TA 中的特定函数,CA 通过指定函数的标识符以及输入参数来调用该函数,这里使用的是TEE_IOC_INVOKE。
5、当 CA 完成所有请求后,可以使用TEE_IOC_CLOSE_SESSION关闭会话。
客户端和 TEE 之间的大部分通信对驱动程序来说是不透明的。驱动程序的主要工作是管理上下文、接收来自客户端的请求、将它们转发到 TEE 并将结果发回 。
0x02 对 TEE 驱动器的模糊测试
CVE-2021-44733 是使用 syzkaller 模糊测试发现的,下面提供了相关的描述文件。ioctl$TEE_SHM_REGISTER_FD只是 Linaro内核树的一部分,根据 syzkaller 文档正确配置后,“Setting up the environment”中提供的环境就可以用于模糊测试了。
#include resource fd_tee0[fd] resource session_resource[int32] openat$tee0(fd const[AT_FDCWD], dev ptr[in, string["/dev/tee0"]], flags flags[open_flags], mode flags[open_mode]) fd_tee0 ioctl$TEE_OPEN_SESSION(fd fd_tee0, cmd const[0x8010a402], arg ptr[inout, tee_ioctl_buf_data_session]) ioctl$TEE_INVOKE(fd fd_tee0, cmd const[0x8010a403], arg ptr[inout, tee_ioctl_buf_data_invoke]) ioctl$TEE_CANCEL(fd fd_tee0, cmd const[0x8008a404], arg ptr[in, tee_ioctl_buf_data_cancel]) ioctl$TEE_CLOSE_SESSION(fd fd_tee0, cmd const[0x8004a405], arg ptr[in, tee_ioctl_buf_data_close]) ioctl$TEE_VERSION(fd fd_tee0, cmd const[0x800ca400], arg ptr[out, tee_ioctl_buf_data_version]) ioctl$TEE_SHM_ALLOC(fd fd_tee0, cmd const[0xc010a401], arg ptr[inout, tee_ioctl_buf_data_shm_alloc]) ioctl$TEE_SHM_REGISTER(fd fd_tee0, cmd const[0xc018a409], arg ptr[inout, tee_ioctl_buf_data_shm_register]) ioctl$TEE_SHM_REGISTER_FD(fd fd_tee0, cmd const[0xc018a408], arg ptr[inout, tee_ioctl_buf_data_shm_register_fd]) ioctl$TEE_SUPPL_RECV(fd fd_tee0, cmd const[0x8010a406], arg ptr[inout, tee_ioctl_buf_suppl_recv]) ioctl$TEE_SUPPL_SEND(fd fd_tee0, cmd const[0x8010a407], arg ptr[inout, tee_ioctl_buf_suppl_send]) # COMMON #======================================================= define TEE_IOCTL_UUID_LEN 16 tee_ioctl_param_struct { attr flags[TEE_IOCTL_PARAM_ATTR_TYPE, int64] a int64 b int64 c int64 } TEE_IOCTL_PARAM_ATTR_TYPE = 0, 1, 2, 3, 5, 6, 7 TEE_LOGIN = 0, 1, 2, 4, 5, 6 # OPEN SESSION #======================================================= tee_ioctl_buf_data_session { buf_ptr ptr64[inout, tee_ioctl_open_session_struct] buf_len len[buf_ptr, int64] } tee_ioctl_open_session_struct { uuid array[int8, TEE_IOCTL_UUID_LEN] (in) clnt_uuid array[int8, TEE_IOCTL_UUID_LEN] (in) clnt_login flags[TEE_LOGIN, int32] (in) cancel_id int32 (in) session session_resource (out) ret int32 (out) ret_origin int32 (out) num_params len[params, int32] (in) params array[tee_ioctl_param_struct] (in) } # INVOKE #======================================================= tee_ioctl_buf_data_invoke { buf_ptr ptr64[inout, tee_ioctl_invoke_struct] buf_len len[buf_ptr, int64] } tee_ioctl_invoke_struct { func int32 (in) session session_resource (in) cancel_id int32 (in) ret int32 (out) ret_origin int32 (out) num_params len[params, int32] (in) params array[tee_ioctl_param_struct] (in) } # CANCEL SESSION #======================================================= tee_ioctl_buf_data_cancel { cancel_id int32 (in) session session_resource (in) } # CLOSE SESSION #======================================================= tee_ioctl_buf_data_close { session session_resource (in) } # VERSION #======================================================= tee_ioctl_buf_data_version { impl_id int32 (out) impl_caps int32 (out) gen_caps int32 (out) } # SHM ALLOC #======================================================= tee_ioctl_buf_data_shm_alloc { size int64 (inout) flags const[0, int32] (inout) id int32 (out) } # SHM REGISTER #======================================================= tee_ioctl_buf_data_shm_register { addr int64 (in) length int64 (inout) flags const[0, int32] (inout) id int32 (out) } # SHM REGISTER FD #======================================================= tee_ioctl_buf_data_shm_register_fd { fd int64 (in) size int64 (out) flags const[0, int32] (in) id int32 (out) } [align[8]] # SUPPLICANT RECV #======================================================= tee_ioctl_buf_suppl_recv { func int32 (in) num_params len[params, int32] (inout) params array[tee_ioctl_param_struct] (inout) } # SUPPLICANT SEND #======================================================= tee_ioctl_buf_suppl_send { ret int32 (out) num_params len[params, int32] (in) params array[tee_ioctl_param_struct] (in) }
模糊测试中的崩溃是由于持有互斥对象时 task _ struct 的 use-after-free 漏洞:
================================================================== BUG: KASAN: use-after-free in __mutex_lock.constprop.0+0x118c/0x11c4 Read of size 4 at addr 863b0714 by task optee_example_r/244 CPU: 0 PID: 244 Comm: optee_example_r Tainted: G D 5.14.0 #151 Hardware name: Generic DT based system [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [] (show_stack) from [] (dump_stack_lvl+0x5c/0x68) [] (dump_stack_lvl) from [] (print_address_description.constprop.0+0x38/0x304) [] (print_address_description.constprop.0) from [] (kasan_report+0x1c0/0x1dc) [] (kasan_report) from [] (__mutex_lock.constprop.0+0x118c/0x11c4) [] (__mutex_lock.constprop.0) from [] (mutex_lock+0x128/0x13c) [] (mutex_lock) from [] (tee_shm_release+0x4b0/0x6cc) [] (tee_shm_release) from [] (dma_buf_release+0x1b8/0x2f0) [] (dma_buf_release) from [] (__dentry_kill+0x4c4/0x678) [] (__dentry_kill) from [] (dput+0x630/0xba4) [] (dput) from [] (__fput+0x3b4/0x900) [] (__fput) from [] (task_work_run+0x15c/0x230) [] (task_work_run) from [] (do_exit+0x103c/0x3770) [] (do_exit) from [] (do_group_exit+0x134/0x3ac) [] (do_group_exit) from [] (get_signal+0x7d8/0x2f28) [] (get_signal) from [] (do_work_pending+0x984/0x154c) [] (do_work_pending) from [] (slow_work_pending+0xc/0x20) Exception stack(0x85743fb0 to 0x85743ff8) 3fa0: 00023108 00000080 00000000 00000000 3fc0: 66bca2d0 66bca2d0 66bca2d0 000000f0 66bca2d0 66bca340 00000000 6ec00b0c 3fe0: 66bc9cc8 66bc9cb8 00011655 66c80c20 000e0130 00023108 Allocated by task 242: set_alloc_info+0x48/0x50 __kasan_slab_alloc+0x48/0x58 kmem_cache_alloc+0x14c/0x314 copy_process+0x2014/0x7b18 kernel_clone+0x244/0xfc8 sys_clone+0xc8/0xec ret_fast_syscall+0x0/0x58 0x6ec00a10 Freed by task 67: kasan_set_track+0x28/0x30 kasan_set_free_info+0x20/0x34 __kasan_slab_free+0xdc/0x108 kmem_cache_free+0x80/0x394 __put_task_struct+0x2b4/0x35c delayed_put_task_struct+0x104/0x384 rcu_core+0x91c/0x2a68 __do_softirq+0x2fc/0xfb8 Last potentially related work creation: kasan_record_aux_stack+0xb8/0xc0 call_rcu+0x9c/0xfd0 put_task_struct_rcu_user+0x9c/0xbc finish_task_switch+0x534/0xa10 __schedule+0x934/0x1adc schedule_idle+0x9c/0x120 do_idle+0x2ec/0x434 cpu_startup_entry+0x18/0x1c start_kernel+0x3ec/0x430 The buggy address belongs to the object at 863b0700 which belongs to the cache task_struct of size 1664 The buggy address is located 20 bytes inside of 1664-byte region [863b0700, 863b0d80) The buggy address belongs to the page: page:f09c9565 refcount:1 mapcount:0 mapping:00000000 index:0x0 pfn:0x463b0 head:f09c9565 order:3 compound_mapcount:0 compound_pincount:0 flags: 0x10200(slab|head|zone=0) raw: 00010200 00000000 00000122 82802e00 00000000 80120012 ffffffff 00000001 page dumped because: kasan: bad access detected Memory state around the buggy address: 863b0600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 863b0680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >863b0700: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ 863b0780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 863b0800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ==================================================================
这是通过关闭TEE_IOC_SHM_ALLOC中的所有文件描述符而触发的,在我们的例子中,一个不同的线程会打开一个会话,指向一个不存在的 TA。通过 Syzkaller 重现此问题,并通过对TEE_ioc_open_session 的调用,我们发现属于 kmalloc-64缓存的对象中存在另一个 UAF:
================================================================== BUG: KASAN: use-after-free in tee_shm_put+0x8c/0x98 Read of size 4 at addr 86467020 by task optee_example_h/216 CPU: 0 PID: 216 Comm: optee_example_h Not tainted 5.14.0 #21 Hardware name: Generic DT based system [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack_lvl+0x40/0x4c) [] (dump_stack_lvl) from [] (print_address_description.constprop.0+0x5c/0x2d8) [] (print_address_description.constprop.0) from [] (kasan_report+0x1b4/0x1d0) [] (kasan_report) from [] (tee_shm_put+0x8c/0x98) [] (tee_shm_put) from [] (tee_ioctl+0x1578/0x2e44) [] (tee_ioctl) from [] (sys_ioctl+0x918/0x1e70) [] (sys_ioctl) from [] (ret_fast_syscall+0x0/0x58) Exception stack(0x86417fa8 to 0x86417ff0) 7fa0: 00000080 00000000 00000003 8010a402 200001c0 00000003 7fc0: 00000080 00000000 00423018 00000036 66c562d0 66c55e10 66c562d0 6ebebafc 7fe0: 66c55cb0 66c55ca0 004114bd 66cebd72 Allocated by task 216: tee_shm_alloc+0x15c/0x7e8 tee_ioctl+0x8d0/0x2e44 sys_ioctl+0x918/0x1e70 ret_fast_syscall+0x0/0x58 0x66c55ca0 Freed by task 215: kasan_set_free_info+0x20/0x34 __kasan_slab_free+0xdc/0x108 kfree+0x98/0x294 tee_shm_release+0x1dc/0x610 dma_buf_release+0x180/0x2a0 __dentry_kill+0x488/0x6ac __fput+0x2f0/0x7b4 task_work_run+0x178/0x230 do_work_pending+0xaf8/0x10a8 slow_work_pending+0xc/0x20 0x66d5bd16 The buggy address belongs to the object at 86467000 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 32 bytes inside of 64-byte region [86467000, 86467040) The buggy address belongs to the page: page:(ptrval) refcount:1 mapcount:0 mapping:00000000 index:0x0 pfn:0x46467 flags: 0x200(slab|zone=0) raw: 00000200 00000000 00000122 82401200 00000000 00200020 ffffffff 00000001 page dumped because: kasan: bad access detected Memory state around the buggy address: 86466f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86466f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >86467000: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ 86467080: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc 86467100: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ==================================================================
该漏洞是通过对 TEE 驱动程序进行模糊测试而发现的,无需与系统上运行的现有 TA 建立任何会话。这可以通过 syzkaller 中的伪系统调用进一步扩展,以便建立和启动与某个 TA 的会话。
0x03 根本原因分析
漏洞的根本原因是tee_shm:dmabuf对象寿命跟踪的设计问题。驱动程序的设计目的是让用户空间在调用tee_ioctl_shm_alloc()后保留唯一的引用计数。
假设如果能在驱动程序的 IDR 对象中仍然找到该对象,则对 dmabuf 的引用仍然有效并且其引用计数可以递增。事实证明,这只是部分正确的。dmabuf 内存仍由 dmabuf 驱动程序拥有,但它可能正在被销毁,并且无法通过再次使引用计数非零来停止。
触发漏洞的场景是多线程应用程序,其中一个线程关闭 dmabuf 文件描述符,同时另一个线程调用 IOCTL 命令TEE_IOC_OPEN_SESSION或TEE_IOC_INVOKE引用该共享内存。
当用户空间关闭 fd 时,跟踪 dmabuf 的销毁将在内核中运行以下代码:
fput()
fput_many() >> 文件引用计数为零,窗口开启。
[task_work gets scheduled]
__fput
dput
dma_buf_release
tee_shm_release
mutex_lock(teedev->mutex)
idr_remove(teedev->idr, shm->id)>> 无法再从用户空间引用 shm 对象,窗口关闭。
mutex_unlock()
这意味着 IDR Table及其互斥锁不能保证dmabuf和相应的tee_shm仍然有效,通过调用 tee_shm_get_from_id ()来竞争 fput ()的进程可以获得对即将停止的 shm 的引用。
/** * tee_shm_get_from_id() - Find shared memory object and increase reference * count * @ctx: Context owning the shared memory * @id: Id of shared memory object * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure */ struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id) { struct tee_device *teedev; struct tee_shm *shm; if (!ctx) return ERR_PTR(-EINVAL); teedev = ctx->teedev; mutex_lock(&teedev->mutex); shm = idr_find(&teedev->idr, id); if (!shm || shm->ctx != ctx) shm = ERR_PTR(-EINVAL); else if (shm->flags & TEE_SHM_DMA_BUF) get_dma_buf(shm->dmabuf); mutex_unlock(&teedev->mutex); return shm; }
0x04 利用 UAF 漏洞
为了利用此漏洞,必须在对象被释放之后和触发 UAF 之前进行重新分配。
在调用tee_shm_get_from_id()之后,函数tee_shm_put()会被调用,该函数对dma_buf_put()的输入参数tee_shm:dmabuf对象进行解析。
/** * tee_shm_put() - Decrease reference count on a shared memory handle * @shm: Shared memory handle */ void tee_shm_put(struct tee_shm *shm) { if (shm->flags & TEE_SHM_DMA_BUF) dma_buf_put(shm->dmabuf); } EXPORT_SYMBOL_GPL(tee_shm_put);
该tee_shm对象可以在 UAF 之前重新分配,因为它属于 kmalloc-64 缓存,必须重新分配:
伪造 tee_shm, tee_shm:dmabuf,dma_buf:file对象 设置 file->f_count = 1 制作一个file:file_operations将fasync函数指针设置为任意地址的对象
然后在__fput()调用dma_buf_put()whenfile->f_count为零后调用此函数。
PAN (Privileged Access Never) 缓解了这种情况,因为必须在用户空间内存中引用伪造的对象才能在file:f_ops结构中设置任意函数指针。因此CONFIG_CPU_SW_DOMAIN_PAN必须禁用它才能在提供的环境中工作。
此外,为了成功地重新分配空闲的shm对象,IOCTL调用TEE_IOC_OPEN_会话或TEE_IOC_INVOKE必须由执行文件描述符关闭和堆喷线程的线程抢占,该线程填充kmalloc-64缓存。为了实现这一点,内核必须配置CONFIG_PREEMPT。在这个PoC中,Nicolas Fabretti的文章中的堆喷是基于阻塞sendmsg()使用的。
总之,free和UAF必须发生在同一个系统调用中。除此之外,释放也很难触发,因为它需要在系统调用中进行竞争。释放后,它与实际UAF之间会有一个时间窗口,在这个时间窗口中,必须执行堆喷来重新分配释放的对象。下图显示了漏洞代码中涉及的线程及其角色。
三种类型的线程连续运行。为了抢占系统调用线程,它以尽可能低的优先级SCHED_IDLE运行,而其他线程的优先级设置为SCHED_OTHER。因为我们使用的是blocking sendmsg(),所以每次喷洒都必须在自己的线程中运行,并且必须在触发UAF的同一个CPU内核上运行,因为每个内核都保留自己的kmalloc缓存。在步骤1b)中,还有许多释放线程将文件描述符从共享内存分配中关闭。有关UAF漏洞触发和函数指针覆盖的完整利用代码,请参见[10]。
0x05 设置OPTEE 环境
要使用存在漏洞的内核和 OPTEE 重现环境,可以从以下存储库克隆并使用以下方法构建:
$ mkdir optee-qemu && cd optee-qemu $ repo init -u https://github.com/pjlantz/optee-qemu.git $ repo sync $ cd build $ make toolchains -j2 $ make run
成功构建后,会出现三个控制台,一个用于 QEMU - 在 QEMU 控制台中按“c”以启动。第二个控制台显示secure world的输出,最后一个控制台将引导至 Linux以 root 身份登录。
运行Exploit代码,直到FaseNc函数指针设置为0x22000000。
until optee_exploit | grep "0x22000000" /var/log/messages; do sleep 0.01; done
由于PXN在PC=0x22000000时会阻止执行,因此操作将停止。利用策略可能会因内核版本而异,也可能会执行内核ROP并进行堆栈旋转,或者使vDSO区域可写并将paylaod写入。在未来的工作中,研究使用ret2dir和一些physmap喷雾是否可以绕过PAN也可能是有趣的。通过在linux/中设置CONFIG_CPU_SW_DOMAIN_PAN=y,可以在内核中启用PAN。配置。在真正的硬件上,它默认在ARMv8上启用。1和AArch64,对于ARMv7和AArch32,可以使用此设置对PAN进行软件仿真[8]。
0x06 参考资料
[1] CVE-2021-44733 - https://nvd.nist.gov/vuln/detail/CVE-2021-44733
[2] TEE subsystem - https://www.kernel.org/doc/html/latest/staging/tee.html
[3] Globalplatform TEE API - https://globalplatform.org/specs-library/?filter-committee=tee
[4] OP-TEE OS - https://github.com/OP-TEE/optee_os
[5] BKK16-110: A Gentle Introduction to Trusted Execution and OP-TEE - https://connect.linaro.org/resources/bkk16/bkk16-110/
[6] Syzkaller - https://github.com/google/syzkaller
[7] Lexfo's security blog, by Nicolas Fabretti: CVE-2017-11176: A step-by-step Linux Kernel exploitation - https://blog.lexfo.fr/cve-2017-11176-linux-kernel-exploitation-part3.html
[8] Linux Kernel Security Subsystem: Exploit Methods/Userspace data usage - http://kernsec.org/wiki/index.php/Exploit_Methods/Userspace_data_usage
[9] [PATCH v2] tee: handle lookup of shm with reference count 0 - https://lore.kernel.org/lkml/[email protected]/T/
[10] Proof of concept exploit - https://github.com/pjlantz/optee_examples/tree/master/exploit/host
如若转载,请注明原文地址