xorl %eax, %eax

Linux kernel SPARC64 /proc/iomem Uninitialized Memory Access

leave a comment »

This vulnerability was reported by Mikulas Patocka of Red Hat on 19 March 2009 and affects Linux kernel 2.6.22-rc1 up to 2.6.29 where it was patched. The bug is fairly simple. When a user attempts to read the contents of /proc/iomem on a SPARC64 processor, kernel internally calls pci_register_iommu_region() for registering the required PCI I/O memory. This function can be found at arch/sparc64/kernel/pci_common.c like this:

static void pci_register_iommu_region(struct pci_pbm_info *pbm)
{
        const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL);

        if (vdma) {
                struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL);

                if (!rp) {
                        prom_printf("Cannot allocate IOMMU resource.\n");
                        prom_halt();
                }
                rp->name = "IOMMU";
                rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
                rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
                rp->flags = IORESOURCE_BUSY;
                request_resource(&pbm->mem_space, rp);
        }
}

This is taken from 2.6.28 release of the Linux kernel. The above routine is called by pci_determine_mem_io_space() which does exactly what its name implies. So, it initially calls of_get_property() to retrieve virtual-dma of pbm->op->node PCI node. If there is some virtual DMA property in the given node, it allocates space using kmalloc() for a pointer to a resource structure. At last, it initializes that structure and invokes request_resource() to reserve the resource. This function attempts to access data of that resource pointer allocated using kmalloc(). Since kmalloc() doesn’t initialize the allocated space this will result in uninitialized  memory access. To fix this, the following patch was applied:

        if (vdma) {
-               struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL);
+               struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);

                if (!rp) {

Written by xorl

June 5, 2009 at 12:58

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