[PATCH v4] ima_fs: Avoid creating measurement lists for unsupported hash algos
Roberto Sassu
roberto.sassu at huaweicloud.com
Thu Feb 19 08:54:57 UTC 2026
On Tue, 2026-01-27 at 16:20 +0100, Roberto Sassu wrote:
> On Tue, 2026-01-27 at 15:03 +0000, Dmitry Safonov via B4 Relay wrote:
> > From: Dmitry Safonov <dima at arista.com>
> >
> > ima_init_crypto() skips initializing ima_algo_array[i] if the algorithm
> > from ima_tpm_chip->allocated_banks[i].crypto_id is not supported.
> > It seems avoid adding the unsupported algorithm to ima_algo_array will
> > break all the logic that relies on indexing by NR_BANKS(ima_tpm_chip).
>
> The patch looks good, although I didn't try yet myself.
>
> I would make the commit message slightly better, with a more fluid
> explanation.
>
> ima_tpm_chip->allocated_banks[i].crypto_id is initialized to
> HASH_ALGO__LAST if the TPM algorithm is not supported. However there
> are places relying on the algorithm to be valid because it is accessed
> by hash_algo_name[].
>
> Thus solve the problem by creating a file name that does not depend on
> the crypto algorithm to be initialized, ...
>
> Also print the template entry digest as populated by IMA.
>
> Something along these lines.
>
> Also, I have a preference for lower case instead of capital case for
> the file name, given the other names.
Hi Dmitry
do you have time to make these small changes, so that we queue the
patch for the next kernel?
Thanks
Roberto
> Could you also avoid the >, otherwise the mailer thinks it is a reply?
>
> Thanks
>
> Roberto
>
> > On 6.12.40 I observe the following read out-of-bounds in hash_algo_name:
> >
> > > ==================================================================
> > > BUG: KASAN: global-out-of-bounds in create_securityfs_measurement_lists+0x396/0x440
> > > Read of size 8 at addr ffffffff83e18138 by task swapper/0/1
> > >
> > > CPU: 4 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.12.40 #3
> > > Call Trace:
> > > <TASK>
> > > dump_stack_lvl+0x61/0x90
> > > print_report+0xc4/0x580
> > > ? kasan_addr_to_slab+0x26/0x80
> > > ? create_securityfs_measurement_lists+0x396/0x440
> > > kasan_report+0xc2/0x100
> > > ? create_securityfs_measurement_lists+0x396/0x440
> > > create_securityfs_measurement_lists+0x396/0x440
> > > ima_fs_init+0xa3/0x300
> > > ima_init+0x7d/0xd0
> > > init_ima+0x28/0x100
> > > do_one_initcall+0xa6/0x3e0
> > > kernel_init_freeable+0x455/0x740
> > > kernel_init+0x24/0x1d0
> > > ret_from_fork+0x38/0x80
> > > ret_from_fork_asm+0x11/0x20
> > > </TASK>
> > >
> > > The buggy address belongs to the variable:
> > > hash_algo_name+0xb8/0x420
> > >
> > > The buggy address belongs to the physical page:
> > > page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x107ce18
> > > flags: 0x8000000000002000(reserved|zone=2)
> > > raw: 8000000000002000 ffffea0041f38608 ffffea0041f38608 0000000000000000
> > > raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
> > > page dumped because: kasan: bad access detected
> > >
> > > Memory state around the buggy address:
> > > ffffffff83e18000: 00 01 f9 f9 f9 f9 f9 f9 00 01 f9 f9 f9 f9 f9 f9
> > > ffffffff83e18080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > > > ffffffff83e18100: 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 00 05 f9 f9
> > > ^
> > > ffffffff83e18180: f9 f9 f9 f9 00 00 00 00 00 00 00 04 f9 f9 f9 f9
> > > ffffffff83e18200: 00 00 00 00 00 00 00 00 04 f9 f9 f9 f9 f9 f9 f9
> > > ==================================================================
> >
> > Seems like the TPM chip supports sha3_256, which isn't yet in
> > tpm_algorithms:
> > > tpm tpm0: TPM with unsupported bank algorithm 0x0027
> >
> > Use TPM_ALG_<ID> as a postfix for file names for unsupported hashing algorithms.
> >
> > This is how it looks on the test machine I have:
> > > # ls -1 /sys/kernel/security/ima/
> > > ascii_runtime_measurements
> > > ascii_runtime_measurements_TPM_ALG_27
> > > ascii_runtime_measurements_sha1
> > > ascii_runtime_measurements_sha256
> > > binary_runtime_measurements
> > > binary_runtime_measurements_TPM_ALG_27
> > > binary_runtime_measurements_sha1
> > > binary_runtime_measurements_sha256
> > > policy
> > > runtime_measurements_count
> > > violations
> >
> > Fixes: 9fa8e7625008 ("ima: add crypto agility support for template-hash algorithm")
> > Signed-off-by: Dmitry Safonov <dima at arista.com>
> > Cc: Enrico Bravi <enrico.bravi at polito.it>
> > Cc: Silvia Sisinni <silvia.sisinni at polito.it>
> > Cc: Roberto Sassu <roberto.sassu at huawei.com>
> > Cc: Mimi Zohar <zohar at linux.ibm.com>
> > ---
> > Changes in v4:
> > - Use ima_tpm_chip->allocated_banks[algo_idx].digest_size instead of hash_digest_size[algo]
> > (Roberto Sassu)
> > - Link to v3: https://lore.kernel.org/r/20260127-ima-oob-v3-1-1dd09f4c2a6a@arista.com
> > Testing note: I test it on v6.12.40 kernel backport, which slightly differs as
> > lookup_template_data_hash_algo() was yet present.
> >
> > Changes in v3:
> > - Now fix the spelling *for real* (sorry, messed it up in v2)
> > - Link to v2: https://lore.kernel.org/r/20260127-ima-oob-v2-1-f38a18c850cf@arista.com
> >
> > Changes in v2:
> > - Instead of skipping unknown algorithms, add files under their TPM_ALG_ID (Roberto Sassu)
> > - Fix spelling (Roberto Sassu)
> > - Copy @stable on the fix
> > - Link to v1: https://lore.kernel.org/r/20260127-ima-oob-v1-1-2d42f3418e57@arista.com
> > ---
> > security/integrity/ima/ima_fs.c | 34 ++++++++++++++++++----------------
> > 1 file changed, 18 insertions(+), 16 deletions(-)
> >
> > diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> > index 012a58959ff0..9a00a0547619 100644
> > --- a/security/integrity/ima/ima_fs.c
> > +++ b/security/integrity/ima/ima_fs.c
> > @@ -132,16 +132,12 @@ int ima_measurements_show(struct seq_file *m, void *v)
> > char *template_name;
> > u32 pcr, namelen, template_data_len; /* temporary fields */
> > bool is_ima_template = false;
> > - enum hash_algo algo;
> > int i, algo_idx;
> >
> > algo_idx = ima_sha1_idx;
> > - algo = HASH_ALGO_SHA1;
> >
> > - if (m->file != NULL) {
> > + if (m->file != NULL)
> > algo_idx = (unsigned long)file_inode(m->file)->i_private;
> > - algo = ima_algo_array[algo_idx].algo;
> > - }
> >
> > /* get entry */
> > e = qe->entry;
> > @@ -160,7 +156,8 @@ int ima_measurements_show(struct seq_file *m, void *v)
> > ima_putc(m, &pcr, sizeof(e->pcr));
> >
> > /* 2nd: template digest */
> > - ima_putc(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
> > + ima_putc(m, e->digests[algo_idx].digest,
> > + ima_tpm_chip->allocated_banks[algo_idx].digest_size);
> >
> > /* 3rd: template name size */
> > namelen = !ima_canonical_fmt ? strlen(template_name) :
> > @@ -229,16 +226,12 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
> > struct ima_queue_entry *qe = v;
> > struct ima_template_entry *e;
> > char *template_name;
> > - enum hash_algo algo;
> > int i, algo_idx;
> >
> > algo_idx = ima_sha1_idx;
> > - algo = HASH_ALGO_SHA1;
> >
> > - if (m->file != NULL) {
> > + if (m->file != NULL)
> > algo_idx = (unsigned long)file_inode(m->file)->i_private;
> > - algo = ima_algo_array[algo_idx].algo;
> > - }
> >
> > /* get entry */
> > e = qe->entry;
> > @@ -252,7 +245,8 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
> > seq_printf(m, "%2d ", e->pcr);
> >
> > /* 2nd: template hash */
> > - ima_print_digest(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
> > + ima_print_digest(m, e->digests[algo_idx].digest,
> > + ima_tpm_chip->allocated_banks[algo_idx].digest_size);
> >
> > /* 3th: template name */
> > seq_printf(m, " %s", template_name);
> > @@ -404,16 +398,24 @@ static int __init create_securityfs_measurement_lists(void)
> > char file_name[NAME_MAX + 1];
> > struct dentry *dentry;
> >
> > - sprintf(file_name, "ascii_runtime_measurements_%s",
> > - hash_algo_name[algo]);
> > + if (algo == HASH_ALGO__LAST)
> > + sprintf(file_name, "ascii_runtime_measurements_TPM_ALG_%x",
> > + ima_tpm_chip->allocated_banks[i].alg_id);
> > + else
> > + sprintf(file_name, "ascii_runtime_measurements_%s",
> > + hash_algo_name[algo]);
> > dentry = securityfs_create_file(file_name, S_IRUSR | S_IRGRP,
> > ima_dir, (void *)(uintptr_t)i,
> > &ima_ascii_measurements_ops);
> > if (IS_ERR(dentry))
> > return PTR_ERR(dentry);
> >
> > - sprintf(file_name, "binary_runtime_measurements_%s",
> > - hash_algo_name[algo]);
> > + if (algo == HASH_ALGO__LAST)
> > + sprintf(file_name, "binary_runtime_measurements_TPM_ALG_%x",
> > + ima_tpm_chip->allocated_banks[i].alg_id);
> > + else
> > + sprintf(file_name, "binary_runtime_measurements_%s",
> > + hash_algo_name[algo]);
> > dentry = securityfs_create_file(file_name, S_IRUSR | S_IRGRP,
> > ima_dir, (void *)(uintptr_t)i,
> > &ima_measurements_ops);
> >
> > ---
> > base-commit: 63804fed149a6750ffd28610c5c1c98cce6bd377
> > change-id: 20260127-ima-oob-9fa83a634d7b
> >
> > Best regards,
More information about the Linux-security-module-archive
mailing list