<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          終于!“30 歲”的 Linux 內(nèi)核 C 語(yǔ)言將升級(jí)到 C11

          共 2174字,需瀏覽 5分鐘

           ·

          2022-03-06 09:02

          上周,Linux 內(nèi)核郵件列表上關(guān)于“社區(qū)最近討論了是否為內(nèi)核采用現(xiàn)代 C 語(yǔ)言標(biāo)準(zhǔn)”的信息引發(fā)業(yè)內(nèi)關(guān)注。剛剛,Linux 開(kāi)源社區(qū)已正式宣布:內(nèi)核 C 語(yǔ)言版本將在未來(lái)升級(jí)到 C11,且預(yù)計(jì)將在今年 5 月份的 5.18 版本之后生效。



          這個(gè)突然的決定,也終于讓擁有 30 年歷史的 Linux 內(nèi)核 C 語(yǔ)言迎來(lái)了升級(jí)。


          眾所周知,想要說(shuō)服固執(zhí)的 Linux 之父 Linus Torvalds 絕非易事。那么,這一次 Linus Torvalds 為何終于松口了呢?這里面,似乎還真有那么一點(diǎn)偶然因素。


          事件起因還是要回到上周的那次的 Linux 社區(qū)討論。


          一條 Bug 引發(fā)的“連鎖反應(yīng)”

          據(jù)悉,當(dāng)時(shí)一位名叫 Jakob Koschel 的博士生正在研究與內(nèi)核鏈表原語(yǔ)相關(guān)的推測(cè)性執(zhí)行漏洞,過(guò)程中他發(fā)現(xiàn)了一個(gè)問(wèn)題:Linux 內(nèi)核廣泛使用 struct list_head 定義的雙鏈表:


          struct?list_head?{
          struct?list_head?*next,?*prev;
          };

          通常,開(kāi)發(fā)者通過(guò)將此類(lèi)結(jié)構(gòu)嵌入其他結(jié)構(gòu)里的方式,來(lái)使任何相關(guān)的結(jié)構(gòu)類(lèi)型都可以創(chuàng)建鏈表。同時(shí),該內(nèi)核還提供了大量可用于遍歷和操作鏈表的函數(shù)和宏。其中一個(gè)就是 list_for_each_entry(),這是一個(gè)偽裝成控件結(jié)構(gòu)的宏。

          恰巧,問(wèn)題出在了這個(gè)宏上。

          我們假設(shè)該內(nèi)核包含以下結(jié)構(gòu):


          struct?foo?{
          int?fooness;
          struct?list_head?list;
          };

          List 中的元素則可用于創(chuàng)建 foo 結(jié)構(gòu)的雙鏈接列表。

          假設(shè)有一個(gè)名為 foo_list 的結(jié)構(gòu)聲明作為此類(lèi)鏈表的頭,則可以使用以下代碼遍歷此鏈表:


          struct?foo?*iterator;

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

          list 參數(shù)告訴宏 foo 結(jié)構(gòu)中 list_head 結(jié)構(gòu)的名稱(chēng)。對(duì)于迭代器指向的列表中的每個(gè)元素,該循環(huán)將執(zhí)行一次。

          而這樣就會(huì)導(dǎo)致 USB 子系統(tǒng)中出現(xiàn)錯(cuò)誤:在退出宏后,傳遞給該宏的迭代器仍可使用。當(dāng)然,這是一件非?!拔kU(xiǎn)”的事情。


          所以,Koschel 提交了一個(gè)補(bǔ)丁,重新編寫(xiě)了有問(wèn)題的代碼,通過(guò)在循環(huán)結(jié)束后停止使用迭代器來(lái)修復(fù)這個(gè)錯(cuò)誤。隨后,Jakob Koschel 將(投機(jī)性安全列表迭代器建議)修復(fù)的與內(nèi)核鏈接表相關(guān)的預(yù)測(cè)執(zhí)行漏洞的補(bǔ)丁提交給了 Linus Torvalds。

          Linux 之父終于被說(shuō)服

          最初,Linus Torvalds 本人似乎對(duì)這個(gè)補(bǔ)丁并不是很喜歡,也不知道該補(bǔ)丁與推測(cè)性執(zhí)行漏洞有什么關(guān)系。但經(jīng)過(guò) Koschel 詳細(xì)解釋之后,Linus 承認(rèn)了這只是一個(gè)常見(jiàn)的 Bug。

          然而,事情并非那么簡(jiǎn)單,Linus 很快就意識(shí)到了真正的問(wèn)題:傳遞給鏈表遍歷宏的迭代器必須在循環(huán)本身之外的范圍內(nèi)聲明。

          而出現(xiàn)這種不可預(yù)測(cè)的錯(cuò)誤的原因是 C89 中沒(méi)有“在循環(huán)中聲明變量”。


          我們知道,雖然 Linux 內(nèi)核正在快速發(fā)展,但它也依賴(lài)于一些非常古老的工具,其中之一就是其內(nèi)核代碼仍在使用 1989 年版的 C 語(yǔ)言標(biāo)準(zhǔn),也就是說(shuō),該標(biāo)準(zhǔn)是在內(nèi)核項(xiàng)目啟動(dòng) 30 多年前編寫(xiě)的。

          像 list_for_each_entry()這樣的宏,基本上總是將最后一個(gè) HEAD 條目泄漏出循環(huán),就是因?yàn)椴荒茉谘h(huán)本身中聲明迭代器變量。

          如果可以編寫(xiě)一個(gè)迭代器列表遍歷宏來(lái)聲明自己,那么迭代器在循環(huán)外就不可見(jiàn),也不會(huì)出現(xiàn)這樣的問(wèn)題。

          然而,由于內(nèi)核停留在C89標(biāo)準(zhǔn)上,因此不可能在循環(huán)中聲明變量。

          因此,Linus 決定,“讓我們升級(jí)一下”,也許是時(shí)候升級(jí)到 C99 標(biāo)準(zhǔn)了,盡管 C99 也有 20 多年的歷史了,但它至少比 C89 更新一點(diǎn),且可以在循環(huán)中聲明變量。

          既然 C89 已經(jīng)過(guò)時(shí)了,為什么這么多年都沒(méi)有改變呢?Linus 解釋稱(chēng),“這是因?yàn)槲覀冊(cè)谝恍┡f的 gcc 編譯器版本上遇到了一些奇怪的問(wèn)題,這些版本不能隨意升級(jí)。”

          然而,現(xiàn)在 Linux 內(nèi)核已經(jīng)將 gcc 的最低要求提高到了 5.1 版,過(guò)去那些奇怪的 Bug 應(yīng)該消失了。

          另一位核心開(kāi)發(fā)者 Arnd Bergmann 也對(duì)此事比較關(guān)注,他認(rèn)為可以升級(jí)到 C11 甚至更高版本,但升級(jí)到 C17 或 C2x 會(huì)破壞 gcc-5/6/7 支持,因此升級(jí)到 C11 更容易實(shí)現(xiàn)。

          最終,Linus Torvalds 支持了這個(gè)想法,并宣布將“在 5.18 版合并窗口的早期嘗試一下”。

          雖然接下來(lái)轉(zhuǎn)移到 C11 可能會(huì)導(dǎo)致一些意想不到的 Bug 也說(shuō)不定,但如果一切順利,下一個(gè) Linux 內(nèi)核版本將正式轉(zhuǎn)移到 C11。您對(duì)此次升級(jí)事件有何看法呢?也歡迎在下方交流互動(dòng)。

          文章轉(zhuǎn)載:SegmentFault

          (版權(quán)歸原作者所有,侵刪)


          點(diǎn)擊下方“閱讀原文”查看更多

          瀏覽 88
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  美女张开腿让男人捅视频 | 久热99| 黄色性爱网址 | 免费播放片色情A片 | 国产a不卡 |