Re: [PATCH] KEYS: trusted: Fix TPM teardown ordering

Jarkko Sakkinen <[email protected]>
Newsgroups org.kernel.vger.keyrings,org.kernel.vger.linux-integrity,org.kernel.vger.linux-kernel,org.kernel.vger.linux-security-module,org.kernel.vger.stable
Message-ID <[email protected]>
On Fri, Jul 31, 2026 at 10:09:24PM +0800, Chengfeng Ye wrote:
> trusted_tpm_exit() drops the TPM chip reference and frees the digest
> array before unregistering the trusted key type. key_type_lookup()
> holds key_types_sem for reading until the key operation finishes, while
> unregister_key_type() takes it for writing. It therefore provides the
> synchronization point that must precede backend teardown.
> 
> The current order permits this interleaving:
> 
>   CPU 0                              CPU 1
>   trusted_tpm_exit()                 key_type_lookup("trusted")
>     put_device(&chip->dev)             trusted_tpm_seal()
>     kfree(digests)                       pcrlock()
>     unregister_key_type()                  tpm_pcr_extend(..., digests)
> 
> CPU 1 can consequently dereference the freed digest array. The chip can
> also be released before callbacks stop using it.
> 
> KASAN reported:
> 
>   BUG: KASAN: slab-use-after-free in tpm_pcr_extend+0x1f0/0x200
>   Read of size 2 at addr ffff88810872d000 by task poc/89
>   Call Trace:
>     tpm_pcr_extend+0x1f0/0x200
>     pcrlock+0x42/0x70 [trusted]
>     trusted_tpm_seal+0x1b6/0x570 [trusted]
>     trusted_instantiate+0x293/0x340 [trusted]
>     __key_instantiate_and_link+0xb2/0x2b0
>     __key_create_or_update+0x61e/0xb50
>     __do_sys_add_key+0x1b8/0x310
>   Allocated by task 88:
>     __kmalloc_noprof+0x1a7/0x490
>     do_one_initcall+0xa1/0x390
>     do_init_module+0x2df/0x840
>   Freed by task 90:
>     kfree+0x131/0x3c0
>     trusted_tpm_exit+0x59/0xa0 [trusted]
>     __do_sys_delete_module+0x346/0x510
> 
> Move unregister_key_type() before releasing either resource. This stops
> new lookups and waits for in-flight key operations to finish before the
> backend state is destroyed.

Thank for the great report.

> 
> Fixes: 0b6cf6b97b7e ("tpm: pass an array of tpm_extend_digest structures to tpm_pcr_extend()")
> Cc: [email protected]
> Signed-off-by: Chengfeng Ye <[email protected]>
> ---
>  security/keys/trusted-keys/trusted_tpm1.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
> index 13513819991e..8f57c6111e7e 100644
> --- a/security/keys/trusted-keys/trusted_tpm1.c
> +++ b/security/keys/trusted-keys/trusted_tpm1.c
> @@ -987,9 +987,9 @@ static int __init trusted_tpm_init(void)
>  static void trusted_tpm_exit(void)
>  {
>  	if (chip) {
> +		unregister_key_type(&key_type_trusted);
>  		put_device(&chip->dev);
>  		kfree(digests);
> -		unregister_key_type(&key_type_trusted);
>  	}
>  }
>  
> -- 
> 2.43.0
> 

Reviewed-by: Jarkko Sakkinen <[email protected]>

BR, Jarkko
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.