国产精品1024永久观看,大尺度欧美暖暖视频在线观看,亚洲宅男精品一区在线观看,欧美日韩一区二区三区视频,2021中文字幕在线观看

  • <option id="fbvk0"></option>
    1. <rt id="fbvk0"><tr id="fbvk0"></tr></rt>
      <center id="fbvk0"><optgroup id="fbvk0"></optgroup></center>
      <center id="fbvk0"></center>

      <li id="fbvk0"><abbr id="fbvk0"><dl id="fbvk0"></dl></abbr></li>

      一種針對(duì)Linux內(nèi)核頁表隔離的功能調(diào)用改造方法與流程

      文檔序號(hào):11287141閱讀:635來源:國知局
      一種針對(duì)Linux內(nèi)核頁表隔離的功能調(diào)用改造方法與流程

      本發(fā)明屬于計(jì)算機(jī)操作系統(tǒng)安全領(lǐng)域,即一種基于內(nèi)核模塊隔離的保護(hù)內(nèi)核模塊安全的研究,涉及一種針對(duì)linux內(nèi)核頁表隔離的功能調(diào)用改造方法。



      背景技術(shù):

      隨著技術(shù)的發(fā)展,linux系統(tǒng)已在各行各業(yè)都得到了廣泛的應(yīng)用,這其中就包括金融、保險(xiǎn)、政府機(jī)關(guān)等對(duì)安全性要求較高的行業(yè),然而linux內(nèi)核作為系統(tǒng)中最重要的部分,其安全性一直為人所詬病。導(dǎo)致linux安全性不高的原因有很多,最根本的原因在于其宏內(nèi)核的設(shè)計(jì)模式使得內(nèi)核中的各個(gè)模塊都能以最高權(quán)限訪問整個(gè)內(nèi)核地址空間,從而任意模塊的漏洞都可能會(huì)擴(kuò)散到內(nèi)核的其他模塊,最終導(dǎo)致整個(gè)系統(tǒng)的崩潰。

      隨著惡意攻擊手段的不斷增加,包括沙箱、可信技術(shù)及訪問控制在內(nèi)的傳統(tǒng)防御機(jī)制已無法滿足內(nèi)核的安全性。為此,學(xué)界和工業(yè)界引入了安全隔離機(jī)制來提供一個(gè)安全隔離的運(yùn)行環(huán)境以保護(hù)內(nèi)核。根據(jù)隔離機(jī)制實(shí)現(xiàn)方式的不同,我們可以將其歸納為硬件隔離技術(shù)和軟件隔離技術(shù)兩類。所謂硬件隔離技術(shù),是指對(duì)相關(guān)芯片設(shè)計(jì)一個(gè)專門用于存儲(chǔ)系統(tǒng)關(guān)鍵數(shù)據(jù)的安全硬件模塊,并通過硬件限制其它模塊的非法訪問,以此達(dá)到隔離的目的,常見的應(yīng)用模型有可信平臺(tái)模塊tpm和trustzone安全處理架構(gòu)兩種。然而硬件隔離技術(shù)往往依賴于硬件類型,這會(huì)降低隔離產(chǎn)品的通用性。所謂軟件隔離技術(shù),是指在軟件層構(gòu)建一個(gè)安全的隔離運(yùn)行環(huán)境用于存放系統(tǒng)中的敏感數(shù)據(jù)和相關(guān)代碼,使這些數(shù)據(jù)和代碼不會(huì)受到外界惡意攻擊的影響。虛擬化隔離技術(shù)是最常見的軟件隔離技術(shù)之一,它之所以能作為系統(tǒng)安全隔離的手段之一,是因?yàn)樘摂M機(jī)管理軟件能攔截并模擬處理客戶操作系統(tǒng)的敏感指令,阻止客戶機(jī)對(duì)主機(jī)的非法操作,并且保證各個(gè)客戶機(jī)的獨(dú)立性,使得某個(gè)客戶機(jī)的惡意操作不會(huì)擴(kuò)散到其它客戶機(jī)上。然而,虛擬機(jī)目前只能隔離一些動(dòng)態(tài)載入的驅(qū)動(dòng)模塊,而對(duì)于包括文件系統(tǒng)在內(nèi)的靜態(tài)模塊的隔離困難較大。

      針對(duì)以上兩種內(nèi)核隔離機(jī)制的缺陷,提出了基于內(nèi)存頁表不可見性的內(nèi)核隔離方案。具體做法是將被隔離模塊的代碼和數(shù)據(jù)單獨(dú)映射到由特定頁表控制的物理地址空間中,并控制該頁表的訪問區(qū)間,以此實(shí)現(xiàn)模塊間的隔離。然而原linux系統(tǒng)采用宏內(nèi)核模式來設(shè)計(jì)模塊間的功能調(diào)用機(jī)制,全部過程都處于同一個(gè)進(jìn)程上下文中,但在內(nèi)存不可見的情況下,一個(gè)進(jìn)程是無法訪問兩個(gè)被隔離模塊的。如果不對(duì)原功能調(diào)用形式進(jìn)行改造,被隔離模塊依舊會(huì)通過直接調(diào)用接口函數(shù)的方式訪問其它模塊,屆時(shí)相關(guān)的內(nèi)存訪問操作會(huì)被拒絕,導(dǎo)致系統(tǒng)不能完整地處理用戶請求。

      針對(duì)上述原linux內(nèi)核功能調(diào)用的缺陷,本發(fā)明提出了一種針對(duì)linux內(nèi)核頁表隔離的功能調(diào)用改造方法,即分別在文件系統(tǒng)和內(nèi)核中插入存根子模塊和回調(diào)子模塊,并將功能調(diào)用由原來的宏內(nèi)核模式改成微內(nèi)核模式,使系統(tǒng)在保證內(nèi)核代碼和數(shù)據(jù)的安全性的同時(shí),能夠讓被隔離模塊正常訪問內(nèi)核代碼并正確處理用戶空間的服務(wù)請求。



      技術(shù)實(shí)現(xiàn)要素:

      發(fā)明目的:本發(fā)明所要解決的技術(shù)問題是針對(duì)原linux內(nèi)核的功能調(diào)用方式無法適用于基于內(nèi)存頁表不可見性的內(nèi)核模塊隔離方案這一問題,提出了一種針對(duì)linux內(nèi)核頁表隔離的功能調(diào)用改造方法。

      為了解決以上問題,本發(fā)明公開了一種針對(duì)linux內(nèi)核頁表隔離的功能調(diào)用改造方法,該方法所有的步驟均運(yùn)行與linux平臺(tái),用于將被隔離模塊間的功能調(diào)用方式由原來的宏內(nèi)核模式改為微內(nèi)核模式,以允許被隔離模塊依舊可以正常的訪問內(nèi)核中其它模塊的代碼和數(shù)據(jù)。

      所述針對(duì)linux內(nèi)核頁表隔離的功能調(diào)用改造方法的步驟如下:

      包括如下步驟:

      步驟1,在clang編譯器中編寫插件,利用該插件分析被隔離模塊并獲得其函數(shù)調(diào)用關(guān)系圖;

      步驟2,編寫查找算法在函數(shù)調(diào)用關(guān)系圖中查找其它模塊的所有接口函數(shù)調(diào)用點(diǎn);

      步驟3,根據(jù)所得的接口函數(shù)編寫相應(yīng)的存根函數(shù)和回調(diào)函數(shù),并分別存入被隔離模塊的存根子模塊以及內(nèi)核的回調(diào)子模塊中;

      步驟4,在每個(gè)接口函數(shù)調(diào)用點(diǎn)處都用對(duì)應(yīng)的存根函數(shù)替換原接口函數(shù);

      步驟5,針對(duì)數(shù)據(jù)處理過程中的一致性問題,提出了對(duì)進(jìn)程控制塊進(jìn)行重定向的方法。

      本發(fā)明步驟1包括如下步驟:

      步驟1-1,在clang編譯器內(nèi)部編寫相關(guān)插件并重新編譯llvm,使其在構(gòu)造完抽象語法樹后都以深度優(yōu)先的范式遍歷樹中的節(jié)點(diǎn),并過濾出調(diào)用函數(shù)節(jié)點(diǎn)、被調(diào)用函數(shù)節(jié)點(diǎn)以及被調(diào)用函數(shù)指針節(jié)點(diǎn);

      步驟1-2,用步驟1-1得到的編譯器插件分析linux內(nèi)核源碼中的被隔離模塊部分,得到其中包括函數(shù)指針在內(nèi)的函數(shù)調(diào)用關(guān)系圖;為了解決歧義性問題,還必須將架構(gòu)相關(guān)文件和配置文件導(dǎo)入插件中;

      步驟1-3,將步驟1-2得到的函數(shù)調(diào)用關(guān)系信息格式化到指定的哈希表中,其中關(guān)鍵字為調(diào)用函數(shù)名,值為包括函數(shù)指針在內(nèi)的被調(diào)用函數(shù)列表;無論是調(diào)用函數(shù)名還是被調(diào)用函數(shù)名都以字符串形式保存,并且此時(shí)鍵值對(duì)中無模塊標(biāo)簽。

      本發(fā)明步驟1-1包括以下步驟:

      步驟1-1-1,重載handletranslationunit函數(shù),在該函數(shù)內(nèi)部調(diào)用traversedecl函數(shù),從而讓clang編譯器每次構(gòu)造完抽象語法樹后都以深度優(yōu)先的范式遍歷樹中的節(jié)點(diǎn);

      步驟1-1-2,重載的visitfunctiondecl函數(shù),使得clang編譯器每當(dāng)遇到函數(shù)聲明/類型節(jié)點(diǎn)時(shí),都會(huì)自動(dòng)過濾掉函數(shù)聲明的情況,并將保留下來的函數(shù)定義信息作為調(diào)用函數(shù)保存;

      步驟1-1-3,重載的visitdeclrefexpr函數(shù),使得clang編譯器每當(dāng)遇到引用表達(dá)式類型節(jié)點(diǎn)時(shí),都會(huì)自動(dòng)過濾掉非函數(shù)表達(dá)式的情況,并將保留下來的函數(shù)表達(dá)式信息作為被調(diào)用函數(shù)保存;

      步驟1-1-4,重載的visitmemberexpr函數(shù),使得clang編譯器每當(dāng)遇到成員表達(dá)式類型節(jié)點(diǎn)時(shí),都會(huì)自動(dòng)過濾掉非函數(shù)指針的情況,并將保留下來的函數(shù)指針信息作為被調(diào)用函數(shù)指針保存。

      本發(fā)明步驟2包括以下步驟:

      步驟2-1,從內(nèi)核鏡像vmlinux中提取各個(gè)模塊的函數(shù)符號(hào)信息和接口函數(shù)信息,其中每個(gè)函數(shù)項(xiàng)都包含對(duì)應(yīng)的模塊信息;將函數(shù)符號(hào)信息和接口函數(shù)信息按需存放到函數(shù)符號(hào)表和接口函數(shù)表中;

      步驟2-2,遍歷步驟1中的得到的被隔離模塊的函數(shù)調(diào)用關(guān)系圖,對(duì)每個(gè)調(diào)用函數(shù)或被調(diào)用函數(shù)都在步驟2-1中的得到的函數(shù)符號(hào)表中搜索對(duì)應(yīng)的模塊信息,并將得到的模塊信息以字符串標(biāo)簽的形式打印到函數(shù)調(diào)用關(guān)系圖中的相應(yīng)位置;

      步驟2-3,設(shè)計(jì)并實(shí)現(xiàn)了按模塊查找接口函數(shù)調(diào)用點(diǎn)的功能;利用該算法分析步驟2-2中得到的帶模塊標(biāo)簽的函數(shù)調(diào)用關(guān)系圖,以獲取被隔離模塊中所有調(diào)用其它模塊接口函數(shù)的位置;

      步驟2-4,設(shè)計(jì)并實(shí)現(xiàn)了按函數(shù)查找接口函數(shù)調(diào)用點(diǎn)的功能;利用該算法分析步驟2-2中得到的帶模塊標(biāo)簽的函數(shù)調(diào)用關(guān)系圖,以獲取被查找函數(shù)的調(diào)用關(guān)系鏈中所有調(diào)用其它模塊接口函數(shù)的位置。

      本發(fā)明步驟2-1包括以下步驟:

      步驟2-1-1,調(diào)用nm命令從內(nèi)核鏡像vmlinux中提取出帶位置信息的內(nèi)核符號(hào)表;

      步驟2-1-2,根據(jù)符號(hào)類型從步驟2-1-1得到的內(nèi)核符號(hào)表中篩選出函數(shù)符號(hào)信息和接口函數(shù)信息,其中將類型為t或t符號(hào)整理為函數(shù)符號(hào)信息,而將類型為t的符號(hào)整理為接口函數(shù)信息;

      步驟2-1-3,設(shè)計(jì)兩種哈希表,分別以函數(shù)名和函數(shù)地址為關(guān)鍵字;將步驟2-1-2得到的函數(shù)符號(hào)信息存入以函數(shù)名為關(guān)鍵字的哈希表中,并將該哈希表作為函數(shù)符號(hào)表;將步驟2-1-2得到的接口函數(shù)表按兩種格式分別存入以函數(shù)名為關(guān)鍵字的哈希表和已函數(shù)地址為關(guān)鍵字的哈希表中,這兩個(gè)哈希表都稱為接口函數(shù)表。

      本發(fā)明步驟2-3包括以下步驟:

      步驟2-3-1,將函數(shù)調(diào)用關(guān)系圖中的第一個(gè)關(guān)鍵字函數(shù)(即第一個(gè)調(diào)用函數(shù))作為當(dāng)前關(guān)鍵字函數(shù);

      步驟2-3-2,獲得當(dāng)前關(guān)鍵字函數(shù)對(duì)應(yīng)的被調(diào)用函數(shù)列表;遍歷該被調(diào)用函數(shù)列表,依次檢查被調(diào)用函數(shù)的模塊標(biāo)簽是否是被查找模塊或頭文件:若是,則直接跳到下一被調(diào)用函數(shù);否則,將當(dāng)前關(guān)鍵字函數(shù)和該被調(diào)用函數(shù)組成的二元組作為接口函數(shù)調(diào)用點(diǎn)記錄下來;

      步驟2-3-3,待該關(guān)鍵字函數(shù)對(duì)應(yīng)的被調(diào)用函數(shù)值列表遍歷完畢后,檢查函數(shù)調(diào)用關(guān)系圖中是否還有下一個(gè)關(guān)鍵字未被處理:若有,則獲取下一個(gè)關(guān)鍵字函數(shù)作為當(dāng)前關(guān)鍵字函數(shù)返回步驟2-3-2繼續(xù)執(zhí)行;否則,結(jié)束查找算法。

      本發(fā)明步驟2-4包括以下步驟:

      步驟2-4-1,將被查找函數(shù)作為當(dāng)前關(guān)鍵字函數(shù);

      步驟2-4-2,深度優(yōu)先遍歷當(dāng)前關(guān)鍵字函數(shù)對(duì)應(yīng)的被調(diào)用函數(shù)值列表,若表項(xiàng)函數(shù)在目標(biāo)模塊中,則將當(dāng)前關(guān)鍵字函數(shù)和該被調(diào)用函數(shù)組成的二元組作為接口函數(shù)調(diào)用點(diǎn)記錄下來;否則,執(zhí)行步驟2-4-3;

      步驟2-4-3,若表項(xiàng)函數(shù)位于頭文件或所在模塊與被查找函數(shù)相同,則以該表項(xiàng)函數(shù)作為當(dāng)前關(guān)鍵字函數(shù)返回步驟2-4-2中繼續(xù)查找;否則,直接取下一表項(xiàng)函數(shù)作為當(dāng)前關(guān)鍵字返回步驟2-4-2中繼續(xù)查找,直到遍歷結(jié)束。

      本發(fā)明步驟3包括以下步驟:

      步驟3-1,設(shè)計(jì)并實(shí)現(xiàn)了一種接口函數(shù)改造方案:在被隔離模塊和內(nèi)核中分別設(shè)計(jì)并實(shí)現(xiàn)存根子模塊和回調(diào)子模塊;當(dāng)被隔離模塊需要訪問內(nèi)核中的代碼或數(shù)據(jù)時(shí)會(huì)重定向到存根子模塊中,存根子模塊負(fù)責(zé)打包消息并通過ipc傳遞到內(nèi)核中;回調(diào)子模塊收到消息后交由回調(diào)子模塊執(zhí)行,回調(diào)子模塊負(fù)責(zé)拆解消息塊以獲取其中的參數(shù)等信息,之后執(zhí)行真正的工作函數(shù)(即原接口函數(shù)),最后將返回值打包反饋給被隔離模塊;

      步驟3-2,設(shè)計(jì)并實(shí)現(xiàn)了存根子模塊和回調(diào)子??谥g用于ipc傳輸?shù)南K,其內(nèi)部包含六個(gè)成員對(duì)象,分別是當(dāng)前進(jìn)程的current、回調(diào)函數(shù)指針、指向?qū)崊⑷萜鞯姆盒椭羔?、指向返回值的泛型指針、結(jié)束位以及反饋消息的隊(duì)列號(hào);其中當(dāng)前進(jìn)程的current值用于解決數(shù)據(jù)一致性問題,回調(diào)函數(shù)指針用于告訴內(nèi)核需要調(diào)用哪個(gè)回調(diào)函數(shù)處理,指向?qū)崊⑷萜鞯闹羔樣糜诖鎯?chǔ)各種類型和數(shù)量的實(shí)參,返回值指針用于存儲(chǔ)各種類型的返回值,結(jié)束位用于指示核心態(tài)工作是否結(jié)束,反饋消息隊(duì)列號(hào)用于告訴內(nèi)核將帶有返回值的消息塊發(fā)送到哪個(gè)消息隊(duì)列中;

      步驟3-3,設(shè)計(jì)并實(shí)現(xiàn)了用于存儲(chǔ)各種類型和數(shù)量實(shí)參的參數(shù)容器,本發(fā)明根據(jù)參數(shù)數(shù)量設(shè)計(jì)了八種實(shí)參容器,實(shí)現(xiàn)過程中利用c語言中的宏定義來模擬高級(jí)語言中的模板,并通過模板實(shí)例化的方式來統(tǒng)一傳輸各種類型和數(shù)量的實(shí)參。

      本發(fā)明步驟3-1包括以下步驟:

      步驟3-1-1,根據(jù)步驟2-1中得到的接口函數(shù)表,為每個(gè)接口函數(shù)都編寫對(duì)應(yīng)的存根函數(shù)和回調(diào)函數(shù),分別存放到被隔離模塊的存根子模塊和內(nèi)核的回調(diào)子模塊中;

      步驟3-1-2,存根函數(shù)的執(zhí)行過程:生成并初始化消息塊,包括注冊回調(diào)函數(shù)、被隔離模塊的當(dāng)前current值、反饋消息隊(duì)列號(hào);創(chuàng)建并初始化參數(shù)容器,并將其掛載到消息塊中;調(diào)用消息模塊提供的api函數(shù)msgsnd發(fā)送消息;在先前注冊的消息隊(duì)列號(hào)上等待內(nèi)核的反饋消息;解析反饋消息中的返回值并繼續(xù)執(zhí)行下一指令;

      步驟3-1-2,回調(diào)函數(shù)的執(zhí)行過程:解析獲得的消息塊并用其中的pcb指針偽裝自己的current,以此實(shí)現(xiàn)數(shù)據(jù)一致性;創(chuàng)建參數(shù)容器,并以此解析消息塊中的具體參數(shù);將具體參數(shù)傳入真正的工作函數(shù)(即原接口函數(shù)),并將返回值存入原消息塊的相關(guān)位置;調(diào)用消息模塊提供的api函數(shù)msgsnd,將原消息塊(此時(shí)存有返回值)發(fā)送到消息塊中指定的消息隊(duì)列中。

      本發(fā)明步驟4需要根據(jù)被調(diào)用函數(shù)的類型進(jìn)行分類操作:

      若接口函數(shù)調(diào)用點(diǎn)處調(diào)用的是一個(gè)普通函數(shù),則直接在源碼中用對(duì)應(yīng)的存根函數(shù)替換原接口函數(shù);若接口函數(shù)調(diào)用點(diǎn)處調(diào)用的是一個(gè)函數(shù)指針,則先在步驟2-1-3中得到的以函數(shù)地址為關(guān)鍵字的接口函數(shù)表中查詢該函數(shù)指針是否指向一個(gè)接口函數(shù)的指針,若是,則調(diào)用對(duì)應(yīng)的存根函數(shù);否則,直接執(zhí)行該函數(shù)指針。

      本發(fā)明步驟5包括以下步驟:

      步驟5-1,為被隔離模塊保存一個(gè)獨(dú)一無二而的全局變量temp(假設(shè)被隔離模塊是單進(jìn)程的),用來存儲(chǔ)內(nèi)核傳過來的pcb指針;

      步驟5-2,被隔離模塊每次接收到新的消息塊時(shí),都用該消息塊中的current成員去更新全局變量temp;

      步驟5-3,根據(jù)需要重定義current:通過get_current()判斷當(dāng)前進(jìn)程是被隔離模塊進(jìn)程還是內(nèi)核進(jìn)程,若是被隔離模塊進(jìn)程,則返回全局變量temp;若是內(nèi)核進(jìn)程,則直接返回get_current()的結(jié)果。

      附圖說明

      下面結(jié)合附圖和具體實(shí)施方式對(duì)本發(fā)明做更進(jìn)一步的具體說明,本發(fā)明的上述或其他方面的優(yōu)點(diǎn)將會(huì)變得更加清楚。

      圖1為本發(fā)明的背景圖,即基于內(nèi)存頁表不可見性的內(nèi)核隔離框架圖。

      圖2為本發(fā)明的實(shí)現(xiàn)流程圖

      圖3為函數(shù)調(diào)用關(guān)系分析軟件的內(nèi)部流程圖

      圖4為接口函數(shù)調(diào)用點(diǎn)查找過程的原理圖

      圖5為改造后的功能調(diào)用框架圖

      圖6為進(jìn)程控制塊重定向的原理圖

      具體實(shí)施方式

      下面結(jié)合附圖對(duì)本發(fā)明做進(jìn)一步說明。

      本發(fā)明提出了一種針對(duì)linux內(nèi)核頁表隔離的功能調(diào)用改造方法,通過對(duì)linux系統(tǒng)的模塊間功能調(diào)用方式進(jìn)行改造,以保證隔離后被隔離模塊能正常訪問內(nèi)核中其它模塊的代碼和數(shù)據(jù)。

      圖1為基于內(nèi)存頁表不可見性的內(nèi)核隔離框架圖,展示了該隔離環(huán)境下一次完整的用戶空間服務(wù)請求的執(zhí)行過程,具體步驟如下:

      步驟1,應(yīng)用程序發(fā)出的與被隔離模塊相關(guān)的服務(wù)請求時(shí)會(huì)被hook到被隔離模塊進(jìn)程中執(zhí)行;

      步驟2,當(dāng)被隔離模塊模塊需要訪問內(nèi)核其它模塊的代碼和數(shù)據(jù)時(shí),并不會(huì)直接調(diào)用原來的接口函數(shù),取而代之的是調(diào)用存根子模塊中對(duì)應(yīng)的存儲(chǔ)函數(shù),這些存根函數(shù)負(fù)責(zé)生成消息塊并選擇合適的消息隊(duì)列號(hào),然后通過消息模塊發(fā)送到內(nèi)核中的回調(diào)子模塊;

      步驟3,內(nèi)核收到消息后交由回調(diào)子模塊處理,回調(diào)子模塊調(diào)用消息塊中先前注冊的回調(diào)函數(shù)執(zhí)行真正的工作函數(shù),并將返回值通過消息模塊返回給被隔離模塊以便執(zhí)行后續(xù)指令;

      步驟4,當(dāng)被隔離模塊完成整個(gè)服務(wù)請求后,會(huì)將最終的返回值交給內(nèi)核,然后由內(nèi)核交給用戶應(yīng)用程序。

      圖2為本發(fā)明的實(shí)現(xiàn)流程圖,展示了功能調(diào)用改造的實(shí)現(xiàn)過程,具體步驟如下:

      步驟1,在clang編譯器中編寫插件,利用該插件分析被隔離模塊并獲得其函數(shù)調(diào)用關(guān)系圖,具體插件的實(shí)現(xiàn)方法如圖3所示;

      步驟2,編寫查找算法在函數(shù)調(diào)用關(guān)系圖中查找其它模塊的所有接口函數(shù)調(diào)用點(diǎn),具體接口函數(shù)調(diào)用點(diǎn)查找算法的實(shí)現(xiàn)方法如圖4所示;

      步驟3,根據(jù)所得的接口函數(shù)編寫相應(yīng)的存根函數(shù)和回調(diào)函數(shù),并分別存入被隔離模塊的存根子模塊以及內(nèi)核的回調(diào)子模塊中,存根子模塊和回調(diào)子模塊的內(nèi)部構(gòu)造如圖5所示;

      步驟4,在每個(gè)接口函數(shù)調(diào)用點(diǎn)處都用對(duì)應(yīng)的存根函數(shù)替換原接口函數(shù),具體工作步驟如下:

      步驟4-1,判斷當(dāng)前接口函數(shù)調(diào)用點(diǎn)處調(diào)用的是一個(gè)普通函數(shù)還是一個(gè)函數(shù)指針,若是一個(gè)普通函數(shù),則執(zhí)行步驟4-2;若是一個(gè)函數(shù)指針,則執(zhí)行步驟4-3;

      步驟4-2,直接在源碼中用對(duì)應(yīng)的存根函數(shù)替換原接口函數(shù);

      步驟4-3,先在以函數(shù)地址為關(guān)鍵字的接口函數(shù)表中查詢該函數(shù)指針是否指向一個(gè)接口函數(shù)的指針,若是,則調(diào)用對(duì)應(yīng)的存根函數(shù);否則,直接執(zhí)行該函數(shù)指針。

      步驟5,針對(duì)數(shù)據(jù)處理過程中的一致性問題,設(shè)計(jì)并實(shí)現(xiàn)了對(duì)進(jìn)程控制塊進(jìn)行重定向的方法,進(jìn)程控制塊重定向的具體實(shí)現(xiàn)方法如圖6所示。

      圖3為函數(shù)調(diào)用關(guān)系分析軟件(即clang編譯器插件)的內(nèi)部流程圖,展示了本發(fā)明中函數(shù)調(diào)用關(guān)系分析軟件模塊的實(shí)現(xiàn)方法,具體步驟如下:

      步驟1,分別對(duì)visitfunctiondecl函數(shù)、visitdeclrefexpr函數(shù)以及visitmemberexpr函數(shù)進(jìn)行重載,這些被重載的函數(shù)用于分析抽象語法樹并得到包括函數(shù)指針在內(nèi)的函數(shù)調(diào)用關(guān)系圖,具體實(shí)現(xiàn)原理如下:

      步驟1-1,重載visitfunctiondecl函數(shù),內(nèi)部調(diào)用isthisdeclarationadefinition函數(shù)用于判斷當(dāng)前ast節(jié)點(diǎn)表示的是一個(gè)函數(shù)聲明還是一個(gè)函數(shù)定義,若表示的是一個(gè)函數(shù)定義,則將當(dāng)前函數(shù)作為關(guān)鍵字保存到哈希表中,并為該關(guān)鍵字函數(shù)創(chuàng)建一個(gè)空的值列表用于保存它的被調(diào)用函數(shù)集,否則,直接跳過;該步驟用于獲得函數(shù)調(diào)用關(guān)系圖中的調(diào)用函數(shù)信息;

      步驟1-2,重載visitdeclrefexpr函數(shù),內(nèi)部利用動(dòng)態(tài)類型轉(zhuǎn)換判斷當(dāng)前ast節(jié)點(diǎn)是否是函數(shù)類型節(jié)點(diǎn),若是,則將當(dāng)前函數(shù)作為被調(diào)用函數(shù)保存到最近關(guān)鍵字函數(shù)所對(duì)應(yīng)的值列表中,否則,直接跳過;該步驟用于獲得函數(shù)調(diào)用關(guān)系圖中的被調(diào)用函數(shù)信息;

      步驟1-3,重載visitmemberexpr函數(shù),內(nèi)部調(diào)用isfunctionpointertype函數(shù)用于當(dāng)前ast節(jié)點(diǎn)表示的是否是一個(gè)函數(shù)指針,若是,則將當(dāng)前指針作為被調(diào)用函數(shù)指針保存到最近關(guān)鍵字函數(shù)所對(duì)應(yīng)的值列表中,否則,直接跳過;該步驟用于獲得函數(shù)調(diào)用關(guān)系圖中的被調(diào)用函數(shù)指針信息。

      步驟2,重載handletranslationunit函數(shù),內(nèi)部traversedecl函數(shù)用于以深度優(yōu)先的方式遍歷ast的每個(gè)節(jié)點(diǎn),并根據(jù)節(jié)點(diǎn)的類型調(diào)用相應(yīng)的重載訪問函數(shù)進(jìn)行處理,例如在訪問到函數(shù)聲明/定義類型節(jié)點(diǎn)時(shí),會(huì)調(diào)用步驟1-1中實(shí)現(xiàn)的visitfunctiondecl重載函數(shù)僅獲得函數(shù)定義相關(guān)信息;clang編譯器每次構(gòu)造完抽象語法樹后都會(huì)調(diào)用該驅(qū)動(dòng)函數(shù),綜合步驟1和步驟2中的重載函數(shù),可以在每次ast構(gòu)造結(jié)束后都獲得相關(guān)源碼的函數(shù)調(diào)用關(guān)系圖。

      圖4為接口函數(shù)調(diào)用點(diǎn)查找過程的原理圖,展示了本發(fā)明中接口函數(shù)調(diào)用點(diǎn)查找算法模塊的實(shí)現(xiàn)方法,具體步驟如下:

      步驟1,從內(nèi)核鏡像vmlinux中整理出函數(shù)符號(hào)表和接口函數(shù)表,具體實(shí)現(xiàn)過程如下:

      步驟1-1,通過nm命令從內(nèi)核鏡像vmlinux中獲得帶有位置信息的內(nèi)核符號(hào)表,并根據(jù)符號(hào)類型篩選出函數(shù)符號(hào)信息和接口函數(shù)信息,其中將類型為t或t的符號(hào)整理為函數(shù)符號(hào)信息,而將類型為t的符號(hào)整理為接口函數(shù)信息;

      步驟1-2,設(shè)計(jì)兩種哈希表,分別以函數(shù)名和函數(shù)地址為關(guān)鍵字;將步驟1-1得到的函數(shù)符號(hào)信息存入以函數(shù)名為關(guān)鍵字的哈希表中,并將該哈希表作為函數(shù)符號(hào)表;將步驟1-1得到的接口函數(shù)表按兩種格式分別存入以函數(shù)名為關(guān)鍵字的哈希表和已函數(shù)地址為關(guān)鍵字的哈希表中,這兩個(gè)哈希表都稱為接口函數(shù)表。

      步驟2,遍歷被隔離模塊的函數(shù)調(diào)用關(guān)系圖,對(duì)每個(gè)調(diào)用函數(shù)或被調(diào)用函數(shù)都在步驟1中的得到的函數(shù)符號(hào)表中搜索對(duì)應(yīng)的模塊信息,并將得到的模塊信息以字符串標(biāo)簽的形式打印到函數(shù)調(diào)用關(guān)系圖中的相應(yīng)位置;

      步驟3,設(shè)計(jì)兩種接口函數(shù)調(diào)用點(diǎn)查找算法,分別提供按模塊查找和按函數(shù)查找接口函數(shù)調(diào)用點(diǎn)的功能;利用這兩個(gè)算法對(duì)步驟2中得到的帶有模塊標(biāo)簽的函數(shù)調(diào)用關(guān)系圖進(jìn)行分析,以得到被隔離模塊中所有調(diào)用其它模塊接口函數(shù)的位置:

      步驟3-1,在按模塊查找接口函數(shù)調(diào)用點(diǎn)的算法中,遍歷帶模塊標(biāo)簽的函數(shù)關(guān)系調(diào)用圖,首先將第一個(gè)關(guān)鍵字(即調(diào)用函數(shù))作為當(dāng)前關(guān)鍵字函數(shù);接著遍歷當(dāng)前關(guān)鍵字函數(shù)對(duì)應(yīng)的值列表(即被調(diào)用函數(shù)列表),依次判斷列表中的被調(diào)用函數(shù)的定義是否在當(dāng)前模塊或頭文件中:若是,則繼續(xù)檢查下一個(gè)被調(diào)用函數(shù);否則,將當(dāng)前的調(diào)用函數(shù)和被調(diào)用函數(shù)組成二元組,保存在特定的哈希表中,以便后續(xù)打印結(jié)果。

      步驟3-2,在按函數(shù)查找接口函數(shù)調(diào)用點(diǎn)的算法中,遍歷帶模塊標(biāo)簽的函數(shù)關(guān)系調(diào)用圖,首先將被查找函數(shù)作為當(dāng)前關(guān)鍵字函數(shù);接著深度優(yōu)先遍歷當(dāng)前關(guān)鍵字函數(shù)的第一層被調(diào)用函數(shù)列表,判斷列表中的被調(diào)用函數(shù)的定義是否在當(dāng)前模塊或頭文件中(為了提高效率,可以先判斷當(dāng)前的被調(diào)用函數(shù)是否已被檢查過,并跳過那些已被檢查的函數(shù)):若是,則將該被調(diào)用函數(shù)作為當(dāng)前關(guān)鍵字函數(shù)按之前的方式繼續(xù)遞歸檢查;否則,將當(dāng)前關(guān)鍵字函數(shù)和該被調(diào)用函數(shù)組成的二元組作為接口函數(shù)調(diào)用點(diǎn)保存在特定的哈希表中,以便后續(xù)打印結(jié)果。

      圖5為改造后的功能調(diào)用框架圖,展示了功能調(diào)用改造后被隔離模塊間的交互過程,具體實(shí)現(xiàn)過程如下:

      步驟1,存根函數(shù)的執(zhí)行流程如下:

      步驟1-1,生成并初始化消息塊,包括注冊回調(diào)函數(shù)、發(fā)送方當(dāng)前pcb以及接收方反饋消息所在的消息隊(duì)列號(hào);

      步驟1-2,創(chuàng)建并初始化參數(shù)容器,并將其掛載到消息塊中;

      步驟1-3,調(diào)用消息模塊提供的api函數(shù)msgsnd發(fā)送消息;

      步驟1-4,在指定的消息隊(duì)列號(hào)上等待接收方的反饋消息;

      步驟1-5,解析反饋消息中的返回值,并繼續(xù)執(zhí)行下一指令。

      步驟2,回調(diào)函數(shù)的執(zhí)行流程如下:

      步驟2-1,解析獲得的消息塊,并用其中的pcb指針偽裝自己的current,以此實(shí)現(xiàn)一致性;

      步驟2-2,創(chuàng)建參數(shù)容器,并以此解析消息塊中的具體參數(shù);

      步驟2-3,將具體參數(shù)傳入真正的工作函數(shù)(即原接口函數(shù)),并將返回值存入原消息塊的相關(guān)位置;

      步驟2-4,調(diào)用消息模塊提供的api函數(shù)msgsnd,并將原消息塊(此時(shí)存有返回值)發(fā)送到消息塊中指定的消息隊(duì)列中。

      圖6為進(jìn)程控制塊重定向的原理圖,展示了本發(fā)明是如何通過重定向current以解決數(shù)據(jù)一致性問題的,具體實(shí)現(xiàn)過程如下:

      步驟1,為被隔離模塊保存一個(gè)獨(dú)一無二而的全局變量temp,用來存儲(chǔ)內(nèi)核傳過來的pcb指針;

      步驟2,根據(jù)需要重定義current,具體做法是通過get_current()判斷當(dāng)前進(jìn)程是被隔離模塊進(jìn)程還是內(nèi)核進(jìn)程,若是被隔離模塊進(jìn)程,則返回全局變量temp;若是內(nèi)核進(jìn)程,則直接返回get_current()的結(jié)果;

      步驟3,被隔離模塊每次從內(nèi)核接收到新的消息塊時(shí),都用該消息塊中描述pcb的成員去更新其全局變量temp,以此達(dá)到實(shí)時(shí)性的目的。

      綜上所述,本發(fā)明解決了原linux內(nèi)核的功能調(diào)用方式無法適用于基于內(nèi)存頁表不可見性的內(nèi)核模塊隔離方案這一問題,依次通過提取函數(shù)調(diào)用關(guān)系圖、查找接口函數(shù)調(diào)用點(diǎn)、編寫存根子模塊和回調(diào)子模塊、接口函數(shù)調(diào)用點(diǎn)源碼替換以及重定向進(jìn)程控制塊這五個(gè)步驟,將被隔離模塊間的功能調(diào)用方式由原來的宏內(nèi)核模式改為微內(nèi)核模式,以允許被隔離模塊依舊可以正常的訪問內(nèi)核中其它模塊的代碼和數(shù)據(jù)。目前本發(fā)明已經(jīng)成功應(yīng)用于文件系統(tǒng)隔離和驅(qū)動(dòng)隔離。

      本發(fā)明提供了一種針對(duì)linux內(nèi)核頁表隔離的功能調(diào)用改造方法,對(duì)本技術(shù)領(lǐng)域的普通技術(shù)人員來說,在不脫離本發(fā)明原理的前提下,還適用于若干場景,例如利用該方法對(duì)linux進(jìn)行微內(nèi)核化。這些應(yīng)用場景也應(yīng)視為本發(fā)明的保護(hù)范圍。

      當(dāng)前第1頁1 2 
      網(wǎng)友詢問留言 已有0條留言
      • 還沒有人留言評(píng)論。精彩留言會(huì)獲得點(diǎn)贊!
      1