From bb5eeccef38bcbcc156d6be3c5870a91d3941d4b Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Wed, 8 May 2013 11:22:31 -0500 Subject: [PATCH] dahdi: Prevent memory corruption on device unload. The channels now have embedded 'struct devices' that contain a device_private pointer in which to store the device private data. When a device is unregistered in the system the device privata data is freed by the device core, even though the chan_release function doesn't free the memory associated with the device, So when dev_set_drvdata() is called, it's writing into freed memory. We also need zero out the embedded struct device before registration, since we do not have any guarantee that it points to valid memory (or, if a channel was unregisterd with sysfs, and then reregistered without being cleared out). Otherwise the core could try to use the previously freed private data again. Signed-off-by: Shaun Ruffell Signed-off-by: Russ Meyerriecks --- drivers/dahdi/dahdi-sysfs-chan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dahdi/dahdi-sysfs-chan.c b/drivers/dahdi/dahdi-sysfs-chan.c index f6fe7de..b77e186 100644 --- a/drivers/dahdi/dahdi-sysfs-chan.c +++ b/drivers/dahdi/dahdi-sysfs-chan.c @@ -240,6 +240,7 @@ int chan_sysfs_create(struct dahdi_chan *chan) span = chan->span; devt = MKDEV(MAJOR(dahdi_channels_devt), chan->channo); dev = &chan->chan_device; + memset(dev, 0, sizeof(*dev)); dev->devt = devt; dev->bus = &chan_bus_type; dev->parent = span->span_device; @@ -253,7 +254,7 @@ int chan_sysfs_create(struct dahdi_chan *chan) if (res) { chan_err(chan, "%s: device_register failed: %d\n", __func__, res); - dev_set_drvdata(dev, NULL); + put_device(dev); return res; } set_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags); @@ -272,7 +273,6 @@ void chan_sysfs_remove(struct dahdi_chan *chan) dev = &chan->chan_device; BUG_ON(dev_get_drvdata(dev) != chan); device_unregister(dev); - dev_set_drvdata(dev, NULL); /* FIXME: should have been done earlier in dahdi_chan_unreg */ chan->channo = -1; clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);