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

tpm: Address !chip->auth in tpm_buf_append_name()

Unless tpm_chip_bootstrap() was called by the driver, !chip->auth can
cause a null derefence in tpm_buf_append_name(). Thus, address
!chip->auth in tpm_buf_append_name() and remove the fallback
implementation for !TCG_TPM2_HMAC.

Cc: stable@vger.kernel.org # v6.10+
Reported-by: Stefan Berger <stefanb@linux.ibm.com>
Closes: https://lore.kernel.org/linux-integrity/20240617193408.1234365-1-stefanb@linux.ibm.com/
Fixes: d0a25bb961e6 ("tpm: Add HMAC session name/handle append")
Tested-by: Michael Ellerman <mpe@ellerman.id.au> # ppc
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

Jarkko Sakkinen and committed by
Jarkko Sakkinen
a61809a3 25ee48a5

+132 -112
+1 -1
drivers/char/tpm/Makefile
··· 16 16 tpm-y += eventlog/tpm1.o 17 17 tpm-y += eventlog/tpm2.o 18 18 tpm-y += tpm-buf.o 19 + tpm-y += tpm2-sessions.o 19 20 20 - tpm-$(CONFIG_TCG_TPM2_HMAC) += tpm2-sessions.o 21 21 tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o 22 22 tpm-$(CONFIG_EFI) += eventlog/efi.o 23 23 tpm-$(CONFIG_OF) += eventlog/of.o
+118 -101
drivers/char/tpm/tpm2-sessions.c
··· 83 83 #define AES_KEY_BYTES AES_KEYSIZE_128 84 84 #define AES_KEY_BITS (AES_KEY_BYTES*8) 85 85 86 - static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy, 87 - u32 *handle, u8 *name); 88 - 89 86 /* 90 87 * This is the structure that carries all the auth information (like 91 88 * session handle, nonces, session key and auth) from use to use it is ··· 145 148 u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE]; 146 149 }; 147 150 151 + #ifdef CONFIG_TCG_TPM2_HMAC 148 152 /* 149 153 * Name Size based on TPM algorithm (assumes no hash bigger than 255) 150 154 */ ··· 160 162 u16 alg = get_unaligned_be16(name); 161 163 return size_map[alg] + 2; 162 164 } 165 + 166 + static int tpm2_parse_read_public(char *name, struct tpm_buf *buf) 167 + { 168 + struct tpm_header *head = (struct tpm_header *)buf->data; 169 + off_t offset = TPM_HEADER_SIZE; 170 + u32 tot_len = be32_to_cpu(head->length); 171 + u32 val; 172 + 173 + /* we're starting after the header so adjust the length */ 174 + tot_len -= TPM_HEADER_SIZE; 175 + 176 + /* skip public */ 177 + val = tpm_buf_read_u16(buf, &offset); 178 + if (val > tot_len) 179 + return -EINVAL; 180 + offset += val; 181 + /* name */ 182 + val = tpm_buf_read_u16(buf, &offset); 183 + if (val != name_size(&buf->data[offset])) 184 + return -EINVAL; 185 + memcpy(name, &buf->data[offset], val); 186 + /* forget the rest */ 187 + return 0; 188 + } 189 + 190 + static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name) 191 + { 192 + struct tpm_buf buf; 193 + int rc; 194 + 195 + rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC); 196 + if (rc) 197 + return rc; 198 + 199 + tpm_buf_append_u32(&buf, handle); 200 + rc = tpm_transmit_cmd(chip, &buf, 0, "read public"); 201 + if (rc == TPM2_RC_SUCCESS) 202 + rc = tpm2_parse_read_public(name, &buf); 203 + 204 + tpm_buf_destroy(&buf); 205 + 206 + return rc; 207 + } 208 + #endif /* CONFIG_TCG_TPM2_HMAC */ 209 + 210 + /** 211 + * tpm_buf_append_name() - add a handle area to the buffer 212 + * @chip: the TPM chip structure 213 + * @buf: The buffer to be appended 214 + * @handle: The handle to be appended 215 + * @name: The name of the handle (may be NULL) 216 + * 217 + * In order to compute session HMACs, we need to know the names of the 218 + * objects pointed to by the handles. For most objects, this is simply 219 + * the actual 4 byte handle or an empty buf (in these cases @name 220 + * should be NULL) but for volatile objects, permanent objects and NV 221 + * areas, the name is defined as the hash (according to the name 222 + * algorithm which should be set to sha256) of the public area to 223 + * which the two byte algorithm id has been appended. For these 224 + * objects, the @name pointer should point to this. If a name is 225 + * required but @name is NULL, then TPM2_ReadPublic() will be called 226 + * on the handle to obtain the name. 227 + * 228 + * As with most tpm_buf operations, success is assumed because failure 229 + * will be caused by an incorrect programming model and indicated by a 230 + * kernel message. 231 + */ 232 + void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, 233 + u32 handle, u8 *name) 234 + { 235 + #ifdef CONFIG_TCG_TPM2_HMAC 236 + enum tpm2_mso_type mso = tpm2_handle_mso(handle); 237 + struct tpm2_auth *auth; 238 + int slot; 239 + #endif 240 + 241 + if (!tpm2_chip_auth(chip)) { 242 + tpm_buf_append_u32(buf, handle); 243 + /* count the number of handles in the upper bits of flags */ 244 + buf->handles++; 245 + return; 246 + } 247 + 248 + #ifdef CONFIG_TCG_TPM2_HMAC 249 + slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE) / 4; 250 + if (slot >= AUTH_MAX_NAMES) { 251 + dev_err(&chip->dev, "TPM: too many handles\n"); 252 + return; 253 + } 254 + auth = chip->auth; 255 + WARN(auth->session != tpm_buf_length(buf), 256 + "name added in wrong place\n"); 257 + tpm_buf_append_u32(buf, handle); 258 + auth->session += 4; 259 + 260 + if (mso == TPM2_MSO_PERSISTENT || 261 + mso == TPM2_MSO_VOLATILE || 262 + mso == TPM2_MSO_NVRAM) { 263 + if (!name) 264 + tpm2_read_public(chip, handle, auth->name[slot]); 265 + } else { 266 + if (name) 267 + dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n"); 268 + } 269 + 270 + auth->name_h[slot] = handle; 271 + if (name) 272 + memcpy(auth->name[slot], name, name_size(name)); 273 + #endif 274 + } 275 + EXPORT_SYMBOL_GPL(tpm_buf_append_name); 276 + 277 + #ifdef CONFIG_TCG_TPM2_HMAC 278 + 279 + static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy, 280 + u32 *handle, u8 *name); 163 281 164 282 /* 165 283 * It turns out the crypto hmac(sha256) is hard for us to consume ··· 680 566 + auth->passphrase_len, hmac); 681 567 } 682 568 EXPORT_SYMBOL(tpm_buf_fill_hmac_session); 683 - 684 - static int tpm2_parse_read_public(char *name, struct tpm_buf *buf) 685 - { 686 - struct tpm_header *head = (struct tpm_header *)buf->data; 687 - off_t offset = TPM_HEADER_SIZE; 688 - u32 tot_len = be32_to_cpu(head->length); 689 - u32 val; 690 - 691 - /* we're starting after the header so adjust the length */ 692 - tot_len -= TPM_HEADER_SIZE; 693 - 694 - /* skip public */ 695 - val = tpm_buf_read_u16(buf, &offset); 696 - if (val > tot_len) 697 - return -EINVAL; 698 - offset += val; 699 - /* name */ 700 - val = tpm_buf_read_u16(buf, &offset); 701 - if (val != name_size(&buf->data[offset])) 702 - return -EINVAL; 703 - memcpy(name, &buf->data[offset], val); 704 - /* forget the rest */ 705 - return 0; 706 - } 707 - 708 - static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name) 709 - { 710 - struct tpm_buf buf; 711 - int rc; 712 - 713 - rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC); 714 - if (rc) 715 - return rc; 716 - 717 - tpm_buf_append_u32(&buf, handle); 718 - rc = tpm_transmit_cmd(chip, &buf, 0, "read public"); 719 - if (rc == TPM2_RC_SUCCESS) 720 - rc = tpm2_parse_read_public(name, &buf); 721 - 722 - tpm_buf_destroy(&buf); 723 - 724 - return rc; 725 - } 726 - 727 - /** 728 - * tpm_buf_append_name() - add a handle area to the buffer 729 - * @chip: the TPM chip structure 730 - * @buf: The buffer to be appended 731 - * @handle: The handle to be appended 732 - * @name: The name of the handle (may be NULL) 733 - * 734 - * In order to compute session HMACs, we need to know the names of the 735 - * objects pointed to by the handles. For most objects, this is simply 736 - * the actual 4 byte handle or an empty buf (in these cases @name 737 - * should be NULL) but for volatile objects, permanent objects and NV 738 - * areas, the name is defined as the hash (according to the name 739 - * algorithm which should be set to sha256) of the public area to 740 - * which the two byte algorithm id has been appended. For these 741 - * objects, the @name pointer should point to this. If a name is 742 - * required but @name is NULL, then TPM2_ReadPublic() will be called 743 - * on the handle to obtain the name. 744 - * 745 - * As with most tpm_buf operations, success is assumed because failure 746 - * will be caused by an incorrect programming model and indicated by a 747 - * kernel message. 748 - */ 749 - void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, 750 - u32 handle, u8 *name) 751 - { 752 - enum tpm2_mso_type mso = tpm2_handle_mso(handle); 753 - struct tpm2_auth *auth = chip->auth; 754 - int slot; 755 - 756 - slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE)/4; 757 - if (slot >= AUTH_MAX_NAMES) { 758 - dev_err(&chip->dev, "TPM: too many handles\n"); 759 - return; 760 - } 761 - WARN(auth->session != tpm_buf_length(buf), 762 - "name added in wrong place\n"); 763 - tpm_buf_append_u32(buf, handle); 764 - auth->session += 4; 765 - 766 - if (mso == TPM2_MSO_PERSISTENT || 767 - mso == TPM2_MSO_VOLATILE || 768 - mso == TPM2_MSO_NVRAM) { 769 - if (!name) 770 - tpm2_read_public(chip, handle, auth->name[slot]); 771 - } else { 772 - if (name) 773 - dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n"); 774 - } 775 - 776 - auth->name_h[slot] = handle; 777 - if (name) 778 - memcpy(auth->name[slot], name, name_size(name)); 779 - } 780 - EXPORT_SYMBOL(tpm_buf_append_name); 781 569 782 570 /** 783 571 * tpm_buf_check_hmac_response() - check the TPM return HMAC for correctness ··· 1327 1311 1328 1312 return rc; 1329 1313 } 1314 + #endif /* CONFIG_TCG_TPM2_HMAC */
+13 -10
include/linux/tpm.h
··· 490 490 { 491 491 } 492 492 #endif 493 + 494 + static inline struct tpm2_auth *tpm2_chip_auth(struct tpm_chip *chip) 495 + { 496 + #ifdef CONFIG_TCG_TPM2_HMAC 497 + return chip->auth; 498 + #else 499 + return NULL; 500 + #endif 501 + } 502 + 503 + void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, 504 + u32 handle, u8 *name); 505 + 493 506 #ifdef CONFIG_TCG_TPM2_HMAC 494 507 495 508 int tpm2_start_auth_session(struct tpm_chip *chip); 496 - void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, 497 - u32 handle, u8 *name); 498 509 void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf, 499 510 u8 attributes, u8 *passphrase, 500 511 int passphraselen); ··· 531 520 } 532 521 static inline void tpm2_end_auth_session(struct tpm_chip *chip) 533 522 { 534 - } 535 - static inline void tpm_buf_append_name(struct tpm_chip *chip, 536 - struct tpm_buf *buf, 537 - u32 handle, u8 *name) 538 - { 539 - tpm_buf_append_u32(buf, handle); 540 - /* count the number of handles in the upper bits of flags */ 541 - buf->handles++; 542 523 } 543 524 static inline void tpm_buf_append_hmac_session(struct tpm_chip *chip, 544 525 struct tpm_buf *buf,