staging: next: configfs: fix release link
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@microchip.com> Link: https://lore.kernel.org/r/1579793906-5054-7-git-send-email-christian.gromm@microchip.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b7935e52dd
commit
f9e6b51a99
@ -128,6 +128,8 @@ static ssize_t mdev_link_create_link_store(struct config_item *item,
|
|||||||
return ret;
|
return ret;
|
||||||
list_add_tail(&mdev_link->list, &mdev_link_list);
|
list_add_tail(&mdev_link->list, &mdev_link_list);
|
||||||
mdev_link->create_link = tmp;
|
mdev_link->create_link = tmp;
|
||||||
|
mdev_link->destroy_link = false;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,13 +145,16 @@ static ssize_t mdev_link_destroy_link_store(struct config_item *item,
|
|||||||
return ret;
|
return ret;
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return count;
|
return count;
|
||||||
mdev_link->destroy_link = tmp;
|
|
||||||
ret = most_remove_link(mdev_link->device, mdev_link->channel,
|
ret = most_remove_link(mdev_link->device, mdev_link->channel,
|
||||||
mdev_link->comp);
|
mdev_link->comp);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (!list_empty(&mdev_link_list))
|
if (!list_empty(&mdev_link_list))
|
||||||
list_del(&mdev_link->list);
|
list_del(&mdev_link->list);
|
||||||
|
|
||||||
|
mdev_link->destroy_link = tmp;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,13 +383,20 @@ static void mdev_link_release(struct config_item *item)
|
|||||||
struct mdev_link *mdev_link = to_mdev_link(item);
|
struct mdev_link *mdev_link = to_mdev_link(item);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!list_empty(&mdev_link_list)) {
|
if (mdev_link->destroy_link)
|
||||||
|
goto free_item;
|
||||||
|
|
||||||
ret = most_remove_link(mdev_link->device, mdev_link->channel,
|
ret = most_remove_link(mdev_link->device, mdev_link->channel,
|
||||||
mdev_link->comp);
|
mdev_link->comp);
|
||||||
if (ret && (ret != -ENODEV))
|
if (ret) {
|
||||||
pr_err("Removing link failed.\n");
|
pr_err("Removing link failed.\n");
|
||||||
list_del(&mdev_link->list);
|
goto free_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!list_empty(&mdev_link_list))
|
||||||
|
list_del(&mdev_link->list);
|
||||||
|
|
||||||
|
free_item:
|
||||||
kfree(to_mdev_link(item));
|
kfree(to_mdev_link(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user