public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [OOPS] linux-2.6.7-bk20: possible use-after-free in platform_device_unregister()
@ 2004-07-10 18:31 Denis Vlasenko
  2004-07-10 19:49 ` Dmitry Torokhov
  0 siblings, 1 reply; 2+ messages in thread
From: Denis Vlasenko @ 2004-07-10 18:31 UTC (permalink / raw)
  To: linux-kernel

I compile kernels with
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_SLAB=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_FRAME_POINTER=y

Kernel oopsed while probing for devices in depca.c:

static void __init depca_platform_probe (void)
{
        int i;
        struct platform_device *pldev;

        for (i = 0; depca_io_ports[i].iobase; i++) {
                depca_io_ports[i].device = NULL;

                /* if an address has been specified on the command
                 * line, use it (if valid) */
                if (io && io != depca_io_ports[i].iobase)
                        continue;

                if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
                        continue;

                memset (pldev, 0, sizeof (*pldev));
                pldev->name = depca_string;
                pldev->id   = i;
                pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
                pldev->dev.release       = depca_platform_release;
                depca_io_ports[i].device = pldev;

                if (platform_device_register (pldev)) {
                        kfree (pldev);
                        depca_io_ports[i].device = NULL;
                        continue;
                }

                if (!pldev->dev.driver) {
                /* The driver was not bound to this device, there was
                 * no hardware at this address. Unregister it, as the
                 * release fuction will take care of freeing the
                 * allocated structure */

                        depca_io_ports[i].device = NULL;
===>                    platform_device_unregister (pldev);
                }
        }
}

void platform_device_unregister(struct platform_device * pdev)
{
        int i;

        if (pdev) {
                device_unregister(&pdev->dev);

                for (i = 0; i < pdev->num_resources; i++) {
                        struct resource *r = &pdev->resource[i];
===>                    if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO))
                                release_resource(r);
                }
        }
}

That if() corresponds to "testl  $0x300,0xc(%eax)" instruction in assembler.
%eax == 6b6b6b6b there at that moment (looks like poison). oops.

I verified that pdev->num_resources==0 upon entry to
platform_device_unregister().

device_unregister() must be deallocating *pdev, poisoning
its contents. pdev->num_resources!=0, and pdev->resource[i]
is garbage too.

However, I don't see where does it free *pdev.

Source of device_unregister() is below for easy reference.
--
vda

void device_unregister(struct device * dev)
{
        pr_debug("DEV: Unregistering device. ID = '%s'\n", dev->bus_id);
        device_del(dev);
        put_device(dev);
}

void device_del(struct device * dev)
{
        struct device * parent = dev->parent;

        down_write(&devices_subsys.rwsem);
        if (parent)
                list_del_init(&dev->node);
        up_write(&devices_subsys.rwsem);

        /* Notify the platform of the removal, in case they
         * need to do anything...
         */
        if (platform_notify_remove)
                platform_notify_remove(dev);
        bus_remove_device(dev);
        device_pm_remove(dev);
        kobject_del(&dev->kobj);
        if (parent)
                put_device(parent);
}


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-07-10 19:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-10 18:31 [OOPS] linux-2.6.7-bk20: possible use-after-free in platform_device_unregister() Denis Vlasenko
2004-07-10 19:49 ` Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox