From patchwork Thu May 21 15:25:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 11563335 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9DB9A739 for ; Thu, 21 May 2020 15:26:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7AB8F207D8 for ; Thu, 21 May 2020 15:26:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1590074775; bh=jHhhgwwpysg3wUnqnfQpkJN4YsEugW4Huv4OE1HIiWE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=hdxRNzQmn5ved7TIYk7TpcaXrEJQrQIJ2Y7Uf3hiFqHX91MoLsp9P0b9vA4Qs0uol DScnfwgGaxycL+5NORmaDQl3FG8uGY8LZVxTUIGBrcTtn2to5WuaddmotKPR+Ld+ro JXp8fcGJqxwGkVbUEI6UbRxLVnB+zKAMz/Z51wdQ= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730093AbgEUP0O (ORCPT ); Thu, 21 May 2020 11:26:14 -0400 Received: from mail.kernel.org ([198.145.29.99]:34258 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730456AbgEUP0M (ORCPT ); Thu, 21 May 2020 11:26:12 -0400 Received: from localhost.localdomain (unknown [157.51.235.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5BEB4207D8; Thu, 21 May 2020 15:26:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1590074772; bh=jHhhgwwpysg3wUnqnfQpkJN4YsEugW4Huv4OE1HIiWE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LNGKNcaI4mjZxJ8+7JLEzVvnzAmYjpxHPyWA0iiHvCfcZFDU4HlW9AbQ1quizfVbR 426vERFb+GHQKQMTh0skSx98/dscQhmlJZG7zyaE4VHDz1uji37VW8TJ2hhrleqrdN NLdaAmYpApcSOm9QhUBOALichnYcoFXXUSvfzmYU= From: mani@kernel.org To: gregkh@linuxfoundation.org Cc: hemantk@codeaurora.org, jhugo@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Bhaumik Bhatt , Manivannan Sadhasivam Subject: [PATCH 04/14] bus: mhi: core: Read transfer length from an event properly Date: Thu, 21 May 2020 20:55:30 +0530 Message-Id: <20200521152540.17335-5-mani@kernel.org> X-Mailer: git-send-email 2.26.GIT In-Reply-To: <20200521152540.17335-1-mani@kernel.org> References: <20200521152540.17335-1-mani@kernel.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Hemant Kumar When MHI Driver receives an EOT event, it reads xfer_len from the event in the last TRE. The value is under control of the MHI device and never validated by Host MHI driver. The value should never be larger than the real size of the buffer but a malicious device can set the value 0xFFFF as maximum. This causes driver to memory overflow (both read or write). Fix this issue by reading minimum of transfer length from event and the buffer length provided. Signed-off-by: Hemant Kumar Signed-off-by: Bhaumik Bhatt Reviewed-by: Jeffrey Hugo Reviewed-by: Manivannan Sadhasivam Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/core/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c index 64022865cb75..a394691d9383 100644 --- a/drivers/bus/mhi/core/main.c +++ b/drivers/bus/mhi/core/main.c @@ -513,7 +513,10 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, mhi_cntrl->unmap_single(mhi_cntrl, buf_info); result.buf_addr = buf_info->cb_buf; - result.bytes_xferd = xfer_len; + + /* truncate to buf len if xfer_len is larger */ + result.bytes_xferd = + min_t(u16, xfer_len, buf_info->len); mhi_del_ring_element(mhi_cntrl, buf_ring); mhi_del_ring_element(mhi_cntrl, tre_ring); local_rp = tre_ring->rp; @@ -597,7 +600,9 @@ static int parse_rsc_event(struct mhi_controller *mhi_cntrl, result.transaction_status = (ev_code == MHI_EV_CC_OVERFLOW) ? -EOVERFLOW : 0; - result.bytes_xferd = xfer_len; + + /* truncate to buf len if xfer_len is larger */ + result.bytes_xferd = min_t(u16, xfer_len, buf_info->len); result.buf_addr = buf_info->cb_buf; result.dir = mhi_chan->dir;