From patchwork Wed Mar 18 04:50:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 451219 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 CF3C014011D for ; Wed, 18 Mar 2015 15:50:21 +1100 (AEDT) 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 1YY5vs-00085i-Oa; Wed, 18 Mar 2015 04:50:16 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1YY5vr-00085c-E8 for tpmdd-devel@lists.sourceforge.net; Wed, 18 Mar 2015 04:50:15 +0000 X-ACL-Warn: Received: from mga11.intel.com ([192.55.52.93]) by sog-mx-4.v43.ch3.sourceforge.com with esmtp (Exim 4.76) id 1YY5vq-0006O7-9Q for tpmdd-devel@lists.sourceforge.net; Wed, 18 Mar 2015 04:50:15 +0000 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP; 17 Mar 2015 21:50:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,420,1422950400"; d="scan'208";a="468746413" Received: from mstrzele-mobl.ger.corp.intel.com (HELO localhost) ([10.252.19.195]) by FMSMGA003.fm.intel.com with ESMTP; 17 Mar 2015 21:42:48 -0700 From: Jarkko Sakkinen To: Peter Huewe , Ashley Lai , Marcel Selhorst Date: Wed, 18 Mar 2015 06:50:01 +0200 Message-Id: <1426654201-4761-1-git-send-email-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.1.4 X-Spam-Score: -0.0 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain X-Headers-End: 1YY5vq-0006O7-9Q Cc: christophe.ricard@gmail.com, linux-kernel@vger.kernel.org, tpmdd-devel@lists.sourceforge.net, jason.gunthorpe@obsidianresearch.com Subject: [tpmdd-devel] [PATCH] tpm: fix: sanitized code paths in tpm_chip_register() 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 I started to work with PPI interface so that it would be available under character device sysfs directory and realized that chip registeration was still too messy. In TPM 1.x in some rare scenarios (errors that almost never occur) wrong order in deinitialization steps was taken in teardown. I reproduced these scenarios by manually inserting error codes in the place of the corresponding function calls. The key problem is that the teardown is messy with two separate code paths (this was inherited when moving code from tpm-interface.c). Moved TPM 1.x specific register/unregister functionality to own helper functions and added single code path for teardown in tpm_chip_register(). Now the code paths have been fixed and it should be easier to review later on this part of the code. Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm-chip.c | 56 +++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index cf43f4b..e5b0481 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -170,6 +170,33 @@ static void tpm_dev_del_device(struct tpm_chip *chip) device_unregister(&chip->dev); } +static int tpm1_chip_register(struct tpm_chip *chip) +{ + int rc; + + if (chip->flags & TPM_CHIP_FLAG_TPM2) + return 0; + + rc = tpm_sysfs_add_device(chip); + if (rc) + return rc; + + chip->bios_dir = tpm_bios_log_setup(chip->devname); + + return 0; +} + +static void tpm1_chip_unregister(struct tpm_chip *chip) +{ + if (chip->flags & TPM_CHIP_FLAG_TPM2) + return; + + if (chip->bios_dir) + tpm_bios_log_teardown(chip->bios_dir); + + tpm_sysfs_del_device(chip); +} + /* * tpm_chip_register() - create a character device for the TPM chip * @chip: TPM chip to use. @@ -185,22 +212,17 @@ int tpm_chip_register(struct tpm_chip *chip) { int rc; - /* Populate sysfs for TPM1 devices. */ - if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { - rc = tpm_sysfs_add_device(chip); - if (rc) - goto del_misc; - - chip->bios_dir = tpm_bios_log_setup(chip->devname); - } + rc = tpm1_chip_register(chip); + if (rc) + return rc; rc = tpm_add_ppi(chip); if (rc) - goto del_sysfs; + goto out_err; rc = tpm_dev_add_device(chip); if (rc) - return rc; + goto out_err; /* Make the chip available. */ spin_lock(&driver_lock); @@ -210,10 +232,9 @@ int tpm_chip_register(struct tpm_chip *chip) chip->flags |= TPM_CHIP_FLAG_REGISTERED; return 0; -del_sysfs: - tpm_sysfs_del_device(chip); -del_misc: - tpm_dev_del_device(chip); +out_err: + tpm_remove_ppi(chip); + tpm1_chip_unregister(chip); return rc; } EXPORT_SYMBOL_GPL(tpm_chip_register); @@ -238,13 +259,8 @@ void tpm_chip_unregister(struct tpm_chip *chip) spin_unlock(&driver_lock); synchronize_rcu(); - if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { - if (chip->bios_dir) - tpm_bios_log_teardown(chip->bios_dir); - tpm_sysfs_del_device(chip); - } - tpm_remove_ppi(chip); + tpm1_chip_unregister(chip); tpm_dev_del_device(chip); } EXPORT_SYMBOL_GPL(tpm_chip_unregister);