安全研究

安全漏洞
Linux Kernel ib700wdt.c缓冲区溢出漏洞

发布日期:2008-12-17
更新日期:2008-12-30

受影响系统:
Linux kernel 2.6.x
不受影响系统:
Linux kernel 2.6.28-rc1
描述:
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。

<*来源:Zvonimir Rakamaric (zrakamar@cs.ubc.ca
  
  链接:http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.27.y.git;a=commit;h=7c2500f17d65092d93345f3996cf82ebca17e9ff
        http://bugzilla.kernel.org/show_bug.cgi?format=multiple&id=11399
*>

建议:
厂商补丁:

Linux
-----
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.28-rc1.tar.bz2

浏览次数:2761
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障