在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 kernelunuseable.
http://slacksite.com/slackware/oops.html
小試了一把,在p是NULL的情況下,*p=1;(寫操作)和{int b = *p; printk("%d
",b);}(讀操作)
上完整代碼. 會不會代碼太簡單, 指針訪問被優化掉了?你用用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.6c++ - What is the difference between NULL, and 0Question 5.17推薦閱讀:
※使用Bioconda管理Linux系統中的生物信息軟體
※沒有 Linux 和開源軟體的世界會變得怎麼樣
※獲取自旋鎖和禁止中斷的時候為什麼不能睡眠?
※linux 下root用戶執行rm -rf /後,系統會有哪些反應,會立刻死機嗎?
※在Android的發展歷程中有沒有什麼有趣的故事或者小細節?