您好,登錄后才能下訂單哦!
本篇內容主要講解“linux內核用戶空間0虛擬地址映射漏洞怎么修復”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“linux內核用戶空間0虛擬地址映射漏洞怎么修復”吧!
前一段時間project zero的jann horn披露了一個linux內核用戶空間0虛擬地址映射漏洞,通過這個漏洞可以繞過mmap_min_addr的限制,再配合一個內核中的null pointer dereference漏洞理論上有提權的可能。這個漏洞是非常有趣的,這里分享一下我的分析。
POC很短,我們直接來看POC:
觸發漏洞的點在于LD_DEBUG=help su 1>&%d向/proc/self/mem中寫入了數據,其實LD_DEBUG=help su并不重要,重要的是通過它調用write函數。下面我們就來一步一步分析從這行代碼到漏洞點的過程。
linux內核對于文件系統通用的結構體是file_operations,fs/proc/base.c中的代碼提供與/proc相關的操作。
LD_DEBUG=help su 1>&%d會調用write函數,在這里也就是mem_write函數。mem_write函數是對mem_rw函數的封裝。
在while循環中,如果是寫首先通過copy_from_user函數將待寫內容buf拷貝到分配的page中,然后調用access_remote_vm函數寫入遠程進程。讀則相反。
access_remote_vm函數是對__access_remote_vm函數的封裝(這里注意分析mmap.c中的代碼,nommu.c中的代碼是用在沒有MMU的CPU上的)。
在__access_remote_vm函數的while循環中調用get_user_pages_remote函數,get_user_pages_remote函數和get_user_pages函數都是對__get_user_pages_locked的封裝,作用在于查找并將給定的虛擬地址范圍固定到page。之后通過kmap函數將page映射到永久內存映射區,如果是寫操作則調用copy_to_user_page函數之后調用set_page_dirty_lock函數將page設置為臟,讀操作則調用copy_from_user_page函數。之后調用kunmap函數取消映射。
get_user_pages_remote函數和get_user_pages函數的區別在于是否跨進程。get_user_pages_remote函數調用__get_user_pages_locked函數時設置了FOLL_REMOTE標志區分。
__get_user_pages_locked函數在for循環中首先調用__get_user_pages函數將start 開始的nr_pages個頁固定到pages,返回成功固定的頁的個數。
__get_user_pages函數首先查找vma,調用follow_page_mask函數查詢頁表獲取虛擬地址對應的物理頁,如果返回null會調用faultin_page函數。獲取到page的指針之后存在pages數組中。
__get_user_pages函數返回值大于0說明調用成功,減少nr_pages增加pages_done,nr_pages為0則退出循環。
再固定一個頁,正常情況下應該返回0退出循環,如果沒有退出循環nr_pages減1,pages_done加1,start地址加一個PAGE_SIZE重新開始固定。
__get_user_pages函數查找vma是通過調用find_extend_vma函數實現的,如果vma->vm_start <= addr說明addr在VMA空間范圍內;否則說明addr落在空洞中。如果設置了VM_GROWSDOWN標志位調用expand_stack函數擴展vma。
expand_stack函數是對expand_downwards函數的封裝。
expand_downwards函數中做的首先就是調用security_mmap_addr函數檢查權限。
security_mmap_addr函數是對cap_mmap_addr函數的封裝。
終于來到了漏洞點,cap_mmap_addr函數中檢查的是current_cred(),是執行write操作的進程的cred而不是vma被改變的進程的cred。在POC中是通過system函數調用LD_DEBUG=help su 1>&%d命令執行的write操作,當然是另外一個進程。
完整調用鏈:mem_write -> mem_rw -> access_remote_vm -> __access_remote_vm -> get_user_pages_remote -> __get_user_pages_locked -> __get_user_pages -> find_extend_vma -> expand_stack -> expand_downwards -> security_mmap_addr -> cap_mmap_addr
POC執行效果如下。
補丁也是由jann horn提供的,expand_downwards函數不再調用security_mmap_addr函數了,直接和mmap_min_addr比較。
到此,相信大家對“linux內核用戶空間0虛擬地址映射漏洞怎么修復”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。