From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751761AbcDQJR1 (ORCPT ); Sun, 17 Apr 2016 05:17:27 -0400 Received: from mga14.intel.com ([192.55.52.115]:61646 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751668AbcDQJRY (ORCPT ); Sun, 17 Apr 2016 05:17:24 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,496,1455004800"; d="scan'208";a="960386496" From: Tomas Winkler To: Greg Kroah-Hartman Cc: Alexander Usyskin , linux-kernel@vger.kernel.org, , Tomas Winkler Subject: [char-misc-next 2/3] mei: fix NULL dereferencing during FW initiated disconnection Date: Sun, 17 Apr 2016 12:16:03 -0400 Message-Id: <1460909764-7983-2-git-send-email-tomas.winkler@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1460909764-7983-1-git-send-email-tomas.winkler@intel.com> References: <1460909764-7983-1-git-send-email-tomas.winkler@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alexander Usyskin In the case when disconnection is initiated from the FW the driver is flushing items from the write control list while iterating over it: mei_irq_write_handler() list_for_each_entry_safe(ctrl_wr_list) <-- outer loop mei_cl_irq_disconnect_rsp() mei_cl_set_disconnected() mei_io_list_flush(ctrl_wr_list) <-- destorying list We move the list flushing to the completion routine. Cc: #4.2+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler --- drivers/misc/mei/client.c | 4 ++++ drivers/misc/mei/hbm.c | 3 +-- drivers/misc/mei/interrupt.c | 5 +---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index bab17e4197b6..09f5280fa021 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1767,6 +1767,10 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) wake_up(&cl->wait); break; + case MEI_FOP_DISCONNECT_RSP: + mei_io_cb_free(cb); + mei_cl_set_disconnected(cl); + break; default: BUG_ON(0); } diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 5eaa4638e824..5aa606c8a827 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -877,8 +877,7 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev, cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT_RSP, NULL); if (!cb) return -ENOMEM; - cl_dbg(dev, cl, "add disconnect response as first\n"); - list_add(&cb->list, &dev->ctrl_wr_list.list); + list_add_tail(&cb->list, &dev->ctrl_wr_list.list); } return 0; } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 1e5cb1f704f8..704dc6caad6d 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -194,10 +194,7 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, return -EMSGSIZE; ret = mei_hbm_cl_disconnect_rsp(dev, cl); - mei_cl_set_disconnected(cl); - mei_io_cb_free(cb); - mei_me_cl_put(cl->me_cl); - cl->me_cl = NULL; + list_move_tail(&cb->list, &cmpl_list->list); return ret; } -- 2.5.5