<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>

          LWN: 改進(jìn)GCC的 -fanalyzer 選項(xiàng)!

          共 3533字,需瀏覽 8分鐘

           ·

          2021-10-11 18:45

          關(guān)注了就能看到更多這么棒的文章哦~

          Improvements to GCC's -fanalyzer option

          By Jonathan Corbet
          September 23, 2021
          LPC
          DeepL assisted translation
          https://lwn.net/Articles/869880/

          GNU Tools Cauldron(GNU 工具鏈開發(fā)者的年度聚會(huì))已經(jīng)是連續(xù)第二年在 Linux Plumbers 在線大會(huì)上作為一個(gè)專門 track 來進(jìn)行了。在 2021 年的會(huì)議上,David Malcolm 首先介紹了 GCC -fanalyzer 選項(xiàng)相關(guān)的工作,該選項(xiàng)提供了一些靜態(tài)分析功能。在 -fanalyzer 這一個(gè)領(lǐng)域已經(jīng)有了很多進(jìn)展,而且在即將發(fā)布的 GCC 12 版本中還會(huì)有更多的功能,包括增加的一系列檢查可能已經(jīng)發(fā)現(xiàn)內(nèi)核中的若干漏洞了。

          GCC 在被調(diào)用時(shí)如果帶有 -fanalyzer 選項(xiàng)的話,它會(huì)運(yùn)行一個(gè) module 來創(chuàng)建一個(gè) "爆炸圖,exploded graph",可以將程序的控制流和數(shù)據(jù)流的狀態(tài)信息結(jié)合在一起顯示出來。其包括對(duì)內(nèi)存內(nèi)容的抽象描述、對(duì)變量值的已知限制、以及代碼是不是可能正在 signal handler 中運(yùn)行等等信息。然后,analyzer 就可以使用這個(gè)圖來嘗試探索代碼中所有感興趣的路徑,看看可能會(huì)發(fā)生什么。

          GCC 10 版本中,針對(duì)潛在錯(cuò)誤方面已經(jīng)新增了 15 個(gè) warning 信息,如兩次釋放內(nèi)存、釋放內(nèi)存后繼續(xù)使用、signal handler 程序中不安全的函數(shù)調(diào)用、可能在將敏感數(shù)據(jù)寫入日志文件等等。兩次釋放的檢測(cè)正是讓人們有動(dòng)力開發(fā)這些檢查功能的主要因素。GCC 11 中又增加了五個(gè) warning,包括可以檢查出從一個(gè) allocator 中獲得的內(nèi)存是否被意外地釋放到另一個(gè) allocator 中了,以及對(duì)位移運(yùn)算中一些未定義行為的檢查。GCC 11 中還支持使用插件來擴(kuò)展 analyzer。在 test suite 里面就可以找到一個(gè)插件樣例,用于檢查出 Python 全局解釋器鎖(GIL)的錯(cuò)誤使用。

          最近,Malcolm 在思考針對(duì) GCC 12 應(yīng)該做些什么。他原本想增加對(duì) C++ 的支持,但后來發(fā)現(xiàn)他自己更愿意改進(jìn) C 語言相關(guān)的功能。在得出這個(gè)結(jié)論之前,他已經(jīng)在 GCC 11 中實(shí)現(xiàn)了 new 和 delete 的支持,并把異常處理(exception handling)作為了他自己的下一個(gè)目標(biāo),但結(jié)果發(fā)現(xiàn)這個(gè)領(lǐng)域 "相當(dāng)復(fù)雜"。同時(shí),谷歌夏季代碼挑戰(zhàn)項(xiàng)目的學(xué)生 Ankur Saini 也增加了對(duì)虛擬函數(shù)的支持。因此,C++ 這方面已經(jīng)取得了一些進(jìn)展,但 Malcolm 的工作目前將繼續(xù)集中在 C 語言上。

          有幾個(gè) C 語言的問題引起了他的注意,其中之一是緩沖區(qū)溢出的檢測(cè)。他實(shí)現(xiàn)了一個(gè)原型方案,可以根據(jù) symbol 捕捉記錄動(dòng)態(tài)分配的 size,并在后續(xù)讀寫時(shí)可能超出這個(gè) size 的時(shí)候給出 diagnostics 診斷信息。但是很難確定應(yīng)該在什么時(shí)候來報(bào)出 warning,現(xiàn)有代碼中產(chǎn)生了太多的誤報(bào)(他的說法是 "a wall of noise"),因此無法真正實(shí)用起來。

          不過,他想到有一種方法可能可以找到一類特定的問題:就是針對(duì)那些可能被攻擊者影響某次 access 是否有效的位置。這就引出了 taint detection(污染檢測(cè))以及如何確定程序中的信任邊界(trust boundaries)在哪里的問題。要想對(duì)隨便一段 C 代碼來確認(rèn)這兩點(diǎn),這會(huì)是一個(gè)非常困難的問題。不過,針對(duì)特定程序的話,是可以進(jìn)行標(biāo)注(annotate)并獲得有用的診斷信息。他的注意力轉(zhuǎn)向了內(nèi)核,因?yàn)閮?nèi)核具有一個(gè)定義非常明確的信任邊界,以及一個(gè)用來跨越該邊界進(jìn)行數(shù)據(jù)搬移的 API。通過對(duì) copy_from_user() 以及 system-call handler 函數(shù)的標(biāo)注,就可能可以發(fā)現(xiàn)那些沒有對(duì)用戶所提供的數(shù)據(jù)進(jìn)行檢查(sanitize)的代碼。

          GCC 有一個(gè)屬性(access),用來描述數(shù)據(jù)是如何在某個(gè)的變量或函數(shù)中移動(dòng)的。Malcolm 為該屬性增加了兩個(gè)新的可用值(untrusted_read 和 untrusted_write),用來標(biāo)記讀取來自于(或?qū)懭肽繕?biāo)是)一個(gè)不受信任的位置的數(shù)據(jù)。因此,比如通過 copy_from_user() 讀入內(nèi)核的數(shù)據(jù)就會(huì)被標(biāo)記為 untrusted_read。他還為這些函數(shù)添加了一個(gè)新的 tainted 屬性,用來表示該函數(shù)的所有參數(shù)都應(yīng)被視為不可信任的。通過修改內(nèi)核頭文件中的一個(gè)宏,他就能夠?qū)?nèi)核中所有的 system-call handler 函數(shù)都打上這個(gè) tainted 屬性。也可以對(duì)其他一些函數(shù)進(jìn)行類似標(biāo)記,比如說內(nèi)核生成的文件系統(tǒng)的 callback 函數(shù)。

          有了這些標(biāo)注之后,analyzer 就可以檢測(cè)到兩類問題:信息泄露(information leaks)和使用了污染數(shù)據(jù)(tainted data)。信息泄露都是發(fā)生在將未進(jìn)行初始化的數(shù)據(jù)直接寫回到用戶空間的時(shí)候。這種情況相對(duì)比較容易檢測(cè),或者至少他是這樣認(rèn)為的。作為這類問題的一個(gè)例子,Malcolm 提出了 CVE-2017-18549,這是一個(gè)將 stack 中的隨機(jī)數(shù)據(jù)寫回用戶空間的驅(qū)動(dòng)程序 bug。在這種情況下,被寫入的這個(gè)未進(jìn)行初始化的數(shù)據(jù)是在一個(gè)原本被正常進(jìn)行了初始化的結(jié)構(gòu)中填入的 padding 數(shù)據(jù),analyzer 就可以發(fā)現(xiàn)這個(gè)問題。要讓這個(gè)問題得到 fix,需要對(duì)未初始化數(shù)據(jù)的跟蹤記錄代碼進(jìn)行重構(gòu),這不是一個(gè)容易的任務(wù)。

          還有一個(gè)類似的問題,是從用戶空間讀取數(shù)據(jù)進(jìn)行修改,然后把結(jié)果 copy 回用戶空間,也許是 copy 到另一個(gè)位置。如果 read 操作失敗了的話,內(nèi)核可能會(huì)對(duì)未初始化的數(shù)據(jù)進(jìn)行一些處理然后直接寫入用戶空間。要 fix 這個(gè)問題,需要對(duì)處理 copy_from_user()失敗的情況。一旦完成了這個(gè)工作之后,analyzer 也就可以處理 realloc() 了,盡管它有三種可能結(jié)果。

          當(dāng)用戶提供的數(shù)據(jù)被拿來當(dāng)作數(shù)組的索引時(shí),就會(huì)出現(xiàn)數(shù)據(jù)被污損(tainted)的情況。這種情況更難檢測(cè),但似乎更重要一些,因?yàn)檫@種類型的漏洞往往可以被利用來攻破內(nèi)核。例如 CVE-2011-0521 這種情況下,內(nèi)核代碼會(huì)讀取一個(gè)有符號(hào)的 "size" 值,根據(jù)所允許的最大值來進(jìn)行檢查,但是沒有檢查是不是負(fù)數(shù)就直接使用它了。改進(jìn)后的 analyzer 就能夠捕捉到這種情況。

          他仍在研究如何實(shí)現(xiàn)這個(gè)功能的原型,期待可以展示給大家看。作為這個(gè)工作的一部分,他開發(fā)了一個(gè)世界上的最糟糕的內(nèi)核 module,其中包含了他能想到的所有問題。不過,由于內(nèi)核使用了大量的 inline 匯編代碼,這使得 analyzer 要做的事情在分析完整內(nèi)核的情況下就變得更加復(fù)雜。他已經(jīng)為這個(gè)功能添加了一些基本的處理代碼,但是目前并沒有去檢查實(shí)際的匯編操作碼(opcodes)。

          他一直在針對(duì) upstream 的內(nèi)核來不斷運(yùn)行自己的檢查功能,并且已經(jīng)發(fā)現(xiàn)了一個(gè)真正的漏洞,這個(gè)漏洞已經(jīng)被報(bào)告出來但是尚未被修復(fù)或披露出來。因此,Malcolm 的最新成果代碼仍然只能放在在公司內(nèi)部的代碼倉(cāng)庫(kù)中。因?yàn)樗l(fā)現(xiàn)了真正的系統(tǒng)漏洞,那么在它所發(fā)現(xiàn)的問題被修復(fù)之前,他可不想把工具發(fā)布出來成為幫助攻擊者的 zero-day-finding 工具。其他大部分工作現(xiàn)在都提交到 GCC 12 的主分支中了。他希望能夠在 GCC 12 stage 1 周期結(jié)束前就完成這項(xiàng)工作并將其推到 upstream(https://gcc.gnu.org/develop.html?這里可以看到 GCC 開發(fā)周期的各個(gè) stage 的含義)。

          關(guān)于這個(gè)項(xiàng)目的更多信息可以在 GCC wiki (https://gcc.gnu.org/wiki/DavidMalcolm/StaticAnalyzer) 中找到。

          全文完
          LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。

          歡迎分享、轉(zhuǎn)載及基于現(xiàn)有協(xié)議再創(chuàng)作~

          長(zhǎng)按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開源社區(qū)的各種新近言論~



          瀏覽 54
          點(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>
                  久久精品四区 | 天干夜天干天天天爽色播 | 午夜日逼网站 | 亚洲黄色在线电影 | A片免费网站在线观看 |