Skip to content

Commit

Permalink
tpm: tpm_ibm_vtpm: Fix unallocated banks
Browse files Browse the repository at this point in the history
The nr_allocated_banks and allocated banks are initialized as part of
tpm_chip_register. Currently, this is done as part of auto startup
function. However, some drivers, like the ibm vtpm driver, do not run
auto startup during initialization. This results in uninitialized memory
issue and causes a kernel panic during boot.

This patch moves the pcr allocation outside the auto startup function
into tpm_chip_register. This ensures that allocated banks are initialized
in any case.

Fixes: 879b589 ("tpm: retrieve digest size of unknown algorithms with PCR read")
Reported-by: Michal Suchanek <[email protected]>
Signed-off-by: Nayna Jain <[email protected]>
Reviewed-by: Mimi Zohar <[email protected]>
Tested-by: Sachin Sant <[email protected]>
Tested-by: Michal Suchánek <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Signed-off-by: Jarkko Sakkinen <[email protected]>
  • Loading branch information
naynajain authored and Jarkko Sakkinen committed Aug 4, 2019
1 parent 1e5ac63 commit fa4f99c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 17 deletions.
20 changes: 20 additions & 0 deletions drivers/char/tpm/tpm-chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,20 @@ static int tpm_add_hwrng(struct tpm_chip *chip)
return hwrng_register(&chip->hwrng);
}

static int tpm_get_pcr_allocation(struct tpm_chip *chip)
{
int rc;

rc = (chip->flags & TPM_CHIP_FLAG_TPM2) ?
tpm2_get_pcr_allocation(chip) :
tpm1_get_pcr_allocation(chip);

if (rc > 0)
return -ENODEV;

return rc;
}

/*
* tpm_chip_register() - create a character device for the TPM chip
* @chip: TPM chip to use.
Expand All @@ -573,6 +587,12 @@ int tpm_chip_register(struct tpm_chip *chip)
if (rc)
return rc;
rc = tpm_auto_startup(chip);
if (rc) {
tpm_chip_stop(chip);
return rc;
}

rc = tpm_get_pcr_allocation(chip);
tpm_chip_stop(chip);
if (rc)
return rc;
Expand Down
2 changes: 2 additions & 0 deletions drivers/char/tpm/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf);
ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
const char *desc, size_t min_cap_length);
int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max);
int tpm1_get_pcr_allocation(struct tpm_chip *chip);
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
int tpm_pm_resume(struct device *dev);
Expand Down Expand Up @@ -449,6 +450,7 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
u32 *value, const char *desc);

ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
int tpm2_auto_startup(struct tpm_chip *chip);
void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
Expand Down
36 changes: 24 additions & 12 deletions drivers/char/tpm/tpm1-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,18 +699,6 @@ int tpm1_auto_startup(struct tpm_chip *chip)
goto out;
}

chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks),
GFP_KERNEL);
if (!chip->allocated_banks) {
rc = -ENOMEM;
goto out;
}

chip->allocated_banks[0].alg_id = TPM_ALG_SHA1;
chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1];
chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1;
chip->nr_allocated_banks = 1;

return rc;
out:
if (rc > 0)
Expand Down Expand Up @@ -779,3 +767,27 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
return rc;
}

/**
* tpm1_get_pcr_allocation() - initialize the allocated bank
* @chip: TPM chip to use.
*
* The function initializes the SHA1 allocated bank to extend PCR
*
* Return:
* * 0 on success,
* * < 0 on error.
*/
int tpm1_get_pcr_allocation(struct tpm_chip *chip)
{
chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks),
GFP_KERNEL);
if (!chip->allocated_banks)
return -ENOMEM;

chip->allocated_banks[0].alg_id = TPM_ALG_SHA1;
chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1];
chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1;
chip->nr_allocated_banks = 1;

return 0;
}
6 changes: 1 addition & 5 deletions drivers/char/tpm/tpm2-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ struct tpm2_pcr_selection {
u8 pcr_select[3];
} __packed;

static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
{
struct tpm2_pcr_selection pcr_selection;
struct tpm_buf buf;
Expand Down Expand Up @@ -1040,10 +1040,6 @@ int tpm2_auto_startup(struct tpm_chip *chip)
goto out;
}

rc = tpm2_get_pcr_allocation(chip);
if (rc)
goto out;

rc = tpm2_get_cc_attrs_tbl(chip);

out:
Expand Down

0 comments on commit fa4f99c

Please sign in to comment.