This is a note to let you know that I've just added the patch titled
mei: bus: need to unlink client before freeing
to my char-misc git tree which can be found at git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git in the char-misc-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From 34f1166afd67f9f48a08c52f36180048908506a4 Mon Sep 17 00:00:00 2001
From: Tomas Winkler tomas.winkler@intel.com Date: Mon, 27 Aug 2018 22:40:16 +0300 Subject: mei: bus: need to unlink client before freeing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit
In case a client fails to connect in mei_cldev_enable(), the caller won't call the mei_cldev_disable leaving the client in a linked stated. Upon driver unload the client structure will be freed in mei_cl_bus_dev_release(), leaving a stale pointer on a fail_list. This will eventually end up in crash during power down flow in mei_cl_set_disonnected().
RIP: mei_cl_set_disconnected+0x5/0x260[mei] Call trace: mei_cl_all_disconnect+0x22/0x30 mei_reset+0x194/0x250 __synchronize_hardirq+0x43/0x50 _cond_resched+0x15/0x30 mei_me_intr_clear+0x20/0x100 mei_stop+0x76/0xb0 mei_me_shutdown+0x3f/0x80 pci_device_shutdown+0x34/0x60 kernel_restart+0x0e/0x30
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200455 Fixes: 'c110cdb17148 ("mei: bus: make a client pointer always available")' Cc: stable@vger.kernel.org 4.10+ Tested-by: Georg Müller georgmueller@gmx.net Signed-off-by: Tomas Winkler tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/mei/bus.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 13c6c9a2248a..fc3872fe7b25 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -521,17 +521,15 @@ int mei_cldev_enable(struct mei_cl_device *cldev)
cl = cldev->cl;
+ mutex_lock(&bus->device_lock); if (cl->state == MEI_FILE_UNINITIALIZED) { - mutex_lock(&bus->device_lock); ret = mei_cl_link(cl); - mutex_unlock(&bus->device_lock); if (ret) - return ret; + goto out; /* update pointers */ cl->cldev = cldev; }
- mutex_lock(&bus->device_lock); if (mei_cl_is_connected(cl)) { ret = 0; goto out; @@ -875,12 +873,13 @@ static void mei_cl_bus_dev_release(struct device *dev)
mei_me_cl_put(cldev->me_cl); mei_dev_bus_put(cldev->bus); + mei_cl_unlink(cldev->cl); kfree(cldev->cl); kfree(cldev); }
static const struct device_type mei_cl_device_type = { - .release = mei_cl_bus_dev_release, + .release = mei_cl_bus_dev_release, };
/**
linux-stable-mirror@lists.linaro.org