From patchwork Tue Jul 4 13:54:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Steffen X-Patchwork-Id: 784028 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3x25xL0fWPz9s74 for ; Wed, 5 Jul 2017 00:29:42 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=sourceforge.net header.i=@sourceforge.net header.b="QD5ZJrHR"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=sf.net header.i=@sf.net header.b="SqrlQrbh"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=infineon.com header.i=@infineon.com header.b="DtYEB7Ub"; dkim-atps=neutral Received: from localhost ([127.0.0.1] helo=sfs-ml-1.v29.ch3.sourceforge.com) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1dSOpc-0002jJ-Ns; Tue, 04 Jul 2017 14:29:36 +0000 Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191] helo=mx.sourceforge.net) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1dSOpb-0002j3-BG for tpmdd-devel@lists.sourceforge.net; Tue, 04 Jul 2017 14:29:35 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=5Wp85UmCEC6n4uqwTAlt0XLCaePIPFGYyZaF68R2L2w=; b=QD5ZJrHR5dGcLIEt0KWhqHgCxlqtiSrrn3S8cpjVkukdGXxstCSGAv67QnqlqRA+Wl6I7CxIuiONleRgAvw5XBd07E1vX9jgEaNMe0bnvTs6g7F9QTa0geWx6n5U9PluKJg3Cb/11pjSjR9LZ1tfQ9rj9TI3EHwP3oVCR+Z9Gwk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x; h=Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=5Wp85UmCEC6n4uqwTAlt0XLCaePIPFGYyZaF68R2L2w=; b=SqrlQrbhLOMb4lXjzERiJqiYG3igpdwMpDkDZFkQ9mRM3AkDeudAwbIuKYazVIs4ywcXOeWwE/ZaVptTvM/S73i2amtD0CYMnz7XYNC+S45IijwKoDgEHF8iZRpH+tK8OCgvgdy+pdjFUuZaLkOUE2vGzMzLmOG6laJn/ciyBeE=; Received-SPF: pass (sog-mx-1.v43.ch3.sourceforge.com: domain of infineon.com designates 217.10.52.18 as permitted sender) client-ip=217.10.52.18; envelope-from=alexander.steffen@infineon.com; helo=smtp2.infineon.com; Received: from smtp2.infineon.com ([217.10.52.18]) by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1dSOpa-0005r2-5O for tpmdd-devel@lists.sourceforge.net; Tue, 04 Jul 2017 14:29:35 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=infineon.com; i=@infineon.com; q=dns/txt; s=IFXMAIL; t=1499178574; x=1530714574; h=from:to:cc:subject:date:message-id:mime-version; bh=uB2+fHSyhrmLI+NBk46DLpfZBfzmGK0c7XCJcfEKeLg=; b=DtYEB7UbeRWZzbkbZnu3QPBrGRWFkeaV16OxGXBwz+xsA0fR8Csm7Vmz eeyFSSdJ4SYwOLAjz7PX1imvRk/GrdnYRIMsOejDC8DokmQFP53qbkvlc X+oZE5xlWJPg4Hb8wxOquGxRaD4eCHNAN5drKn9i8XMtwqpbuW4Rfa5jk c=; X-SBRS: None Received: from unknown (HELO mucxv003.muc.infineon.com) ([172.23.11.20]) by smtp2.infineon.com with ESMTP/TLS/AES256-GCM-SHA384; 04 Jul 2017 15:54:47 +0200 Received: from MUCSE608.infineon.com (unknown [172.23.7.109]) by mucxv003.muc.infineon.com (Postfix) with ESMTPS; Tue, 4 Jul 2017 15:54:46 +0200 (CEST) Received: from MUCSE603.infineon.com (172.23.7.104) by MUCSE608.infineon.com (172.23.7.109) with Microsoft SMTP Server (TLS) id 15.0.1263.5; Tue, 4 Jul 2017 15:54:47 +0200 Received: from ABGN5CG4522MQD.eu.infineon.com (172.29.170.97) by MUCSE603.infineon.com (172.23.7.104) with Microsoft SMTP Server (TLS) id 15.0.1263.5; Tue, 4 Jul 2017 15:54:46 +0200 From: Alexander Steffen To: Date: Tue, 4 Jul 2017 15:54:18 +0200 Message-ID: <20170704135419.1692-1-Alexander.Steffen@infineon.com> X-Mailer: git-send-email 2.11.1.windows.1 MIME-Version: 1.0 X-Originating-IP: [172.29.170.97] X-ClientProxiedBy: MUCSE601.infineon.com (172.23.7.102) To MUCSE603.infineon.com (172.23.7.104) X-Spam-Score: -1.6 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1dSOpa-0005r2-5O Subject: [tpmdd-devel] [PATCH 1/2] tpm-dev-common: Reject too short writes X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stable@vger.kernel.org Errors-To: tpmdd-devel-bounces@lists.sourceforge.net tpm_common_write() in tpm-dev-common.c discards the information how much data has actually been written to the buffer. Instead, all other code has to rely on the commandSize field in the TPM command header to figure out how many valid bytes are supposed to be in the buffer. But there is nothing that enforces the value in the header to match the actual buffer contents. So by claiming a larger size in the header than has been written, stale buffer contents are sent to the TPM. With this commit, this problem is detected and rejected accordingly. This should have been fixed with CVE-2011-1161 long ago, but apparently a correct version of that patch never made it into the kernel. Cc: stable@vger.kernel.org Signed-off-by: Alexander Steffen --- drivers/char/tpm/tpm-dev-common.c | 2 +- drivers/char/tpm/tpm-interface.c | 9 ++++++--- drivers/char/tpm/tpm.h | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c index 610638a..c39b581 100644 --- a/drivers/char/tpm/tpm-dev-common.c +++ b/drivers/char/tpm/tpm-dev-common.c @@ -119,7 +119,7 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf, return -EPIPE; } out_size = tpm_transmit(priv->chip, space, priv->data_buffer, - sizeof(priv->data_buffer), 0); + sizeof(priv->data_buffer), in_size, 0); tpm_put_ops(priv->chip); if (out_size < 0) { diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 3123a6e..a452cd0 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -375,6 +375,7 @@ static bool tpm_validate_command(struct tpm_chip *chip, * @chip: TPM chip to use * @buf: TPM command buffer * @bufsiz: length of the TPM command buffer + * @bufvalid: number of valid bytes in the TPM command buffer * @flags: tpm transmit flags - bitmap * * Return: @@ -382,7 +383,8 @@ static bool tpm_validate_command(struct tpm_chip *chip, * A negative number for system errors (errno). */ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, - u8 *buf, size_t bufsiz, unsigned int flags) + u8 *buf, size_t bufsiz, size_t bufvalid, + unsigned int flags) { struct tpm_output_header *header = (void *)buf; int rc; @@ -401,7 +403,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); if (count == 0) return -ENODATA; - if (count > bufsiz) { + if (count > bufsiz || count > bufvalid) { dev_err(&chip->dev, "invalid count value %x %zx\n", count, bufsiz); return -E2BIG; @@ -522,7 +524,8 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, int err; ssize_t len; - len = tpm_transmit(chip, space, (u8 *)buf, bufsiz, flags); + len = tpm_transmit(chip, space, (u8 *)buf, bufsiz, + be32_to_cpu(header->length), flags); if (len < 0) return len; diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 71d661a..116f2b8 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -509,7 +509,8 @@ enum tpm_transmit_flags { }; ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, - u8 *buf, size_t bufsiz, unsigned int flags); + u8 *buf, size_t bufsiz, size_t bufvalid, + unsigned int flags); ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, const void *buf, size_t bufsiz, size_t min_rsp_body_length, unsigned int flags,