?作者 | 千山、言征
審校 | 云昭
進入2023年,技術圈都在圍觀大洋彼岸的聊天機器ChatGPT,但對于編程圈而言,沒有什么比內存安全更能引起熱議。近期美國國家安全局(NSA)點名批評C++,建議使用Rust等內存安全的語言,霎時間讓“編程語言的安全問題”擺到桌面上,那么,C++到底能扛住這波壓力,“存活(安全)”下來嗎?
面對來自政府方面的壓力,C++創建者Bjarne Stroustrup最終還是低頭了。他一改之前的激奮言辭,不再喊話“誰誰不懂C++”、“沒有看到30多年來C++的進步”等,而是開始傾向于“編程語言也應該與時俱進”的說辭,加入了改變編程語言本身以解決安全問題的隊伍之中,這一點對其他核心貢獻者來說顯然出乎意料。
1、安全掉隊的C++,正在找對策
C++社區一直存在安全爭議,其內存安全漏洞引起了很多開發者的警覺。
1月中旬,官方C++“指導小組”發布了一份聲明,解決了人們對C++安全性的擔憂。雖然許多語言現在都支持“基本類型安全”,即確保變量只訪問由其數據類型明確定義的內存部分,但C++一直難以提供類似的保證。
這個由C++創建者Bjarne Stroustrup共同撰寫的新聲明現在似乎呼吁改變C++編程語言本身,以解決安全問題。“我們現在支持這樣的想法,即安全性的更改不僅需要在工具中,而且需要在語言/編譯器和庫中可見。”
“指導小組”還支持其長期以來首選的調試工具,以確保安全(以及“推動工具,以便在識別人類難以識別的安全問題時進行更全面的分析”)。但1月份的聲明強調了它對C++內部變化的建議。
具體來說,它建議“將幾個特性打包到概要文件中”(概要文件稍后定義為“定義要執行的屬性的限制和要求的集合”,例如,通過觸發自動分析。)
這樣,新的安全更改“應該是可見的,這樣安全代碼部分就可以被命名(可能使用配置文件),并且可以與普通代碼混合。”
這種新方法最終不僅帶來了安全性,還帶來了靈活性,其配置文件專門設計用于支持嵌入式計算、性能敏感應用程序或高度特定的問題領域,如汽車、航空航天、航空電子、核或醫療應用程序。
指導小組還建議:“例如,我們甚至可能有安全嵌入式、安全汽車、安全醫療、性能游戲、性能HPC和歐盟政府法規的安全配置文件。”。
在文件的其他地方,他們的表述更為簡潔。“為了支持不止一個‘安全’概念,我們需要能夠說出它們的名字。”
但提議的改變與去年12月與美聯邦政府攤牌時出現的想法相呼應。1月中旬的聲明指出,一個特別重要的組織,即美國商務部頗具影響力的國家標準與技術研究所,對C++的安全性提出了擔憂。11月,美國國家安全局(National Security Agency)也在一份關于軟件內存安全的信息表中調用了C++(作為其任務的一部分,以識別對各種聯邦系統的威脅,并“發布網絡安全規范和緩解措施”)。
也許正是這種來自高層的擔憂最終埋下了變革的種子…
2、國家安全問題
美國國家安全局援引了微軟和谷歌的分析評估。
微軟在2019年的一次會議上透露,從2006年到2018年,其發現的70%的漏洞都是因內存安全問題造成的;據Google估計,Chrome中存在了類似比例的內存安全漏洞,另外90%的Android系統漏洞也都是內存安全問題。
他們隨后警告稱,黑客可以利用這些漏洞進行遠程代碼執行或其他不利影響,這通常會危及設備,并且成為大規模網絡入侵的第一步。因此,無論是內存溢出、內存分配漏洞、還是變量未初始化,“所有這些內存問題都太常見了。”
2019年微軟安全演示發現,從2006年到2018年,70%的漏洞涉及內存安全
顯然,軟件分析工具和“操作環境選項”可以發現許多問題,但美國國家安全局仍然建議,“在可能的情況下”,只使用內存安全語言。
為了明確起見,他們將其定義為一種語言,通過運行時和編譯時檢查,內存“作為計算機語言的一部分自動管理;它不依賴于程序員添加代碼來實現內存保護。”NSA提供了C#、Go、Java、Ruby、Rust和Swift等示例。
在美國國家安全局看來,常用的編程語言如C++,在內存管理方面提供了很大的靈活性,但用這種語言開發的應用程序的安全性很大程度上需要依賴程序員的檢測環節。但是只要程序員自身有所疏忽,就可能帶來嚴重的內存安全隱患。盡管不少軟件分析工具能夠檢測到內存管理問題,操作環境選項也可以提供一些防護,但內存安全語言所提供的固有保護可以規避或減輕大多數內存管理問題。
去年12月,Stroustrup在開放標準網站上回應稱,他并不認為這些語言“在我所關心的使用范圍內”優于C++。
Stroustrup還反對美國國家安全局對安全的討論“僅限于內存安全,而忽略了一種語言可能(并且將會)被用來違反某種形式的安全和保障的十幾種其他方式……‘安全’的定義不止一種,我們可以通過編程風格、支持庫和通過靜態分析執行的組合來實現各種安全。”
在這一過程中,Stroustrup還提出了第二個論點:在一些性能至關重要的現實場景中,“并非所有人都將‘安全’放在首位。”因此Stroustrup認為,“明智”的做法是列出安全問題(包括未定義的行為),然后根據需要使用預執行調試工具(如靜態分析器)找到防止這些問題的方法。
沿著這些路線,Stroustrup已經在為C++調用編譯器選項和代碼注釋,以請求類型安全(和資源安全),說這“讓你只在需要的地方應用安全保證,并在需要的地方使用你最喜歡的調優技術…”
新提出的“配置文件”似乎是實現這一目標的一種語言方式。
3、理性看待C++的安全性
Stroustrup還反對在美國安全局的文件中將C++與C混為一談。他指出,即使是現在,“C++核心指南也專門致力于為那些需要的人提供靜態保證的類型安全和資源安全,而不會破壞代碼庫,因為這些代碼庫可以在沒有這種強有力的保證或引入額外的工具鏈的情況下進行管理。”
微軟的Visual Studio分析器(及其內存安全配置文件)以及許多靜態分析器已經支持這些核心準則。Stroustrup認為,這種方法允許C++“完全實現這些保證,而花費的成本只是轉向各種新穎的‘安全’語言的一小部分”。
Stroustrup還引用了他在2021年寫的另一篇論文,該論文指出:“從1979年開始,完全的類型和資源安全就一直是C++的理想(目標),并且可以通過語言規則和靜態分析強制執行的明智編程技術實現。”(后來Stroustrup寫道,解決方案是“一套精心設計的編程規則,由庫設施支持,并由靜態分析強制執行”。)
論文承認,就其本身而言,“默認情況下,核心指南不提供完整的類型和資源安全”——但認為它可以通過實施額外的規則來保證(例如,“由微軟Visual Studio發布的核心指南檢查器實現”)。Stroustrup對Rust基于編譯器的類型檢查表示認可,他寫道:“編譯器不是我們唯一的工具,從來都不是”,并提供了(預編譯)靜態分析可以執行的強大檢查的具體示例。例如,靜態分析可以:
- 防止不安全的類型轉換
- 防止創建未初始化的對象
- 確保沒有內存引用指針“轉義”超出其狹窄定義的范圍而錯誤地指向其他對象
在去年12月對美國安全據的回應中,Stroustrup寫道,我們生活在一個“數十億行C++代碼不會神奇消失”的世界里,并補充說,逐漸采用這些安全規則(以及在適當的情況下采用不同的安全規則)是很重要的。
在某種程度上,美國國家安全局的論文似乎同意其中的一些觀點。其文件包括了關于“強化”用非內存安全語言編寫的代碼的技巧,推薦了用于靜態分析(檢查源代碼)和動態分析(在代碼執行時執行)的工具,以及簡化結果的漏洞相關工具。“解決這些工具發現的問題可能需要大量的工作,但會產生更健壯和安全的代碼。”
美國國家安全局的文件確實提到了“對非內存安全語言使用附加保護”所提供的“相當大的保護”。(它還建議通過控制流保護、地址空間布局隨機化和數據執行預防等安全功能強化編譯和執行環境。)
4、憶往昔,C++做長期主義者
在Honeypot的《不為人知的開發者故事》(Untold Developer Stories)的一次新采訪中,72歲的Stroustrup回顧了自己的學生時代,當他還是個年輕人時,獲得了獲得了數學和計算機科學碩士學位的他發現自己的數學不如想象中那么好,但“機器架構真的很有趣”。
當被問及,如果有時間機器可以讓他回到最初創建C++的時候,他最想改變的東西是什么?Bjarne說,現在的他不會比創建C++時的那個他更了解那個時代,他做的任何改動可能都無法適應那個內存只有1MB的工作環境,也沒法編譯到早期的640MB Windows電腦上。
“編程語言設計的有趣之處在于,如果你成功了,你就擁有了多年前和幾十年前所做的一切,你必須忍受它。一旦你得到了用戶,你就有責任,其中一個責任就是不破壞他們的代碼……有數千億行C++代碼,我們無法破壞它們。”
Stroustrup強調了他對C++的信心。“我認為C++可以做Rust可以做的任何事情,我希望它使用起來簡單得多。”但他在2020年的采訪中也表示,基本類型安全——確保變量只能訪問其清晰劃分的內存塊——是他最早的設計目標之一,也是他花了幾十年時間試圖實現的目標。
5、沒有時間機器,一切猶如開始
這位年逾古稀的C++創建者,此時雖然已經恢復信心,但對于評論者的言論有些小難過,“當我聽到人們在談論C++時,這些人就好似回到八九十年代那樣(指指點點)。”
但正如前文所述,世間沒有時間機器,C++的設計理念也要隨著所處的時代一路演進。
C++在誕生近四十年后,依然保持著強大的生命力。Stroustrup認為保持其穩定性,并追求漸進式進化是必要的。
“我從一開始就知道,我不可能構建理想的語言,因此我必須以漸進式發展為目標:改進。說真的,我并不相信完美語言的構想:要怎樣就算是完美呢?對誰來說(是完美的)?”他補充說:“為了應對不斷變化的世界的挑戰,融入新思想,改進是必須的。”
參考鏈接:https://thenewstack.io/can-c-be-saved-bjarne-stroustrup-on-ensuring-memory-safety/