日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核熱補丁安全隱患的探索

Linux閱碼場 ? 來源:云巔論劍 ? 作者:扶風(fēng) 丁緩 雛雁 ? 2021-10-11 11:54 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Linux 內(nèi)核熱補丁可以修復(fù)正在運行的 linux 內(nèi)核,是一種維持線上穩(wěn)定性不可缺少的措施,現(xiàn)在比較常見的比如 kpatch 和 livepatch。內(nèi)核熱補丁可以修復(fù)內(nèi)核中正在運行的函數(shù),用已修復(fù)的函數(shù)替換掉內(nèi)核中存在問題的函數(shù)從而達(dá)到修復(fù)目的。

函數(shù)替換的思想比較簡單,就是在執(zhí)行舊函數(shù)時繞開它的執(zhí)行邏輯而跳轉(zhuǎn)到新的函數(shù)中,有一種比較簡單粗暴的方式,就是將原函數(shù)的第一條指令修改為“ jump 目標(biāo)函數(shù)”指令,即直接跳轉(zhuǎn)到新的函數(shù)以達(dá)到替換目的。

那么,問題來了,這么做靠譜嗎?直接將原函數(shù)的第一條指令修改為 jump 指令,會破壞掉原函數(shù)和它的調(diào)用者之間的寄存器上下文關(guān)系,存在安全隱患!本文會針對該問題進(jìn)行探索和驗證。

安全性沖擊:問題呈現(xiàn)

對于函數(shù)調(diào)用,假設(shè)存在這樣兩個函數(shù) funA 和 funB,其中 funA 調(diào)用 funB 函數(shù),這里稱 funA 為 caller(調(diào)用者),funB 為 callee(被調(diào)用者),funA 和 funB 都使用了相同的寄存器 R,如下所示:

dd6f51f2-297a-11ec-82a8-dac502259ad0.png

圖1 funA 和 funB 都使用了寄存器 R,funA 再次使用 R 時已經(jīng)被 funB 修改

因此,當(dāng) funA 再次使用到 R 的數(shù)據(jù)已經(jīng)是錯誤的數(shù)據(jù)了。如果 funA 在調(diào)用 funB 前保存寄存器 R 中的數(shù)據(jù),funB 返回后再將數(shù)據(jù)恢復(fù)到 R 中,或者 funB 先保存 R 中原有的數(shù)據(jù),然后在返回前恢復(fù),就可以解決這類問題。

唯一的調(diào)用約定

那寄存器該由 caller 還是 callee 來保存?這就需要遵循函數(shù)的調(diào)用約定(call convention),不同的 ABI 和不同的平臺,函數(shù)的調(diào)用約定是不一樣的,對于 Linux 來說,它遵循的是 System V ABI 的 call convention,x86_64 平臺下函數(shù)調(diào)用約定有且只有一種,調(diào)用者 caller 和被調(diào)用者 callee 需要對相應(yīng)的寄存器進(jìn)行保存和恢復(fù)操作:

Caller-save registers : RDI, RSI, RDX, RCX, R8, R9, RAX, R10, R11

Callee-save registers : RBX, RBP, R12, R13, R14, R15

調(diào)用約定,gcc 它遵守了嗎?

設(shè)問:當(dāng)函數(shù)實現(xiàn)很簡單,只用到了少量寄存器,那沒使用到的還需要保存嗎?

答案:it depends。根據(jù)編譯選項決定。

眾所周知,GCC 編譯器有 -O0、-O1、-O2 和 -Ox 等編譯優(yōu)化選項,優(yōu)化范圍和深度隨 x 增大而增大(-O0是不優(yōu)化,其中隱含的意思是,它會嚴(yán)格遵循 ABI 中的調(diào)用約定,對所有使用的寄存器進(jìn)行保存和恢復(fù))。

Linux 內(nèi)核選用的都是 -O2 優(yōu)化。GCC 會選擇性的不遵守調(diào)用約定,也就是設(shè)問里提到的,不需要保存沒使用到的寄存器。當(dāng)【運行時替換】撞見【調(diào)用約定】

GCC 之所以可以做這個優(yōu)化,是因為 GCC 高屋建瓴,了解程序的執(zhí)行流。當(dāng)它知道 callee,caller 的寄存器分配情況,就會大膽且安全地做各種優(yōu)化。

但是,運行時替換破壞了這個假設(shè),GCC 所掌握的 callee 信息,極有可能是錯誤的。那么這些優(yōu)化可能會引發(fā)嚴(yán)重問題。這里以一個具體的實例進(jìn)行詳細(xì)說明,這是一個用戶態(tài)的例子( x86_64 平臺):

//test.c 文件//編譯命令:gcc test.c -o test -O2 (kernel 采用的是 O2 優(yōu)化選項)//執(zhí)行過程:。/test//輸入?yún)?shù):4

#include 《sys/mman.h》#include 《string.h》#include 《stdio.h》#include 《math.h》

#define noinline __attribute__ ((noinline)) //禁止內(nèi)聯(lián)

static noinline int c(int x){ return x * x * x;}

static noinline int b(int x){ return x;}

static noinline int newb(int x){ return c(x * 2) * x;}

static noinline int a(int x){ int volatile tmp = b(x); // tmp = 8 ** 3 * 4 return x + tmp; // return 4(not 8) + tmp}

int main(void){ int x; scanf(“%d”, &x);

if (mprotect((void*)(((unsigned long)&b) & (~0xFFFF)), 15, PROT_WRITE | PROT_EXEC | PROT_READ)) { perror(“mprotect”); return 1; }

/* 利用 jump 指令將函數(shù) b 替換為 newb 函數(shù) */ ((char*)b)[0] = 0xe9; *(long*)((unsigned long)b + 1) = (unsigned long)&newb - (unsigned long)&b - 5; printf(“%d”, a(x)); return 0;}

程序解釋:該程序是對輸入的數(shù)字進(jìn)行計算,運行時利用 jump 指令將程序中的函數(shù) b 替換為 newb 函數(shù),即,將 y = x + x 計算過程替換為 y = x + (2x) ^ 3 * x;

程序編譯:gcc test.c -o test -O2,這里我們采用的是與編譯內(nèi)核相同的優(yōu)化選項 -O2;

程序執(zhí)行:。/test,輸入?yún)?shù):4,輸出結(jié)果:2056;

程序錯誤:2056 是錯誤的結(jié)果,應(yīng)該是 2052,而且直接調(diào)用 newb 函數(shù)編譯執(zhí)行的結(jié)果是 2052。

該例子說明,直接使用 jump 指令替換函數(shù)在 -O2 的編譯優(yōu)化下,會出現(xiàn)問題,安全性受到了質(zhì)疑和沖擊?。。?/p>

安全性沖擊:分析問題

上述例子中,我們將函數(shù) b 用 jump 指令替換為 newb 函數(shù),在 -O2 的編譯優(yōu)化下出現(xiàn)了計算錯誤的結(jié)果,因此,我們需要對函數(shù)的調(diào)用執(zhí)行過程進(jìn)行仔細(xì)分析,挖掘問題所在。首先,我們先來查看一下該程序的反匯編(指令:objdump -d test),并重點關(guān)注 a、b 和 newb 函數(shù):

dda37d7e-297a-11ec-82a8-dac502259ad0.png

圖2 -O2 編譯優(yōu)化的反匯編結(jié)果

匯編解釋:main:-》 將參數(shù) 4 存放到 edi 寄存器中-》 調(diào)用 a 函數(shù):-》 調(diào)用 b 函數(shù),直接跳轉(zhuǎn)到 newb 函數(shù): -》 將 edi 寄存器中的值存放到 edx 寄存器 -》 edi 寄存器與自身相加后結(jié)果放入 edi -》 調(diào)用 c 函數(shù): -》 將 edi 寄存器中的值存到 eax 寄存器 -》 edi 乘以 eax 后結(jié)果放入 eax -》 edi 乘以 eax 后結(jié)果放入 eax -》 返回到 newb 函數(shù) -》 將 edx 與 eax 相乘后結(jié)果放入 eax-》 返回到 a 函數(shù)-》 將 edi 與 eax 相加后結(jié)果放入 eax-》 返回 main 函數(shù)

(注意:b 函數(shù)中沒有對 edi 寄存器進(jìn)行寫操作,而且它的代碼段被修改為 jump 指令跳轉(zhuǎn)到 newb 函數(shù))

數(shù)據(jù)出錯的原因在于,在函數(shù) newb 中,使用到了 a 函數(shù)中使用的 edi 寄存器,edi 寄存器中的值在 newb 函數(shù)中被修改為 8,當(dāng) newb 函數(shù)返回后,edi 的值仍然是 8,a 函數(shù)繼續(xù)使用了該值,因此,計算過程變?yōu)椋?^3 * 4 + 8 = 2056,而正確的計算結(jié)果應(yīng)該是 8^3 * 4 + 4 = 2052。

接下來不進(jìn)行編譯優(yōu)化(-O0),其輸出結(jié)果是正確的 2052,反匯編如下所示:

de1c7954-297a-11ec-82a8-dac502259ad0.png

圖3 不進(jìn)行編譯優(yōu)化的反匯編

從反匯編中可以看到,函數(shù) a 在調(diào)用 b 函數(shù)前,將 edi 寄存器的值存在了棧上,調(diào)用之后,將棧上的數(shù)據(jù)再取出,最后進(jìn)行相加。這就說明,-O2 優(yōu)化選項將 edi 寄存器的保存和恢復(fù)操作優(yōu)化掉了,而在調(diào)用約定中,edi 寄存器本就該屬于 caller 進(jìn)行保存/恢復(fù)的。至于為什么編譯器會進(jìn)行優(yōu)化,我們此刻的猜想是:

a 函數(shù)本來調(diào)用的是 b 函數(shù),而且編譯器知道 b 函數(shù)中沒有使用到 edi 寄存器,因此調(diào)用者 a 函數(shù)沒有對該寄存器進(jìn)行保存和恢復(fù)操作。但是編譯器不知道的是,在程序運行時,b 函數(shù)的代碼段被動態(tài)修改,利用 jump 指令替換為 newb 函數(shù),而在 newb 函數(shù)中對 edi 寄存器進(jìn)行了數(shù)據(jù)讀寫操作,于是出現(xiàn)了錯誤。

這是一個典型的沒有保存 caller-save 寄存器導(dǎo)致數(shù)據(jù)出錯的場景。而編譯內(nèi)核采用的也是 -O2 選項。如果將該場景應(yīng)用到內(nèi)核函數(shù)熱替換是否會出現(xiàn)這類問題呢?于是,我們帶著問題繼續(xù)探索。

安全性沖擊:探索問題

不再觀察到 bug

我們構(gòu)造了一個內(nèi)核函數(shù)熱替換的實例,將上面的用戶態(tài)的例子移植到我們構(gòu)造的場景中,通過內(nèi)核模塊修改原函數(shù)的代碼段,用 jump 指令直接替換原來的 b 函數(shù)。然而加載模塊后,結(jié)果是正確的 2052,經(jīng)過反匯編我們發(fā)現(xiàn),內(nèi)核中 a 函數(shù)對 edi 寄存器進(jìn)行了保存操作:

de732a88-297a-11ec-82a8-dac502259ad0.png

圖4 內(nèi)核中 a 函數(shù)的反匯編

內(nèi)核和模塊編譯時采用的是 -O2 優(yōu)化選項,而此處 a 函數(shù)并沒有被優(yōu)化,仍然保存了 edi 寄存器。

此時我們預(yù)測:對于內(nèi)核函數(shù)的熱替換來說,使用 jump 做函數(shù)替換是安全的。

神奇的 -pg 選項

我們猜想是否是內(nèi)核編譯時使用其它的編譯選項導(dǎo)致問題不能復(fù)現(xiàn)。果不其然,經(jīng)過探索我們發(fā)現(xiàn)內(nèi)核編譯使用的 -pg 選項導(dǎo)致問題不再復(fù)現(xiàn)。

通過翻閱 GCC 手冊得知,-pg 選項是為了支持 GNU 的 gprop 性能分析工具所引入的,它能在函數(shù)中增加一條 call mount 指令,去做一些分析工作。

在內(nèi)核中,如果開啟了 CONFIG_FUNCTION_TRACER,則會使能 -pg 選項。

deb8d1c8-297a-11ec-82a8-dac502259ad0.png

圖5 開啟 CONFIG_FUNCTION_TRACER 使能 -pg 選項

FUNCTION_TRACE 即我們常說的 ftrace 功能,ftrace 大大提升了內(nèi)核的運行時調(diào)試能力。ftrace 功能除了 -pg 選項,還要求打開 -mfentry 選項,后者的作用是將函數(shù)對 mcount 的調(diào)用放到函數(shù)的第一條指令處,然后通過 scripts/recordmcount.pl 腳本將該條 call 指令修改為 nop 指令。但 -mfentry 與本文主題沒有關(guān)聯(lián),不再細(xì)說。

為了驗證這個結(jié)論,我們回到上一節(jié)的用戶態(tài)例子,并且增加了 -pg 編譯選項:“gcc test.c -o test -O2 -pg”,此時運行結(jié)果果然正確了。查看其反匯編:

defef0e0-297a-11ec-82a8-dac502259ad0.png

圖6 增加 -pg 選項后的匯編

可以看到,每個函數(shù)都有 call mcount 指令,而且 a 函數(shù)中將 edi 寄存器保存到 ebx 中,在 newb 函數(shù)中又保存 ebx 寄存器。為什么在增加了 call mount 指令后,會做寄存器的保存操作?我們猜想,會不會是因為,由于 call mount 操作相當(dāng)于調(diào)用了一個未知的函數(shù)( mcount 沒有定義在同一個文件中),因此,GCC 認(rèn)為這樣未知的操作可能會污染了寄存器的數(shù)據(jù),所以它才進(jìn)行了保存現(xiàn)場的操作。

于是我們?nèi)サ袅?-pg 選項,手動增加了 call mount 的行為進(jìn)行驗證:在另一個源文件 mcount.c 中增加一個函數(shù) void mcount() { asm(“nop ”); },在 test.c 文件中增加對 mcount 函數(shù)的聲明,a 函數(shù)中增加對該函數(shù)的調(diào)用:

extern void mcount(); //聲明 mcount 函數(shù)

static noinline int a(int x){ int volatile tmp = b(x); // tmp = 8 ** 3 * 4 mcount(); return x + tmp; // return 4(not 8) + tmp}

經(jīng)過編譯:gcc test.c mcount.c -O2 后運行,發(fā)現(xiàn)計算結(jié)果正確,而且反匯編中 a 函數(shù)保存了寄存器:

df356d3c-297a-11ec-82a8-dac502259ad0.png

圖7 調(diào)用 mcount 函數(shù)后的匯編

繼續(xù)驗證猜想,將 mcount 函數(shù)放在 test.c 文件中,計算結(jié)果錯誤,而且,反匯編中沒有保存寄存器,于是我們得到了這樣的猜想結(jié)論:

GCC 在編譯某個源文件時,如果文件內(nèi)的某個函數(shù)(比如場景中的函數(shù) a)調(diào)用了其它文件中的一個未知函數(shù)(比如場景中的 mcount 函數(shù)),則 GCC 會在該函數(shù)中保存寄存器;

開啟 -pg 選項,增加了對 mcount 的調(diào)用,因此會在函數(shù)中增加對寄存器現(xiàn)場的保存操作,對 -O2 選項的函數(shù)調(diào)用優(yōu)化起到了屏蔽作用。

神秘的 -fipa-ra 選項:真正的幕后主使

經(jīng)過我們的探索和資料的查閱,發(fā)現(xiàn)了這個 -fipa-ra 選項,可以說它是優(yōu)化的幕后主使。GCC 手冊中給出 -fipa-ra 選項的解釋是:

Use caller save registers for allocation if those registers are not used by any called function. In that case it is not necessary to save and restore them around calls. This is only possible if called functions are part of same compilation unit as current function and they are compiled before it. Enabled at levels -O2, -O3, -Os, however the option is disabled if generated code will be instrumented for profiling (-p, or -pg) or if callee’s register usage cannot be known exactly (this happens on targets that do not expose prologues and epilogues in RTL)。

這里主要是說,如果開啟這個選項,那么,callee 中如果沒有使用到 caller 使用的寄存器,就沒有必要保存這些寄存器,前提是,callee 與 caller 在同一個編譯單元中而且 callee 函數(shù)比 caller 先被編譯,這樣才可能出現(xiàn)前面的優(yōu)化。如果開啟了 -O2 及以上的編譯優(yōu)化選項,則會使能 -fipa-ra 選項,然而,如果開啟了 -p 或者 -pg 這些選項,或者,無法明確 callee 所使用的寄存器,-fipa-ra 選項會被禁用。

這段話,其實已經(jīng)能 cover 掉我們前面大部分猜想的測試驗證:

-O2 選項自動使能 -fipa-ra 進(jìn)行優(yōu)化:在我們的場景中,函數(shù) a 使用的 edi 寄存器,在函數(shù) b 中沒有使用到,因此函數(shù) a 被優(yōu)化,沒有保存 edi 寄存器,但是在 newb 函數(shù)中,使用到了 edi 寄存器,且數(shù)據(jù)被修改,將 newb 函數(shù)替換函數(shù) b,則計算結(jié)果出錯;

在 -O2 中使用 -pg 選項會禁用 -fipa-ra:編譯時使用 -pg 選項,計算結(jié)果是正確的,而且函數(shù) a 保存了 edi 寄存器,說明沒有對函數(shù) a 進(jìn)行優(yōu)化;

不在同一編譯單元不會被優(yōu)化:去掉 -pg 選項,在函數(shù) a 中手動調(diào)用 mcount 函數(shù),將這個函數(shù)放在 test.c(與函數(shù) a 為同一編譯單元)與放在另一個文件 mcount.c(不同編譯單元)中的計算結(jié)果不同:同一編譯單元中計算結(jié)果是錯誤的,而且函數(shù) a 沒有保存寄存器現(xiàn)場;不在同一編譯單元中,計算結(jié)果是正確的,函數(shù) a(caller) 保存了寄存器現(xiàn)場,因為編譯器無法明確函數(shù) b(callee)所使用的寄存器。

notrace:它是二度沖擊嗎?

用過 ftrace 或者內(nèi)核開發(fā)者應(yīng)該對 notrace 屬性不陌生,內(nèi)核中有一些被 notrace 修飾的函數(shù)。notrace 其實就是給函數(shù)增加 no_instrument_function 屬性。例如,在 X86 的定義:

#define notrace __attribute__((no_instrument_function))

字面上來看,notrace 和 -pg 的含義可以說完全對立,-pg 讓 jump 變得安全,是否又會在 notrace 上栽一個跟斗呢?幸運的是,我們接下來將看到,notrace 僅僅是禁止了 instrument function,而沒有破壞安全性。

gcc 手冊中的 -pg 選項給出這樣的解釋:

Generate extra code to write profile information suitable for the analysis program prof (for -p) or gprof (for -pg)。 You must use this option when compiling the source files you want data about, and you must also use it when linking. You can use the function attribute no_instrument_function to suppress profiling of individual functions when compiling with these options.

這里主要是說,加上 notrace 屬性的函數(shù),不會產(chǎn)生調(diào)用 mcount 的行為,那么,是否意味著不再保護寄存器現(xiàn)場,換句話說,notrace 的出現(xiàn)是否會繞過“-pg 選項對 -fipa-ra 優(yōu)化的屏蔽”?于是我們又增加 notrace 屬性進(jìn)行驗證:在 a 函數(shù)中增加 notrace 的屬性,因為 a 函數(shù)是 caller,編譯時開啟 -pg 選項,然后檢查計算結(jié)果及反匯編,最后發(fā)現(xiàn),計算結(jié)果正確,而且匯編代碼中保存了寄存器現(xiàn)場。

我們又對所有的函數(shù)追加了 notrace 屬性,計算結(jié)果正確且寄存器現(xiàn)場被保護。但是這些簡單的驗證不足以證明,于是我們通過閱讀 GCC 源碼發(fā)現(xiàn)

通過源碼閱讀,可以確定的是,當(dāng)使用了 -pg 選項后,會禁用 -fipa-rq 優(yōu)化選項,GCC 檢查每一個函數(shù)的時候都會檢查該選項,如果為 false,則不會對該函數(shù)進(jìn)行優(yōu)化。

由于 flag_ipa_ra 是一個全局選項,并不是函數(shù)粒度的,notrace 也無能為力。因此,這里可以排除對 notrace 的顧慮。

安全性保障:得出結(jié)論

經(jīng)過上述的探索分析以及官方資料的查閱,我們可以得出結(jié)論:

內(nèi)核函數(shù)的熱替換,利用 jump 指令直接跳轉(zhuǎn)到新函數(shù)的方式是安全的;

論據(jù):

Linux 遵循的 System V ABI 中的 call conversion 在 x86-64 下有且只有一種;

GCC -fipa-ra 選項會對 call conversion 進(jìn)行優(yōu)化,-O2 選項會自動使能該選項,但是 -pg 選項會禁用 -fipa-ra 優(yōu)化選項;

notrace 屬性無法繞過“ -pg 禁用 -fipa-ra”。

ARM64 下的探索驗證

通過翻閱手冊得知,ARMv8 ABI 中對過程調(diào)用時通用寄存器的使用準(zhǔn)則如下

Argument registers (X0-X7)

These are used to pass parameters to a function and to return a result. They can be used as scratch registers or as caller-saved register variables that can hold intermediate values within a function, between calls to other functions. The fact that 8 registers are available for passing parameters reduces the need to spill parameters to the stack when compared with AArch32.

Caller-saved temporary registers (X9-X15)

If the caller requires the values in any of these registers to be preserved across a call to another function, the caller must save the affected registers in its own stack frame. They can be modified by the called subroutine without the need to save and restore them before returning to the caller.

Callee-saved registers (X19-X29)

These registers are saved in the callee frame. They can be modified by the called subroutine as long as they are saved and restored before returning.

Registers with a special purpose (X8, X16-X18, X29, X30)

X8 is the indirect result register. This is used to pass the address location of an indirect result, for example, where a function returns a large structure.

X16 and X17 are IP0 and IP1, intra-procedure-call temporary registers. These can be used by call veneers and similar code, or as temporary registers for intermediate values between subroutine calls. They are corruptible by a function. Veneers are small pieces of code which are automatically inserted by the linker, for example when the branch target is out of range of the branch instruction.

X18 is the platform register and is reserved for the use of platform ABIs. This is an additional temporary register on platforms that don‘t assign a special meaning to it.

X29 is the frame pointer register (FP)。

X30 is the link register (LR)。

Figure 9.1 shows the 64-bit X registers. For more information on registers, see 。 For information on floating-point parameters, see Floating-point parameters.

可見,ARMv8 ABI 中對函數(shù)調(diào)用時的寄存器使用有了明確的規(guī)定。

我們對于前面 x86-64 下的探索驗證過程在 arm64 平臺下重新做了測試,相同的代碼和相同的測試過程,得出的結(jié)論和 x86-64 下的結(jié)論是一致的,即,在 arm64 下,直接利用 jump 指令實現(xiàn)函數(shù)替換同樣是安全的。

其它場景的討論

其它語言不能保證其安全性

對于 C 語言而言,在不同的架構(gòu)和系統(tǒng)下都有固定的 ABI 和 calling conventions,但是其它的語言不能保證,比如 rust 語言,rust 自身并沒有固定的 ABI,比如社區(qū)對 rust 定義 ABI 的討論,而且 rustc 編譯器的優(yōu)化和 gcc 可能會有不同,因此可能也會出現(xiàn)上述 caller/callee-save 寄存器的問題。

kpatch 的真面目

kpatch 利用的是 ftrace 進(jìn)行函數(shù)替換的,它的原理如下所示:

ftrace 的主要作用是用來做 trace 的,會在函數(shù)頭部或者尾部 hook 一個函數(shù)進(jìn)行一些額外的處理,這些函數(shù)在運行過程中可能會污染被 trace 的函數(shù)的寄存器上下文,因此 ftrace 定義了一個 trampoline 進(jìn)行寄存器的保存和恢復(fù)操作(圖11 中的紅框),這樣從 hook 函數(shù)回來后,寄存器現(xiàn)場仍然是原來的模樣。

kpatch 用 ftrace 進(jìn)行函數(shù)替換,hook 的函數(shù)是 kpatch 中的函數(shù),該函數(shù)的作用是修改 regs 中的 ip 字段的值,也就是將新函數(shù)的地址給到了 ip 字段,等 trampoline 恢復(fù)寄存器現(xiàn)場后,就直接跳轉(zhuǎn)到新的函數(shù)函數(shù)去執(zhí)行了。所以,對于 kpatch 而言,ftrace 的保存和恢復(fù)現(xiàn)場操作保護的是 kpatch 中修改 ip 字段函數(shù)的過程,而不是它要替換的新函數(shù)。

如果修復(fù)的是一個熱函數(shù),那么 ftrace 的 trampoline 會對性能產(chǎn)生一定的影響。所以,若考慮到性能的場景,那么使用 jump 指令直接替換函數(shù)可以很大的減少額外的性能開銷。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    4

    文章

    1476

    瀏覽量

    43099
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11822

    瀏覽量

    219602
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4422

    瀏覽量

    67873

原文標(biāo)題:內(nèi)核熱補丁,真的安全么?

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    如何理解Linux內(nèi)核中的PCIe驅(qū)動

    我們習(xí)慣了用 Verilog 去死磕 PCIe 的底層協(xié)議狀態(tài)機。但一旦越過硬件邊界來到操作系統(tǒng)層面,Linux 內(nèi)核是如何接管并驅(qū)動這些 PCI/PCIe 設(shè)備的呢?由于不同的 CPU 架構(gòu)實現(xiàn)了
    的頭像 發(fā)表于 04-11 17:22 ?1289次閱讀

    不間斷電源怎么接線?手把手教你正確安裝,避免安全隱患

    ?買了UPS不間斷電源,保護好了關(guān)鍵設(shè)備,卻在接線這一步犯了難。這是很多用戶在選購UPS后遇到的真實困惑。接錯了怎么辦?會不會燒設(shè)備?有沒有安全隱患?UPS的接線確實不像普通插座那樣簡單插上就行
    的頭像 發(fā)表于 03-31 14:19 ?805次閱讀
    不間斷電源怎么接線?手把手教你正確安裝,避免<b class='flag-5'>安全隱患</b>

    筑牢零碳園區(qū)的安全防線——電氣安全隱患預(yù)警

    零碳園區(qū)在追求能效最優(yōu)的同時,絕不能忽視用能安全。電氣安全是保障園區(qū)穩(wěn)定運行的紅線。據(jù)統(tǒng)計,許多電氣火災(zāi)事故源于線路老化、絕緣損壞、接觸不良等隱蔽性故障,這些隱患在初期難以被肉眼發(fā)現(xiàn),一旦爆發(fā),將
    的頭像 發(fā)表于 03-12 09:58 ?160次閱讀
    筑牢零碳園區(qū)的<b class='flag-5'>安全</b>防線——電氣<b class='flag-5'>安全隱患</b>預(yù)警

    儲能安全警報:冷卻液泄漏的隱患與檢測難題 | 星科創(chuàng)科技解讀

    深圳市星科創(chuàng)科技有限公司深度剖析儲能系統(tǒng)中冷卻液/電解液泄漏的巨大安全隱患,揭示傳統(tǒng)檢測方法的局限,并提出創(chuàng)新的非接觸檢測思路。
    的頭像 發(fā)表于 01-22 17:18 ?712次閱讀

    破解施工現(xiàn)場用電安全隱患:ASJ系列剩余電流繼電器的解決方案

    施工現(xiàn)場的臨時用電系統(tǒng)較為復(fù)雜且環(huán)境多變,存在眾多安全隱患。電氣設(shè)備的漏電故障可能引發(fā)人員觸電傷亡、電氣火災(zāi)等嚴(yán)重事故,對施工人員的生命安全和工程的順利進(jìn)行構(gòu)成巨大威脅。ASJ 系列剩余電流繼電器作為一種漏電保護裝置,在施工現(xiàn)場的安全
    的頭像 發(fā)表于 01-19 17:19 ?706次閱讀
    破解施工現(xiàn)場用電<b class='flag-5'>安全隱患</b>:ASJ系列剩余電流繼電器的解決方案

    臨時用電有哪些常見安全隱患?提供用電安全解決方案

    為進(jìn)一步加強全市限額以下小型房屋建筑工程安全生產(chǎn)管理,依據(jù)相關(guān)法律法規(guī)和標(biāo)準(zhǔn),梳理了管理 通用要求 和 常見安全隱患 。今天發(fā)布常見安全隱患的第二篇—— 臨時用電 施工現(xiàn)場常見安全隱患
    的頭像 發(fā)表于 01-13 17:12 ?1292次閱讀
    臨時用電有哪些常見<b class='flag-5'>安全隱患</b>?提供用電<b class='flag-5'>安全</b>解決方案

    電氣隱患 “早發(fā)現(xiàn)”!安科瑞 ASCB3 智能微斷,賦能銀行安全高效運營

    首位,成為金融行業(yè)亟需解決的安全隱患。 銀行用電:看不見的風(fēng)險無處不在 銀行營業(yè)場所的用電系統(tǒng)復(fù)雜多樣,覆蓋營業(yè)網(wǎng)點、自助銀行、辦公大樓及數(shù)據(jù)中心等多個區(qū)域。這些場所普遍存在三大安全隱患: 基礎(chǔ)管理落后 :多數(shù)銀行營業(yè)場所的用
    的頭像 發(fā)表于 12-02 16:04 ?456次閱讀
    電氣<b class='flag-5'>隱患</b> “早發(fā)現(xiàn)”!安科瑞 ASCB3 智能微斷,賦能銀行<b class='flag-5'>安全</b>高效運營

    【米爾RK3506國產(chǎn)開發(fā)板評測】3、實時補丁以及EtherCAT IGH移植

    EtherCAT IgH需要保證高實時性,Preempt-RT是一種針對實時性能進(jìn)行了優(yōu)化的Linux內(nèi)核。與普通的Linux內(nèi)核相比,Preempt-RT具有以下優(yōu)勢: 實時性能
    發(fā)表于 10-27 10:09

    【米爾NXP i.MX 91開發(fā)板評測】移植和運行RT-Linux,實時性能測試

    介紹 實時性系統(tǒng)應(yīng)用廣泛,在工業(yè)自動化、醫(yī)療設(shè)備、汽車電子等領(lǐng)域扮演著十分重要的角色,我們用i.MX91開發(fā)板來移植運行RT-Linux,看看它的實時性能表現(xiàn)如何 實時補丁 下載并應(yīng)用RT補丁
    發(fā)表于 09-01 10:11

    福祿克紅外熱像儀助力安全隱患排查

    在石油石化、油質(zhì)或液體儲運、冶金等行業(yè)中,錯綜復(fù)雜的地上及地下管線構(gòu)成了龐大的設(shè)備網(wǎng)絡(luò)。這些管線看似平靜,實則可能隱藏著重大的安全隱患。傳統(tǒng)的肉眼檢查方法往往難以發(fā)現(xiàn)這些潛在問題,而紅外熱像技術(shù)則成為了一種揭開隱藏真相的有效手段。
    的頭像 發(fā)表于 08-22 15:20 ?983次閱讀

    國產(chǎn)!全志T113-i 雙核Cortex-A7@1.2GHz 工業(yè)開發(fā)板—Linux-RT應(yīng)用開發(fā)案例

    PREEMPT機制進(jìn)行補丁。PREEMPT_RT補丁的關(guān)鍵是最小化不可搶占的內(nèi)核代碼量,同時最小化必須更改的代碼量,以便提供這種附加的可搶占性。PREEMPT_RT補丁利用
    的頭像 發(fā)表于 07-30 10:33 ?980次閱讀
    國產(chǎn)!全志T113-i 雙核Cortex-A7@1.2GHz 工業(yè)開發(fā)板—<b class='flag-5'>Linux</b>-RT應(yīng)用開發(fā)案例

    迅為RK3568開發(fā)板OpeHarmony學(xué)習(xí)開發(fā)手冊1.1-內(nèi)核移植優(yōu)化

    ;copy 到 out 目錄-->打新補丁 那么優(yōu)化思路是什么呢? out/kernel/src_tmp/linux-5.10/ linux-5.10/ 下的內(nèi)核源碼是已經(jīng)打過原
    發(fā)表于 07-26 10:37

    充電寶自燃隱患引發(fā)關(guān)注:如何確保充電寶安全?

    近期,一場圍繞充電寶的安全風(fēng)暴席卷全國。不少品牌因電芯缺陷存在自燃隱患,引發(fā)了公眾對充電寶安全性的廣泛關(guān)注。本期我們將探討充電寶的安全隱患以及如何通過技術(shù)手段解決這些問題。充電寶
    的頭像 發(fā)表于 07-23 11:37 ?1192次閱讀
    充電寶自燃<b class='flag-5'>隱患</b>引發(fā)關(guān)注:如何確保充電寶<b class='flag-5'>安全</b>?

    物聯(lián)網(wǎng)工程師為什么要學(xué)Linux?

    。 四、行業(yè)趨勢與未來兼容性 1)開源與自主可控 Linux的開源性使其成為企業(yè)構(gòu)建自主物聯(lián)網(wǎng)生態(tài)的首選,避免閉源系統(tǒng)(如VxWorks)的授權(quán)限制和安全隱患。例如,華為LiteOS等國產(chǎn)物聯(lián)網(wǎng)系統(tǒng)
    發(fā)表于 05-26 10:32

    如何解決銀行安全用電存在的安全隱患

    進(jìn)度要求。 2020年,中國郵政儲蓄銀行辦公室(郵銀發(fā)〔2020〕48號)《中國郵政儲蓄銀行安全保衛(wèi)工作提質(zhì)升級活動2020年工作方案》亦要求對銀行場景內(nèi)消防安全、火災(zāi)隱患做到防范與控制,加強自我管理、評估、提升的工作機制,確保
    的頭像 發(fā)表于 05-13 13:19 ?700次閱讀
    如何解決銀行<b class='flag-5'>安全</b>用電存在的<b class='flag-5'>安全隱患</b>?
    奇台县| 象山县| 栾城县| 洪雅县| 南召县| 繁峙县| 富平县| 江安县| 旌德县| 榆林市| 东丰县| 莱西市| 五大连池市| 城市| 保定市| 凤山市| 霍州市| 吉隆县| 洮南市| 青龙| 石楼县| 宝坻区| 林口县| 西华县| 清流县| 威宁| 内黄县| 平谷区| 拉孜县| 苍梧县| 湖南省| 类乌齐县| 将乐县| 互助| 靖边县| 津南区| 湄潭县| 温州市| 思南县| 长兴县| 建始县|