色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

    文章

    2731

    瀏覽量

    47664
  • Linux
    +關注

    關注

    87

    文章

    11342

    瀏覽量

    210164
  • 函數
    +關注

    關注

    3

    文章

    4345

    瀏覽量

    62885

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

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

收藏 人收藏

    評論

    相關推薦

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

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

    飛凌嵌入式ElfBoard ELF 1板卡-Linux內核移植之內核簡介

    學到本章節,大家應該對Linux操作系統都有了一定的了解,但可能還不知道我們拿到手的內核源碼都經歷了什么。linux有一個龐大的開源社區,每個人都可以向開源社區提交代碼。由于linux
    發表于 12-13 09:03

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

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

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

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

    詳解linux內核的uevent機制

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

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

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

    Linux內核測試技術

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

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

    大家在看內核代碼時會經常看的以上術語,但在ARM的芯片手冊中并沒有用到這些術語,而是使用L1,L2,L3頁這種術語。
    的頭像 發表于 08-07 15:53 ?1102次閱讀
    <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 ?337次閱讀
    <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 ?889次閱讀

    帶奇偶校驗發生器/校驗器和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 ?2702次閱讀
    使用 PREEMPT_RT 在 Ubuntu 中構建實時 <b class='flag-5'>Linux</b> <b class='flag-5'>內核</b>

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

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

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

    Linux 內核郵件列表中一篇已有六年歷史的老帖近日再次引發激烈討論 —— 主題是建議將 Linux 內核的開發語言從 C 轉換為更現代的 C++。
    的頭像 發表于 01-31 14:11 ?674次閱讀
    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 ?1212次閱讀
    主站蜘蛛池模板: 成人国产亚洲精品A区天堂蜜臀 | 黑人干亚洲人 | 国产精品久久久久久影院 | 国产自产第一区c国产 | 激情丛林电影完整在线 | 欧美亚洲精品真实在线 | 花蝴蝶高清观看免费 | 伊人情涩网| good神马电影伦理午夜 | 午夜无码片在线观看影院 | 久久青草免费线观最新 | 亚洲国产日韩欧美视频二区 | 亚洲 欧美 另类 中文 在线 | 全黄h全肉细节文在线观看 全黄H全肉细节文短篇 | 国产亚洲精品福利视频 | 久久精品亚洲牛牛影视 | 伊人伊人伊人 | 久久精品免视看国产 | 亚洲三级在线中文字幕 | 性色无码AV久久蜜臀 | 久久免费看少妇高潮A片2012 | 久章草一区二区 | 亚洲视频无码高清在线 | 美女的jj| 欧美黑大炮18p | 99re8在线视频精品 | 男人J桶女人P视频无遮挡网站 | 日本高清二区 | 亚洲综合色五月久久婷婷 | 荡乳乱公小说 | 快播性爱电影 | 啦啦啦WWW在线观看免费高清版 | 午夜精品久久久内射近拍高清 | A片毛片免费视频在线看 | 亚洲欧美综合中文字幕 | 快播官方网站 | 被男按摩师添的好爽在线直播 | 我解开了岳的乳第一个女人 | 99九九精品国产高清自在线 | 女人操男人 | 天天影视色欲 影视 |