lkml.org 
[lkml]   [2018]   [Sep]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.18 119/235] mei: bus: need to unlink client before freeing
    Date
    4.18-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Tomas Winkler <tomas.winkler@intel.com>

    commit 34f1166afd67f9f48a08c52f36180048908506a4 upstream.

    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(-)

    --- a/drivers/misc/mei/bus.c
    +++ b/drivers/misc/mei/bus.c
    @@ -505,17 +505,15 @@ int mei_cldev_enable(struct mei_cl_devic

    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;
    @@ -859,12 +857,13 @@ static void mei_cl_bus_dev_release(struc

    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,
    };

    /**

    \
     
     \ /
      Last update: 2018-09-24 14:35    [W:4.148 / U:0.212 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site