Rust大步跨入Android平臺

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"近日,谷歌宣佈Android開源項目(AOSP)現在支持Rust編程語言來開發OS。這一舉動將讓正火的Rust語言熱度再次上漲。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"內存安全錯誤"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目前,C和C++的內存安全錯誤仍然是不正確性來源中最難解決的問題。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"谷歌指出,內存安全錯誤是穩定性問題的罪魁禍首,它在Android嚴重安全漏洞中長期佔據大約70%的比例。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Android操作系統廣泛使用Java,以有效保護Android平臺的大部分內容免受內存錯誤的影響。但不幸的是,系統中比較低級的層是不能選擇Java和Kotlin的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/e0\/e07c3bc7fa620d6c932a3bd930993f98.jpeg","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"OS中的較低級別需要的是系統編程語言,如C、C++和Rust等。這些語言設計時考慮到了可控和可預測性的目標。它們提供對低級系統資源和硬件的訪問。它們的資源需求相對輕量,並具有更可預測的性能特徵。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於C和C++,開發人員負責管理內存的生命週期。但是,這樣做很容易出錯,尤其是在複雜的多線程代碼庫中更是如此。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust使用編譯時檢查(強制執行對象生命週期\/所有權)和運行時檢查(確保內存訪問有效)的組合來提供內存安全保證。提供這種安全性的同時,Rust的性能表現足以匹敵C和C++。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"谷歌表示,“除了正在進行和即將到來的改進內存錯誤檢測的措施外,我們還在進一步努力設法防患於未然。內存安全語言是預防內存錯誤的成本效益最優的手段。”"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"沙箱的侷限性"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"谷歌披露,所有Android進程均已沙箱化。它們通過遵循三選二規則(Rule of 2)來確定功能是否需要額外的隔離和特權。這種規則很簡單:給定三個選項,開發人員只能選擇以下三個選項中的兩個。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/76\/76072dac39cc177ef5fe0fb9d86f6cce.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對Android來說,這意味着如果代碼是用C\/C++編寫並解析了不可靠的輸入,則應將其包含在一個嚴格受限和無特權的沙箱中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"遵守三選二規則的好處是可以有效降低安全漏洞的嚴重性和暴露程度,但是它也存在一些侷限:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沙箱的成本很高。它需要的新進程會消費額外的開銷並引入延遲,這是由於IPC和額外的內存佔用導致的。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沙箱無法消除代碼中的漏洞。高漏洞密度會降低其有效性,讓攻擊者可以將多個漏洞鏈接在一起。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"像Rust這樣的內存安全語言可以通過兩種方式來克服這些限制:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"降低代碼中錯誤的密度,從而提高當前沙箱的效率。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"減少谷歌對沙箱的需求,從而引入更安全、更省資源的新特性。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"近50%的錯誤出現短於一年"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"根據分析,大多數內存錯誤出現在新的或最近修改的代碼中,大約有50%錯誤出現還不到一年。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/ae\/aee35bc1c50e0ab41a47dd9f5e16fc07.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,谷歌表示,“我們在內存安全語言方面的工作最好專注於新開發的代碼,而不是重寫成熟的C\/C++代碼。並且,引入一種新的編程語言並不能解決我們現有C\/C++代碼中的錯誤。即便我們重新分配Android團隊中所有軟件工程師的工作,要重寫幾千萬行代碼也是完全不可行的。“"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相比之下,較舊的內存錯誤很少見,很多人可能會覺得很驚訝。谷歌還發現,較舊的代碼並不是亟需改進的。\"隨着時間的推移,軟件錯誤會被逐漸發現和修復,因此我們可以預期還在維護但未處於活躍開發狀態的代碼中的錯誤量會逐漸減少\"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"谷歌還指出,對於複雜的C\/C++代碼庫來說,通常只有少數人能夠開發和審查錯誤修復,而且即使花費大量精力來修復錯誤,有時修復本身也會是不正確的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當錯誤相對少見且危險的錯誤得到優先關注時,錯誤檢測纔是最有效的。爲了獲得從錯誤檢測中獲得的改進所帶來的好處,谷歌稱“首先防止引入新的錯誤”。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"預防爲主"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust語言實現了一系列現代化的語言特性,從而提高了代碼的正確性:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"內存安全性"},{"type":"text","text":":搭配編譯器和運行時檢查來增強內存安全性。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"數據併發"},{"type":"text","text":":防止數據爭用。它讓用戶能輕鬆編寫高效、線程安全的代碼,也讓Rust打出了“無畏併發”的口號。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"更具表現力的類型系統"},{"type":"text","text":":幫助防止邏輯編程錯誤(例如newtype包裝器、帶有內容的enum變體)。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"引用和變量是默認不可變的"},{"type":"text","text":":幫助開發人員遵循最小特權的安全原則,僅在實際需要時纔將引用或變量標記爲可變。C++有常量,而且傾向於偶爾且不一致地使用常量。相比之下,Rust編譯器會爲永不突變的可變值提供警告,來幫助避免散亂的可變性註釋。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"標準庫中更好的錯誤處理"},{"type":"text","text":":將Result中可能失敗的調用包裝起來,於是編譯器會要求用戶檢查失敗,即使是未返回所需值的函數也是如此。這樣就避免了RageAgainstCage之類的漏洞,這種漏洞是來源於未處理錯誤的。Rust簡化了通過?運算符傳播錯誤的過程,並優化了Result以降低開銷,從而鼓勵用戶以相同的樣式編寫易錯的函數並獲得相同的保護。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"初始化"},{"type":"text","text":":要求所有變量在使用前都初始化。未初始化的內存漏洞一直是Android上3-5%的安全漏洞的源頭。在Android11中,谷歌開始在C\/C++中自動初始化內存以減少這種問題。然而,初始化到零並不總是安全的,尤其是對於返回值這樣的事物,因爲它可能成爲新的錯誤不當處理來源。而Rust要求每個變量在使用前都要初始化爲該類型的合法成員,避免了無意初始化爲不安全值的問題。類似Clang for C\/C++,Rust編譯器意識到了初始化的要求,並避免了雙重初始化的所有潛在性能開銷。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"更安全的整數處理"},{"type":"text","text":":默認情況下,Rust調試版本會啓用溢出清理功能。如果程序員確實打算讓一個計算溢出,則鼓勵他們指定一個wrap_add;否則,則指定一個saturating_add。谷歌打算爲Android的所有版本啓用溢出清理功能。此外,所有整數類型轉換都是顯式轉換:在分配給變量或嘗試對其他類型進行算術運算時,開發人員不會在函數調用期間意外地轉換。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"據悉,在過去18個月中,谷歌一直在向Android開源項目增加對Rust的支持。不過,它也坦言,”在Android平臺上添加新語言是一項艱鉅的任務。不僅需要維護很多工具鏈和依賴項,更新測試基礎架構和工具鏈,還要培訓開發人員“。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"谷歌稱,未來幾年計劃將Rust擴展到OS的更多部分。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章