以下是CVE-2009-0029的概述:
Linux内核2.6.28及更早版本的s390,powerpc,sparc64和mips 64位平台上的ABI要求64位寄存器中的32位参数在从用户发送时正确地进行符号扩展 - 模式应用程序,但无法验证这一点,这允许本地用户通过精心设计的系统调用导致拒绝服务(崩溃)或可能获得权限。
这怎么会出现?为什么缺陷不会影响x86_64或Intel Itanium?
Linux内核通过替换下面__SYSCALL_DEFINEx
的marco定义来解决这个缺陷
#define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))
到
#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__))
我真的不知道怎么解决这个问题?
答案 0 :(得分:1)
在这些体系结构中,32位值由64位寄存器处理。
因此,如果函数具有32位int
参数,则恶意调用者可以将值放入此寄存器中,该值大于int
的值。
此外,因为编译器“知道”int
不能具有不适合int
变量的值,所以不容易检查该值是否超出范围,因为编译器可以优化该检查。
作为一种变通方法,SyS_xxx
函数首先假定其所有参数都是64位long
值,然后将它们显式转换为实际类型。
在x86_64和Itanium上,处理器在访问32位值时忽略寄存器的高位。