擴充套件LLVM的Checked C使C語言的空間記憶體更安全
Checked C是由Microsoft Research組織開發的開源、合作專案 ,它的目標是擴充套件C語言,方便程式員寫出更為可靠的程式,不會出現類似快取溢位、越界記憶體訪問以及不正確的型別轉換等問題。Checked C的程式碼可以和標準C程式碼共存,方便移植。
即將在IEEE Cybersecurity Development Conference 2018上發表 的一篇文章中,研究員介紹了Checked C主要的功能和優勢 。
Checked C借鑑了許多之前safe-C的想法,但是二者有所不同,Checked C的設計重點在允許增量轉換的同時平衡控制、互操作以及高效能。
該語言非常重視向後相容性,它引入了檢查指標的概念,來保證靜態和動態訪問驗證。Checked C語言尤其重視記憶體訪問的空間安全問題,這代表著指標在分配的記憶體中始終是解引用的。Checked C的三個設計重點如下所示:
- C指標表示得到了保留,所以Checked C的記憶體層與C相同。這有助於現存C程式碼庫和庫的互操作性。
- 顯式指明分配給指標的記憶體塊邊界,降低了編譯時和執行時的負擔。
- 檢查區域和邊界安全介面讓Checked C和原來的C程式碼的混合變成可能。完全移植過的程式碼將放在稱為檢查區域的sp中,在其中每個指標的訪問都不會受到空間記憶體異常的限制。檢查過的程式碼可以訪問不安全的遺留C程式碼,這將通過邊界安全的註解實現,這些註解將會新增到未檢查的程式碼引數、返回值、功能、記錄型別和全域性變數中。
Checked C給C語言添加了兩個新的指標型別,_Ptr<T> 和Array_ptr<T>。前者專門用於解引用,而後者支援指標運算。在解引用之前,編譯器將動態地保證這兩類指標的有效性。下面的例子展示瞭如何定義使用兩個_Array_ptr<T>引數的功能:
void append( _Array_ptr<char> dst : count(dst_count), _Array_ptr<char> src : count(src_count), size_t dst_count, size_t src_count) { _Dynamic_check(src_count <= dst_count); for (size_t i = 0; i < src_count; i++) { if (src[i] == ’\0’) { break; } dst[i] = src[i]; } }
在建立陣列的時候,程式設計師可以使用_Checked關鍵字指定檢查邊界:
int buf _Checked[10]
根據Checked C開發者所述,要讓現有的C程式碼轉換為使用檢查指標和陣列的程式碼需要很多程式碼變更工作,可能會影響大概17.5%行程式碼。為了加快程序,團隊正在開發自動轉換的工具。有趣的是,Checked C部分形式化的特點可以保證任何違背空間安全的動作都將隔離在檢查區域之外。今後這一方面的努力方向將擴充套件到動態大小陣列上。
最後需要提出的是,初步基準測試顯示,檢查行為增加了平均8.6%的執行時間。Checked C是作為LLVM的擴充套件實現的,可以點選這裡 下載。
檢視英文原文:Checked C Extends LLVM to Bring Spatial Memory Safety to C
感謝冬雨對本文的審校。