標籤:

在Linux內核模塊中對空指針解引用,為什麼內核不掛?

我寫了一個簡單的Linux內核模塊,然後在mod_init中訪問一個空指針:

char* p = NULL;

*p = 1;

這樣。

為什麼這樣內核都不掛?


如果不是在 interrupt handler 之類的 critical part 出現空指針異常的話,內核一般是會 oops ,然後把這個模塊 uncleanly release ;否則就直接 kernel panic 。

你這個例子里代碼是否被編譯器自動優化了也是一個值得考慮的點。

Linux Kernel Programming: "Unable to handle kernel NULL pointer dereference"

Oopses are caused by the kernel dereferencing an invalid pointer. In a user-space

program this would normally cause a segmentation fault, also known as a segfault.

A user-space program cannot recover from a segfault. When this occurs in the

kernel, however, it is called an oops and doesnt necessarily leave the kernel

unuseable.

http://slacksite.com/slackware/oops.html


小試了一把,在p是NULL的情況下,*p=1;(寫操作)和{int b = *p; printk("%d
",b);}(讀操作)

均曝出:BUG: unable to handle kernel NULL pointer dereference at (null)和call stack

通過dmesg可以看到上述信息。

更新:測試的過程中還斷網了一次,以為是遠程機器死了,所以之前的回答是錯誤的,修改了回答。


上完整代碼. 會不會代碼太簡單, 指針訪問被優化掉了?

你用用objdump反彙編一下內核模塊看看.

按道理應該 Unable to handle kernel NULL pointer dereference at virtual address 0000000.

參考一下空指針的解引用


http://wangxu.me/translation/2009/09/03/null-pointers-1/


Trap based exception handler


可以看下最新的samba的cve-2015-0240漏洞,原因就是指針未初始化,且釋放未初始化的指針導致崩潰甚至遠程代碼執行


之前的回答確實有問題。

你這個代碼會產生異常,內核處理異常就好了,不會向用戶空間那樣產生 segmentation fault,

畢竟在內核內訪問內核空間不是問題。

問題在於寫了 NULL 指針,對內核而言是異常事件。

編寫內核或者驅動代碼的要求就是:不做「非法」的事情,要安全要高效。

用戶空進程訪問內核空間地址是非法的,會引起 Segmentation fault, 字面意義上這是訪問了非法的段,實際上某些機器上 NULL 是某個段地址+偏移量。

在用戶空間也可以對 NULL 指針解引用而不訪問。比如:

struct foo_bar *obj = NULL

obj = (struct foo_bar *)malloc(sizeof(*obj));

int *obj = NULL;

*obj;

*obj;

Question 5.6

c++ - What is the difference between NULL, and 0

Question 5.17


推薦閱讀:

使用Bioconda管理Linux系統中的生物信息軟體
沒有 Linux 和開源軟體的世界會變得怎麼樣
獲取自旋鎖和禁止中斷的時候為什麼不能睡眠?
linux 下root用戶執行rm -rf /後,系統會有哪些反應,會立刻死機嗎?
在Android的發展歷程中有沒有什麼有趣的故事或者小細節?

TAG:Linux | Linux內核 |