From patchwork Tue Nov 22 12:40:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabio Urquiza X-Patchwork-Id: 9441037 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7148C600BA for ; Tue, 22 Nov 2016 13:01:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 614CC284C4 for ; Tue, 22 Nov 2016 13:01:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 537D628527; Tue, 22 Nov 2016 13:01:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.4 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 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 mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 70171284C4 for ; Tue, 22 Nov 2016 13:01:36 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=sfs-ml-4.v29.ch3.sourceforge.com) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1c9Aha-00009C-ER; Tue, 22 Nov 2016 13:01:34 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1c9AhZ-000097-5c for tpmdd-devel@lists.sourceforge.net; Tue, 22 Nov 2016 13:01:33 +0000 Received-SPF: pass (sog-mx-4.v43.ch3.sourceforge.com: domain of cesar.org.br designates 209.85.220.178 as permitted sender) client-ip=209.85.220.178; envelope-from=flus@cesar.org.br; helo=mail-qk0-f178.google.com; Received: from mail-qk0-f178.google.com ([209.85.220.178]) by sog-mx-4.v43.ch3.sourceforge.com with esmtps (TLSv1:AES128-SHA:128) (Exim 4.76) id 1c9AhT-00050W-HH for tpmdd-devel@lists.sourceforge.net; Tue, 22 Nov 2016 13:01:33 +0000 Received: by mail-qk0-f178.google.com with SMTP id x190so22331396qkb.0 for ; Tue, 22 Nov 2016 05:01:27 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=bltEYSpNtkVIrq7ifHGM8YY4hdzEbAAutULhy5+Gpr0=; b=G6owJqMTtDrPBOC9RO3Z46p0KCvQfBViSGDC9sHWTH4vNRX4MWDbtW3tqGj0SFZNnh IVlRhTeepr73hac5RpR09QqAW1s/6u0/T/36A7cBLr0RC17YRltsCugtSxDiPOa42j5g Z14QKN9EN+cSRX9v7pKcyqh8l/pV64NFzuFSPU0nhulW/vw88oeh7fen//+Onm7WqSlb fPGcRj7qCEVkzvtkhUDeB9AIp+McpP0WLyAsxUoMcY4RMSc+sI/olhh80+8k4gKK2dR8 G0jQVEPia59OO6nVMJ7+dZXMTQgrYGyIlL4vtTvqMN0LrJdrOgunXSko9wm8GfRMJw4g 2GnQ== X-Gm-Message-State: AKaTC00fuHHEURvbvDeyI17EzYQ1YLmUrJUZVdKpkFPTtLKv+KC/OhLnbEUSse6C8kJgY7zz X-Received: by 10.55.155.7 with SMTP id d7mr24665186qke.81.1479818431443; Tue, 22 Nov 2016 04:40:31 -0800 (PST) Received: from ubuntu.rce.tvgvt ([177.133.125.149]) by smtp.gmail.com with ESMTPSA id b94sm13610904qkb.16.2016.11.22.04.40.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Nov 2016 04:40:31 -0800 (PST) From: Fabio Urquiza To: tpmdd-devel@lists.sourceforge.net Date: Tue, 22 Nov 2016 09:40:07 -0300 Message-Id: <20161122124007.16487-1-flus@cesar.org.br> X-Mailer: git-send-email 2.9.3 X-Headers-End: 1c9AhT-00050W-HH Subject: [tpmdd-devel] [PATCH] tpm_i2c_atmel: fix i2c_atmel_recv() when response is greater than 35 bytes X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: tpmdd-devel-bounces@lists.sourceforge.net X-Virus-Scanned: ClamAV using ClamSMTP If the variable expected_len is greater than 35 bytes, i2c_atmel_recv() ignores the amount of data already read in i2c_atmel_read_status() and request more data than what the device is ready to supply. As result the TPM data sent to the upper layers will miss the first 35 bytes of the response and will be filled with garbage in the end. TCSP_GetRandom_Internal before fix: tpm_i2c_atmel 0-0020: i2c_atmel_send(buf=00 c1 00 00 00 0e 00 00 00 46 00 00 00 20 len=e) -> sts=14 tpm_i2c_atmel 0-0020: i2c_atmel_read_status: sts=-6 tpm_i2c_atmel 0-0020: i2c_atmel_read_status: sts=35 tpm_i2c_atmel 0-0020: i2c_atmel_recv reread(buf=3b ec a5 17 37 27 2a fb a0 cc ce ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff count=1000) -> ret=46 TCSP_GetRandom_Internal after fix: tpm_i2c_atmel 0-0020: i2c_atmel_send(buf=00 c1 00 00 00 0e 00 00 00 46 00 00 00 20 len=e) -> sts=14 tpm_i2c_atmel 0-0020: i2c_atmel_read_status: sts=-6 tpm_i2c_atmel 0-0020: i2c_atmel_read_status: sts=35 tpm_i2c_atmel 0-0020: i2c_atmel_recv reread(buf=00 c4 00 00 00 2e 00 00 00 00 00 00 00 20 63 dc 83 a1 55 e6 b4 5d 5a 10 70 63 28 5c 5b a8 87 ca 57 fd 45 c3 a0 62 1b c2 1d b3 d2 0d 8f 19 count=1000) -> ret=46 Signed-off-by: Fabio Urquiza --- drivers/char/tpm/tpm_i2c_atmel.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index 95ce2e9..a02f5a7 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c @@ -75,9 +75,9 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count) struct tpm_output_header *hdr = (struct tpm_output_header *)priv->buffer; u32 expected_len; - int rc; + int rc = priv->len; - if (priv->len == 0) + if (rc == 0) return -EIO; /* Get the message size from the message header, if we didn't get the @@ -87,7 +87,7 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count) if (expected_len > count) return -ENOMEM; - if (priv->len >= expected_len) { + if (rc >= expected_len) { dev_dbg(&chip->dev, "%s early(buf=%*ph count=%0zx) -> ret=%d\n", __func__, (int)min_t(size_t, 64, expected_len), buf, count, @@ -96,7 +96,8 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count) return expected_len; } - rc = i2c_master_recv(client, buf, expected_len); + memcpy(buf, priv->buffer, rc); + rc += i2c_master_recv(client, buf + rc, expected_len - rc); dev_dbg(&chip->dev, "%s reread(buf=%*ph count=%0zx) -> ret=%d\n", __func__, (int)min_t(size_t, 64, expected_len), buf, count,