在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux內核態缺頁會發生什么 - 玩轉Exception fixup表

Linux閱碼場 ? 來源:Linuxer ? 2020-06-03 15:08 ? 次閱讀

近日,我在寫內核模塊的時候犯了一個低級錯誤:

直接access用戶態的內存而沒有使用copy_to_user/copy_from_user!

在內核看來,用戶態提供的虛擬地址是不可信的,所以在一旦在內核態訪問用戶態內存發生缺頁中斷,處理起來是非常棘手的。

Linux內核的做法是提供了一張 異常處理表 ,使用專有的函數來訪問用戶態內存。類似 try-catch塊一般。具體詳情可參見copy_to_user/copy_from_user的實現以及內核文檔Documentation/x86/exception-tables.txt的描述。

本來簡單看下這個異常處理表能怎么玩。

首先,我們可以寫一片代碼,將內核的異常處理表dump下來:

// show_extable.c#include #include int (*_lookup_symbol_name)(unsigned long, char *);unsigned long (*_get_symbol_pos)(unsigned long, void *, void *);unsigned long start_ex, end_ex; int init_module(void){ unsigned long i; unsigned long orig, fixup, originsn, fixinsn, offset, size; char name[128], fixname[128]; _lookup_symbol_name = (void *)kallsyms_lookup_name("lookup_symbol_name"); _get_symbol_pos = (void *)kallsyms_lookup_name("get_symbol_pos"); start_ex = (unsigned long)kallsyms_lookup_name("__start___ex_table"); end_ex = (unsigned long)kallsyms_lookup_name("__stop___ex_table"); // 按照exception_table_entry的sizeof從start遍歷到end。 for(i = start_ex; i < end_ex; i += 2*sizeof(unsigned long)) { orig = i; // 取出exception_table_entry的insn字段地址。 fixup = i + sizeof(unsigned int); // 取出fixup字段地址。 originsn = orig + *(unsigned int *)orig; // 根據相對偏移字段求出絕對地址 originsn |= 0xffffffff00000000; fixinsn = fixup + *(unsigned int *)fixup; fixinsn |= 0xffffffff00000000; _get_symbol_pos(originsn, &size, &offset); _lookup_symbol_name(originsn, name); _lookup_symbol_name(fixinsn, fixname); printk("[%lx]%s+0x%lx/0x%lx [%lx]%s ", originsn, name, offset, size, fixinsn, fixname); } return -1;}MODULE_LICENSE("GPL");

我們看下輸出:

# ___sys_recvmsg+0x253位置發生異常,跳轉到ffffffff81649396處理異常。[ 7655.267616] [ffffffff8150d7a3]___sys_recvmsg+0x253/0x2b0 [ffffffff81649396]bad_to_user...# create_elf_tables+0x3cf位置處如果發生異常,跳轉到ffffffff81648a07地址執行異常處理。[ 7655.267727] [ffffffff8163250e]create_elf_tables+0x3cf/0x509 [ffffffff81648a1b]bad_gs

一般而言,類似bad_to_user,bad_from_user之類的異常處理函數都是直接返回用戶一個錯誤碼,比如Bad address之類,并不是直接用戶程序直接段錯誤,這一點和用戶態訪問非法地址直接發送SIGSEGV有所不同。比如:

#include int main(int argc, char **argv){ int fd; int ret; char *buf = (char *)0x56; // 顯然是一個非法地址。 fd = open("/proc/sys/net/nf_conntrack_max", O_RDWR | O_CREAT, S_IRWXU); perror("open"); ret = read(fd, buf, 100); perror("read");}

執行之:

[root@localhost test]# ./a.outopen: Successread: Bad address # 沒有段錯誤,只是一個普通錯誤。

我們能不能將其行為修改成和用戶態訪問非法地址一致呢?簡單,替換掉bad_to_user即可,代碼如下:

// fix_ex.c#include #include #include int (*_lookup_symbol_name)(unsigned long, char *);unsigned long (*_get_symbol_pos)(unsigned long, void *, void *);unsigned long start_ex, end_ex;void *_bad_from_user, *_bad_to_user; void kill_user_from(void){ printk("經理!rush tighten beat electric discourse! "); force_sig(SIGSEGV, current);} void kill_user_to(void){ printk("經理!rush tighten beat electric discourse! SB 皮鞋 "); force_sig(SIGSEGV, current);} unsigned int old, new; int (*_lookup_symbol_name)(unsigned long, char *);unsigned long (*_get_symbol_pos)(unsigned long, void *, void *); int hook_fixup(void *origfunc1, void *origfunc2, void *newfunc1, void *newfunc2){ unsigned long i; unsigned long fixup, fixinsn; char fixname[128]; for(i = start_ex; i < end_ex; i += 2*sizeof(unsigned long)) { fixup = i + sizeof(unsigned int); fixinsn = fixup + *(unsigned int *)fixup; fixinsn |= 0xffffffff00000000; _lookup_symbol_name(fixinsn, fixname); if (!strcmp(fixname, origfunc1) || !strcmp(fixname, origfunc2)) { unsigned long new; unsigned int newfix; if (!strcmp(fixname, origfunc1)) { new = (unsigned long)newfunc1; } else { new = (unsigned long)newfunc2; } new -= fixup; newfix = (unsigned int)new; *(unsigned int *)fixup = newfix; } } return 0;} int init_module(void){ _lookup_symbol_name = (void *)kallsyms_lookup_name("lookup_symbol_name"); _get_symbol_pos = (void *)kallsyms_lookup_name("get_symbol_pos"); _bad_from_user = (void *)kallsyms_lookup_name("bad_from_user"); _bad_to_user = (void *)kallsyms_lookup_name("bad_to_user"); start_ex = (unsigned long)kallsyms_lookup_name("__start___ex_table"); end_ex = (unsigned long)kallsyms_lookup_name("__stop___ex_table"); hook_fixup("bad_from_user", "bad_to_user", kill_user_from, kill_user_to); return 0;}void cleanup_module(void){ hook_fixup("kill_user_from", "kill_user_to", _bad_from_user, _bad_to_user);} MODULE_LICENSE("GPL");

編譯,加載,重新執行我們的a.out:

[root@localhost test]# insmod ./fix_ex.ko[root@localhost test]# ./a.outopen: Success段錯誤[root@localhost test]# dmesg[ 8686.091738] 經理!rush tighten beat electric discourse! SB 皮鞋[root@localhost test]#

發生了段錯誤,并且打印出了讓經理趕緊打電話的句子。

其實,我的目的并不是這樣的,我真正的意思是,Linux的異常處理鏈表,又是一個藏污納垢的好地方,我們可以在上面的hook函數中藏一些代碼,比如說inline hook之類的,然后呢?然后靜悄悄地等待用戶態進程的bug導致異常處理被執行。將代碼注入的時間線拉長,從而更難讓運維和經理注意到。

讓代碼注入的時間點和模塊插入的時間點分開,讓事情更加混亂。不過,注意好隱藏模塊或者oneshot哦。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 模塊
    +關注

    關注

    7

    文章

    2730

    瀏覽量

    47634
  • Linux
    +關注

    關注

    87

    文章

    11333

    瀏覽量

    210054
  • 函數
    +關注

    關注

    3

    文章

    4344

    瀏覽量

    62845

原文標題:Linux內核態缺頁會發生什么 - 玩轉Exception fixup表

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

收藏 人收藏

    評論

    相關推薦

    騰訊云內核團隊修復Linux關鍵Bug

    騰訊云操作系統(Tencent OS)內核團隊近日在Linux社區取得了顯著成果。他們提交的兩項改進方案,成功解決了自2021年以來一直困擾眾多一線廠商,并在近期讓多個Linux頂級
    的頭像 發表于 12-31 10:58 ?232次閱讀

    嵌入式工程師都在找的【Linux內核調試技術】建議收藏!

    在嵌入式系統的開發中,Linux內核調試是一個至關重要的環節。 隨著處理器技術的不斷進步和嵌入式領域的蓬勃發展,掌握有效的內核調試技術成為了開發者們的一項必備技能。本文將介紹幾種常見的Lin
    發表于 11-28 15:37

    deepin社區亮相第19屆中國Linux內核開發者大會

    中國 Linux 內核開發者大會,作為中國 Linux 內核領域最具影響力的峰會之一,一直以來都備受矚目。
    的頭像 發表于 10-29 16:35 ?545次閱讀

    詳解linux內核的uevent機制

    linux內核中,uevent機制是一種內核和用戶空間通信的機制,用于通知用戶空間應用程序各種硬件更改或其他事件,比如插入或移除硬件設備(如USB驅動器或網絡接口)。uevent表示“用戶空間
    的頭像 發表于 09-29 17:01 ?872次閱讀

    linux驅動程序如何加載進內核

    Linux系統中,驅動程序是內核與硬件設備之間的橋梁。它們允許內核與硬件設備進行通信,從而實現對硬件設備的控制和管理。 驅動程序的編寫 驅動程序的編寫是Linux驅動開發的基礎。在編
    的頭像 發表于 08-30 15:02 ?548次閱讀

    Linux內核測試技術

    Linux 內核Linux操作系統的核心部分,負責管理硬件資源和提供系統調用接口。隨著 Linux 內核的不斷發展和更新,其復雜性和代碼規
    的頭像 發表于 08-13 13:42 ?544次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內核</b>測試技術

    Linux內核中頁映射的基礎知識

    大家在看內核代碼時會經常看的以上術語,但在ARM的芯片手冊中并沒有用到這些術語,而是使用L1,L2,L3頁這種術語。
    的頭像 發表于 08-07 15:53 ?1072次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內核</b>中頁<b class='flag-5'>表</b>映射的基礎知識

    Linux內核中的頁面分配機制

    Linux內核中是如何分配出頁面的,如果我們站在CPU的角度去看這個問題,CPU能分配出來的頁面是以物理頁面為單位的。也就是我們計算機中常講的分頁機制。本文就看下Linux內核是如何管
    的頭像 發表于 08-07 15:51 ?325次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內核</b>中的頁面分配機制

    歡創播報 華為宣布鴻蒙內核已超越Linux內核

    1 華為宣布鴻蒙內核已超越Linux內核 ? 6月21日,在華為開發者大會上, HarmonyOS NEXT(鴻蒙NEXT)——真正獨立于安卓和iOS的鴻蒙操作系統,正式登場。這是HarmonyOS
    的頭像 發表于 06-27 11:30 ?883次閱讀

    帶奇偶校驗發生器/校驗器和3輸出的16位收發器ABT16657數據

    電子發燒友網站提供《帶奇偶校驗發生器/校驗器和3輸出的16位收發器ABT16657數據.pdf》資料免費下載
    發表于 05-30 09:45 ?0次下載
    帶奇偶校驗<b class='flag-5'>發生</b>器/校驗器和3<b class='flag-5'>態</b>輸出的16位收發器ABT16657數據<b class='flag-5'>表</b>

    使用 PREEMPT_RT 在 Ubuntu 中構建實時 Linux 內核

    盟通技術干貨構建實時Linux內核簡介盟通技術干貨Motrotech如果需要在Linux中實現實時計算性能,進而有效地將Linux轉變為RTOS,那么大多數發行版都可以打上名為PREE
    的頭像 發表于 04-12 08:36 ?2662次閱讀
    使用 PREEMPT_RT 在 Ubuntu 中構建實時 <b class='flag-5'>Linux</b> <b class='flag-5'>內核</b>

    假焊現象為什么會發生?如何處理?

    假焊現象在生產過程中比較容易發生,許多商家對此非常苦惱。今天佳金源錫膏廠家就為大家詳細的介紹一下無鉛免洗錫膏假焊現象為什么會發生,在發生之后應該做出哪些對策進行處理:產生原因:無鉛免洗錫膏印刷過程中
    的頭像 發表于 02-22 17:50 ?655次閱讀
    假焊現象為什么<b class='flag-5'>會發生</b>?如何處理?

    C++在Linux內核開發中從爭議到成熟

    Linux 內核郵件列表中一篇已有六年歷史的老帖近日再次引發激烈討論 —— 主題是建議將 Linux 內核的開發語言從 C 轉換為更現代的 C++。
    的頭像 發表于 01-31 14:11 ?663次閱讀
    C++在<b class='flag-5'>Linux</b><b class='flag-5'>內核</b>開發中從爭議到成熟

    Ubuntu 24.04 LTS選用Linux 6.8為默認內核

    關于Ubuntu 24.04 LTS使用何種內核版本,一直備受關注。Canonical工程師Andrea Righi昨日宣布,Ubuntu 24.04將默認搭載Linux 6.8內核
    的頭像 發表于 01-29 11:27 ?1197次閱讀

    linux內核主要由哪幾個部分組成,作用是什么

    Linux內核主要由以下幾個部分組成: 進程管理:Linux內核負責管理和調度系統中的進程。它通過進程調度算法來決定哪個進程在什么時間運行以及如何分配系統資源。 內存管理:
    的頭像 發表于 01-22 14:34 ?2758次閱讀
    主站蜘蛛池模板: 玖玖爱这里只有精品| 黄网站色| 精品在线视频一区| 激情丁香婷婷| 成人在线免费电影| 四虎a456tncom| 天堂在线免费视频| 欧美色爱综合| 老师你好滑下面好湿h| 伊人久久综合成人亚洲| 午夜两性网| 性生大片一级毛片免费观看| 很黄很暴力 很污秽的小说| 综合99| 免费观看黄网站| 永久免费看毛片| 色老太视频| 狠狠色影院| 国产一级又色又爽又黄大片| brazzersvideosexhd欧美高清| 国产精品va一区二区三区| 亚洲第一免费视频| 黄色网址日本| 亚洲一区二区免费在线观看| 国产成人精品三级在线| 特黄特色| 久久成人国产精品青青| 午夜视频一区二区| 天天干天天爽| 欧美性黑人极品1819hd| 精品国产高清在线看国产| 色婷婷婷丁香亚洲综合不卡| 激情五月开心网| 天天干天天插天天射| 久久伊人草| 亚1州区2区三区4区产品| 开心激情播播网| 天天爽天天| 久久婷五月综合| 日产精品卡二卡三卡四卡无卡乱码| 婷婷亚洲综合一区二区|