Linux核心C語言將升級

夢共裡醉發表於2022-03-17
根據   核心郵件列表的訊息,社群近日討論了是否要為核心採用現代 C 語言標準。

雖然 Linux 核心在快速發展,但它同時依賴著一些非常古老的工具,其中之一就是核心程式碼仍在使用1989年版本的 C 語言標準——此標準在30多年前核心專案啟動之前就已經編寫完成。從討論結果來看,這一情況有望在5.18版本核心中改變。

Jakob Koschel 在向 Linus Torvalds 遞交的補丁()中修復了核心連結串列相關的預測執行漏洞。

Linux核心C語言將升級Linux核心C語言將升級

起因是 Jakob 發現了一個問題,Linux 核心廣泛使用由 struct list_head 定義的雙向連結串列:

structlist_head{	structlist_head*next,*prev;};

這種結構體通常被嵌入到其他結構體中,通過這種方式,開發者可以使用任何感興趣的結構型別製作連結串列。除此之外,核心還提供了大量可用於遍歷和操作連結串列的函式和巨集。其中之一是 list_for_each_entry(),這是一個偽裝成控制結構的巨集。要了解如何使用此巨集,請假設核心包含如下結構:

structfoo{intfooness;structlist_headlist;};

list 成員可用於建立 foo 結構體的雙向連結串列,假設我們有一個叫做 foo_list 的結構宣告作為此類連結串列的頭,使用以下程式碼可以遍歷此列表:

struct foo *iterator;
list_for_each_entry(iterator, &foo_list, list) {
do_something_with(iterator);
}
/* Should not use iterator here */

list 引數告訴巨集在 foo 結構中 list_head 結構體的名稱。此迴圈將為列表中的每個元素執行一次,迭代器指向該元素。由此導致了 USB 子系統中的一個 bug:傳遞給該巨集的迭代器在退出巨集後還能被使用。

Koschel 通過重新編寫有問題的程式碼,以在迴圈後停止使用迭代器來解決問題。

不過 Linus 卻對補丁修復的問題表示不解,也沒有看到它與預測執行漏洞的關係。Koschel 對此進行了進一步解釋,對此 Linus 認為這只是一個普通的 bug。但不久之後 Linus 發現了問題的根源所在:傳遞給列表遍歷巨集的迭代器,必須在迴圈本身之外的範圍內宣告。

隨後,Linus 認為也許可以採用更直接的修復如塊級變數宣告。但 C89不支援,而1999年釋出的 C99標準支援。所以 Linux 核心也許是時候轉向使用 C99標準了。

Linus 說到,核心程式碼一直停留在 C89的原因之一是編譯器 gcc 的舊版本會出現奇怪的問題,導致初始化程式被破壞。不過現在核心要求的 GCC 最低版本已經提高到了 v5.1,那些 bug 可能不再相關了。

另一位密切關注架構編譯器問題的核心開發者 Arnd Bergmann 提議直接升級到 C11甚至 C2x,儘管他不確定 C11是否會帶來任何對核心有用的新內容。不過如果升級到 C17或 C2x,會破壞對 gcc-5/6/7的支援,因此升級到 C11更容易實現,而且跨越太大核心社群未必接受。

Linus贊成了這個想法,在 Bergmann確認應該可以這樣做之後,Linus宣佈將在下一個核心版本 v5.18中嘗試使用 C11標準。如果一切順利,下一個核心版本使用的 C 語言標準有望升級到 C11。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31524109/viewspace-2871515/,如需轉載,請註明出處,否則將追究法律責任。

相關文章