xorl %eax, %eax

Linux kernel NinjaSCSI-32Bi PCMCIA SCSI Buffer Overflow

leave a comment »

This bug was reported to the LKML by Jiri Slaby on 8 August 2009. The vulnerable function can be found at drivers/scsi/pcmcia/nsp_cs.c like this:

/*======================================================================
    nsp_cs_config() is scheduled to run after a CARD_INSERTION event
    is received, to configure the PCMCIA socket, and to make the
    ethernet device available to the system.
======================================================================*/
       ...
static int nsp_cs_config(struct pcmcia_device *link)
{
        int               ret;
        scsi_info_t      *info   = link->priv;
        struct nsp_cs_configdata *cfg_mem;
        struct Scsi_Host *host;
        nsp_hw_data      *data = &nsp_data_base;

        nsp_dbg(NSP_DEBUG_INIT, "in");

        cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
        if (!cfg_mem)
                return -ENOMEM;
        cfg_mem->data = data;
       ...
        return -ENODEV;
} /* nsp_cs_config */

As you can see, ‘cfg_mem’ pointer is initialized with sizeof(cfg_mem). Since this variable is a pointer to a nsp_cs_configdata structure, sizeof operator will return 4 in 32-bit platforms and 8 on 64-bit ones. However, as we can see from drivers/scsi/pcmcia/nsp_cs.c and include/pcmcia/cs.h, that structure should have more space…

drivers/scsi/pcmcia/nsp_cs.c:
/*======================================================================
    nsp_cs_config() is scheduled to run after a CARD_INSERTION event
    is received, to configure the PCMCIA socket, and to make the
    ethernet device available to the system.
======================================================================*/

struct nsp_cs_configdata {
        nsp_hw_data             *data;
        win_req_t               req;
};

include/pcmcia/cs.h:
/* For RequestWindow */
typedef struct win_req_t {
    u_int       Attributes;
    u_long      Base;
    u_int       Size;
    u_int       AccessSpeed;
} win_req_t;

Consequently, the operations following can result in heap memory corruption. To fix this, they updated the allocation line like this:

 	nsp_dbg(NSP_DEBUG_INIT, "in");
 
-	cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
+	cfg_mem = kzalloc(sizeof(*cfg_mem), GFP_KERNEL);
 	if (!cfg_mem)

In order to retrieve the correct size of the structure instead of the size of the pointer.

Written by xorl

August 9, 2009 at 14:11

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