宋寶華:讓Linux的段錯誤(segmentation fault)不再是一個錯誤

2021-02-19 Linux閱碼場

今天周末,娃兒們配合不鬧事,寫一篇短小精悍的文章吧,反正文章長了大家也沒時間看。今天文章的目標是,如何在進程訪問空指針等情況下,產生段錯誤後,不再退出而是繼續運行。

這件事情,對於熔斷(meltdown)漏洞的利用是比較關鍵的,我們都知道,利用meltdown漏洞,在用戶空間是可以偷窺到內核空間數據的,下面的應用程式訪問內核地址k:

array[256];

int c = *k; //k是內核地址

array[c]; //這句話產生了array[c] cache命中的副作用

之後,我們判斷array[0..255]裡面誰訪問的最快,利用這種時間旁路攻擊,獲知k地址存放的是c。

在meltdown漏洞的分析裡,我們重點關注了時間旁路攻擊的好玩的地方,尤其以「李小璐漢堡問題」,說清楚了這種攻擊的原理。但是我們忽略了一個事實,int c = *k; 這句話,本身,是一定會引起段錯誤的,因為用戶空間做了越權訪問。

其實,在熔斷漏洞的代碼中,對SIGSEGV信號,進行了特殊的處理。它截獲了SIGSEGV的信號:

它實際捕獲了SIGSEGV信號,在信號發生後,修改了CPU的跳轉地址。

眾所周知,在Linux裡面,進程對信號的處理有三種方法,捕獲、忽略、預設行為。一般情況下,你什麼都不做,行為就是預設的,比如CTRL+C就會讓進程死。

但是下面的進程,ctrl+c之後不僅死不了,還能列印東西:

原因很簡單,它的2號信號SIGINT被我們捕獲了。

這個從ps命令裡面也可以看出(留意IGNORED和CAUGHT這2列):

當然,我們也可以完全不鳥它,選擇忽略:

這個時候,按ctrl+c就什麼鬼都沒有:

我們還是可以ps一下(留意IGNORED和CAUGHT這2列):

在這麼多信號裡面,除了極少數信號類似SIGKILL、SIGSTOP這種不能捕獲和忽略以外,其他的都是可以被我們拿來把玩的,當然也包括看起來牛逼轟轟的SEGV段錯誤(編號11)的信號。

我必須反覆強調一點,當你用ctrl+c等對應的信號去殺死一個進程A的時候,從來都不是你殺死了A,而是你給A發了個信號,而A在響應這個信號的時候,其對應行為是進程exit。所以,不是你殺死了進程A,而是你發個信號,「通知」目標進程A去死。所以你不能用人類世界的殺死來理解Linux的殺死。Linux的邏輯類似: 你對進程A說:「你去死吧」(發個可以讓它死的信號),A看到這個pending的信號後,啥廢話都不說,立即悶聲死翹翹!所以,你只要改變A的響應行為,就可以選擇不死。

下面的這段代碼,利用了setjmp和longjmp來實現段錯誤後繼續執行:

setjmp這個函數的原理是:

調用這個函數的時候,它會保存執行現場,並返回0;之後調用longjmp,可恢復到setjmp保存的現場,setjmp再次返回,不過這次該函數返回非0。我們在代碼裡面標註下1-5的時間軸可能能方便大家理解:

第1和4步都在setjmp這個位置。上述例子中的關鍵點是,對SIGSEGV進行了捕獲,並在SEGV的信號處理函數中,進行了代碼的跳轉。所以它的執行結果如下:

如果我們刪除了綁定SIGSEGV的這行代碼:

則執行結果為:

在執行*p = 0的時候,得到了我們期待的段錯誤。

(您的打賞是小弟持續原創的動力 ^-^)

Linux閱碼場原創精華文章匯總

更多精彩,盡在"Linux閱碼場",掃描下方二維碼關注

點一點右下角」在看」,為閱碼場打Call~

相關焦點

  • Linux下編譯時出現的錯誤及解決方法
    Linux下編譯時出現的錯誤及解決方法 (1)由於是Linux新手,所以現在才開始接觸線程編程,照著GUN/Linux編程指南中的一個例子輸入編譯,結果出現如下錯誤......
  • Linux 內核如何處理中斷|Linux 中國
    本文字數:2640,閱讀時長大約:4分鐘 https://linux.cn/article-12965-1.html 作者:Stephan Avenwedde 譯者:萌新阿巖 中斷是現代 CPU 工作方式中重要的部分。
  • ARM Linux異常處理之data abort
    fsr_info對以下四種特殊abort將作單獨處理:"section translation fault" do_translation_fault段轉換錯誤,即找不到二級頁表"page translation fault" do_page_fault頁表錯誤,即線性地址無效,沒有對應的物理地址
  • Python 處理錯誤的原則 | Linux 中國
    https://linux.cn/article-13058-1.html作者:Moshe Zadka譯者:Xingyu.Wang處理「異常情況」是編程中爭論最多的問題之一。這可能是因為風險很大:處理不當的錯誤值甚至可以使龐大的系統癱瘓。
  • linux作業系統常用命令及常用問題
    一、linux作業系統常用命令>linux作業系統詳解(linux不再難懂)●man :任何時候你覺得對一個命令行不是很確定,都可以通過輸入「man + 命令」了解這個命令能確切是做什麼的。
  • OpenCV在ARM上的移植 錯誤總結
    所以執行原來可以正常運行的命令 :g++ ADA_LKDEMO.cpp -oADA_LKDEMO`pkg-config --cflags --libs opencv` -ldl 會出現如下錯誤: /usr/local/lib/libopencv_calib3d.so: error adding symbols: 文件格式錯誤 collect2
  • 宋寶華: 資料庫為什麼有可能喜歡Linux AIO(異步I/O)?
    AIO和傳統epoll()的本質區別是,epoll()等方式,它只是一個事件獲取機制,獲取事件後,之後的read(), write()還是要走Linux的傳統路線,經過Linux內核本身的各個層次(如page cache,IO調度等)。
  • WIN10 linux子系統發生Authentication failure錯誤的解決方案
    今天小哥在使用linux子系統的時候,遇到了su命令發生Authentication failure錯誤。如下圖。於是解決一下。這個錯誤一般是三個原因造成的:1、輸入的帳號密碼是錯誤的。2、剛安裝完系統,沒有設置root用戶密碼。
  • Linux伺服器常出現的錯誤及其代表的含義
    伺服器收到了一個校驗和錯誤的ICMP數據包。 這類的數據包有可能是非法產生的垃圾數據.但從目前來看伺服器收到這樣的數據非常多.一般都忽略。一般代理伺服器在工作時會每秒鐘轉發幾千個數據包.收到幾個錯誤數據包不會影響正常的工作.這是問我最多的一類提示了。一般類的提示NET: N messages suppressed.
  • 考研英語寫作常犯三大錯誤
    下面我們來剖析一下大家在寫作中常犯的錯誤,來幫助考生進一步明確考研寫作備考中需要注意的問題,並給大家一些方法建議。   一、詞彙拼寫錯誤較為嚴重,詞彙選用不當。應對策略就是平時閱讀過程中注意單詞拼寫,關注單詞使用語境,多積累高級詞彙和句型。   It can make our life decrese fault.
  • ARM Linux異常處理之data abort二
    fsr_info對以下四種特殊abort將作單獨處理:l"section translation fault"do_translation_fault段轉換錯誤,即找不到二級頁表l"page translation fault"do_page_fault頁表錯誤,即線性地址無效,沒有對應的物理地址l"section permission
  • 測試平臺-記一次Segmentation fault (core dumped)問題解決過程
    問題解決了,但是部署效率的問題並沒有優化,好在運維基於當前的現狀(很少更新依賴文件requirement)提供了解決方案:在Python基礎鏡像的基礎上,打上依賴包生成一個新的基礎鏡像,這樣所有的服務只需要拷貝對應的代碼到容器裡即可。
  • mistake與fault的區別 Blog#33
    >mistake [miˈsteik]:錯誤、失誤、口誤、筆誤。fault [fɔ:lt]:過錯、過失、故障、缺點、缺陷。二、用法對比分析1、mistake主要指某人行為、看法、言辭方面的錯誤,產生不想要的結果。例句1:Sorry, I』ve made a mistake.對不起,我弄錯了。
  • mistake和fault的用法區別
    ,誤解,誤會」,多指缺乏正確理解造成行動上或認識上的錯誤。fault多指性格上的弱點、行為上的過失,強調過失應負的責任。常用搭配:at fault 有過錯;find fault挑毛病,找錯。請大家看下面的例句:1、I think it's a serious mistake to confuse books with life...我認為把書本同生活混為一談是大錯特錯。
  • 中文分詞工具評估:chinese-segmentation-evaluation
    http://www.52nlp.cn/author/tiandiweizun中文分詞工具評估項目地址:https://github.com/tiandiweizun/chinese-segmentation-evaluation
  • 事實證明 Linux 永遠是 number 1
    嗨,我正在寫一個簡單的程序,我要讓這個程序列印出一個整數。
  • 修復 Ubuntu 中「Unable to lock the administration directory」的錯誤
    編譯自: http://www.tecmint.com/fix-unable-to-lock-the-administration-directory-var-lib-dpkg-lock 作者: Aaron Kili譯者: geekpi在 Ubuntu 或者它的衍生版如 Linux Mint(我已經作為日常工作使用的系統)中使用 apt-get 命令或者其相對更新的APT 管理工具時
  • Ubuntu11.10安裝BusyBox:致命錯誤
    GEN archival/Kbuild GEN archival/Config.in GEN archival/libarchive/Kbuild GEN modutils/Kbuild GEN modutils/Config.in GEN selinux/Kbuild GEN selinux/Config.in GEN util-linux
  • 周末大咖說 | 英語學習中,常見的「錯誤」
    fault表示「過錯」,強調的是為造成的錯誤所承擔的責任,同時也有「缺點」的意思,尤其指性格上的缺點。在比賽中,fault意思是「犯規」。fault也可以指機器、系統中的錯誤故障。例如:It was his fault that we were late. 我們遲到都是他的錯。
  • Linux 系統內核的調試
    kgdb補丁的主要作用是在Linux內核中添加了一個調試Stub。調試Stub是Linux內核中的一小段代碼,提供了運行gdb的開發機和所調試內核之間的一個媒介。gdb和調試stub之間通過gdb串行協議進行通訊。gdb串行協議是一種基於消息的ASCII碼協議,包含了各種調試命令。當設置斷點時,kgdb負責在設置斷點的指令前增加一條trap指令,當執行到斷點時控制權就轉移到調試stub中去。