一、 漏洞描述
CVE-ID: CVE-2016-5195
漏洞名稱: Linux寫拷貝污染(也叫:臟牛(Dirty COW))
漏洞危害:低權(quán)限用戶可利用該漏洞在linux系統(tǒng)上實(shí)現(xiàn)本地提權(quán)
影響范圍:Linux內(nèi)核>=2.6.22(包括Pc與Android)
二、 漏洞原理
Linux內(nèi)核的內(nèi)存子系統(tǒng)在處理寫時(shí)拷貝(Copy-on-Write)時(shí)存在條件競爭漏洞,導(dǎo)致可以破壞私有只讀內(nèi)存映射。一個低權(quán)限的本地用戶能夠利用此漏洞獲取其它只讀內(nèi)存映射的寫權(quán)限,有可能進(jìn)一步導(dǎo)致提權(quán)漏洞。
三、 漏洞細(xì)節(jié)
到目前為止,該漏洞的利用程序尚未公布。該漏洞由于get_user_pages()的條件競爭漏洞導(dǎo)致。沒有什么辦法能夠保證handle_mm_fault()一定能夠觸發(fā)COW條件-如果另一個線程結(jié)束并以某種方式修改了頁表,handle_mm_fault()將會終止,我們需要重試這個操作。這還算好的,get_user_pages()最后是嘗試讀取操作,因此理論上寫訪問結(jié)束時(shí)會丟失已經(jīng)污染的位或者一個內(nèi)存頁上沒有適合COW的地方。這讓get_user_pages()總是嘗試寫訪問由于"follow_page()"產(chǎn)生的寫訪問需要一個可寫的污染位集合。這簡化了解決競爭的代碼:如果COW由于某些原因執(zhí)行失敗了,我們只需要不斷重復(fù)執(zhí)行。
提交者在11年前就嘗試修復(fù)這個古老的漏洞,提交編號4ceb5db9757a("修復(fù) get_user_pages() 的寫訪問競爭"),但是后來由于s390問題又回滾了,提交編號 f33ea7f404e5("修復(fù) get_user_pages漏洞")。
同時(shí),s390已經(jīng)修復(fù)很久了,現(xiàn)在我們能夠通過適當(dāng)?shù)男r?yàn)pte_dirty()位來修復(fù)。s390 污染位已經(jīng)在abf09bed3cce 中實(shí)現(xiàn)了(("s390/mm:實(shí)現(xiàn)軟件污染位")。更好的內(nèi)核需要自行查看內(nèi)存頁。
同樣,VM的擴(kuò)展性變得更好,并且使用了一個更好的競爭使得觸發(fā)更容易。
為了修復(fù)它,我們引入一個新的內(nèi)部FOLL_COW標(biāo)志來標(biāo)記“yes,我們已經(jīng)做了一 次寫拷貝了”來取代與FOLL_WRITE之間的競爭游戲,然后使用pte污染標(biāo)記去校驗(yàn) FOLL_COW標(biāo)記是否仍然生效。
四、 漏洞驗(yàn)證
測試的Poc在https://github.com/dirtycow/dirtycow.github.io/blob/master/dirtyc0w.c
將代碼下載到本地后,使用gcc進(jìn)行編譯。根據(jù)源碼的注釋,可以看出利用poc將foo文件的內(nèi)容進(jìn)行篡改。同理只要把/etc/passwd中低權(quán)限用戶的 uid改成 0 后面這個低權(quán)限用戶就可以以 root權(quán)限登錄了。
五、 修復(fù)方案
Linux團(tuán)隊(duì)正在積極修復(fù)漏洞。
普通用戶可通過系統(tǒng)更新到最新發(fā)行版修復(fù)此漏洞。
開發(fā)人員可通過重新編譯內(nèi)核修復(fù)。