f9334ff
From patchwork Wed Sep 25 17:27:05 2019
f9334ff
Content-Type: text/plain; charset="utf-8"
f9334ff
MIME-Version: 1.0
f9334ff
Content-Transfer-Encoding: 7bit
f9334ff
X-Patchwork-Submitter: Jerry Snitselaar <jsnitsel@redhat.com>
f9334ff
X-Patchwork-Id: 11161161
f9334ff
Return-Path: <SRS0=gTbe=XU=vger.kernel.org=linux-integrity-owner@kernel.org>
f9334ff
Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
f9334ff
 [172.30.200.123])
f9334ff
	by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 88B8A1747
f9334ff
	for <patchwork-linux-integrity@patchwork.kernel.org>;
f9334ff
 Wed, 25 Sep 2019 17:27:13 +0000 (UTC)
f9334ff
Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
f9334ff
	by mail.kernel.org (Postfix) with ESMTP id 66F4F217F4
f9334ff
	for <patchwork-linux-integrity@patchwork.kernel.org>;
f9334ff
 Wed, 25 Sep 2019 17:27:13 +0000 (UTC)
f9334ff
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
f9334ff
        id S2505171AbfIYR1J (ORCPT
f9334ff
        <rfc822;patchwork-linux-integrity@patchwork.kernel.org>);
f9334ff
        Wed, 25 Sep 2019 13:27:09 -0400
f9334ff
Received: from mx1.redhat.com ([209.132.183.28]:41496 "EHLO mx1.redhat.com"
f9334ff
        rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
f9334ff
        id S2505170AbfIYR1J (ORCPT <rfc822;linux-integrity@vger.kernel.org>);
f9334ff
        Wed, 25 Sep 2019 13:27:09 -0400
f9334ff
Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com
f9334ff
 [10.5.11.22])
f9334ff
        (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
f9334ff
        (No client certificate requested)
f9334ff
        by mx1.redhat.com (Postfix) with ESMTPS id 4CE7C1056FB1;
f9334ff
        Wed, 25 Sep 2019 17:27:08 +0000 (UTC)
f9334ff
Received: from cantor.redhat.com (ovpn-117-191.phx2.redhat.com [10.3.117.191])
f9334ff
        by smtp.corp.redhat.com (Postfix) with ESMTP id D081B1001B12;
f9334ff
        Wed, 25 Sep 2019 17:27:07 +0000 (UTC)
f9334ff
From: Jerry Snitselaar <jsnitsel@redhat.com>
f9334ff
To: linux-efi@vger.kernel.org
f9334ff
Cc: linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org,
f9334ff
        stable@vger.kernel.org, Matthew Garrett <mjg59@google.com>,
f9334ff
        Ard Biesheuvel <ard.biesheuvel@linaro.org>,
f9334ff
        Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
f9334ff
Subject: [PATCH v3] tpm: only set efi_tpm_final_log_size after successful
f9334ff
 event log parsing
f9334ff
Date: Wed, 25 Sep 2019 10:27:05 -0700
f9334ff
Message-Id: <20190925172705.17358-1-jsnitsel@redhat.com>
f9334ff
MIME-Version: 1.0
f9334ff
X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22
f9334ff
X-Greylist: Sender IP whitelisted,
f9334ff
 not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.64]);
f9334ff
 Wed, 25 Sep 2019 17:27:08 +0000 (UTC)
f9334ff
Sender: linux-integrity-owner@vger.kernel.org
f9334ff
Precedence: bulk
f9334ff
List-ID: <linux-integrity.vger.kernel.org>
f9334ff
X-Mailing-List: linux-integrity@vger.kernel.org
f9334ff
f9334ff
If __calc_tpm2_event_size fails to parse an event it will return 0,
f9334ff
resulting tpm2_calc_event_log_size returning -1. Currently there is
f9334ff
no check of this return value, and efi_tpm_final_log_size can end up
f9334ff
being set to this negative value resulting in a panic like the
f9334ff
the one given below.
f9334ff
f9334ff
Also __calc_tpm2_event_size returns a size of 0 when it fails
f9334ff
to parse an event, so update function documentation to reflect this.
f9334ff
f9334ff
[    0.774340] BUG: unable to handle page fault for address: ffffbc8fc00866ad
f9334ff
[    0.774788] #PF: supervisor read access in kernel mode
f9334ff
[    0.774788] #PF: error_code(0x0000) - not-present page
f9334ff
[    0.774788] PGD 107d36067 P4D 107d36067 PUD 107d37067 PMD 107d38067 PTE 0
f9334ff
[    0.774788] Oops: 0000 [#1] SMP PTI
f9334ff
[    0.774788] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.3.0-0.rc2.1.elrdy.x86_64 #1
f9334ff
[    0.774788] Hardware name: LENOVO 20HGS22D0W/20HGS22D0W, BIOS N1WET51W (1.30 ) 09/14/2018
f9334ff
[    0.774788] RIP: 0010:memcpy_erms+0x6/0x10
f9334ff
[    0.774788] Code: 90 90 90 90 eb 1e 0f 1f 00 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 f3 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48 89 d1 <f3> a4 c3 0f 1f 80 00 00 00 00 48 89 f8 48 83 fa 20 72 7e 40 38 fe
f9334ff
[    0.774788] RSP: 0000:ffffbc8fc0073b30 EFLAGS: 00010286
f9334ff
[    0.774788] RAX: ffff9b1fc7c5b367 RBX: ffff9b1fc8390000 RCX: ffffffffffffe962
f9334ff
[    0.774788] RDX: ffffffffffffe962 RSI: ffffbc8fc00866ad RDI: ffff9b1fc7c5b367
f9334ff
[    0.774788] RBP: ffff9b1c10ca7018 R08: ffffbc8fc0085fff R09: 8000000000000063
f9334ff
[    0.774788] R10: 0000000000001000 R11: 000fffffffe00000 R12: 0000000000003367
f9334ff
[    0.774788] R13: ffff9b1fcc47c010 R14: ffffbc8fc0085000 R15: 0000000000000002
f9334ff
[    0.774788] FS:  0000000000000000(0000) GS:ffff9b1fce200000(0000) knlGS:0000000000000000
f9334ff
[    0.774788] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
f9334ff
[    0.774788] CR2: ffffbc8fc00866ad CR3: 000000029f60a001 CR4: 00000000003606f0
f9334ff
[    0.774788] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
f9334ff
[    0.774788] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
f9334ff
[    0.774788] Call Trace:
f9334ff
[    0.774788]  tpm_read_log_efi+0x156/0x1a0
f9334ff
[    0.774788]  tpm_bios_log_setup+0xc8/0x190
f9334ff
[    0.774788]  tpm_chip_register+0x50/0x1c0
f9334ff
[    0.774788]  tpm_tis_core_init.cold.9+0x28c/0x466
f9334ff
[    0.774788]  tpm_tis_plat_probe+0xcc/0xea
f9334ff
[    0.774788]  platform_drv_probe+0x35/0x80
f9334ff
[    0.774788]  really_probe+0xef/0x390
f9334ff
[    0.774788]  driver_probe_device+0xb4/0x100
f9334ff
[    0.774788]  device_driver_attach+0x4f/0x60
f9334ff
[    0.774788]  __driver_attach+0x86/0x140
f9334ff
[    0.774788]  ? device_driver_attach+0x60/0x60
f9334ff
[    0.774788]  bus_for_each_dev+0x76/0xc0
f9334ff
[    0.774788]  ? klist_add_tail+0x3b/0x70
f9334ff
[    0.774788]  bus_add_driver+0x14a/0x1e0
f9334ff
[    0.774788]  ? tpm_init+0xea/0xea
f9334ff
[    0.774788]  ? do_early_param+0x8e/0x8e
f9334ff
[    0.774788]  driver_register+0x6b/0xb0
f9334ff
[    0.774788]  ? tpm_init+0xea/0xea
f9334ff
[    0.774788]  init_tis+0x86/0xd8
f9334ff
[    0.774788]  ? do_early_param+0x8e/0x8e
f9334ff
[    0.774788]  ? driver_register+0x94/0xb0
f9334ff
[    0.774788]  do_one_initcall+0x46/0x1e4
f9334ff
[    0.774788]  ? do_early_param+0x8e/0x8e
f9334ff
[    0.774788]  kernel_init_freeable+0x199/0x242
f9334ff
[    0.774788]  ? rest_init+0xaa/0xaa
f9334ff
[    0.774788]  kernel_init+0xa/0x106
f9334ff
[    0.774788]  ret_from_fork+0x35/0x40
f9334ff
[    0.774788] Modules linked in:
f9334ff
[    0.774788] CR2: ffffbc8fc00866ad
f9334ff
[    0.774788] ---[ end trace 42930799f8d6eaea ]---
f9334ff
[    0.774788] RIP: 0010:memcpy_erms+0x6/0x10
f9334ff
[    0.774788] Code: 90 90 90 90 eb 1e 0f 1f 00 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 f3 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48 89 d1 <f3> a4 c3 0f 1f 80 00 00 00 00 48 89 f8 48 83 fa 20 72 7e 40 38 fe
f9334ff
[    0.774788] RSP: 0000:ffffbc8fc0073b30 EFLAGS: 00010286
f9334ff
[    0.774788] RAX: ffff9b1fc7c5b367 RBX: ffff9b1fc8390000 RCX: ffffffffffffe962
f9334ff
[    0.774788] RDX: ffffffffffffe962 RSI: ffffbc8fc00866ad RDI: ffff9b1fc7c5b367
f9334ff
[    0.774788] RBP: ffff9b1c10ca7018 R08: ffffbc8fc0085fff R09: 8000000000000063
f9334ff
[    0.774788] R10: 0000000000001000 R11: 000fffffffe00000 R12: 0000000000003367
f9334ff
[    0.774788] R13: ffff9b1fcc47c010 R14: ffffbc8fc0085000 R15: 0000000000000002
f9334ff
[    0.774788] FS:  0000000000000000(0000) GS:ffff9b1fce200000(0000) knlGS:0000000000000000
f9334ff
[    0.774788] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
f9334ff
[    0.774788] CR2: ffffbc8fc00866ad CR3: 000000029f60a001 CR4: 00000000003606f0
f9334ff
[    0.774788] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
f9334ff
[    0.774788] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
f9334ff
[    0.774788] Kernel panic - not syncing: Fatal exception
f9334ff
[    0.774788] Kernel Offset: 0x1d000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
f9334ff
[    0.774788] ---[ end Kernel panic - not syncing: Fatal exception ]---
f9334ff
f9334ff
The root cause of the issue that caused the failure of event parsing
f9334ff
in this case is resolved by Peter Jone's patchset dealing with large
f9334ff
event logs where crossing over a page boundary causes the page with
f9334ff
the event count to be unmapped.
f9334ff
f9334ff
Fixes: c46f3405692de ("tpm: Reserve the TPM final events table")
f9334ff
Cc: linux-efi@vger.kernel.org
f9334ff
Cc: linux-integrity@vger.kernel.org
f9334ff
Cc: stable@vger.kernel.org
f9334ff
Cc: Matthew Garrett <mjg59@google.com>
f9334ff
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
f9334ff
Cc: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
f9334ff
Signed-off-by: Jerry Snitselaar <jsnitsel@redhat.com>
f9334ff
Reviewed-by:  <jarkko.sakkinen@linux.intel.com>
f9334ff
---
f9334ff
v3: rebase on top of Peter Jone's patchset
f9334ff
v2: added FW_BUG to pr_err, and renamed label to out_calc.
f9334ff
    Updated doc comment for __calc_tpm2_event_size.
f9334ff
f9334ff
 drivers/firmware/efi/tpm.c   | 9 ++++++++-
f9334ff
 include/linux/tpm_eventlog.h | 2 +-
f9334ff
 2 files changed, 9 insertions(+), 2 deletions(-)
f9334ff
f9334ff
diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c
f9334ff
index b9ae5c6f9b9c..703469c1ab8e 100644
f9334ff
--- a/drivers/firmware/efi/tpm.c
f9334ff
+++ b/drivers/firmware/efi/tpm.c
f9334ff
@@ -85,11 +85,18 @@ int __init efi_tpm_eventlog_init(void)
f9334ff
 						    final_tbl->nr_events,
f9334ff
 						    log_tbl->log);
f9334ff
 	}
f9334ff
+
f9334ff
+	if (tbl_size < 0) {
f9334ff
+		pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n");
f9334ff
+		goto out_calc;
f9334ff
+	}
f9334ff
+
f9334ff
 	memblock_reserve((unsigned long)final_tbl,
f9334ff
 			 tbl_size + sizeof(*final_tbl));
f9334ff
-	early_memunmap(final_tbl, sizeof(*final_tbl));
f9334ff
 	efi_tpm_final_log_size = tbl_size;
f9334ff
 
f9334ff
+out_calc:
f9334ff
+	early_memunmap(final_tbl, sizeof(*final_tbl));
f9334ff
 out:
f9334ff
 	early_memunmap(log_tbl, sizeof(*log_tbl));
f9334ff
 	return ret;
f9334ff
diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h
f9334ff
index 12584b69a3f3..2dfdd63ac034 100644
f9334ff
--- a/include/linux/tpm_eventlog.h
f9334ff
+++ b/include/linux/tpm_eventlog.h
f9334ff
@@ -152,7 +152,7 @@ struct tcg_algorithm_info {
f9334ff
  * total. Once we've done this we know the offset of the data length field,
f9334ff
  * and can calculate the total size of the event.
f9334ff
  *
f9334ff
- * Return: size of the event on success, <0 on failure
f9334ff
+ * Return: size of the event on success, 0 on failure
f9334ff
  */
f9334ff
 
f9334ff
 static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,