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