From ff477d073f2e71a1fa59f86cb44bd9d48674a71b Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 4 Sep 2015 16:53:31 +0100 Subject: [PATCH] greybus: loopback: make sure to list_del on connection_exit gb_loopback_connection_exit does a kfree on a data structure associated with a loopback connection but fails to do a corresponding list_del(). On subsequent enumerations this can lead to a NULL pointer dereference. Each list_add in gb_loopback_connection_init() must have a corresponding list_del in gb_loopback_connection_exit(), this patch adds the relevant list_del() and ensures that an appropriate mutex protecting gb_dev.list is held while doing so. Signed-off-by: Bryan O'Donoghue Reported-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/loopback.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index 8dd648cc0796..231d1d4c1104 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -944,18 +944,23 @@ static void gb_loopback_connection_exit(struct gb_connection *connection) struct gb_loopback *gb = connection->private; struct kobject *kobj = &connection->bundle->intf->module->dev.kobj; - gb_dev.count--; - connection->private = NULL; if (!IS_ERR_OR_NULL(gb->task)) kthread_stop(gb->task); + mutex_lock(&gb_dev.mutex); + + connection->private = NULL; kfifo_free(&gb->kfifo_lat); kfifo_free(&gb->kfifo_ts); if (!gb_dev.count) sysfs_remove_groups(kobj, loopback_dev_groups); sysfs_remove_groups(&connection->dev.kobj, loopback_con_groups); debugfs_remove(gb->file); + list_del(&gb->entry); kfree(gb); + gb_dev.count--; + + mutex_unlock(&gb_dev.mutex); } static struct gb_protocol loopback_protocol = { -- 2.20.1