Skip to content

Commit 92b7e49

Browse files
committed
Merge tag 'tpmdd-next-v5.9' of git://git.infradead.org/users/jjs/linux-tpmdd
Pull tpm updates from Jarkko Sakkinen: "An issue was fixed with the TPM space buffer size. The buffer is used to store in-TPM objects while swapped out of the TPM for a /dev/tpmrm0 session. The code incorrectly used PAGE_SIZE, which obviously can vary. With these changes the buffer has a fixed size of 16 kB. In addition, this contains support for acquiring TPM even log from TPM2 ACPI table. This method is used by QEMU in particular" * tag 'tpmdd-next-v5.9' of git://git.infradead.org/users/jjs/linux-tpmdd: tpm: Add support for event log pointer found in TPM2 ACPI table acpi: Extend TPM2 ACPI table with missing log fields tpm: Unify the mismatching TPM space buffer sizes tpm: Require that all digests are present in TCG_PCR_EVENT2 structures
2 parents c6fe44d + 85467f6 commit 92b7e49

File tree

8 files changed

+82
-42
lines changed

8 files changed

+82
-42
lines changed

drivers/char/tpm/eventlog/acpi.c

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
4949
void __iomem *virt;
5050
u64 len, start;
5151
struct tpm_bios_log *log;
52-
53-
if (chip->flags & TPM_CHIP_FLAG_TPM2)
54-
return -ENODEV;
52+
struct acpi_table_tpm2 *tbl;
53+
struct acpi_tpm2_phy *tpm2_phy;
54+
int format;
5555

5656
log = &chip->log;
5757

@@ -61,23 +61,44 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
6161
if (!chip->acpi_dev_handle)
6262
return -ENODEV;
6363

64-
/* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
65-
status = acpi_get_table(ACPI_SIG_TCPA, 1,
66-
(struct acpi_table_header **)&buff);
67-
68-
if (ACPI_FAILURE(status))
69-
return -ENODEV;
70-
71-
switch(buff->platform_class) {
72-
case BIOS_SERVER:
73-
len = buff->server.log_max_len;
74-
start = buff->server.log_start_addr;
75-
break;
76-
case BIOS_CLIENT:
77-
default:
78-
len = buff->client.log_max_len;
79-
start = buff->client.log_start_addr;
80-
break;
64+
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
65+
status = acpi_get_table("TPM2", 1,
66+
(struct acpi_table_header **)&tbl);
67+
if (ACPI_FAILURE(status))
68+
return -ENODEV;
69+
70+
if (tbl->header.length <
71+
sizeof(*tbl) + sizeof(struct acpi_tpm2_phy))
72+
return -ENODEV;
73+
74+
tpm2_phy = (void *)tbl + sizeof(*tbl);
75+
len = tpm2_phy->log_area_minimum_length;
76+
77+
start = tpm2_phy->log_area_start_address;
78+
if (!start || !len)
79+
return -ENODEV;
80+
81+
format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
82+
} else {
83+
/* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
84+
status = acpi_get_table(ACPI_SIG_TCPA, 1,
85+
(struct acpi_table_header **)&buff);
86+
if (ACPI_FAILURE(status))
87+
return -ENODEV;
88+
89+
switch (buff->platform_class) {
90+
case BIOS_SERVER:
91+
len = buff->server.log_max_len;
92+
start = buff->server.log_start_addr;
93+
break;
94+
case BIOS_CLIENT:
95+
default:
96+
len = buff->client.log_max_len;
97+
start = buff->client.log_start_addr;
98+
break;
99+
}
100+
101+
format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
81102
}
82103
if (!len) {
83104
dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
@@ -98,7 +119,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
98119
memcpy_fromio(log->bios_event_log, virt, len);
99120

100121
acpi_os_unmap_iomem(virt, len);
101-
return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
122+
return format;
102123

103124
err:
104125
kfree(log->bios_event_log);

drivers/char/tpm/tpm-chip.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,8 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
386386
chip->cdev.owner = THIS_MODULE;
387387
chip->cdevs.owner = THIS_MODULE;
388388

389-
chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
390-
if (!chip->work_space.context_buf) {
391-
rc = -ENOMEM;
392-
goto out;
393-
}
394-
chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
395-
if (!chip->work_space.session_buf) {
389+
rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);
390+
if (rc) {
396391
rc = -ENOMEM;
397392
goto out;
398393
}

drivers/char/tpm/tpm.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ enum tpm_addr {
5959

6060
#define TPM_TAG_RQU_COMMAND 193
6161

62+
/* TPM2 specific constants. */
63+
#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */
64+
6265
struct stclear_flags_t {
6366
__be16 tag;
6467
u8 deactivated;
@@ -228,7 +231,7 @@ unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
228231
int tpm2_probe(struct tpm_chip *chip);
229232
int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip);
230233
int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
231-
int tpm2_init_space(struct tpm_space *space);
234+
int tpm2_init_space(struct tpm_space *space, unsigned int buf_size);
232235
void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
233236
void tpm2_flush_space(struct tpm_chip *chip);
234237
int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,

drivers/char/tpm/tpm2-space.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,21 @@ static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
3838
}
3939
}
4040

41-
int tpm2_init_space(struct tpm_space *space)
41+
int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
4242
{
43-
space->context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
43+
space->context_buf = kzalloc(buf_size, GFP_KERNEL);
4444
if (!space->context_buf)
4545
return -ENOMEM;
4646

47-
space->session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
47+
space->session_buf = kzalloc(buf_size, GFP_KERNEL);
4848
if (space->session_buf == NULL) {
4949
kfree(space->context_buf);
50+
/* Prevent caller getting a dangling pointer. */
51+
space->context_buf = NULL;
5052
return -ENOMEM;
5153
}
5254

55+
space->buf_size = buf_size;
5356
return 0;
5457
}
5558

@@ -311,8 +314,10 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
311314
sizeof(space->context_tbl));
312315
memcpy(&chip->work_space.session_tbl, &space->session_tbl,
313316
sizeof(space->session_tbl));
314-
memcpy(chip->work_space.context_buf, space->context_buf, PAGE_SIZE);
315-
memcpy(chip->work_space.session_buf, space->session_buf, PAGE_SIZE);
317+
memcpy(chip->work_space.context_buf, space->context_buf,
318+
space->buf_size);
319+
memcpy(chip->work_space.session_buf, space->session_buf,
320+
space->buf_size);
316321

317322
rc = tpm2_load_space(chip);
318323
if (rc) {
@@ -492,7 +497,7 @@ static int tpm2_save_space(struct tpm_chip *chip)
492497
continue;
493498

494499
rc = tpm2_save_context(chip, space->context_tbl[i],
495-
space->context_buf, PAGE_SIZE,
500+
space->context_buf, space->buf_size,
496501
&offset);
497502
if (rc == -ENOENT) {
498503
space->context_tbl[i] = 0;
@@ -509,9 +514,8 @@ static int tpm2_save_space(struct tpm_chip *chip)
509514
continue;
510515

511516
rc = tpm2_save_context(chip, space->session_tbl[i],
512-
space->session_buf, PAGE_SIZE,
517+
space->session_buf, space->buf_size,
513518
&offset);
514-
515519
if (rc == -ENOENT) {
516520
/* handle error saving session, just forget it */
517521
space->session_tbl[i] = 0;
@@ -557,8 +561,10 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
557561
sizeof(space->context_tbl));
558562
memcpy(&space->session_tbl, &chip->work_space.session_tbl,
559563
sizeof(space->session_tbl));
560-
memcpy(space->context_buf, chip->work_space.context_buf, PAGE_SIZE);
561-
memcpy(space->session_buf, chip->work_space.session_buf, PAGE_SIZE);
564+
memcpy(space->context_buf, chip->work_space.context_buf,
565+
space->buf_size);
566+
memcpy(space->session_buf, chip->work_space.session_buf,
567+
space->buf_size);
562568

563569
return 0;
564570
out:

drivers/char/tpm/tpmrm-dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static int tpmrm_open(struct inode *inode, struct file *file)
2121
if (priv == NULL)
2222
return -ENOMEM;
2323

24-
rc = tpm2_init_space(&priv->space);
24+
rc = tpm2_init_space(&priv->space, TPM2_SPACE_BUFFER_SIZE);
2525
if (rc) {
2626
kfree(priv);
2727
return -ENOMEM;

include/acpi/actbl3.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,13 @@ struct acpi_table_tpm2 {
415415
/* Platform-specific data follows */
416416
};
417417

418+
/* Optional trailer for revision 4 holding platform-specific data */
419+
struct acpi_tpm2_phy {
420+
u8 start_method_specific[12];
421+
u32 log_area_minimum_length;
422+
u64 log_area_start_address;
423+
};
424+
418425
/* Values for start_method above */
419426

420427
#define ACPI_TPM2_NOT_ALLOWED 0

include/linux/tpm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct tpm_space {
9696
u8 *context_buf;
9797
u32 session_tbl[3];
9898
u8 *session_buf;
99+
u32 buf_size;
99100
};
100101

101102
struct tpm_bios_log {

include/linux/tpm_eventlog.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,16 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
211211

212212
efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
213213

214-
/* Check if event is malformed. */
214+
/*
215+
* Perform validation of the event in order to identify malformed
216+
* events. This function may be asked to parse arbitrary byte sequences
217+
* immediately following a valid event log. The caller expects this
218+
* function to recognize that the byte sequence is not a valid event
219+
* and to return an event size of 0.
220+
*/
215221
if (memcmp(efispecid->signature, TCG_SPECID_SIG,
216-
sizeof(TCG_SPECID_SIG)) || count > efispecid->num_algs) {
222+
sizeof(TCG_SPECID_SIG)) ||
223+
!efispecid->num_algs || count != efispecid->num_algs) {
217224
size = 0;
218225
goto out;
219226
}

0 commit comments

Comments
 (0)