BUGTRAQ ID: 33003
CVE(CAN) ID: CVE-2008-5702
Linux Kernel是开放源码操作系统Linux所使用的内核。
Linux kernel的drivers/watchdog/ib700wdt.c中的ibwdt_ioctl函数存在缓冲区下溢漏洞,本地用户可以通过特定的/dev/watchdog WDIOC_SETTIMEOUT IOCTL调用来触发这个溢出,导致拒绝服务或执行任意内核态代码。
以下是ib700wdt.c文件中有漏洞的代码段:
static int wd_times[] = {
30, /* 0x0 /
28, / 0x1 /
26, / 0x2 /
24, / 0x3 /
22, / 0x4 /
20, / 0x5 /
18, / 0x6 /
16, / 0x7 /
14, / 0x8 /
12, / 0x9 /
10, / 0xA /
8, / 0xB /
6, / 0xC /
4, / 0xD /
2, / 0xE /
0, / 0xF */
};
function ibwdt_ioctl:
…
case WDIOC_SETTIMEOUT:
if (get_user(new_margin, p))
return -EFAULT;
if (ibwdt_set_heartbeat(new_margin))
return -EINVAL;
ibwdt_ping();
/* Fall */
case WDIOC_GETTIMEOUT:
return put_user(wd_times[wd_margin], p);
…
function ibwdt_set_heartbeat:
static int
ibwdt_set_heartbeat(int t)
{
int i;
if ((t < 0) || (t > 30))
return -EINVAL;
for (i = 0x0F; i > -1; i--)
if (wd_times[i] > t)
break;
wd_margin = i;
return 0;
}
如果使用30这个值调用ibwdt_set_heartbeat(int t),则由于t == 30,ibwdt_set_heartbeat中的((t < 0) || (t > 30))检查就不会失败,但在循环中,wd_times[i] >检查不会为真,因为没有wd_times大于t的值(也就是30)。退出循环时i == -1,因此将wd_margin设置为-1。
Linux kernel 2.6.x
厂商补丁:
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
<a href=“http://kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.28-rc1.tar.bz2” target=“_blank”>http://kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.28-rc1.tar.bz2</a>