Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp895154yba; Thu, 18 Apr 2019 11:21:55 -0700 (PDT) X-Google-Smtp-Source: APXvYqxIjyBY5XSjzHfEdKbXxSancQk1Fe1jfAr5R3hkdXIuC8s9k508lStNEANtpNjpDjFoHdj7 X-Received: by 2002:a63:c749:: with SMTP id v9mr6992382pgg.432.1555611715451; Thu, 18 Apr 2019 11:21:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555611715; cv=none; d=google.com; s=arc-20160816; b=sY4hAY8qZDgBMXVKoONl3A71mBSsaescRGsym/nk//STvRE22Ycl8im1IKPdYiBquq rtsCnqnb6mQOrCz9sA5CmmjYB16G4QTwKwNU7qw4cVmyQPbZq23nk2UuzlSdcXRFM1pV L7yGDklJ3yDFQBN7d6fAR9g9CdgpHCVJ8+A+CyQcGYff8yt2XIi9Y264+xXZZyyNBjvT DaX6145HFxx8ECWZx/h0Kkez3iBFUNjYRwYzTPoK8A/9pUOjUbBLyhqsyzXDxUkJMj5h MvTEUtiOORtXinVXtUAQf0+ksttbals+hYp8uQBEpUHoAb0c2rcqbwl4hpb8tzBccwR8 Abyw== 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=9XEb3r5Om+1H49NuGqQZMYdiO2zNQRb2zQsbaEdES8M=; b=fu8gUfd3Iiy/EAx5tn9imgGKI3yjPsXltVhm/S/mcRwUrtT2PcA2H5S1V+cBPXowZg ULhm6B2XKV0m2RkquKxqrGlOAEY3Nxl1WspKBc2CfieWDHFeIl+8H3CV0OoLYbxnSeeV 9Swp2xFRY8UDl8L/3nE/E8pRFDuCUtUHTJ9SWiSoTCecuLDrpuDhNLVTSVOv+nN+DEBz BpHkHcqY+d38+jGGr7Rx3YYZj3GsxL6z+K20TisKG81YZfwbbYe0YJOSCnhckDbi+Tiz wt40Qf5BqObzUPetuSZxdmdx/kbR0I6BpKuUMgsdeqtZAI0C1fHA2GkE/x/xbz+eNTYK tkNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=hJX3jUYo; 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 r75si3012690pfa.10.2019.04.18.11.21.40; Thu, 18 Apr 2019 11:21:55 -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=hJX3jUYo; 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 S2391821AbfDRSJB (ORCPT + 99 others); Thu, 18 Apr 2019 14:09:01 -0400 Received: from mail.kernel.org ([198.145.29.99]:40436 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391339AbfDRSJA (ORCPT ); Thu, 18 Apr 2019 14:09:00 -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 5CA712186A; Thu, 18 Apr 2019 18:08:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555610938; bh=mQ2b/31a81MGavEgJgBk0I+S/AhGwY0H5szIEEgdydk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hJX3jUYoRg3ESuPOI5NGzjLm/5+QaZFKB0eSUlG/PkK2BSg77HfbqSO66/vHO7Sba xO5pELTAkkGwC3QmeZF1uo0TE/WITOj9ho78N1aBh+Ll0UqduzRNwh0koLHsc5C3cg t1mWqPOHmXlbYExA6gSJubxKBahzbtCWnK5CCwng= 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 , "Sasha Levin (Microsoft)" Subject: [PATCH 4.9 48/50] tpm/tpm_crb: Avoid unaligned reads in crb_recv() Date: Thu, 18 Apr 2019 19:57:59 +0200 Message-Id: <20190418160428.166924413@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190418160422.455656724@linuxfoundation.org> References: <20190418160422.455656724@linuxfoundation.org> User-Agent: quilt/0.66 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 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: Sasha Levin (Microsoft) --- 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 fa0f66809503..d29f78441cdb 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -102,19 +102,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 + * unrecoverable condition. + */ if (ioread32(&priv->cca->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; } -- 2.19.1