“nfs”文件系統的mount()系統調用存在雙重獲取漏洞。
理論上,Double Fetch是一個有條件的競爭漏洞,這是一場內核模式和用戶模式之間的數據訪問的較量。Double fetch類型漏洞產生于多線程數據訪問時,并且沒有做必要的安全同步措施。多線程時,對同一數據一個線程讀一個線程寫,可能引起數據訪問異常,而這個異常如果能被利用,這就是一個漏洞。在現代操作系統(如linux和BSD衍生產品)中,虛擬內存位置通常是在內核空間和用戶空間之間進行分區的。有關雙重獲取漏洞的更多信息請點擊這里。
第一次獲取發生在“this ”實例中。在這個示例中,將在NFS中解析外部數據表示(XDR)變量。你現在可能在想XDR到底是什么?外部數據表示(XDR)是一種只能用于描述數據的數據格式描述語言。它根本不是一種編程語言。這種語言允許你以清晰和簡潔的方式描述復雜的數據格式。XDR“編程”語言類似于C編程語言,NFS和其他協議使用XDR來描述其數據的格式。
因此,本質上,他們從用戶區復制所有XDR變量的長度,然后對剛從用戶區復制的arglength變量進行大小檢查:
所以顯然 argslength 不能大于 (16*1024 = 16384);。這很好,它很可能只是一個標準。之后它會四舍五入 argslength 并分配一個 xdrbuf:
因此,在分配這個緩沖區后,他們嘗試從用戶空間的第1920行復制所有XDR參數:
這會將所有參數從 data 復制到 argslength 到新分配的 xdrbuf。完成后,這將傳遞給 mountnfs 函數:
好,我們來看看mountnfs函數!它接受研究人員們的xdrbuf作為參數。
在這個塊中,它將使用xb_init_buffer函數初始化xb。因此,xb 屬于 struct xdrbuf 類型。讓我們先看一下這個定義的上下文。
研究人員們可以看到,這個結構將在xb_init_buffer中初始化,所以讓我們也來看看:
所以這個 bzero 是整個 xdrbuf 結構并將類型設置為 XDRBUF BUFFER,然后它將緩沖區的基地址設置為從用戶空間復制的 xdrbuf,將緩沖區的大小和數據的長度設置為 XDRword 的 2 倍,它等于 8,它初始化了一些指向研究人員的 xdrbuf 的指針。一旦 xdrbuf 結構被初始化,他們將繼續使用 xb_get_32 從結構的指針中獲取一些 32 位數據到研究人員的 xdrbuf。他們將使用它來獲取版本和 argslength。請注意,這個 argslength 是 xdrbuf 中的一個 XDR 變量,它在第二次 copyin 調用期間被復制到內核空間中。這表明惡意線程可以在第 1902 行的第一次獲取和第 1920 行的第二次獲取之間操作用戶空間中的 argslength 變量。
之后,他們將使用 xb_init_buffer 以研究人員在用戶空間中更改的惡意大小重新初始化 xdrbuf 結構,盡管自使用 xb_malloc 分配以來 xdrbuf 的實際大小沒有改變。然后惡意攻擊者可以利用它來導致內存損壞錯誤。
現在研究人員們知道了漏洞是如何運作的,那這個漏洞是如何解決的?研究人員檢查了第二次獲取的arglength是否與第一次復制的arglength相同。在這種情況下,研究人員認為這是一個可行的解決方案。
目前研究人員已經將該漏洞的修復信息反饋給了蘋果公司,并希望蘋果能改變他們處理這類漏洞的方式。在研究人員看來,蘋果管理此類漏洞的方式是人們考慮將漏洞出售給像Zerodium這樣的第三方供應商的主要原因。