Received: by 2002:ac0:8c9a:0:0:0:0:0 with SMTP id r26csp3873736ima; Mon, 4 Feb 2019 06:38:37 -0800 (PST) X-Google-Smtp-Source: ALg8bN5ylDI46MFat1D+rAEvq5yU3IzmkFIaB7HCQv/CW84we1QZTwCBgHXpyiTS77iWvbUmlCuE X-Received: by 2002:a62:ed0f:: with SMTP id u15mr50290213pfh.188.1549291117542; Mon, 04 Feb 2019 06:38:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549291117; cv=none; d=google.com; s=arc-20160816; b=uj5vZkG7wkNWNfyYijeHypA28FgzJ66YtF1mpRTHa7BjvXFKQKLWoDafndb1YLFOt1 fS38Ccm4zIj1KOS38tOcUD/raH1ckepITzZBT1sVZmVemcasAHnthXhA0OjBtuLFIQ80 U8WB3o0AjAyYeSROOa42e+og4QlCbiQyvM/acD25czrXqvD8VRZr0yHrUU0U1rlcLFMP piprnbUupeZxdYyOHCq+T5g1oYNn/6STpZ1XCPi9sP5AFBzuTVqnMMQ9WQ24iZbDN96X apJqxQKkcEDLzPGMD1O675dxeou/aXmEB8VfKnQsMqEPJDWMrIHmruYpFtilakpbPHA7 ZBow== 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 :message-id:date:subject:cc:to:from; bh=BFDp+vdKhaAxE+a+5WBnHfCVZJiz8lx5qoe6OJOSQMQ=; b=iWfO+OEc23HxeSFZizlW5Ftk5RCX4rfc93IOUcnsgb2oUCOFa2GeRisC0BicYMAUn5 UF01zcmOO5numRGnyZ1FaPZwtgyLBz2UV3EAfuh1MQGAFTwI4kgaegTK7rqMNL4NDckw Bcyol5NDjOIrF3nN6TtaMRJ6Xrx7GCzgjdgqobYZmANrCUNdX/X7OVudfkfrN9JMoF8z 0i8parMSZStkXNQovU0QJiQHVwVpMnSW7d6yaD7WTWSGiWzCcvtfULCplJ560R4F6VY+ tOJ3cSV+vLMauWOIxIhEt/ls/JA4Kczx6sTAltcQP9VPq9T6d5j8chCwU4uikmVS9Hwg hnFA== ARC-Authentication-Results: i=1; mx.google.com; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n2si176997pgr.67.2019.02.04.06.38.21; Mon, 04 Feb 2019 06:38:37 -0800 (PST) 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; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730629AbfBDN7t (ORCPT + 99 others); Mon, 4 Feb 2019 08:59:49 -0500 Received: from mga06.intel.com ([134.134.136.31]:10826 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728298AbfBDN7s (ORCPT ); Mon, 4 Feb 2019 08:59:48 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Feb 2019 05:59:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,560,1539673200"; d="scan'208";a="112267954" Received: from jsakkine-mobl1.tm.intel.com (HELO localhost) ([10.237.50.172]) by orsmga007.jf.intel.com with ESMTP; 04 Feb 2019 05:59:45 -0800 From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, Jarkko Sakkinen , stable@vger.kernel.org, James Morris , Tomas Winkler , Jerry Snitselaar Subject: [PATCH v2] tpm/tpm_crb: Avoid unaligned reads in crb_recv() Date: Mon, 4 Feb 2019 15:59:43 +0200 Message-Id: <20190204135943.15756-1-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- v2: * There was a trailing double colon in the end of the short summary. * Check requested and expected length against TPM_HEADER_SIZE. * Add some explanatory comments to crb_recv(). drivers/char/tpm/tpm_crb.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 36952ef98f90..c084e61299aa 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -287,19 +287,29 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count) 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 unrecovable + * 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 8 bytes (not just 6 bytes, which would cover the response length + * field) in order to make sure that the reminding memory accesses 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; } -- 2.19.1