Bug 475733 - (CVE-2008-5702) CVE-2008-5702 kernel: watchdog: ib700wdt.c - buffer_underflow bug
CVE-2008-5702 kernel: watchdog: ib700wdt.c - buffer_underflow bug
Status: CLOSED ERRATA
Product: Security Response
Classification: Other
Component: vulnerability (Show other bugs)
unspecified
All Linux
low Severity low
: ---
: ---
Assigned To: Red Hat Product Security
impact=low,source=kernelbugzilla,publ...
: Security
Depends On: 475735 475736 475737 475738 475739
Blocks:
  Show dependency treegraph
 
Reported: 2008-12-10 02:27 EST by Eugene Teo (Security Response)
Modified: 2010-12-23 22:52 EST (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2010-12-23 22:52:28 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Eugene Teo (Security Response) 2008-12-10 02:27:46 EST
From Zvonimir Rakamaric:
Steps to a possible buffer_underflow bug in ib700wdt.c, function ibwdt_ioctl:

1. new margin is loaded using get_user(new_margin, p) in case WDIOC_SETTIMEOUT in the function ibwdt_ioctl. Important: assume that new_margin == 30
2. ibwdt_set_heartbeat(new_margin) is called
3. the check "if ((t < 0) || (t > 30))" in ibwdt_set_heartbeat is not going to fail because t == 30 (t is new_margin)
4. in the loop, the check wd_times[i] > t is never going to be true because none of the wd_times are greater than the value of t (i.e. 30)
5. we are exiting the loop with i == -1 and therefore setting wd_margin to -1 in the line wd_margin = i;
6. we are returning from ibwdt_set_heartbeat and wd_margin is -1
7. we fall through to case WDIOC_GETTIMEOUT
8. we access the wd_times array with wd_margin == -1 on line "return put_user(wd_times[wd_margin], p);"

[...]
Furthermore, here are the pieces of code which are causing this
buffer-underflow bug in 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;
}
Comment 3 Eugene Teo (Security Response) 2008-12-10 02:34:54 EST
Reference: http://bugzilla.kernel.org/show_bug.cgi?id=11399
Comment 4 Eugene Teo (Security Response) 2008-12-10 02:35:39 EST
Upstream commit:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7c2500f
Comment 7 Vincent Danen 2010-12-23 22:52:28 EST
This was addressed via:

Red Hat Enterprise Linux version 4 (RHSA-2009:0014)

Note You need to log in before you can comment on or make changes to this bug.