xorl %eax, %eax

CVE-2010-4164: Linux kernel X.25 Remote Integer Underflow

with 4 comments

Continuing from his previous bug in X.25, Dan Rosenberg releases this one. This bug resides in the same source code file which is the net/x25/x25_facilities.c and here is a snippet that demonstrates it…

/*
 * Parse a set of facilities into the facilities structures. Unrecognised
 *      facilities are written to the debug log file.
 */
int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
{
        unsigned char *p = skb->data;
        unsigned int len;
     ...
        if (skb->len < 1)
                return 0;
 
        len = *p++;

        if (len >= skb->len)
                return -1;

        while (len > 0) {
                switch (*p & X25_FAC_CLASS_MASK) {
                case X25_FAC_CLASS_A:
     ...
                        p   += 2;
                        len -= 2;
                        break;
                case X25_FAC_CLASS_B:
                        switch (*p) {
     ...
                        p   += 3;
                        len -= 3;
                        break;
                case X25_FAC_CLASS_C:
     ...
                case X25_FAC_CLASS_D:
                        switch (*p) {
     ...
                        }
                        len -= p[1] + 2;
                        p += p[1] + 2;
                        break;
                }
        }

        return p - skb->data;
}

As you can see, regardless of the facility class of the received data, ‘len’ will keep decrementing with no check in the resulted value. As Dan Rosenberg states, there is a case of ‘len’ being underflowed when decremented and thus, leading to executing the ‘while’ loop until kernel crashes since ‘len’ is unsigned and will “always” be greater than zero if it’s underflowed.
The fix for this bug is the following…

 		switch (*p & X25_FAC_CLASS_MASK) {
 		case X25_FAC_CLASS_A:
+			if (len < 2)
+				return 0;
 			switch (*p) {

Since class A will decremente ‘len’ by two, it has to make sure that it’s at least two. Consequently we have:

 		case X25_FAC_CLASS_B:
+			if (len < 3)
+				return 0;
 			switch (*p) {

for B class, and then…

 		case X25_FAC_CLASS_C:
+			if (len < 4)
+				return 0;
 			printk(KERN_DEBUG "X.25: unknown facility %02X, "
 			       "values %02X, %02X, %02X\n",
 			       p[0], p[1], p[2], p[3]);

for C class and finally…

 		case X25_FAC_CLASS_D:
+			if (len < p[1] + 2)
+				return 0;
 			switch (*p) {

P.S.: That’s off topic but Mr. Dan Rosenberg I’m not really sure if you’re aware of the consequences of disclosing all those bugs and vulnerabilities. I just want to let you know that you have made some powerful “enemies” in case you didn’t know. Good luck…

Written by xorl

November 14, 2010 at 01:45

Posted in bugs, linux

4 Responses

Subscribe to comments with RSS.

  1. Whoah, some really BM post script. Haha.

    mfukar

    November 14, 2010 at 18:07

  2. Wich enemies? 18-year old wannabe hackers are not powerful sorry.

    alfred

    November 14, 2010 at 18:34

  3. I also find it critical to disclose vulnerabilities so frequently but still greatly appreciate you commenting on it. :)

    OpCodez

    November 14, 2010 at 18:53

  4. drosenbe is lame, and greps too much bro.

    ret

    November 15, 2010 at 23:09


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s