Skip to content

Commit

Permalink
iio: core: Fix double free.
Browse files Browse the repository at this point in the history
When an error occurred during event registration memory was freed twice
resulting in kernel memory corruption and a crash in unrelated code.

The problem was caused by
	iio_device_unregister_eventset()
	iio_device_unregister_sysfs()

being called twice, once on the error path and then
again via iio_dev_release().

Fix this by making these two functions idempotent so they
may be called multiple times.

The problem was observed before applying
	78b3321 iio:core: Handle error when mask type is not separate

Signed-off-by: Martin Fuzzey <mfuzzey@parkeon.com>
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
  • Loading branch information
Martin Fuzzey authored and Jonathan Cameron committed Mar 14, 2015
1 parent af5e1a6 commit c1b03ab
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 2 deletions.
5 changes: 3 additions & 2 deletions drivers/iio/industrialio-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,15 +847,15 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
* @attr_list: List of IIO device attributes
*
* This function frees the memory allocated for each of the IIO device
* attributes in the list. Note: if you want to reuse the list after calling
* this function you have to reinitialize it using INIT_LIST_HEAD().
* attributes in the list.
*/
void iio_free_chan_devattr_list(struct list_head *attr_list)
{
struct iio_dev_attr *p, *n;

list_for_each_entry_safe(p, n, attr_list, l) {
kfree(p->dev_attr.attr.name);
list_del(&p->l);
kfree(p);
}
}
Expand Down Expand Up @@ -936,6 +936,7 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev)

iio_free_chan_devattr_list(&indio_dev->channel_attr_list);
kfree(indio_dev->chan_attr_group.attrs);
indio_dev->chan_attr_group.attrs = NULL;
}

static void iio_dev_release(struct device *device)
Expand Down
1 change: 1 addition & 0 deletions drivers/iio/industrialio-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
error_free_setup_event_lines:
iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list);
kfree(indio_dev->event_interface);
indio_dev->event_interface = NULL;
return ret;
}

Expand Down

0 comments on commit c1b03ab

Please sign in to comment.