From nobody Sat Feb 7 14:22:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2BFD92D3233; Tue, 2 Dec 2025 20:26:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764707216; cv=none; b=k5rNe/eqc192F0UjALs+bLq87LYEKCU0cqqax+BLVmzVG7dlz9DGMSUde9orgjicsf5iDrIoCPchU7aM63uQNTOmkp3BnmlzzfNKQ6WrvjhpTVbEqDr8MxbWOzk8c5/kBZB6Iqj+13vN6vSrfQZrttQ0y9lA2RI5mkQPJm3qlLI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764707216; c=relaxed/simple; bh=uesRYPc4HdFfnRydTNuhfupkkaD5Hsz5hKEBlMZ28Mc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=noLo7tf7naWSOJrro+uch738rUK67vhcFf1SbyAMZvvnpO3cYqgRmrjEn8iBPfFI1VzPEBNKL5S+y0666LwYPBQ0ST6guwNRYxWqmBL2lVxNkhTq26dlpiTrfRjDZsp1ur7GdpUZ1Gy68fvEIZS2RF2NaaaItdb4nhLZ4KeeRHs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dcI0uKcD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dcI0uKcD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1EFF8C4CEF1; Tue, 2 Dec 2025 20:26:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764707215; bh=uesRYPc4HdFfnRydTNuhfupkkaD5Hsz5hKEBlMZ28Mc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dcI0uKcDj9h7Kp1PBMgw9O5OjiXkE8W55dtYsIQw83seY+soDf/KGk+yF2LZYxeki CY7AQLgjsO8khB/7cLrMOvQfzY/n3RoOWGQ2UFfPsp+1NIfbYaOZKRADqhKb31ZZPy xZa1f5y8GURgpeqtJH3yk0j7/MzfuMXwNIZkrt9/46Gf2FnchxCGoQ5mJZoDLkWPab OISaxXPqwJDQzEaeMoYFFgUemz/eLDucmlzfUdniPuyju8qnHApbsYUvxQ+t+e9dI1 MJEYQ8QzaqUOFLiPo9RqIv/V5esQIQnddid6PhvIGwmCN/kd4d3jXGHVEtBIxnaP7m q9kJquc3zpHjw== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Jonathan McDowell , Peter Huewe , Jason Gunthorpe , linux-kernel@vger.kernel.org (open list), stable@vger.kernel.org, James Bottomley , Mimi Zohar , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , Ard Biesheuvel , keyrings@vger.kernel.org (open list:KEYS-TRUSTED), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v2 1/4] tpm2-sessions: fix out of range indexing in name_size Date: Tue, 2 Dec 2025 22:26:38 +0200 Message-ID: <20251202202643.107108-2-jarkko@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251202202643.107108-1-jarkko@kernel.org> References: <20251202202643.107108-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 'name_size' does not have any range checks, and it just directly indexes with TPM_ALG_ID, which could lead into memory corruption at worst. Address the issue by only processing known values and returning -EINVAL for unrecognized values. Make also 'tpm_buf_append_name' and 'tpm_buf_fill_hmac_session' fallible so that errors are detected before causing any spurious TPM traffic. End also the authorization session on failure in both of the functions, as the session state would be then by definition corrupted. Cc: stable@vger.kernel.org # v6.10+ Fixes: 1085b8276bb4 ("tpm: Add the rest of the session HMAC API") Signed-off-by: Jarkko Sakkinen --- v2: - Wrote a better short summary. - Addressed remarks in https://lore.kernel.org/linux-integrity/aS8TIeviaipp= VAha@earth.li/ - Use -EIO consistently in tpm2_fill_hmac_session. These are not input value errors. They could only spun from malformed (kernel) state. - name_size did not have a proper default-case. Reorganize the fallback into that. --- drivers/char/tpm/tpm2-cmd.c | 23 +++- drivers/char/tpm/tpm2-sessions.c | 133 +++++++++++++++------- include/linux/tpm.h | 6 +- security/keys/trusted-keys/trusted_tpm2.c | 29 ++++- 4 files changed, 138 insertions(+), 53 deletions(-) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 5b6ccf901623..4473b81122e8 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -187,7 +187,11 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, } =20 if (!disable_pcr_integrity) { - tpm_buf_append_name(chip, &buf, pcr_idx, NULL); + rc =3D tpm_buf_append_name(chip, &buf, pcr_idx, NULL); + if (rc) { + tpm_buf_destroy(&buf); + return rc; + } tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0); } else { tpm_buf_append_handle(chip, &buf, pcr_idx); @@ -202,8 +206,14 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, chip->allocated_banks[i].digest_size); } =20 - if (!disable_pcr_integrity) - tpm_buf_fill_hmac_session(chip, &buf); + if (!disable_pcr_integrity) { + rc =3D tpm_buf_fill_hmac_session(chip, &buf); + if (rc) { + tpm_buf_destroy(&buf); + return rc; + } + } + rc =3D tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value"); if (!disable_pcr_integrity) rc =3D tpm_buf_check_hmac_response(chip, &buf, rc); @@ -261,7 +271,12 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, s= ize_t max) | TPM2_SA_CONTINUE_SESSION, NULL, 0); tpm_buf_append_u16(&buf, num_bytes); - tpm_buf_fill_hmac_session(chip, &buf); + err =3D tpm_buf_fill_hmac_session(chip, &buf); + if (err) { + tpm_buf_destroy(&buf); + return err; + } + err =3D tpm_transmit_cmd(chip, &buf, offsetof(struct tpm2_get_random_out, buffer), diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessi= ons.c index 6d03c224e6b2..dc6bee7e1ef6 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -144,16 +144,23 @@ struct tpm2_auth { /* * Name Size based on TPM algorithm (assumes no hash bigger than 255) */ -static u8 name_size(const u8 *name) +static int name_size(const u8 *name) { - static u8 size_map[] =3D { - [TPM_ALG_SHA1] =3D SHA1_DIGEST_SIZE, - [TPM_ALG_SHA256] =3D SHA256_DIGEST_SIZE, - [TPM_ALG_SHA384] =3D SHA384_DIGEST_SIZE, - [TPM_ALG_SHA512] =3D SHA512_DIGEST_SIZE, - }; - u16 alg =3D get_unaligned_be16(name); - return size_map[alg] + 2; + u16 hash_alg =3D get_unaligned_be16(name); + + switch (hash_alg) { + case TPM_ALG_SHA1: + return SHA1_DIGEST_SIZE + 2; + case TPM_ALG_SHA256: + return SHA256_DIGEST_SIZE + 2; + case TPM_ALG_SHA384: + return SHA384_DIGEST_SIZE + 2; + case TPM_ALG_SHA512: + return SHA512_DIGEST_SIZE + 2; + default: + pr_warn("tpm: invalid name algorithm: 0x%04\n", hash_alg); + return -EINVAL; + } } =20 static int tpm2_parse_read_public(char *name, struct tpm_buf *buf) @@ -161,6 +168,7 @@ static int tpm2_parse_read_public(char *name, struct tp= m_buf *buf) struct tpm_header *head =3D (struct tpm_header *)buf->data; off_t offset =3D TPM_HEADER_SIZE; u32 tot_len =3D be32_to_cpu(head->length); + int ret; u32 val; =20 /* we're starting after the header so adjust the length */ @@ -172,9 +180,15 @@ static int tpm2_parse_read_public(char *name, struct t= pm_buf *buf) return -EINVAL; offset +=3D val; /* name */ + val =3D tpm_buf_read_u16(buf, &offset); - if (val !=3D name_size(&buf->data[offset])) + ret =3D name_size(&buf->data[offset]); + if (ret < 0) + return ret; + + if (val !=3D ret) return -EINVAL; + memcpy(name, &buf->data[offset], val); /* forget the rest */ return 0; @@ -221,46 +235,72 @@ static int tpm2_read_public(struct tpm_chip *chip, u3= 2 handle, char *name) * As with most tpm_buf operations, success is assumed because failure * will be caused by an incorrect programming model and indicated by a * kernel message. + * + * Ends the authorization session on failure. */ -void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, - u32 handle, u8 *name) +int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, + u32 handle, u8 *name) { #ifdef CONFIG_TCG_TPM2_HMAC enum tpm2_mso_type mso =3D tpm2_handle_mso(handle); struct tpm2_auth *auth; int slot; + int ret; #endif =20 if (!tpm2_chip_auth(chip)) { tpm_buf_append_handle(chip, buf, handle); - return; + return 0; } =20 #ifdef CONFIG_TCG_TPM2_HMAC slot =3D (tpm_buf_length(buf) - TPM_HEADER_SIZE) / 4; if (slot >=3D AUTH_MAX_NAMES) { - dev_err(&chip->dev, "TPM: too many handles\n"); - return; + dev_err(&chip->dev, "too many handles\n"); + ret =3D -EIO; + goto err; } auth =3D chip->auth; - WARN(auth->session !=3D tpm_buf_length(buf), - "name added in wrong place\n"); + if (auth->session !=3D tpm_buf_length(buf)) { + dev_err(&chip->dev, "session state malformed"); + ret =3D -EIO; + goto err; + } tpm_buf_append_u32(buf, handle); auth->session +=3D 4; =20 if (mso =3D=3D TPM2_MSO_PERSISTENT || mso =3D=3D TPM2_MSO_VOLATILE || mso =3D=3D TPM2_MSO_NVRAM) { - if (!name) - tpm2_read_public(chip, handle, auth->name[slot]); + if (!name) { + ret =3D tpm2_read_public(chip, handle, auth->name[slot]); + if (ret) + goto err; + } } else { - if (name) - dev_err(&chip->dev, "TPM: Handle does not require name but one is speci= fied\n"); + if (name) { + dev_err(&chip->dev, "handle 0x%08x does not use a name\n", + handle); + ret =3D -EIO; + goto err; + } } =20 auth->name_h[slot] =3D handle; - if (name) - memcpy(auth->name[slot], name, name_size(name)); + if (name) { + ret =3D name_size(name); + if (ret < 0) + goto err; + + memcpy(auth->name[slot], name, ret); + } +#endif + return 0; + +#ifdef CONFIG_TCG_TPM2_HMAC +err: + tpm2_end_auth_session(chip); + return tpm_ret_to_err(ret); #endif } EXPORT_SYMBOL_GPL(tpm_buf_append_name); @@ -533,11 +573,9 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, s= truct tpm_chip *chip, * encryption key and encrypts the first parameter of the command * buffer with it. * - * As with most tpm_buf operations, success is assumed because failure - * will be caused by an incorrect programming model and indicated by a - * kernel message. + * Ends the authorization session on failure. */ -void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) +int tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) { u32 cc, handles, val; struct tpm2_auth *auth =3D chip->auth; @@ -549,9 +587,12 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, = struct tpm_buf *buf) u8 cphash[SHA256_DIGEST_SIZE]; struct sha256_ctx sctx; struct hmac_sha256_ctx hctx; + int ret; =20 - if (!auth) - return; + if (!auth) { + ret =3D -EIO; + goto err; + } =20 /* save the command code in BE format */ auth->ordinal =3D head->ordinal; @@ -560,9 +601,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, = struct tpm_buf *buf) =20 i =3D tpm2_find_cc(chip, cc); if (i < 0) { - dev_err(&chip->dev, "Command 0x%x not found in TPM\n", cc); - return; + dev_err(&chip->dev, "command 0x%08x not found\n", cc); + ret =3D -EIO; + goto err; } + attrs =3D chip->cc_attrs_tbl[i]; =20 handles =3D (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0); @@ -576,9 +619,9 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, s= truct tpm_buf *buf) u32 handle =3D tpm_buf_read_u32(buf, &offset_s); =20 if (auth->name_h[i] !=3D handle) { - dev_err(&chip->dev, "TPM: handle %d wrong for name\n", - i); - return; + dev_err(&chip->dev, "invalid handle 0x%08x\n", handle); + ret =3D -EIO; + goto err; } } /* point offset_s to the start of the sessions */ @@ -609,12 +652,14 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip,= struct tpm_buf *buf) offset_s +=3D len; } if (offset_s !=3D offset_p) { - dev_err(&chip->dev, "TPM session length is incorrect\n"); - return; + dev_err(&chip->dev, "session length is incorrect\n"); + ret =3D -EIO; + goto err; } if (!hmac) { - dev_err(&chip->dev, "TPM could not find HMAC session\n"); - return; + dev_err(&chip->dev, "could not find HMAC session\n"); + ret =3D -EIO; + goto err; } =20 /* encrypt before HMAC */ @@ -646,8 +691,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, = struct tpm_buf *buf) if (mso =3D=3D TPM2_MSO_PERSISTENT || mso =3D=3D TPM2_MSO_VOLATILE || mso =3D=3D TPM2_MSO_NVRAM) { - sha256_update(&sctx, auth->name[i], - name_size(auth->name[i])); + ret =3D name_size(auth->name[i]); + if (ret < 0) + goto err; + + sha256_update(&sctx, auth->name[i], ret); } else { __be32 h =3D cpu_to_be32(auth->name_h[i]); =20 @@ -668,6 +716,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, = struct tpm_buf *buf) hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce)); hmac_sha256_update(&hctx, &auth->attrs, 1); hmac_sha256_final(&hctx, hmac); + return 0; + +err: + tpm2_end_auth_session(chip); + return ret; } EXPORT_SYMBOL(tpm_buf_fill_hmac_session); =20 diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 0e9e043f728c..1a59f0190eb3 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -528,8 +528,8 @@ static inline struct tpm2_auth *tpm2_chip_auth(struct t= pm_chip *chip) #endif } =20 -void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, - u32 handle, u8 *name); +int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, + u32 handle, u8 *name); void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *bu= f, u8 attributes, u8 *passphrase, int passphraselen); @@ -562,7 +562,7 @@ static inline void tpm_buf_append_hmac_session_opt(stru= ct tpm_chip *chip, #ifdef CONFIG_TCG_TPM2_HMAC =20 int tpm2_start_auth_session(struct tpm_chip *chip); -void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf); +int tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf); int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf, int rc); void tpm2_end_auth_session(struct tpm_chip *chip); diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trus= ted-keys/trusted_tpm2.c index e165b117bbca..7672a4376dad 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -283,7 +283,10 @@ int tpm2_seal_trusted(struct tpm_chip *chip, goto out_put; } =20 - tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); + rc =3D tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); + if (rc) + goto out; + tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_DECRYPT, options->keyauth, TPM_DIGEST_SIZE); =20 @@ -331,7 +334,10 @@ int tpm2_seal_trusted(struct tpm_chip *chip, goto out; } =20 - tpm_buf_fill_hmac_session(chip, &buf); + rc =3D tpm_buf_fill_hmac_session(chip, &buf); + if (rc) + goto out; + rc =3D tpm_transmit_cmd(chip, &buf, 4, "sealing data"); rc =3D tpm_buf_check_hmac_response(chip, &buf, rc); if (rc) @@ -438,7 +444,10 @@ static int tpm2_load_cmd(struct tpm_chip *chip, return rc; } =20 - tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); + rc =3D tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); + if (rc) + goto out; + tpm_buf_append_hmac_session(chip, &buf, 0, options->keyauth, TPM_DIGEST_SIZE); =20 @@ -450,7 +459,10 @@ static int tpm2_load_cmd(struct tpm_chip *chip, goto out; } =20 - tpm_buf_fill_hmac_session(chip, &buf); + rc =3D tpm_buf_fill_hmac_session(chip, &buf); + if (rc) + goto out; + rc =3D tpm_transmit_cmd(chip, &buf, 4, "loading blob"); rc =3D tpm_buf_check_hmac_response(chip, &buf, rc); if (!rc) @@ -497,7 +509,9 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, return rc; } =20 - tpm_buf_append_name(chip, &buf, blob_handle, NULL); + rc =3D tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); + if (rc) + goto out; =20 if (!options->policyhandle) { tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT, @@ -522,7 +536,10 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, NULL, 0); } =20 - tpm_buf_fill_hmac_session(chip, &buf); + rc =3D tpm_buf_fill_hmac_session(chip, &buf); + if (rc) + goto out; + rc =3D tpm_transmit_cmd(chip, &buf, 6, "unsealing"); rc =3D tpm_buf_check_hmac_response(chip, &buf, rc); =20 --=20 2.52.0 From nobody Sat Feb 7 14:22:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E75F02F3605; Tue, 2 Dec 2025 20:27:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764707221; cv=none; b=eDvuuSW2aHVaGfGsTOyR/CwS/QtAwWpBm7C9DivTTTUMkJ6sMntvXWhG1nYnVA5TzWlBd2UqqS2zwqZJHglJzXei2SlfH45U68v9jCVaxRq1R2T4spoAfFpFxD4nQOYqtmF6fbARGTvuoHo6iANjtNE0bFH2GZHrwJTmgbTR32Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764707221; c=relaxed/simple; bh=A+KBwrEGw+Q66tMB4kTs9WcRGbEetXnPSCqTR053tDw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lgXUTaCA6M1zA0WDAcNMpUWCFSmj97I4NMFRSYnTN4nSVvAsp7q3hLIc+dMUC+xfx/v4YRDfZ4/xCANHuZb5k5afNubS/SJg158L539fFWeoi8IVjJwq0QN/pZn1H5ADIq4Klb2M0VsHYO0BtDE36S+x0iZSDWdgVO6bmKWbiBE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QFIapIWz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QFIapIWz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5561AC4CEF1; Tue, 2 Dec 2025 20:27:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764707220; bh=A+KBwrEGw+Q66tMB4kTs9WcRGbEetXnPSCqTR053tDw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QFIapIWzY+MIBJRg1ScP2oZerWjda600/KK2nRiuO1AtMLARD85UfgzRL5pQW6irK qZcPJ8AWrNSucLAt6yWG8Hr6nkAxLWd7WITajMeG5QFYLQXvw2tdzl29RCuG4r6E4X 5dpAhq0t030HL+nauGxOPEwImOwoK48V2OAdrmQ7hk0IUrJSyQ/heldRGsF0ZvjokJ GWvMovmnWn+QMLYtBDF6f+RY69LhJWz36XiSsZySikguaFKQWAVxzKyI8G6ptPH+z1 D5qzT98EVSA/5wlhZMTvf7XwJ2iQuOyVeeAvCPzjED10aCTt/MfSyE7eBYxVIUKpEl ReTrm3XE5Y7rw== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Jonathan McDowell , Peter Huewe , Jason Gunthorpe , linux-kernel@vger.kernel.org (open list), stable@vger.kernel.org, James Bottomley , Ard Biesheuvel Subject: [PATCH v2 2/4] tpm2-sessions: Fix tpm2_read_public range checks Date: Tue, 2 Dec 2025 22:26:39 +0200 Message-ID: <20251202202643.107108-3-jarkko@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251202202643.107108-1-jarkko@kernel.org> References: <20251202202643.107108-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 'tpm2_read_public' has some rudimentary range checks but the function does not ensure that the response buffer has enough bytes for the full TPMT_HA payload. Re-implement the function with necessary checks and validation. Cc: stable@vger.kernel.org # v6.10+ Fixes: d0a25bb961e6 ("tpm: Add HMAC session name/handle append") Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm2-cmd.c | 3 ++ drivers/char/tpm/tpm2-sessions.c | 77 +++++++++++++++++--------------- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 4473b81122e8..58a8477cda85 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -11,8 +11,11 @@ * used by the kernel internally. */ =20 +#include "linux/dev_printk.h" +#include "linux/tpm.h" #include "tpm.h" #include +#include =20 static bool disable_pcr_integrity; module_param(disable_pcr_integrity, bool, 0444); diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessi= ons.c index dc6bee7e1ef6..964f44c2255d 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -163,54 +163,59 @@ static int name_size(const u8 *name) } } =20 -static int tpm2_parse_read_public(char *name, struct tpm_buf *buf) +static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name) { - struct tpm_header *head =3D (struct tpm_header *)buf->data; + u32 mso =3D tpm2_handle_mso(handle); off_t offset =3D TPM_HEADER_SIZE; - u32 tot_len =3D be32_to_cpu(head->length); - int ret; - u32 val; - - /* we're starting after the header so adjust the length */ - tot_len -=3D TPM_HEADER_SIZE; - - /* skip public */ - val =3D tpm_buf_read_u16(buf, &offset); - if (val > tot_len) - return -EINVAL; - offset +=3D val; - /* name */ - - val =3D tpm_buf_read_u16(buf, &offset); - ret =3D name_size(&buf->data[offset]); - if (ret < 0) - return ret; + struct tpm_buf buf; + int rc, rc2; =20 - if (val !=3D ret) + if (mso !=3D TPM2_MSO_PERSISTENT && mso !=3D TPM2_MSO_VOLATILE && + mso !=3D TPM2_MSO_NVRAM) return -EINVAL; =20 - memcpy(name, &buf->data[offset], val); - /* forget the rest */ - return 0; -} - -static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name) -{ - struct tpm_buf buf; - int rc; - rc =3D tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC); if (rc) return rc; =20 tpm_buf_append_u32(&buf, handle); - rc =3D tpm_transmit_cmd(chip, &buf, 0, "read public"); - if (rc =3D=3D TPM2_RC_SUCCESS) - rc =3D tpm2_parse_read_public(name, &buf); =20 - tpm_buf_destroy(&buf); + rc =3D tpm_transmit_cmd(chip, &buf, 0, "TPM2_ReadPublic"); + if (rc) { + tpm_buf_destroy(&buf); + return tpm_ret_to_err(rc); + } =20 - return rc; + /* Skip TPMT_PUBLIC: */ + offset +=3D tpm_buf_read_u16(&buf, &offset); + + /* + * Ensure space for the length field of TPM2B_NAME and hashAlg field of + * TPMT_HA (the extra four bytes). + */ + if (offset + 4 > tpm_buf_length(&buf)) { + tpm_buf_destroy(&buf); + return -EIO; + } + + rc =3D tpm_buf_read_u16(&buf, &offset); + rc2 =3D name_size(&buf.data[offset]); + + if (rc2 < 0) + return rc2; + + if (rc !=3D rc2) { + tpm_buf_destroy(&buf); + return -EIO; + } + + if (offset + rc > tpm_buf_length(&buf)) { + tpm_buf_destroy(&buf); + return -EIO; + } + + memcpy(name, &buf.data[offset], rc); + return 0; } #endif /* CONFIG_TCG_TPM2_HMAC */ =20 --=20 2.52.0 From nobody Sat Feb 7 14:22:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 456AF2F1FE1; Tue, 2 Dec 2025 20:27:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764707226; cv=none; b=Xd8XzzILQfcDmeJyEhEb5nBqTkZD1cz91nh6Hj7iGadBIhLW8r1h1o2mMy1A7mgbQ+j4ZYmM7Py+yfb0RZO0U9gjZnBFVUfF/L+Z5ovr1oYhE82azRbZLGAQnnuJLuo2RXxGuUm5dZSC8k2f7edP0SXMXJ6MnRJBV7w/747htAs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764707226; c=relaxed/simple; bh=/fz2gUtisQmjO8JJgmrs1qRb3Vmy/w9noIBBKmaqlK0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QwQ13Dg/9/Y46W3mZ+jACNEX20qwBU9wW6OjFbxfQSzRaFvvxYEjkEC8V/xTrLHZwq6df1FK4+DgmSZW0295XGOzToHGsz7QPDHh/PINxxhQb2esHDbGrwxcrSKfIxi5/5eZGEjfAGv6g0HGU+uSqThtE8SbwQSXFNbVmDpsf5g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NMR3LB2g; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NMR3LB2g" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8A5ABC16AAE; Tue, 2 Dec 2025 20:27:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764707226; bh=/fz2gUtisQmjO8JJgmrs1qRb3Vmy/w9noIBBKmaqlK0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NMR3LB2gcC+ejHFCf9gir9sii6ZjWguwj+vBBU/OZjTGVhyLTbCRJYO9TAIxWKz5N FKXd+pbDA+SEJ3T2XTjS1aVDXjew52orl8M8K3LztC/L2BWAVT7p+VStl4Hbw94vsp srC+2S3ec2/EOFf7DBLcS7+UBXvOcS/80sRt4JPV0JlSV8jy4qn5UPApT/JVQY+Uxa EieAZpe9ngvxHMLUt11oHg20aG5uElpsLFSgEGdCzDfpq2fENth2aiUqSa6VBurGAV pUfXGmaCenAC8PO3UJZIbTFKLJdAHhHiNBojibUHFZX243DnWK+3JD04UluFifi3qz o0Y8lf8fkwhEA== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Jonathan McDowell , Peter Huewe , Jason Gunthorpe , linux-kernel@vger.kernel.org (open list), Jarkko Sakkinen , Jonathan McDowell , Roberto Sassu , Mimi Zohar Subject: [PATCH v2 3/4] tpm2-sessions: Remove 'attributes' parameter from tpm_buf_append_auth Date: Tue, 2 Dec 2025 22:26:40 +0200 Message-ID: <20251202202643.107108-4-jarkko@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251202202643.107108-1-jarkko@kernel.org> References: <20251202202643.107108-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Jarkko Sakkinen Remove 'attributes' parameter from 'tpm_buf_append_auth', as it is not used by the function. Fixes: 27184f8905ba ("tpm: Opt-in in disable PCR integrity protection") Signed-off-by: Jarkko Sakkinen Reviewed-by: Jonathan McDowell --- drivers/char/tpm/tpm2-cmd.c | 2 +- drivers/char/tpm/tpm2-sessions.c | 5 ++--- include/linux/tpm.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 58a8477cda85..f1e9c35f13a2 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -198,7 +198,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0); } else { tpm_buf_append_handle(chip, &buf, pcr_idx); - tpm_buf_append_auth(chip, &buf, 0, NULL, 0); + tpm_buf_append_auth(chip, &buf, NULL, 0); } =20 tpm_buf_append_u32(&buf, chip->nr_allocated_banks); diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessi= ons.c index 964f44c2255d..7c7a9bc6ba2d 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -311,7 +311,7 @@ int tpm_buf_append_name(struct tpm_chip *chip, struct t= pm_buf *buf, EXPORT_SYMBOL_GPL(tpm_buf_append_name); =20 void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf, - u8 attributes, u8 *passphrase, int passphrase_len) + u8 *passphrase, int passphrase_len) { /* offset tells us where the sessions area begins */ int offset =3D buf->handles * 4 + TPM_HEADER_SIZE; @@ -372,8 +372,7 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip,= struct tpm_buf *buf, #endif =20 if (!tpm2_chip_auth(chip)) { - tpm_buf_append_auth(chip, buf, attributes, passphrase, - passphrase_len); + tpm_buf_append_auth(chip, buf, passphrase, passphrase_len); return; } =20 diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 1a59f0190eb3..e3a6e2fb41a7 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -534,7 +534,7 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip,= struct tpm_buf *buf, u8 attributes, u8 *passphrase, int passphraselen); void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf, - u8 attributes, u8 *passphrase, int passphraselen); + u8 *passphrase, int passphraselen); static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip, struct tpm_buf *buf, u8 attributes, --=20 2.52.0 From nobody Sat Feb 7 14:22:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3F1B2D6E6F; Tue, 2 Dec 2025 20:27:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764707231; cv=none; b=TBONjGdbvAff8r4fYIkiYtAG0ZqkqI8jy9gmdLu8H7i1JHW3VRswZL+WtAFs+/3aTZNHX9xDejdsndr4mDq8GXVzyiM13/hRIup6rItg1iktc5iPEit9LpsHPmhbrlN+TDkk1GVTci7l1NF2zAsNJfFFoukg7ShstA5A1z2LOOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764707231; c=relaxed/simple; bh=lgzJIxyw6/fGv4S6vguA3WAKPvQipuquULpWPkSgse4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qA/6rsCNCWhoHcNutiapf5LnikTqMDQlB7yN9QiGyptD5xskxWhNKPafE9ea3jmP2LTPHdh2/WqmtBn64D2YyMxDb4sh+JJ4LRImQBc8wnqb4NWiVNzDCRrt11FfAHX9spBIDr3O/ZvFToGyCOZfffDCWhI1+lVyfDdxl3OkTLA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YczLsO4D; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YczLsO4D" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A8CCCC4CEF1; Tue, 2 Dec 2025 20:27:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764707231; bh=lgzJIxyw6/fGv4S6vguA3WAKPvQipuquULpWPkSgse4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YczLsO4D1DR4iLeMTuHalJrp+a6pXe7FM3aDkn4GfkOkxzT7s5s9G2nAXnp+lBWo/ o52XlWvPxtwV7H7qq/wiNX1ChQ7dGiSPPgtNXaeT/ZV7YKyuqjDCk5PutC9bHSlkZT iPq8NYWAEJp2H2No35n7Jv3TEv9990BilqnH7FMojESQzGKDXP/InqVxksck6RXvst m2dg7xU2FzKahQFtt57mLki3giACFCcBf27DxvgIp7EbDaAxnx6Vl81DbmvJk4QoUS LZUcZSrwbWOAtiuPD7FXpW/Gsc2+r+ZJyJiLGVVyEArRvebrA6k1X9p3bKbSS6oas4 85ofWgVzJyudw== From: Jarkko Sakkinen To: linux-integrity@vger.kernel.org Cc: Jarkko Sakkinen , Jonathan McDowell , Peter Huewe , Jason Gunthorpe , linux-kernel@vger.kernel.org (open list), Jarkko Sakkinen , Jonathan McDowell , James Bottomley , Mimi Zohar , David Howells , Paul Moore , James Morris , "Serge E. Hallyn" , keyrings@vger.kernel.org (open list:KEYS-TRUSTED), linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) Subject: [PATCH v2 4/4] tpm2-sessions: Open code tpm_buf_append_hmac_session() Date: Tue, 2 Dec 2025 22:26:41 +0200 Message-ID: <20251202202643.107108-5-jarkko@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251202202643.107108-1-jarkko@kernel.org> References: <20251202202643.107108-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Jarkko Sakkinen Open code 'tpm_buf_append_hmac_session_opt' to the call site, as it only masks a call sequence and does otherwise nothing particularly useful. Signed-off-by: Jarkko Sakkinen Reviewed-by: Jonathan McDowell --- drivers/char/tpm/tpm2-cmd.c | 14 +++++++++++--- include/linux/tpm.h | 23 ----------------------- security/keys/trusted-keys/trusted_tpm2.c | 12 ++++++++++-- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index f1e9c35f13a2..94cb887cb4a9 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -270,9 +270,17 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, s= ize_t max) =20 do { tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM); - tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT - | TPM2_SA_CONTINUE_SESSION, - NULL, 0); + if (tpm2_chip_auth(chip)) { + tpm_buf_append_hmac_session(chip, &buf, + TPM2_SA_ENCRYPT | + TPM2_SA_CONTINUE_SESSION, + NULL, 0); + } else { + offset =3D buf.handles * 4 + TPM_HEADER_SIZE; + head =3D (struct tpm_header *)buf.data; + if (tpm_buf_length(&buf) =3D=3D offset) + head->tag =3D cpu_to_be16(TPM2_ST_NO_SESSIONS); + } tpm_buf_append_u16(&buf, num_bytes); err =3D tpm_buf_fill_hmac_session(chip, &buf); if (err) { diff --git a/include/linux/tpm.h b/include/linux/tpm.h index e3a6e2fb41a7..a93df0efebe4 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -535,29 +535,6 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip= , struct tpm_buf *buf, int passphraselen); void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf, u8 *passphrase, int passphraselen); -static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip, - struct tpm_buf *buf, - u8 attributes, - u8 *passphrase, - int passphraselen) -{ - struct tpm_header *head; - int offset; - - if (tpm2_chip_auth(chip)) { - tpm_buf_append_hmac_session(chip, buf, attributes, passphrase, passphras= elen); - } else { - offset =3D buf->handles * 4 + TPM_HEADER_SIZE; - head =3D (struct tpm_header *)buf->data; - - /* - * If the only sessions are optional, the command tag must change to - * TPM2_ST_NO_SESSIONS. - */ - if (tpm_buf_length(buf) =3D=3D offset) - head->tag =3D cpu_to_be16(TPM2_ST_NO_SESSIONS); - } -} =20 #ifdef CONFIG_TCG_TPM2_HMAC =20 diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trus= ted-keys/trusted_tpm2.c index 7672a4376dad..e6b95111ac7d 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -494,8 +494,10 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, struct trusted_key_options *options, u32 blob_handle) { + struct tpm_header *head; struct tpm_buf buf; u16 data_len; + int offset; u8 *data; int rc; =20 @@ -532,8 +534,14 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, tpm2_buf_append_auth(&buf, options->policyhandle, NULL /* nonce */, 0, 0, options->blobauth, options->blobauth_len); - tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT, - NULL, 0); + if (tpm2_chip_auth(chip)) { + tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT, NULL, 0); + } else { + offset =3D buf.handles * 4 + TPM_HEADER_SIZE; + head =3D (struct tpm_header *)buf.data; + if (tpm_buf_length(&buf) =3D=3D offset) + head->tag =3D cpu_to_be16(TPM2_ST_NO_SESSIONS); + } } =20 rc =3D tpm_buf_fill_hmac_session(chip, &buf); --=20 2.52.0