xorl %eax, %eax

Linux kernel IrDA name/attributes Stack Buffer Overflow

leave a comment »

So, I had some spare time this morning and decided to have a look at one of the countless vulnerabilities reported by Dan Rosenberg the past few months. More specifically, this post is about this one. Looking at net/irda/iriap.c of 2.6.38 release of the Linux kernel we have the below routine…

/*
 * Function iriap_getvaluebyclass_indication (self, skb)
 *
 *    getvaluebyclass is requested from peer LM-IAS
 *
 */
static void iriap_getvaluebyclass_indication(struct iriap_cb *self,
                                             struct sk_buff *skb)
{
        struct ias_object *obj;
        struct ias_attrib *attrib;
        int name_len;
        int attr_len;
        char name[IAS_MAX_CLASSNAME + 1];       /* 60 bytes */
        char attr[IAS_MAX_ATTRIBNAME + 1];      /* 60 bytes */
        __u8 *fp;
        int n;
   ...
        fp = skb->data;
        n = 1;

        name_len = fp[n++];
        memcpy(name, fp+n, name_len); n+=name_len;
        name[name_len] = '\0';

        attr_len = fp[n++];
        memcpy(attr, fp+n, attr_len); n+=attr_len;
        attr[attr_len] = '\0';
   ...
        /* We have a match; send the value.  */
        iriap_getvaluebyclass_response(self, obj->id, IAS_SUCCESS,
                                       attrib->value);
}

From the given snippet you can see that this function is used to obtain the class’ values. To be more exact, IrDA LM-IAS (Link Management – Information Access Service). As you can see, the ‘fp’ file pointer is set to point to the received socket’s data section. After parsing the data section’s length value in order to initialize ‘name_len’, it proceeds to copying the data to the fixed size ‘name’ stack allocated buffer using memcpy().
The same procedure follows next for the attributes part of the data section. Since both the source buffer and size limit are user controller in the memcpy() operations, an attacker could trigger a stack based buffer overflow.

To fix this, the following patch was applied

 	name_len = fp[n++];
+
+	IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;);
+
 	memcpy(name, fp+n, name_len); n+=name_len;
 	name[name_len] = '\0';
 
 	attr_len = fp[n++];
+
+	IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;);
+
 	memcpy(attr, fp+n, attr_len); n+=attr_len;
 	attr[attr_len] = '\0';

Which checks using IRDA_ASSERT() that the s length values do not exceed the buffers’ limits.

Written by xorl

April 23, 2011 at 10:57

Posted in bugs, linux

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