Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tpm: Unify the mismatching TPM space buffer sizes

The size of the buffers for storing context's and sessions can vary from
arch to arch as PAGE_SIZE can be anything between 4 kB and 256 kB (the
maximum for PPC64). Define a fixed buffer size set to 16 kB. This should be
enough for most use with three handles (that is how many we allow at the
moment). Parametrize the buffer size while doing this, so that it is easier
to revisit this later on if required.

Cc: stable@vger.kernel.org
Reported-by: Stefan Berger <stefanb@linux.ibm.com>
Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>

+24 -19
+2 -7
drivers/char/tpm/tpm-chip.c
··· 386 386 chip->cdev.owner = THIS_MODULE; 387 387 chip->cdevs.owner = THIS_MODULE; 388 388 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) { 396 391 rc = -ENOMEM; 397 392 goto out; 398 393 }
+4 -1
drivers/char/tpm/tpm.h
··· 59 59 60 60 #define TPM_TAG_RQU_COMMAND 193 61 61 62 + /* TPM2 specific constants. */ 63 + #define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */ 64 + 62 65 struct stclear_flags_t { 63 66 __be16 tag; 64 67 u8 deactivated; ··· 231 228 int tpm2_probe(struct tpm_chip *chip); 232 229 int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip); 233 230 int tpm2_find_cc(struct tpm_chip *chip, u32 cc); 234 - int tpm2_init_space(struct tpm_space *space); 231 + int tpm2_init_space(struct tpm_space *space, unsigned int buf_size); 235 232 void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space); 236 233 void tpm2_flush_space(struct tpm_chip *chip); 237 234 int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
+16 -10
drivers/char/tpm/tpm2-space.c
··· 38 38 } 39 39 } 40 40 41 - int tpm2_init_space(struct tpm_space *space) 41 + int tpm2_init_space(struct tpm_space *space, unsigned int buf_size) 42 42 { 43 - space->context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); 43 + space->context_buf = kzalloc(buf_size, GFP_KERNEL); 44 44 if (!space->context_buf) 45 45 return -ENOMEM; 46 46 47 - space->session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); 47 + space->session_buf = kzalloc(buf_size, GFP_KERNEL); 48 48 if (space->session_buf == NULL) { 49 49 kfree(space->context_buf); 50 + /* Prevent caller getting a dangling pointer. */ 51 + space->context_buf = NULL; 50 52 return -ENOMEM; 51 53 } 52 54 55 + space->buf_size = buf_size; 53 56 return 0; 54 57 } 55 58 ··· 314 311 sizeof(space->context_tbl)); 315 312 memcpy(&chip->work_space.session_tbl, &space->session_tbl, 316 313 sizeof(space->session_tbl)); 317 - memcpy(chip->work_space.context_buf, space->context_buf, PAGE_SIZE); 318 - memcpy(chip->work_space.session_buf, space->session_buf, PAGE_SIZE); 314 + memcpy(chip->work_space.context_buf, space->context_buf, 315 + space->buf_size); 316 + memcpy(chip->work_space.session_buf, space->session_buf, 317 + space->buf_size); 319 318 320 319 rc = tpm2_load_space(chip); 321 320 if (rc) { ··· 497 492 continue; 498 493 499 494 rc = tpm2_save_context(chip, space->context_tbl[i], 500 - space->context_buf, PAGE_SIZE, 495 + space->context_buf, space->buf_size, 501 496 &offset); 502 497 if (rc == -ENOENT) { 503 498 space->context_tbl[i] = 0; ··· 514 509 continue; 515 510 516 511 rc = tpm2_save_context(chip, space->session_tbl[i], 517 - space->session_buf, PAGE_SIZE, 512 + space->session_buf, space->buf_size, 518 513 &offset); 519 - 520 514 if (rc == -ENOENT) { 521 515 /* handle error saving session, just forget it */ 522 516 space->session_tbl[i] = 0; ··· 561 557 sizeof(space->context_tbl)); 562 558 memcpy(&space->session_tbl, &chip->work_space.session_tbl, 563 559 sizeof(space->session_tbl)); 564 - memcpy(space->context_buf, chip->work_space.context_buf, PAGE_SIZE); 565 - memcpy(space->session_buf, chip->work_space.session_buf, PAGE_SIZE); 560 + memcpy(space->context_buf, chip->work_space.context_buf, 561 + space->buf_size); 562 + memcpy(space->session_buf, chip->work_space.session_buf, 563 + space->buf_size); 566 564 567 565 return 0; 568 566 out:
+1 -1
drivers/char/tpm/tpmrm-dev.c
··· 21 21 if (priv == NULL) 22 22 return -ENOMEM; 23 23 24 - rc = tpm2_init_space(&priv->space); 24 + rc = tpm2_init_space(&priv->space, TPM2_SPACE_BUFFER_SIZE); 25 25 if (rc) { 26 26 kfree(priv); 27 27 return -ENOMEM;
+1
include/linux/tpm.h
··· 96 96 u8 *context_buf; 97 97 u32 session_tbl[3]; 98 98 u8 *session_buf; 99 + u32 buf_size; 99 100 }; 100 101 101 102 struct tpm_bios_log {