[PATCH v4 06/10] staging: next: configfs: fix release link

Christian Gromm christian.gromm at microchip.com
Thu Jan 23 15:38:22 UTC 2020


The functions link_destroy and link_release are both deleting list items.
link_release, however, does not check whether a certain link has already
been deleted from the list by function link_destroy. By fixing this
this patch prevents a kernel crash when removing the configuration
directory of a link that already has been destroyed.

Signed-off-by: Christian Gromm <christian.gromm at microchip.com>
---
v4:
	This patch has been added to the series

 drivers/staging/most/configfs.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
index 9818f6c..982d1a1 100644
--- a/drivers/staging/most/configfs.c
+++ b/drivers/staging/most/configfs.c
@@ -127,6 +127,8 @@ static ssize_t mdev_link_create_link_store(struct config_item *item,
 		return ret;
 	list_add_tail(&mdev_link->list, &mdev_link_list);
 	mdev_link->create_link = tmp;
+	mdev_link->destroy_link = false;
+
 	return count;
 }
 
@@ -142,13 +144,16 @@ static ssize_t mdev_link_destroy_link_store(struct config_item *item,
 		return ret;
 	if (!tmp)
 		return count;
-	mdev_link->destroy_link = tmp;
+
 	ret = most_remove_link(mdev_link->device, mdev_link->channel,
 			       mdev_link->comp);
 	if (ret)
 		return ret;
 	if (!list_empty(&mdev_link_list))
 		list_del(&mdev_link->list);
+
+	mdev_link->destroy_link = tmp;
+
 	return count;
 }
 
@@ -377,13 +382,20 @@ static void mdev_link_release(struct config_item *item)
 	struct mdev_link *mdev_link = to_mdev_link(item);
 	int ret;
 
-	if (!list_empty(&mdev_link_list)) {
-		ret = most_remove_link(mdev_link->device, mdev_link->channel,
-				       mdev_link->comp);
-		if (ret && (ret != -ENODEV))
-			pr_err("Removing link failed.\n");
-		list_del(&mdev_link->list);
+	if (mdev_link->destroy_link)
+		goto free_item;
+
+	ret = most_remove_link(mdev_link->device, mdev_link->channel,
+			       mdev_link->comp);
+	if (ret) {
+		pr_err("Removing link failed.\n");
+		goto free_item;
 	}
+
+	if (!list_empty(&mdev_link_list))
+		list_del(&mdev_link->list);
+
+free_item:
 	kfree(to_mdev_link(item));
 }
 
-- 
2.7.4



More information about the devel mailing list