SYSCALL_DEFINE含义
生活随笔
收集整理的這篇文章主要介紹了
SYSCALL_DEFINE含义
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
這篇文章解釋了為什么kernel采用SYSCALL_DEFINEx宏定義!
CVE-2010-3301是其中一個。這個漏洞的成因是,在64位的內(nèi)核上執(zhí)行32位的系統(tǒng)調(diào)用時,作為傳遞系統(tǒng)調(diào)用號的%rax高32位未被清零處理,而且在進行比較的時候直接使用的%eax,導(dǎo)致高32位被忽略:
cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys ia32_do_call: IA32_ARG_FIXUP call *ia32_sys_call_table(,%rax,8)這樣以來,通過靜心構(gòu)造的%rax就可以跳轉(zhuǎn)到它想要的位置去!在這個exploit中,它就利用ptrace()來跟蹤系統(tǒng)調(diào)用,并把計算好的想要跳轉(zhuǎn)地址的偏移傳遞到%rax中,然后執(zhí)行事先放置好的代碼來提升權(quán)限!
修復(fù)方法很簡單,要么把%rax的高位清零,要么比較的時候使用%rax。修復(fù)這個問題的commit是:
http://git.kernel.org/linus/36d001c70d8a0144ac1d038f6876c484849a74de
http://git.kernel.org/linus/eefdca043e8391dcd719711716492063030b55ac
和這個問題類似的問題之前也曾出現(xiàn)過,CVE-2009-0029,問題更嚴重,涉及很多的系統(tǒng)調(diào)用。不同的是,這個涉及64位的內(nèi)核和64位的用戶空間,來自用戶空間的傳遞系統(tǒng)調(diào)用參數(shù)的寄存器的高32位同樣沒被清零,而帶32位參數(shù)(比如int)的系統(tǒng)調(diào)用就會有問題,內(nèi)核代碼只會檢查對它有意義的低32位,高32位就被忽略而直接傳遞到后面去了,這就會帶來問題了。
問題的解決方法也很簡單,就是要把這些寄存器高位清零。說起來簡單,做起來難。要是和上面一樣直接用匯編處理的話,參數(shù)的類型的信息就丟失了,因為你匯編里分不清它到底是32位還是64位;而如果用C處理的話,有那么多系統(tǒng)調(diào)用,一個一個處理?那不符合Linus的作風(fēng)!他是怎么做的呢?用宏!而且用強制轉(zhuǎn)化,把所有的32位參數(shù)聲明為long,然后再強制轉(zhuǎn)化成實際的類型,比如int。去看看__SC_CASTx()和__SC_LONGx()的定義就知道了:
PLAIN TEXT
C:
#define __SC_CAST1(t1, a1) ? ? ?(t1) a1
#define __SC_LONG1(t1, a1) ? ? ?long a1
?
#define __SYSCALL_DEFINEx(x, name, ...) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
? ? ? ? asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); ? ? ? ? ? \
? ? ? ? static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); ? ? ? \
? ? ? ? asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) ? ? ? ? ? ?\
? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
? ? ? ? ? ? ? ? __SC_TEST##x(__VA_ARGS__); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
? ? ? ? ? ? ? ? return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); ? ?\
? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
? ? ? ? SYSCALL_ALIAS(sys##name, SyS##name); ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
? ? ? ? static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__))
可見Linus大神把宏用到了何等出神入化的地步。:-) 這也是為什么你在內(nèi)核中看到系統(tǒng)調(diào)用都是用SYSCALL_DEFINEx()來定義了。
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)#define SYSCALL_DEFINEx(x, sname, ...) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
? ? ? ? __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
#define __SYSCALL_DEFINEx(x, name, ...) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
? ? ? ? asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS_
#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
看這個更直接一點,2.6.35中有這樣的宏定義
mount系統(tǒng)調(diào)用
在fs/namespace.c中,有
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,)
總結(jié)
以上是生活随笔為你收集整理的SYSCALL_DEFINE含义的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode刷题——Z字形变换
- 下一篇: 嵌入式LINUX环境下视频采集知识