tpm: Issue a TPM2_Shutdown for TPM2 devices.
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH v4 1/2 tpm: Issue a TPM2_Shutdown for TPM2 devices.
If a TPM2 loses power without a TPM2_Shutdown command being issued (a "disorderly reboot"), it may lose some state that has yet to be persisted to NVRam, and will increment the DA counter. After the DA counter gets sufficiently large, the TPM will lock the user out.
NOTE: This only changes behavior on TPM2 devices. Since TPM1 uses sysfs, and sysfs relies on implicit locking on chip->ops, it is not safe to allow this code to run in TPM1, or to add sysfs support to TPM2, until that locking is made explicit.
----
v2:
- Properly split changes between this and another commit
- Use proper locking primitive.
- Fix commenting style
v3:
- Re-fix commenting style
v4:
- Update description and tags (Reviewed-by, Cc).
--- drivers/char/tpm/tpm-chip.c | 20 ++++++++++++++++++++ drivers/char/tpm/tpm-sysfs.c | 3 +++ 2 files changed, 23 insertions(+)
drivers/char/tpm/tpm-chip.c +20 -0
@@ -142,6 +142,25 @@ static void tpm_devs_release(struct device *dev)put_device (&chip->dev); } +static void tpm_shutdown (struct device *dev) +{ + struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev); +/* TPM 2.0 requires that the TPM2_Shutdown() command be issued prior to +* loss of power. If it is not, the DA counter will be incremented and, +* eventually, the user will be locked out of their TPM. +* XXX: This codepath relies on the fact that sysfs is not enabled for +* TPM2: sysfs uses an implicit lock on chip->ops, so this use could +* race if TPM2 has sysfs support enabled before TPM sysfs's implicit +* locking is fixed. +*/ +if (chip->flags &TPM_CHIP_FLAG_TPM2 ) { +down_write (&chip->ops_sem); +tpm2_shutdown (chip,TPM_SU_CLEAR ); + chip->ops =NULL ; +up_write (&chip->ops_sem); + } +} +/** * tpm_chip_alloc() - allocate a new struct tpm_chip instance * @pdev: device to which the chip is associated
@@ -181,6 +200,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,device_initialize (&chip->devs); chip->dev.class = tpm_class; + chip->dev.class.shutdown = tpm_shutdown; chip->dev.release = tpm_dev_release; chip->dev.parent = pdev; chip->dev.groups = chip->groups;
drivers/char/tpm/tpm-sysfs.c +3 -0
@@ -294,6 +294,9 @@ static const struct attribute_group tpm_dev_group = {void tpm_sysfs_add_device (struct tpm_chip *chip) { +/* XXX: Before this restriction is removed, tpm_sysfs must be updated +* to explicitly lock chip->ops. +*/ if (chip->flags &TPM_CHIP_FLAG_TPM2 )return ;
Signature · 1 line
2.13.0.219.gdb65acc882-goog
Quoted 82 lines · Josh Zimmerman
If a TPM2 loses power without a
TPM2_Shutdowncommand being issued (a "disorderly reboot"), it may lose some state that has yet to be persisted to NVRam, and will increment the DA counter. After the DA counter gets sufficiently large, the TPM will lock the user out.NOTE: This only changes behavior on TPM2 devices. Since TPM1 uses sysfs, and sysfs relies on implicit locking on
chip->ops, it is not safe to allow this code to run in TPM1, or to add sysfs support to TPM2, until that locking is made explicit.Signed-off-by Josh Zimmerman <[email protected]>Reviewed-by Jarko Sakkinen <[email protected]>----
v2:
- Properly split changes between this and another commit
- Use proper locking primitive.
- Fix commenting style
v3:
- Re-fix commenting style
v4:
- Update description and tags (Reviewed-by, Cc).--- drivers/char/tpm/tpm-chip.c | 20 ++++++++++++++++++++ drivers/char/tpm/tpm-sysfs.c | 3 +++ 2 files changed, 23 insertions(+)drivers/char/tpm/tpm-chip.c +20
-0@@ -142,6 +142,25 @@ static void tpm_devs_release(struct device *dev)put_device (&chip->dev); } +static void tpm_shutdown (struct device *dev) +{ + struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev); +/* TPM 2.0 requires that the TPM2_Shutdown() command be issued prior to +* loss of power. If it is not, the DA counter will be incremented and, +* eventually, the user will be locked out of their TPM. +* XXX: This codepath relies on the fact that sysfs is not enabled for +* TPM2: sysfs uses an implicit lock on chip->ops, so this use could +* race if TPM2 has sysfs support enabled before TPM sysfs's implicit +* locking is fixed. +*/ +if (chip->flags &TPM_CHIP_FLAG_TPM2 ) { +down_write (&chip->ops_sem); +tpm2_shutdown (chip,TPM_SU_CLEAR ); + chip->ops =NULL ; +up_write (&chip->ops_sem); + } +} +/** * tpm_chip_alloc() - allocate a new struct tpm_chip instance * @pdev: device to which the chip is associated @@ -181,6 +200,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,device_initialize (&chip->devs); chip->dev.class = tpm_class; + chip->dev.class.shutdown = tpm_shutdown; chip->dev.release = tpm_dev_release; chip->dev.parent = pdev; chip->dev.groups = chip->groups;drivers/char/tpm/tpm-sysfs.c +3
-1@@ -294,6 +294,9 @@ static const struct attribute_group tpm_dev_group = {void tpm_sysfs_add_device (struct tpm_chip *chip) { +/* XXX: Before this restriction is removed, tpm_sysfs must be updated +* to explicitly lock chip->ops. +*/ if (chip->flags &TPM_CHIP_FLAG_TPM2 )return ; --
Quoted 2 lines
2.13.0.219.gdb65acc882-goog
This was not meant to be sent explicitly to stable@; git send-email "helpfully" added stable@ to the emails cc's despite my --suppress-cc argument. Apologies.
Josh
PATCH v4 2/2 Add "shutdown" to "struct class".
In reply to a message not in the archiveThe TPM class has some common shutdown code that must be executed for all drivers. This adds some needed functionality for that.
-----
v2: Add Signed-off-by.
v3: Remove logically separate change.
v4: Add "acked-by" and "cc".
--- drivers/base/core.c | 5 +++++ include/linux/device.h | 2 ++ 2 files changed, 7 insertions(+)
drivers/base/core.c +5 -0
@@ -2667,6 +2667,11 @@ void device_shutdown(void)pm_runtime_get_noresume (dev);pm_runtime_barrier (dev); +if (dev->class && dev->class->shutdown) { +if (initcall_debug) +dev_info (dev,"shutdown\n" ); + dev->class->shutdown (dev); + }if (dev->bus && dev->bus->shutdown) {if (initcall_debug)dev_info (dev,"shutdown\n" );
include/linux/device.h +2 -0
@@ -378,6 +378,7 @@ int subsys_virtual_register(struct bus_type *subsys,* @suspend: Used to put the device to sleep mode, usually to a low power * state. * @resume: Used to bring the device from the sleep mode. +* @shutdown: Called at shut-down time to quiesce the device. * @ns_type: Callbacks so sysfs can detemine namespaces. * @namespace: Namespace of the device belongs to this class. * @pm: The default device power management operations of this class.
@@ -407,6 +408,7 @@ struct class {int (*suspend)(struct device *dev,pm_message_t state);int (*resume)(struct device *dev); +int (*shutdown)(struct device *dev);const struct kobj_ns_type_operations *ns_type;const void *(*namespace)(struct device *dev);
Signature · 1 line
2.13.0.219.gdb65acc882-goog
Re: [PATCH v4 2/2] Add "shutdown" to "struct class".
Quoted 53 lines · Josh Zimmerman
The TPM class has some common shutdown code that must be executed for all drivers. This adds some needed functionality for that.
Signed-off-by Josh Zimmerman <[email protected]>-----
v2: Add Signed-off-by.
v3: Remove logically separate change.
v4: Add "acked-by" and "cc".--- drivers/base/core.c | 5 +++++ include/linux/device.h | 2 ++ 2 files changed, 7 insertions(+)drivers/base/core.c +5
-0@@ -2667,6 +2667,11 @@ void device_shutdown(void)pm_runtime_get_noresume (dev);pm_runtime_barrier (dev); +if (dev->class && dev->class->shutdown) { +if (initcall_debug) +dev_info (dev,"shutdown\n" ); + dev->class->shutdown (dev); + }if (dev->bus && dev->bus->shutdown) {if (initcall_debug)dev_info (dev,"shutdown\n" );include/linux/device.h +2
-1@@ -378,6 +378,7 @@ int subsys_virtual_register(struct bus_type *subsys,* @suspend: Used to put the device to sleep mode, usually to a low power * state. * @resume: Used to bring the device from the sleep mode. +* @shutdown: Called at shut-down time to quiesce the device. * @ns_type: Callbacks so sysfs can detemine namespaces. * @namespace: Namespace of the device belongs to this class. * @pm: The default device power management operations of this class. @@ -407,6 +408,7 @@ struct class {int (*suspend)(struct device *dev,pm_message_t state);int (*resume)(struct device *dev); +int (*shutdown)(struct device *dev);const struct kobj_ns_type_operations *ns_type;const void *(*namespace)(struct device *dev); --
Quoted 2 lines
2.13.0.219.gdb65acc882-goog
This was not meant to be sent explicitly to stable@; git send-email "helpfully" added stable@ to the emails cc's despite my --suppress-cc argument. Apologies.
Josh