Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp599851img; Fri, 22 Mar 2019 04:55:44 -0700 (PDT) X-Google-Smtp-Source: APXvYqzh92VC1Ut/XFNOT9infeFne8Z+/0J3g+bcpdBIXx1e9HxW5VB8c2iXCmewyCWNhaHohcB0 X-Received: by 2002:a63:d444:: with SMTP id i4mr8598371pgj.149.1553255744260; Fri, 22 Mar 2019 04:55:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553255744; cv=none; d=google.com; s=arc-20160816; b=fYRPHOrC9V3HpeJdEEZmD882oFi2oNiRNN/F1hHsxkJGGOJoz2nJBqEATEyH7pISLf t8ZnmOktYkWJJsmm87XUHFvuRGn6X6UZhaIEnY7JmS9qTev41kQRgPckKa86XpwvM2YZ JsYBhkKHkqSwJ8hykhqnOwaZ/kkILPfqZFIPqsm526DA+JUDdjpLczOfLkckLenytQJE c02Y/GJZ3ZDLLJa20yUWym7CTqeW3czPaRDCxLlkysqOpQwd+muFIDbBWABVxqEyOS/0 PKq9hKgQWNCjVhuPuNDIicLT5eS0RIq1uyh0HdhmrCuD+bnMCz3bYJceduqVUEtkURpa O7Hw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=4H89t8g9uK09R5CnTNbmp2h2YUMfix/JB0RFnLykt2s=; b=ynNviHOG2EWNe+SIaGDLNmbvMa0C7loSo1IQBnnlU3Ro7D8DWtWehiJrOKgvGtSnz3 1M/Mm3+r7SrSgNKlP7JfaDwMc4Ollc3IiC0tcez6wiEjEaPMKLx4aOeYLKBln1XYSngi XrpzCH9R0HSRkwAY1icBsr1fBbyABcbBoL3pYWZD60FMHVzVeCK2wzdS0Exro29yUkoL VwnAgacNr9TiBpRD4CTqeVQUApPlB4I2d5XNJROBg7HtXXdqrJvXHYBqyb+/gIJ1rtZH 2JJ21SXb7JbCByvdtcrubav2Pdx7AjxwmrzZj/Tx6IXFbtJQAjM908OHgNmn2jB3Cb27 SUfg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=R7OTMbKi; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bg1si6758381plb.118.2019.03.22.04.55.29; Fri, 22 Mar 2019 04:55:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=R7OTMbKi; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733219AbfCVLyx (ORCPT + 99 others); Fri, 22 Mar 2019 07:54:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:59366 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732725AbfCVLyt (ORCPT ); Fri, 22 Mar 2019 07:54:49 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 4A3E62192B; Fri, 22 Mar 2019 11:54:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1553255688; bh=qwV1H9GlxX4/W8hiEqdbYRzOcH9r99BXRC8tI1KBc6w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R7OTMbKi+rbUS+6QnEGk2OjcQf5ttqUsC3kmeIbXbvHbVB4qT4RU3iChkwMqHX9+1 /P61ab+0c60M6zwfovQv/hmkc/O/UZ/3rfX+ks7eCw1/FQPFwErixL0aCszUcza/1z VMOVQU4VWlLdqlMcBPe6WkUtbasyh0tINUMackE0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, James Morris , Tomas Winkler , Jerry Snitselaar , Jarkko Sakkinen Subject: [PATCH 4.14 168/183] tpm/tpm_crb: Avoid unaligned reads in crb_recv() Date: Fri, 22 Mar 2019 12:16:36 +0100 Message-Id: <20190322111254.068617618@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190322111241.819468003@linuxfoundation.org> References: <20190322111241.819468003@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jarkko Sakkinen commit 3d7a850fdc1a2e4d2adbc95cc0fc962974725e88 upstream. The current approach to read first 6 bytes from the response and then tail of the response, can cause the 2nd memcpy_fromio() to do an unaligned read (e.g. read 32-bit word from address aligned to a 16-bits), depending on how memcpy_fromio() is implemented. If this happens, the read will fail and the memory controller will fill the read with 1's. This was triggered by 170d13ca3a2f, which should be probably refined to check and react to the address alignment. Before that commit, on x86 memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right thing (from tpm_crb's perspective) for us so far, but we should not rely on that. Thus, it makes sense to fix this also in tpm_crb, not least because the fix can be then backported to stable kernels and make them more robust when compiled in differing environments. Cc: stable@vger.kernel.org Cc: James Morris Cc: Tomas Winkler Cc: Jerry Snitselaar Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface") Signed-off-by: Jarkko Sakkinen Reviewed-by: Jerry Snitselaar Acked-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm_crb.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -288,19 +288,29 @@ static int crb_recv(struct tpm_chip *chi struct crb_priv *priv = dev_get_drvdata(&chip->dev); unsigned int expected; - /* sanity check */ - if (count < 6) + /* A sanity check that the upper layer wants to get at least the header + * as that is the minimum size for any TPM response. + */ + if (count < TPM_HEADER_SIZE) return -EIO; + /* If this bit is set, according to the spec, the TPM is in + * unrecoverable condition. + */ if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR) return -EIO; - memcpy_fromio(buf, priv->rsp, 6); - expected = be32_to_cpup((__be32 *) &buf[2]); - if (expected > count || expected < 6) + /* Read the first 8 bytes in order to get the length of the response. + * We read exactly a quad word in order to make sure that the remaining + * reads will be aligned. + */ + memcpy_fromio(buf, priv->rsp, 8); + + expected = be32_to_cpup((__be32 *)&buf[2]); + if (expected > count || expected < TPM_HEADER_SIZE) return -EIO; - memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6); + memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8); return expected; }