SYSCALL_DEFINE含义
来源:互联网 发布:淘宝客代理软件 编辑:程序博客网 时间:2024/05/02 06:59
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()的定义就知道了:
- #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含义
- SYSCALL_DEFINE含义
- SYSCALL_DEFINE含义
- SYSCALL_DEFINE
- SYSCALL_DEFINE详解
- SYSCALL_DEFINE小记
- linux内核SYSCALL_DEFINE分析
- 系统调用宏SYSCALL_DEFINE
- linux系统调用SYSCALL_DEFINE
- Linux系统调用之SYSCALL_DEFINE
- Linux系统调用之SYSCALL_DEFINE
- ->含义
- ``含义
- linux-kernel 3.5.3Tcp系统调用,源码分析1-宏SYSCALL_DEFINE
- linux-kernel 3.5.3Tcp系统调用,源码分析1-宏SYSCALL_DEFINE
- Synchronized含义
- "/"的含义
- static_cast 含义!
- 输入一行字符,统计其中有多少个单词(第二周实验报告3-1)
- a==true和true==a和区别
- 内存和缓存之间有什么区别?
- Linux 环境下串口通信的编程
- Linux下查看文件和文件夹大小
- SYSCALL_DEFINE含义
- tomcat 增加虚拟目录 列出隐藏本地文件
- ASP.NET中gridview获取当前行的索引值
- 黑马程序员——Java网络编程基础
- Linux的通用makefile模板
- 常用C语言标准库函数
- iOS Code Signing: 解惑
- 基本功练习_3_4_之strcpy函数和memcpy函数
- 初手必看之Nginx详细介绍