CVE-2018-18281—linux内核中关于TLB破绽的剖析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

CVE-2018-18281—linux内核中关于TLB破绽的剖析

申博_安全防护 申博 287次浏览 已收录 0个评论

2019年1月17日,Project Zero的Jann Horn宣布了一篇文章,形貌了他发明的一个linux内核中关于TLB(Translation Lookaside Buffer)的破绽。本文为对这个破绽的详细分析。作者程度有限,若有欠妥还请斧正。

基础知识

锁定和抢占

linux内核支撑三种分歧的抢占模子,必需在build时遴选个中一种。
CONFIG_PREEMPT_NONE(无强迫抢占(效劳器))
CONFIG_PREEMPT_VOLUNTARY(志愿内核抢占(桌面))
CONFIG_PREEMPT(内核可抢占(低耽误桌面))
抢占模子确定当内核愿望中缀以后正在运转内核代码的历程时的操纵:比方,较高优先级的历程已变成可运转且正在守候调理。Pixel 2运用设置装备摆设了CONFIG_PREEMPT的内核。这意味着默许状况下,内核代码可以或许在实行时期的任何时候中缀。以至包孕历程持有互斥锁、旌旗灯号量和它位于RCU读端临界区时(取决于内核设置装备摆设)。只要像自旋锁如许的器械能力抑止抢占。关于进击者来讲,若是应用的破绽须要时候差的话内核是可抢占的黑白常有效的。进击者可以或许会让调理顺序在合作窗口中将历程从CPU中心中移除,然后让历程阔别CPU一段时候。
sched_setaffinity函数设置历程在哪一个或许哪几个CPU中心上运转,一般它的用法以下。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
sched_setscheduler函数为指定的pid设置调理战略policy和参数param。若是pid为0,则设置挪用线程的调理战略和参数。param是一个指向sched_param构造体的指针。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
如今这个构造体仅仅包罗sched_priority这一个成员。关于param的诠释取决于policy。linux中的policy分为一般调理战略(normal scheduling policies)和及时调理战略(real time scheduling policies)。

  • SCHED_NORMAL和SCHED_BATCH调理一般的非及时历程
  • SCHED_FIFO和SCHED_RR和SCHED_DEADLINE则接纳分歧的调理战略调理及时历程
  • SCHED_IDLE则在体系余暇时挪用idle历程

若是设置具有分歧优先级的多个历程运转在一个CPU中心上,那末叫醒优先级较高的历程将会抢占优先级较低的历程。

页分派器

linux页分派器基于buddy分派器,在mm/page_alloc.c中完成。余暇列表(freelist)不仅仅是按order辨别的,在android上还与地区(zone)和迁徙范例(migration type)有关。

地区

地区指定页面可以或许运用的体式格局。Pixel 2上存在以下地区。

  • ZONE_DMA:当有装备不克不及经由历程DMA(Direct Memory Access)接见全部可寻址内存(ZONE_NORMAL)的状况下为这些装备特地拓荒出一段内存,一般是低端内存地区(arm64在4.16之前运用)
  • ZONE_NORMAL:该局部的内存由内核直接映照到线性地点空间的较高局部
    ###迁徙范例
    页面的迁徙范例指定页面以后正在运用哪一种分派(若是页面以后正在运用中)或许页面应当优先运用哪一种分派(若是页面是余暇的)。它的目的是经由历程将内核可以或许收受接管的页面的内容挪动到一同以许可内核稍后经由历程挪动数据来建立更大order的余暇页面。下面是对照主要的几个迁徙范例。
  • MIGRATE_UNMOVABLE:用于弗成挪动的分派(比方一般kmalloc的分派)
  • MIGRATE_MOVABLE:用于内核可以或许将其挪动到另一个物理页面的分派(比方用户空间内存)
  • MIGRATE_RECLAIMABLE:用于内核不克不及简朴地挪动到分歧地点的分派,但内核可以或许在须要开释一些内存时将其开释
  • MIGRATE_CMA:为DMA的一连内存预留的专用内存,只能用于特定的DMA分派和可挪动页的分派
    在页分派器中引入了冷热页的观点。冷页透露表现该余暇页已不再高速缓存中了,热页透露表现该余暇页依然在高速缓存中。冷热页是针关于每CPU的。每一个zone中都邑针关于统统的CPU初始化一个冷热页的per-cpu-pageset(pcp)。冷热页机制只处置惩罚单页分派的状况。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析
    起首经由历程疾速途径分派,若是疾速途径没法分派再经由历程慢速途径分派。在进入慢速途径之前,经由历程get_page_from_freelist函数分派页面的算法大抵以下(疏忽NUMA和原子/及时分派之类的器械)。

  • 关于每一个地区(从最优选的地区到最不优选的地区,在Pixel 2上,当分派非DMA内存时,起首是ZONE_NORMAL,然后是ZONE_DMA),当get_page_from_freelist函数走到try_this_zone时申明选定的地区中有余暇内存。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析

  • 在rmqueue函数中有下面这几种状况。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析

  • 关于order为0也就是单页分派的状况,继承进入rmqueue_pcplist函数。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析

  • 在__rmqueue_pcplist函数中挪用了rmqueue_bulk函数从buddy分派体系平分派页。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析

    ————————————-

    申博网络安全巴士站

    申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

    ————————————-

  • 在rmqueue_bulk函数中挪用了__rmqueue函数。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析

  • __rmqueue函数起首挪用__rmqueue_smallest函数从指定迁徙范例去分派order阶的页,若是order阶对应的链表没有余暇页块就从更大阶的链表中去分派,然后将取得的页块拆解,盈余局部挂到对应order的链表中去。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析

  • 若是我们想要一个可挪动的页,则从MIGRATE_CMA平分派。不然,挪用__rmqueue_fallback函数分派。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析

  • __rmqueue_fallback函数实验从具有分歧迁徙范例的余暇列表中猎取最大order的页,然后可以或许会将它的迁徙范例变动成所需的。
    CVE-2018-18281—linux内核中关于TLB破绽的剖析

下面是几张资助明白的示意图。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
当试图应用物理页的UAF破绽时须要记着页分派器将只管制止转变页的迁徙范例,以是一般可挪动页(匿名用户空间内存和页缓存)将被重用为可挪动页,弗成挪动页(一般的内核内存)将被重用为弗成挪动页。

TLB和分页构造缓存

页表包罗有关虚拟地点怎样映照到物理地点的信息。页表存储在内存中,因而接见速率相对较慢。为了疾速举行地点转换,CPU运用TLB(Translation Lookaside Buffers)缓存这个映照。换句话说,它们险些缓存末了一级页表条目。古代CPU一般有很多分歧用处的TLB:好比Intel CPU有指令TLB,数据TLB和同享L2 TLB。
分页构造缓存的文档对照少,然则照样有官方文件纪录它们的存在和处置惩罚它们时必需接纳的步伐。Intel把它们叫做分页构造缓存(Paging-Structure Caches),arm把它们叫做中央表遍历缓存(Intermediate table walk caches),AMD的文档中把它们作为L2数据TLB的一局部。分页构造缓存存储非末了一级页表条目的副本,当接见没有对应TLB条目的虚拟地点时将运用它们以削减遍历页表的次数。
处置惩罚器可以或许随时消灭和建立TLB和分页构造缓存中的条目。分歧的处置惩罚器体系构造使它们无效的机制也并不雷同。X86架构中供应了使以后逻辑CPU内核的单个TLB条目或全部TLB(不管有无全局条目)无效的指令。在Intel的手册中提到使虚拟地点的TLB条目无效还最少意味着可以或许用于转换该虚拟地点的任何分页构造缓存条目无效。要跨逻辑CPU内核使得TLB失效,操纵体系必需手动运转使每一个逻辑CPU内核上的TLB条目无效的代码,这一般是经由历程APIC(Advanced Programmable Interrupt Controller)将IPI(Inter-Processor Interrupt)从愿望实行TLB失效的处置惩罚器发送到可以或许具有相干逾期TLB或分页构造缓存条目的统统别的处置惩罚器来完成的。ARM架构供应了可以或许实行跨中心TLB失效的指令,然则若是还须要同步软件(如linux内核)中完成的页表遍历,可以或许照样必需发送IPI(取决于用于页表遍历的同步机制)。
用于为页表条目实行缓存失效的通用形式以下。
1.从页表中删除一个条目,但连结对它指向的物理页面的援用。
2.对可以或许运用与以后线程雷同的页表的统统CPU中心实行TLB革新(针对特定地点或全部地点空间)。
3.删除物理页面上保存的援用(可以或许会开释它)。
在作废映照一般数据页和删除页表时,这个历程都是雷同的。一般可以或许举行批处置惩罚以取得更好的机能:起首删除多个页表条目,然后跨内核实行一次TLB革新,末了删除统统页面援用。在X86上(ARM64相似),末了一级PTE(Page Table Entry)中有两个位,CPU可以或许将其作为地点转换的一局部写入:Accessed位指定CPU是不是曾运用页表条目举行地点转换,换句话说,若是未设置Accessed位,则自上次软件写入PTE以来TLB还没有缓存页表条目的值。Dirty位指定CPU是不是曾用页表条目举行写内存接见,换句话说,若是未设置Dirty位,则自上次软件写入PTE以来没有建立可用于写入物理页面的TLB条目。

破绽剖析

破绽道理

在linux体系中历程的内存治理数据构造遭到多个锁的珍爱:mm_struct构造体中的读/写旌旗灯号量mmap_sem用来珍爱VMA(Virtual Memory Area),页表锁用于珍爱对页表的接见。比方mmap/mremap/munmap和用于页面毛病处置惩罚的函数同时运用mmap_sem和页表锁。然则一些别的范例的页表接见(比方在体系中映照给定文件的统统地位上的操纵,如减少文件并开释超越文件新的末端的页表的ftruncate函数)不会保存mmap_sem,只用页表锁。
mremap函数许可用户空间挪动VMA及其联系关系的页表条目,它经由历程mremap_to->move_vma->move_page_tables->move_ptes挪动页表。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
move_ptes函数用于挪动2个L1页表之间的条目(只要mmap_sem)的大抵逻辑以下。
1.若是设置了need_rmap_locks标记(新的VMA已合并到相邻的VMA中),则挪用take_rmap_locks函数。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
2.猎取旧页表和新页表上的页表锁。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
3.挪用了flush_tlb_batched_pending函数,革新由于并行收受接管合作留下的旧的TLB条目。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
4.关于以后页表的局限中的每一个非空条目:
4.1.挪用ptep_get_and_clear函数,原子性地读取页表条目的以后值并消灭它。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
4.2.若是读取的页表条目为Dirty,则将force_flush标记设置为true。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
4.3.把读取的页表条目写入页表以猎取新映照。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
5.解锁新的页表。
6.若是设置了force_flush标记,则对在步调4中接见的旧页表条目实行TLB革新;若是未设置force_flush标记,则向挪用者move_page_tables函数发出须要TLB革新的旌旗灯号。
7.解锁旧的页表。
8.若是设置了need_rmap_locks标记,则挪用drop_rmap_locks函数。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
稍后,在遍历多个页表以后,move_page_tables函数会在要求时对旧地点局限实行TLB革新。
move_ptes函数须要确保在开释旧页表的援用时不再有过期的TLB条目。move_ptes函数中没有删除援用,但move_ptes函数将援用挪动到新的页表条目中。当持有新页表上的页表锁时,同时运转的别的历程依然没法删除新的页表条目并删除其援用,因而在步调4.3以后统统依然一般:页没法开释。然则在第5步以后,另一个历程理论上可以或许与mremap函数合作并删除页。这远远早于move_page_tables函数对旧地点局限实行TLB革新的时候。

破绽应用

为了应用该破绽,我们愿望疾速地从页面缓存中从新分派开释的可挪动页。可以或许经由历程pcp的余暇列表来完成这一点,由于将正本便可挪动的页从新分派为一个可挪动的页比强迫变动迁徙范例更轻易。运用这类战略,我们不克不及进击一般内核内存分派或页表,然则可以或许进击页缓存和匿名用户空间内存。EXP中是进击的页缓存,如许可以或许在进击的症结时候途径中制止别的用户空间历程的滋扰。大抵进击步调以下。
1.从页缓存中删除目的页。
起首须要遴选作为进击目的的页。EXP应用/system/lib64/libandroid_runtime.so中包罗com_android_internal_os_Zygote_nativeForkAndSpecialize函数的页。每当须要启动应用顺序历程时,此函数在zygote历程的高低文中实行,换句话说,它不会经常在余暇装备上运转,这意味着我们可以或许删除它然后有时候触发破绽。可以或许经由历程启动断绝效劳来触发它的实行,因而可以或许在胜利触发破绽后马上实行它。zygote历程具有CAP_SYS_ADMIN功用(而且许可运用它),而且由于它的作用是fork出app历程和system_server的历程,以是它可以或许接见system_server和每一个app的高低文。注入到zygote中的shellcode会读取本身的SELinux高低文,然后运用挪用sethostname函数取得的字符串掩盖主机名。shellcode在arm_shellcode.s中。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
在eviction.c中经由历程fallocate函数应用可实行的具有文件配景的页面形成内存压力从而从页缓存中删除目的页。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
经由历程mincore函数搜检指定的页是不是在页缓存中。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
最好的状况是目的页一旦被删除,鄙人一次接见之前不会从磁盘从新加载。但状况并不是老是云云:内核具有一些提早读取的逻辑,依据观察到的内存接见形式,这些逻辑可以或许从磁盘上读取页面毛病四周的大批数据(最多VM_MAX_READAHEAD,即128KiB)。这是经由历程在filemap_fault函数中挪用do_async_mmap_readahead函数/do_sync_mmap_readahead函数完成的。进击历程可以或许在举行本身的接见时不运用它,然则关于来自别的历程的接见(这些历程可以或许正在实行来自目的文件中别的页面的代码),也应当制止这类行动。由于这个缘由,EXP经由历程fallocate函数删除目的页之前经由历程MADV_RANDOM映照接见目的文件中的统统别的页,以下降接见它们触发提早读取逻辑的几率:当RAM中存在被接见的页时,不会发作同步提早读取;若是接见的页有一个小毛病(即页存在于页缓存中但还不存在响应的页表条目)而没有标记为PG_readahead,异步提早读取也不会发作。
2.分派具有文件配景的页(比方经由历程memfd),并将它们映照为映照1。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
3.触发mremap/ftruncatrace合作开释具有文件配景的页,而不删除映照1的对应TLB条目。
给运转mremap函数的历程设置SCHED_IDLE优先级,而且让它与具有一般优先级的由于read函数阻塞在管道上的历程运转在一个CPU中心上,然后在准确的时候写入该管道的另一端,如许就可以或许抢占mremap函数了。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
/proc/<pid>/status中包罗历程运用的内存的状况,个中VmPTE字段显现历程页表占用的内存量。经由历程看管该字段可以或许检测由mremap函数实行的页表分派以确定在管道另一端挪用write函数的准确机遇。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
在main函数中挪用write函数写入管道的另一端。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
4.从目的页最先读取,致使内核从新分派一个已开释的页作为目的页的页缓存。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
5.在映照1(经由历程旧的TLB)中轮询页的内容,直到个中一个包罗目的页。若是在此之前发作了页面毛病,返回第一步。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
解压,运用payload_dumper提掏出payload.bin中的system.img,解压system.img取得/system/lib64/libandroid_runtime.so。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
肇端地点是0x36000,以是0x36000+0x157000=0x18D000,刚好是0xeb08005f91007108。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
6.此时,我们有一个旧的TLB将旧的映照1转换为目的页。因而,我们如今可以或许经由历程映照1来重复掩盖目的页。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
破绽应用的结果以下(我由于没有相干装备以是没有本身测试)。
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析
CVE-2018-18281—linux内核中关于TLB破绽的剖析

补钉状况

最主要的一处修正就是把对flush_tlb_range函数的挪用放到了新的页表解锁之前。
CVE-2018-18281—linux内核中关于TLB破绽的剖析


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明CVE-2018-18281—linux内核中关于TLB破绽的剖析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址