SYSCALL_DEFINE含义
生活随笔
收集整理的這篇文章主要介紹了
SYSCALL_DEFINE含义
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這篇文章解釋了為什么kernel采用SYSCALL_DEFINEx宏定義!
CVE-2010-3301是其中一個。這個漏洞的成因是,在64位的內核上執行32位的系統調用時,作為傳遞系統調用號的%rax高32位未被清零處理,而且在進行比較的時候直接使用的%eax,導致高32位被忽略:
cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys ia32_do_call: IA32_ARG_FIXUP call *ia32_sys_call_table(,%rax,8)這樣以來,通過靜心構造的%rax就可以跳轉到它想要的位置去!在這個exploit中,它就利用ptrace()來跟蹤系統調用,并把計算好的想要跳轉地址的偏移傳遞到%rax中,然后執行事先放置好的代碼來提升權限!
修復方法很簡單,要么把%rax的高位清零,要么比較的時候使用%rax。修復這個問題的commit是:
http://git.kernel.org/linus/36d001c70d8a0144ac1d038f6876c484849a74de
http://git.kernel.org/linus/eefdca043e8391dcd719711716492063030b55ac
和這個問題類似的問題之前也曾出現過,CVE-2009-0029,問題更嚴重,涉及很多的系統調用。不同的是,這個涉及64位的內核和64位的用戶空間,來自用戶空間的傳遞系統調用參數的寄存器的高32位同樣沒被清零,而帶32位參數(比如int)的系統調用就會有問題,內核代碼只會檢查對它有意義的低32位,高32位就被忽略而直接傳遞到后面去了,這就會帶來問題了。
問題的解決方法也很簡單,就是要把這些寄存器高位清零。說起來簡單,做起來難。要是和上面一樣直接用匯編處理的話,參數的類型的信息就丟失了,因為你匯編里分不清它到底是32位還是64位;而如果用C處理的話,有那么多系統調用,一個一個處理?那不符合Linus的作風!他是怎么做的呢?用宏!而且用強制轉化,把所有的32位參數聲明為long,然后再強制轉化成實際的類型,比如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大神把宏用到了何等出神入化的地步。:-) 這也是為什么你在內核中看到系統調用都是用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系統調用
在fs/namespace.c中,有
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,)
總結
以上是生活随笔為你收集整理的SYSCALL_DEFINE含义的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode刷题——Z字形变换
- 下一篇: 嵌入式LINUX环境下视频采集知识