Huge Dirty COW(CVE-2017-1000405)

Dirtycow可以说是去年的明星漏洞之一,上个月又出来一个Huge Dirty COW,看到心里一惊,这个怕是要出大事情。新漏洞相关连接:

这个漏洞与去年的DirtyCow的原理和Patch相关,可以先了解下Dirtycow的相关内容

Dirtycow利用的关键在于移除掉FOLL_WRITE标志之后再请求页面时,系统分配页面不会再进入COW循环而是直接返回原始页面,导致可以向不可写的页面执行写操作。因此在dirtycow的patch(如下part1)中去不再移除FOLL_WRITE位,而是增加一个FOLL_COW位,用FOLL_COW表示已经COW过。

dirtycow patch part1

1
2
3
if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
- *flags &= ~FOLL_WRITE;
+ *flags |= FOLL_COW;

然后再新增一个函数(如下part2)can_follow_write_pte判断是否可以写,只两种情况可写

  • 1.pte可写
  • 2.有FOLL_FORCE和FOLL_COW标志,并且pte标记为脏(已经COW过,并且写的是脏页)

dirtycow patch part2

1
2
3
4
5
6
7
8
9
/*
* FOLL_FORCE can write to even unwritable pte's, but only
* after we've gone through a COW cycle and they are dirty.
*/
static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
{
return pte_write(pte) ||
((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
}

这样的情况下,如果页是private那只有带有FOLL_FORCE和FOLL_COW标志,并且页是脏页的情况是可写的。

但是在分配THP(Transparent Huge Pages)的过程中,大PMD页直接被设为脏页。

mm/huge_memory.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
pmd_t *pmd)
{
pmd_t _pmd;
/*
* We should set the dirty bit only for FOLL_WRITE but for now
* the dirty bit in the pmd is meaningless. And if the dirty
* bit will become meaningful and we'll only set it with
* FOLL_WRITE, an atomic set_bit will be required on the pmd to
* set the young bit, instead of the current set_pmd_at.
*/
_pmd = pmd_mkyoung(pmd_mkdirty(*pmd));
if (pmdp_set_access_flags(vma, addr & HPAGE_PMD_MASK,
pmd, _pmd, 1))
update_mmu_cache_pmd(vma, addr, pmd);
}

与Dirtycow相同,同样是在__get_user_pages过程中
调用链

1
2
3
4
5
6
7
__get_user_pages
->follow_page_mask
->follow_p4d_mask
->follow_pud_mask
->follow_pmd_mask
->follow_devmap_pmd
->touch_pmd

经过这个过程可以获得一个标记为脏的页面,并且是未COW的,剩下的就是要获取FOLL_FORCE和FOLL_COW标志了。这个过程可以类似dirtyCOW的利用的方式。

因此这个漏洞利用的思路如下:
1.首先经过COW循环,获取到FOLL_COW标志
2.用madvise干掉脏页
3.再次获取页将直接标记为脏
4.写入

总结:
这个漏洞虽相对dirtycow影响还是小一些,因为THP的使用有一定限制,并且我看到的Android上并未启用THP(再android内核的源码中甚至没有touch_pmd),所以对Android的几乎没有影响。

成文仓促,有不正确的地方请不吝指正。