Linux Integrity Measurement development
 help / color / mirror / Atom feed
* Re: [GIT PULL] TPM DEVICE DRIVER: for-next-tpm-7.1-rc1
From: pr-tracker-bot @ 2026-04-26 19:35 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Linus Torvalds, Peter Huewe, Jason Gunthorpe, David Howells,
	keyrings, linux-integrity, linux-kernel
In-Reply-To: <aezY2QpQiSQvnpCf@kernel.org>

The pull request you sent on Sat, 25 Apr 2026 18:08:09 +0300:

> git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-tpm-7.1-rc1

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/1d9f1b5e4374c6b40df1a56b35901312ec98c9af

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply

* Re: [RFC 0/4] tpm_crb: Add command and response buffer chunking support
From: Arun Menon @ 2026-04-27 10:28 UTC (permalink / raw)
  To: Stefan Berger
  Cc: Jarkko Sakkinen, linux-kernel, linux-integrity, Jason Gunthorpe,
	Peter Huewe
In-Reply-To: <7fa63e8a-1ffb-4dcd-af01-0811768ecda9@linux.ibm.com>

On Fri, Apr 24, 2026 at 04:54:03PM -0400, Stefan Berger wrote:
> 
> 
> On 4/23/26 6:43 AM, Arun Menon wrote:
> > On Wed, Apr 08, 2026 at 11:34:54AM +0300, Jarkko Sakkinen wrote:
> > > On Tue, Mar 24, 2026 at 06:11:11PM +0530, Arun Menon wrote:
> > > > Hi Jarkko,
> > > > 
> > > > On Tue, Mar 24, 2026 at 12:41:26PM +0200, Jarkko Sakkinen wrote:
> > > > > On Tue, Mar 24, 2026 at 12:47:59PM +0530, Arun Menon wrote:
> > > > > > The new version of TCG TPM v185 (currently under review [1]) supports
> > > > > > sending data/commands in chunks for the CRB (Command Response Buffer)
> > > > > > interface. This is in line with the initiative to support PQC algorithms.
> > > > > > 
> > > > > > This series implements the logic to send and receive larger TPM
> > > > > > cmd/rsp between the linux guest and the TPM backend in chunks.
> > > > > > Currently, the TPM CRB driver is limited by the physical size of the
> > > > > > MMIO window. When userspace attempts to send a payload that exceeds this
> > > > > > size, the driver rejects it.
> > > > > > 
> > > > > > This series introduces chunking support. The driver now checks the CRB
> > > > > > interface capability for CRB_INTF_CAP_CRB_CHUNK. If supported by the
> > > > > > backend, the driver will slice oversized commands into MMIO-sized
> > > > > > chunks, signalling the backend via CRB_START_NEXT_CHUNK, and finalizing
> > > > > > with CRB_START_INVOKE. Responses are also read back in a similar chunked
> > > > > > manner.
> > > > > > 
> > > > > > If the backend does not support chunking, the driver retains its legacy
> > > > > > behaviour and enforces the standard size limits.
> > > > > > 
> > > > > > This feature also requires the QEMU to interpret the data in chunks and
> > > > > > forward it to the TPM backend and subsequently dispatch the TPM response
> > > > > > in chunks back to the linux guest. This is implemented in [2]
> > > > > > 
> > > > > > [1] https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p07_rc1_121225.pdf
> > > > > > [2] https://lore.kernel.org/qemu-devel/20260319135316.37412-1-armenon@redhat.com/
> > > > > > 
> > > > > > Arun Menon (4):
> > > > > >    tpm_crb: Add definition of TPM CRB chunking fields
> > > > > >    tpm_crb: Add new wrapper function to invoke start method
> > > > > >    tpm_crb: Implement command and response chunking logic
> > > > > >    tpm: Increase TPM_BUFSIZE to 64kB for chunking support
> 
> 64kb? I am only increasing the TPM buffer to 8kb. More does not seem to be
> necessary.

That was a mistake in v1. I have changed that to 8kb in v2.
https://lore.kernel.org/all/20260324181244.17741-5-armenon@redhat.com/

> 
> > > > > > 
> > > > > >   drivers/char/tpm/tpm.h     |   2 +-
> > > > > >   drivers/char/tpm/tpm_crb.c | 194 ++++++++++++++++++++++++++-----------
> > > > > >   2 files changed, 137 insertions(+), 59 deletions(-)
> > > > > > 
> > > > > > -- 
> > > > > > 2.53.0
> > > > > > 
> > > > > 
> > > > > When QEMU has the feature available?
> > > > 
> > > > The QEMU patches are in review at the moment,
> > > > here is the link: https://lore.kernel.org/qemu-devel/20260319135316.37412-1-armenon@redhat.com/
> > > > Hoping to have them merged soon.
> > > 
> > > Right, and additional question: what about swtpm?
> 
> I am waiting for https://github.com/trustedComputingGroup/tpm to show rev185
> with PQC support so that I can merge my patches based on 'their' PQC support
> into the public libtpms repo.
> 

Regards,
Arun Menon


^ permalink raw reply

* Re: [PATCH 0/3] ima: add regular file data hash support for sigv3
From: Kamlesh Kumar @ 2026-04-27 12:57 UTC (permalink / raw)
  To: zohar; +Cc: ebiggers, linux-integrity, stefanb, Kamlesh Kumar
In-Reply-To: <20260324203929.2475782-1-zohar@linux.ibm.com>

On 3/24/26 4:39 PM, Mimi Zohar wrote:
> IMA signature version 3 (sigv3) support was introduced to avoid file
> signature ambiguity. Instead of directly signing a raw fs-verity hash,
> IMA signs the hash of ima_file_id structure, containing the type of
> signature, the hash algorithm, and the hash.
> 
> Pure ML-DSA calculates and signs the hash directly rather than a
> pre-hashed digest. To avoid ML-DSA having to re-calculate the file data
> hash, Eric Biggers suggested signing the smaller ima_file_id structure.
> 
> This patch set adds the sigv3 support for regular file data hashes. A
> subsequent patch set will add the ML-DSA support.
> 
> Mimi Zohar (3):
>    ima: Define asymmetric_verify_v3() to verify IMA sigv3 signatures
>    ima: add regular file data hash signature version 3 support
>    ima: add support to require IMA sigv3 signatures
> 
>   Documentation/ABI/testing/ima_policy   | 10 ++--
>   security/integrity/digsig.c            |  8 +--
>   security/integrity/digsig_asymmetric.c | 58 +++++++++++++++++++++
>   security/integrity/evm/evm_main.c      |  3 +-
>   security/integrity/ima/ima.h           |  1 +
>   security/integrity/ima/ima_appraise.c  | 72 ++++++++------------------
>   security/integrity/ima/ima_policy.c    | 22 ++++----
>   security/integrity/integrity.h         | 14 ++++-
>   8 files changed, 115 insertions(+), 73 deletions(-)
> 
> --
> 2.53.0
> 

I have tested this series along with Stefan's ML-DSA patches [1] and an
additional fix [2] for ima_get_hash_algo().
With all patches applied, I am able to successfully sign files with
ML-DSA-65 and verify IMA sigv3 signatures during appraisal.

[1] https://lore.kernel.org/linux-integrity/20260405231224.4008298-1-stefanb@linux.ibm.com/
[2] https://lore.kernel.org/linux-integrity/20260424110751.5637-1-kam@juniper.net/

Tested-by: Kamlesh Kumar <kam@juniper.net>

^ permalink raw reply

* Re: [PATCH 0/3] ima: add regular file data hash support for sigv3
From: Mimi Zohar @ 2026-04-27 13:30 UTC (permalink / raw)
  To: Kamlesh Kumar; +Cc: ebiggers, linux-integrity, stefanb, Kamlesh Kumar
In-Reply-To: <20260427125743.35245-1-kam@juniper.net>

On Mon, 2026-04-27 at 18:27 +0530, Kamlesh Kumar wrote:
> On 3/24/26 4:39 PM, Mimi Zohar wrote:
> > IMA signature version 3 (sigv3) support was introduced to avoid file
> > signature ambiguity. Instead of directly signing a raw fs-verity hash,
> > IMA signs the hash of ima_file_id structure, containing the type of
> > signature, the hash algorithm, and the hash.
> > 
> > Pure ML-DSA calculates and signs the hash directly rather than a
> > pre-hashed digest. To avoid ML-DSA having to re-calculate the file data
> > hash, Eric Biggers suggested signing the smaller ima_file_id structure.
> > 
> > This patch set adds the sigv3 support for regular file data hashes. A
> > subsequent patch set will add the ML-DSA support.
> > 
> > Mimi Zohar (3):
> >    ima: Define asymmetric_verify_v3() to verify IMA sigv3 signatures
> >    ima: add regular file data hash signature version 3 support
> >    ima: add support to require IMA sigv3 signatures
> > 
> >   Documentation/ABI/testing/ima_policy   | 10 ++--
> >   security/integrity/digsig.c            |  8 +--
> >   security/integrity/digsig_asymmetric.c | 58 +++++++++++++++++++++
> >   security/integrity/evm/evm_main.c      |  3 +-
> >   security/integrity/ima/ima.h           |  1 +
> >   security/integrity/ima/ima_appraise.c  | 72 ++++++++------------------
> >   security/integrity/ima/ima_policy.c    | 22 ++++----
> >   security/integrity/integrity.h         | 14 ++++-
> >   8 files changed, 115 insertions(+), 73 deletions(-)
> > 
> > --
> > 2.53.0
> > 
> 
> I have tested this series along with Stefan's ML-DSA patches [1] and an
> additional fix [2] for ima_get_hash_algo().
> With all patches applied, I am able to successfully sign files with
> ML-DSA-65 and verify IMA sigv3 signatures during appraisal.
> 
> [1] https://lore.kernel.org/linux-integrity/20260405231224.4008298-1-stefanb@linux.ibm.com/
> [2] https://lore.kernel.org/linux-integrity/20260424110751.5637-1-kam@juniper.net/
> 
> Tested-by: Kamlesh Kumar <kam@juniper.net>

Thanks, Kamlesh!

I'd appreciate re-testing with the v3 version now queued in next-integrity-
testing
https://lore.kernel.org/linux-integrity/20260416154039.1648083-1-stefanb@linux.ibm.com
?

Mimi

^ permalink raw reply

* [syzbot] [integrity?] [lsm?] WARNING: bad unlock balance in __filemap_add_folio
From: syzbot @ 2026-04-27 13:36 UTC (permalink / raw)
  To: dmitry.kasatkin, eric.snowberg, jmorris, linux-integrity,
	linux-kernel, linux-security-module, paul, roberto.sassu, serge,
	syzkaller-bugs, zohar

Hello,

syzbot found the following issue on:

HEAD commit:    2e6803928193 Merge tag 'tracefs-v7.1-2' of git://git.kerne..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=117dff16580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=80b28e8d6ef9384a
dashboard link: https://syzkaller.appspot.com/bug?extid=914bc925a90b7e137017
compiler:       Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/690094a31275/disk-2e680392.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/7d17ea4e1f81/vmlinux-2e680392.xz
kernel image: https://storage.googleapis.com/syzbot-assets/c1478f49f523/bzImage-2e680392.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+914bc925a90b7e137017@syzkaller.appspotmail.com

cgroup: Unknown subsys name 'cpuset'
cgroup: Unknown subsys name 'rlimit'
=====================================
WARNING: bad unlock balance detected!
syzkaller #0 Not tainted
-------------------------------------
syz-executor/5795 is trying to release lock (rcu_read_lock) at:
[<ffffffff8b2f32cf>] rcu_lock_release include/linux/rcupdate.h:310 [inline]
[<ffffffff8b2f32cf>] rcu_read_unlock include/linux/rcupdate.h:869 [inline]
[<ffffffff8b2f32cf>] rt_spin_unlock+0x14f/0x200 kernel/locking/spinlock_rt.c:82
but there are no more locks to release!

other info that might help us debug this:
2 locks held by syz-executor/5795:
 #0: ffff888035e50f58 (&ima_iint_mutex_key[depth]){+.+.}-{4:4}, at: process_measurement+0x7fd/0x1c90 security/integrity/ima/ima_main.c:319
 #1: ffff8880434dc100 (mapping.invalidate_lock#2){++++}-{4:4}, at: filemap_invalidate_lock_shared include/linux/fs.h:1094 [inline]
 #1: ffff8880434dc100 (mapping.invalidate_lock#2){++++}-{4:4}, at: do_page_cache_ra mm/readahead.c:333 [inline]
 #1: ffff8880434dc100 (mapping.invalidate_lock#2){++++}-{4:4}, at: page_cache_ra_order+0x2a5/0x490 mm/readahead.c:538

stack backtrace:
CPU: 1 UID: 0 PID: 5795 Comm: syz-executor Not tainted syzkaller #0 PREEMPT_{RT,(full)} 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026
Call Trace:
 <TASK>
 dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
 print_unlock_imbalance_bug+0xdc/0xf0 kernel/locking/lockdep.c:5298
 __lock_release kernel/locking/lockdep.c:5537 [inline]
 lock_release+0x248/0x3c0 kernel/locking/lockdep.c:5889
 rcu_lock_release include/linux/rcupdate.h:310 [inline]
 rcu_read_unlock include/linux/rcupdate.h:869 [inline]
 rt_spin_unlock+0x15b/0x200 kernel/locking/spinlock_rt.c:82
 spin_unlock_irq include/linux/spinlock_rt.h:122 [inline]
 __filemap_add_folio+0xc85/0x1200 mm/filemap.c:931
 filemap_add_folio+0x2de/0x610 mm/filemap.c:967
 page_cache_ra_unbounded+0x407/0x980 mm/readahead.c:282
 do_page_cache_ra mm/readahead.c:334 [inline]
 page_cache_ra_order+0x2b5/0x490 mm/readahead.c:538
 filemap_readahead mm/filemap.c:2664 [inline]
 filemap_get_pages+0x832/0x1e70 mm/filemap.c:2710
 filemap_read+0x44a/0x1240 mm/filemap.c:2806
 __kernel_read+0x50d/0x9c0 fs/read_write.c:532
 integrity_kernel_read+0x89/0xd0 security/integrity/iint.c:28
 ima_calc_file_hash_tfm security/integrity/ima/ima_crypto.c:222 [inline]
 ima_calc_file_hash+0x452/0x870 security/integrity/ima/ima_crypto.c:280
 ima_collect_measurement+0x523/0x9d0 security/integrity/ima/ima_api.c:300
 process_measurement+0x12d9/0x1c90 security/integrity/ima/ima_main.c:425
 ima_file_check+0xe1/0x130 security/integrity/ima/ima_main.c:685
 security_file_post_open+0xb3/0x260 security/security.c:2755
 do_open fs/namei.c:4701 [inline]
 path_openat+0x2e88/0x38a0 fs/namei.c:4858
 do_file_open+0x23e/0x4a0 fs/namei.c:4887
 file_open_name+0x162/0x1c0 fs/open.c:1322
 __do_sys_swapon mm/swapfile.c:3467 [inline]
 __se_sys_swapon+0x856/0x2010 mm/swapfile.c:3432
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f884264c7d7
Code: 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 a7 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffe6306a658 EFLAGS: 00000246 ORIG_RAX: 00000000000000a7
RAX: ffffffffffffffda RBX: 0000000000000008 RCX: 00007f884264c7d7
RDX: 0000000000000000 RSI: 0000000000008000 RDI: 00007f88426e2e5b
RBP: 00007f88426e2e5b R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000008 R11: 0000000000000246 R12: 00007f88428963e0
R13: 00007f88426fdd26 R14: 0000000000200000 R15: 00007f88428963a0
 </TASK>
------------[ cut here ]------------
rrln < 0 || rrln > RCU_NEST_PMAX
WARNING: kernel/rcu/tree_plugin.h:443 at __rcu_read_unlock+0x79/0xe0 kernel/rcu/tree_plugin.h:443, CPU#1: syz-executor/5795
Modules linked in:
CPU: 1 UID: 0 PID: 5795 Comm: syz-executor Not tainted syzkaller #0 PREEMPT_{RT,(full)} 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026
RIP: 0010:__rcu_read_unlock+0x79/0xe0 kernel/rcu/tree_plugin.h:443
Code: 75 66 41 83 3e 00 75 27 43 0f b6 04 3c 84 c0 75 41 8b 03 3d 00 00 00 40 73 0f 5b 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc cc 90 <0f> 0b 90 eb eb e8 6d 00 00 00 eb d2 89 d9 80 e1 07 80 c1 03 38 c1
RSP: 0018:ffffc900046e6418 EFLAGS: 00010286
RAX: 00000000ffffffff RBX: ffff888039e82384 RCX: 0000000000000046
RDX: 0000000000000000 RSI: ffffffff8d8986dc RDI: ffff888039e81ec0
RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
R10: dffffc0000000000 R11: fffffbfff1bcaacc R12: 1ffff110073d0470
R13: ffff888039e81ec0 R14: ffff8880b893c610 R15: dffffc0000000000
FS:  000055555b61b540(0000) GS:ffff8881261fb000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fec05db0e9c CR3: 0000000042cbe000 CR4: 00000000003526f0
Call Trace:
 <TASK>
 rcu_read_unlock include/linux/rcupdate.h:871 [inline]
 rt_spin_unlock+0x160/0x200 kernel/locking/spinlock_rt.c:82
 spin_unlock_irq include/linux/spinlock_rt.h:122 [inline]
 __filemap_add_folio+0xc85/0x1200 mm/filemap.c:931
 filemap_add_folio+0x2de/0x610 mm/filemap.c:967
 page_cache_ra_unbounded+0x407/0x980 mm/readahead.c:282
 do_page_cache_ra mm/readahead.c:334 [inline]
 page_cache_ra_order+0x2b5/0x490 mm/readahead.c:538
 filemap_readahead mm/filemap.c:2664 [inline]
 filemap_get_pages+0x832/0x1e70 mm/filemap.c:2710
 filemap_read+0x44a/0x1240 mm/filemap.c:2806
 __kernel_read+0x50d/0x9c0 fs/read_write.c:532
 integrity_kernel_read+0x89/0xd0 security/integrity/iint.c:28
 ima_calc_file_hash_tfm security/integrity/ima/ima_crypto.c:222 [inline]
 ima_calc_file_hash+0x452/0x870 security/integrity/ima/ima_crypto.c:280
 ima_collect_measurement+0x523/0x9d0 security/integrity/ima/ima_api.c:300
 process_measurement+0x12d9/0x1c90 security/integrity/ima/ima_main.c:425
 ima_file_check+0xe1/0x130 security/integrity/ima/ima_main.c:685
 security_file_post_open+0xb3/0x260 security/security.c:2755
 do_open fs/namei.c:4701 [inline]
 path_openat+0x2e88/0x38a0 fs/namei.c:4858
 do_file_open+0x23e/0x4a0 fs/namei.c:4887
 file_open_name+0x162/0x1c0 fs/open.c:1322
 __do_sys_swapon mm/swapfile.c:3467 [inline]
 __se_sys_swapon+0x856/0x2010 mm/swapfile.c:3432
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f884264c7d7
Code: 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 a7 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffe6306a658 EFLAGS: 00000246 ORIG_RAX: 00000000000000a7
RAX: ffffffffffffffda RBX: 0000000000000008 RCX: 00007f884264c7d7
RDX: 0000000000000000 RSI: 0000000000008000 RDI: 00007f88426e2e5b
RBP: 00007f88426e2e5b R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000008 R11: 0000000000000246 R12: 00007f88428963e0
R13: 00007f88426fdd26 R14: 0000000000200000 R15: 00007f88428963a0
 </TASK>


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply

* [PATCH] tpm: Remove dead NULL check in tpm2_flush_space()
From: Gunnar Kudrjavets @ 2026-04-27 16:32 UTC (permalink / raw)
  To: peterhuewe, jarkko
  Cc: jgg, noodles, linux-integrity, linux-kernel, Justinien Bouron

The 'space' pointer in tpm2_flush_space() is assigned from
&chip->work_space, which is the address of an embedded struct member
within struct tpm_chip. This address can never be NULL, making the
NULL check dead code. The new code follows the existing pattern
established by the other callers in tpm2-space.c which also assign
from &chip->work_space without a NULL check. Remove the dead code
to avoid confusion.

Fixes: e3aaebcbb7c6 ("tpm: Clean up TPM space after command failure")
Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
Assisted-by: Kiro:claude-opus-4.6
Reviewed-by: Justinien Bouron <jbouron@amazon.com>
---
 drivers/char/tpm/tpm2-space.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 60354cd53b5c..1eec72eb8208 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -169,9 +169,6 @@ void tpm2_flush_space(struct tpm_chip *chip)
 	struct tpm_space *space = &chip->work_space;
 	int i;
 
-	if (!space)
-		return;
-
 	for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
 		if (space->context_tbl[i] && ~space->context_tbl[i])
 			tpm2_flush_context(chip, space->context_tbl[i]);

base-commit: 949692da7211572fac419b2986b6abc0cd1aeb76
-- 
2.47.3


^ permalink raw reply related

* Re: [PATCH 05/10] dm-ima: Fix UAF errors and measuring incorrect context
From: Mikulas Patocka @ 2026-04-27 19:33 UTC (permalink / raw)
  To: Benjamin Marzinski
  Cc: Mike Snitzer, dm-devel, linux-integrity, Mimi Zohar,
	Roberto Sassu, Dmitry Kasatkin
In-Reply-To: <20260414002244.1917447-6-bmarzins@redhat.com>

Hi


On Mon, 13 Apr 2026, Benjamin Marzinski wrote:

> +	smp_mb__before_atomic();
> +	atomic_inc(&ima->measure_idx);
> +	wake_up_all(&ima->ima_wq);

There should be smp_mb__after_atomic() after atomic_inc() and before 
wake_up_all(). Otherwise, the increment of atomic_inc could be moved 
inside the wait queue spinlock in wake_up_all and executed after the wait 
queue is checked for being empty.

Generally, the atomic variables and barriers are very hard to get right, 
this is not performance-critical code that would justify the 
complications, so I suggest to use a normal spinlock instead.

You can use something like:
	spin_lock_irq(&ima->ima_wq.lock);
	ima->measure_idx++;
	wake_up_all_locked(&ima->ima_wq);
	spin_unlock_irq(&ima->ima_wq.lock);

--- this would be obviously safe and easy to verify.

Mikulas


^ permalink raw reply

* Re: [PATCH 05/10] dm-ima: Fix UAF errors and measuring incorrect context
From: Mikulas Patocka @ 2026-04-27 19:42 UTC (permalink / raw)
  To: Benjamin Marzinski
  Cc: Mike Snitzer, dm-devel, linux-integrity, Mimi Zohar,
	Roberto Sassu, Dmitry Kasatkin
In-Reply-To: <75a6b1cf-9f0d-8fc2-57d5-f6dee4913c65@redhat.com>



On Mon, 27 Apr 2026, Mikulas Patocka wrote:

> Hi
> 
> 
> On Mon, 13 Apr 2026, Benjamin Marzinski wrote:
> 
> > +	smp_mb__before_atomic();
> > +	atomic_inc(&ima->measure_idx);
> > +	wake_up_all(&ima->ima_wq);
> 
> There should be smp_mb__after_atomic() after atomic_inc() and before 
> wake_up_all(). Otherwise, the increment of atomic_inc could be moved 
> inside the wait queue spinlock in wake_up_all and executed after the wait 
> queue is checked for being empty.
> 
> Generally, the atomic variables and barriers are very hard to get right, 
> this is not performance-critical code that would justify the 
> complications, so I suggest to use a normal spinlock instead.
> 
> You can use something like:
> 	spin_lock_irq(&ima->ima_wq.lock);
> 	ima->measure_idx++;
> 	wake_up_all_locked(&ima->ima_wq);
> 	spin_unlock_irq(&ima->ima_wq.lock);
> 
> --- this would be obviously safe and easy to verify.
> 
> Mikulas

BTW. you can see "&ic->endio_wait.lock" in drivers/md/dm-integrity.c for 
an example, how to use this pattern.

Mikulas


^ permalink raw reply

* Re: [PATCH] tpm: Remove dead NULL check in tpm2_flush_space()
From: Paul Menzel @ 2026-04-27 20:49 UTC (permalink / raw)
  To: Gunnar Kudrjavets
  Cc: peterhuewe, jarkko, jgg, noodles, linux-integrity, linux-kernel,
	Justinien Bouron
In-Reply-To: <20260427163238.20230-1-gunnarku@amazon.com>

Dear Gunnar,


Thank you for your patch.

Am 27.04.26 um 18:32 schrieb Gunnar Kudrjavets:
> The 'space' pointer in tpm2_flush_space() is assigned from
> &chip->work_space, which is the address of an embedded struct member
> within struct tpm_chip. This address can never be NULL, making the
> NULL check dead code. The new code follows the existing pattern
> established by the other callers in tpm2-space.c which also assign
> from &chip->work_space without a NULL check. Remove the dead code
> to avoid confusion.
> 
> Fixes: e3aaebcbb7c6 ("tpm: Clean up TPM space after command failure")
> Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
> Assisted-by: Kiro:claude-opus-4.6
> Reviewed-by: Justinien Bouron <jbouron@amazon.com>
> ---
>   drivers/char/tpm/tpm2-space.c | 3 ---
>   1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
> index 60354cd53b5c..1eec72eb8208 100644
> --- a/drivers/char/tpm/tpm2-space.c
> +++ b/drivers/char/tpm/tpm2-space.c
> @@ -169,9 +169,6 @@ void tpm2_flush_space(struct tpm_chip *chip)
>   	struct tpm_space *space = &chip->work_space;
>   	int i;
>   
> -	if (!space)
> -		return;
> -
>   	for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
>   		if (space->context_tbl[i] && ~space->context_tbl[i])
>   			tpm2_flush_context(chip, space->context_tbl[i]);

gemini/gemini-3.1-pro-preview made a comment [1]. No idea, if it’s valid.


Kind regards,

Paul


[1]: 
https://sashiko.dev/#/patchset/20260427163238.20230-1-gunnarku%40amazon.com

^ permalink raw reply

* Re: [PATCH] tpm: Remove dead NULL check in tpm2_flush_space()
From: Gunnar Kudrjavets @ 2026-04-27 22:57 UTC (permalink / raw)
  To: pmenzel
  Cc: peterhuewe, jarkko, jgg, noodles, linux-integrity, linux-kernel,
	jbouron, gunnarku
In-Reply-To: <e71c6d95-6c83-4fb4-8cd5-f66067fb68c5@molgen.mpg.de>

On Sun, Apr 27, 2026 at 10:49 PM Paul Menzel <pmenzel@molgen.mpg.de> wrote:
> gemini/gemini-3.1-pro-preview made a comment [1]. No idea, if it's valid.

Thanks for forwarding, Paul. AFAICS, the comment is a false positive.

My theory is that Gemini conflates two different variables named
'space':

1. The 'space' parameter passed to tpm_dev_transmit(). This *can* be
   NULL (it is NULL for /dev/tpm0 clients).

2. The local 'space' variable inside tpm2_flush_space(). This is
   assigned from &chip->work_space and can *never* be NULL.

The removed NULL check was testing case (2), not case (1).

Regards,
Gunnar

^ permalink raw reply

* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Paul Moore @ 2026-04-28  1:31 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: Yeoreum Yun, roberto.sassu, Jonathan McDowell,
	linux-security-module, linux-kernel, linux-integrity,
	linux-arm-kernel, kvmarm, jmorris, serge, dmitry.kasatkin,
	eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
	sebastianene
In-Reply-To: <1e51c2fd090e5ceb07b1d09e50650c70fd3ccdb1.camel@linux.ibm.com>

On Fri, Apr 24, 2026 at 6:49 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
> On Fri, 2026-04-24 at 18:10 -0400, Paul Moore wrote:
> > (I'm assuming you meant initcall and not syscall above, but if you're
> > talking about something else, please let me know.)
> >
> > Saying that you aren't comfortable moving IMA initialization to
> > late-sync is inconsistent with allowing IMA initialization to be
> > deferred to late-sync.  Either it is okay to initialize IMA in
> > late-sync or it isn't.  You must pick one.
>
> Yes, we're discussing late_initcall and late_initcall_sync.
>
> I prefer to look at it as being pragmatic. I'd rather err on the side of caution
> and not move the syscall to late_initcall_sync, than move it.

If you were truly erring on the side of caution you wouldn't allow
late-sync initialization without knowing if it was safe or not.
Determine whether IMA initialization is safe at late-sync.  If it is
safe, move the init to late-sync; if not, keep it at late and figure
out another mechanism to sync with the TPM availability.  If needed,
you could probably use the LSM notifier to enable the TPM driver to
signal when it is up and running.

-- 
paul-moore.com

^ permalink raw reply

* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Paul Moore @ 2026-04-28  1:31 UTC (permalink / raw)
  To: Yeoreum Yun
  Cc: Mimi Zohar, roberto.sassu, Jonathan McDowell,
	linux-security-module, linux-kernel, linux-integrity,
	linux-arm-kernel, kvmarm, jmorris, serge, dmitry.kasatkin,
	eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
	sebastianene
In-Reply-To: <aexIwJpno3iPIdRD@e129823.arm.com>

On Sat, Apr 25, 2026 at 12:53 AM Yeoreum Yun <yeoreum.yun@arm.com> wrote:
> > > I understand the need to ensure that the TPM is available, but if it
> > > isn't safe to wait to initialize IMA at late_initcall_sync() then it
> > > would seem like this is a bad option and we need another mechanism to
> > > synchronize IMA with TPM devices.  If it is safe to initalize IMA in
> > > late_initcall_sync(), just do that and be done with it.
> >
> > Within the same initcall level there is no way of ordering the initialization.
> > Yeorum attempted to address the ordering issue in commit 0e0546eabcd6
> > ("firmware: arm_ffa: Change initcall level of ffa_init() to rootfs_initcall"),
> > which is being reverted in this patch set.
> >
> > Ordering within an initcall level needs to be fixed, but for now retrying at
> > late_initcall_sync works for some, hopefully most, cases.
>
> Ordering within an initcall level is not good idea.

Agreed.  That's why we have the different initcall levels.

-- 
paul-moore.com

^ permalink raw reply

* Re: [PATCH] tpm: Remove dead NULL check in tpm2_flush_space()
From: Paul Menzel @ 2026-04-28  6:18 UTC (permalink / raw)
  To: Gunnar Kudrjavets
  Cc: peterhuewe, jarkko, jgg, noodles, linux-integrity, linux-kernel,
	jbouron
In-Reply-To: <20260427225722.17878-1-gunnarku@amazon.com>

Dear Gunnar,


Am 28.04.26 um 00:57 schrieb Gunnar Kudrjavets:
> On Sun, Apr 27, 2026 at 10:49 PM Paul Menzel <pmenzel@molgen.mpg.de> wrote:
>> gemini/gemini-3.1-pro-preview made a comment [1]. No idea, if it's valid.
> 
> Thanks for forwarding, Paul. AFAICS, the comment is a false positive.
> 
> My theory is that Gemini conflates two different variables named
> 'space':
> 
> 1. The 'space' parameter passed to tpm_dev_transmit(). This *can* be
>     NULL (it is NULL for /dev/tpm0 clients).
> 
> 2. The local 'space' variable inside tpm2_flush_space(). This is
>     assigned from &chip->work_space and can *never* be NULL.
> 
> The removed NULL check was testing case (2), not case (1).

Thank you for quickly looking into this. Sorry for the noise.


Kind regards,

Paul

^ permalink raw reply

* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Yeoreum Yun @ 2026-04-28 13:21 UTC (permalink / raw)
  To: Paul Moore
  Cc: Mimi Zohar, roberto.sassu, Jonathan McDowell,
	linux-security-module, linux-kernel, linux-integrity,
	linux-arm-kernel, kvmarm, jmorris, serge, dmitry.kasatkin,
	eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
	sebastianene
In-Reply-To: <CAHC9VhS_WgwhW_NDO91LoTeSzdieGqbwqnwPq8KpavH1_Lwi7g@mail.gmail.com>

Hi Paul,

> On Fri, Apr 24, 2026 at 6:49 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
> > On Fri, 2026-04-24 at 18:10 -0400, Paul Moore wrote:
> > > (I'm assuming you meant initcall and not syscall above, but if you're
> > > talking about something else, please let me know.)
> > >
> > > Saying that you aren't comfortable moving IMA initialization to
> > > late-sync is inconsistent with allowing IMA initialization to be
> > > deferred to late-sync.  Either it is okay to initialize IMA in
> > > late-sync or it isn't.  You must pick one.
> >
> > Yes, we're discussing late_initcall and late_initcall_sync.
> >
> > I prefer to look at it as being pragmatic. I'd rather err on the side of caution
> > and not move the syscall to late_initcall_sync, than move it.
>
> If you were truly erring on the side of caution you wouldn't allow
> late-sync initialization without knowing if it was safe or not.
> Determine whether IMA initialization is safe at late-sync.  If it is
> safe, move the init to late-sync; if not, keep it at late and figure
> out another mechanism to sync with the TPM availability.  If needed,
> you could probably use the LSM notifier to enable the TPM driver to
> signal when it is up and running.

I don't think LSM notifier wouldn't be good since it a one time
notification for initailisation and it wouldn't tell properly
whehter TPM isn't present in system or present unless functions
ima_init() are rewritten to discern the "TPM deferred" and
"TPM doesn't exist" in the system (e.x) boot-aggregate log creation.

One question, though.
In the end, for systems where the TPM has already been probed by late_initcall(),
init_ima() continues to be called at late_initcall(), while the above approach
is introduced for systems where the TPM is not properly initialized by that point.

If init_ima(), which used to be called at late_initcall(),
were instead called at late_initcall_sync(), could this break system integration?
In my view, both late_initcall and late_initcall_sync run during the do_basic_setup() phase,
so it doesn’t seem like this would cause tampering or affect things like the creation of the boot-aggregate log.

Is there any particular reason why init_ima() must be called specifically at late_initcall()?

Thanks.

--
Sincerely,
Yeoreum Yun

^ permalink raw reply

* [PATCH 1/2] ima_violations.sh: Wait for ima_mmap to exit
From: Petr Vorel @ 2026-04-28 16:10 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Cyril Hrubis, Avinesh Kumar, Wei Gao, Mimi Zohar,
	linux-integrity, Martin Doucha

This fixes a race when even 2 sec sleep is not enough (f26399583e was
a wrong approach).

While at it, check for ima_mmap exit code (missing since ever).

Fixes: f26399583e ("ima/{ima_measurements,ima_violations}.sh: Avoid running on tmpfs")
Fixes: 3a8efbcc46 ("This patch adds Integrity Measurement Architecture(IMA) testing support ...")
Reported-by: Martin Doucha <mdoucha@suse.cz>
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 .../kernel/security/integrity/ima/tests/ima_violations.sh | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
index 13cc9d804d..0c03c30786 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
@@ -157,6 +157,8 @@ test2()
 
 test3()
 {
+	local pid
+
 	tst_res TINFO "verify open_writers using mmapped files"
 
 	local search="open_writers"
@@ -168,6 +170,7 @@ test3()
 	echo 'testing testing' > $FILE
 
 	ima_mmap -f $FILE &
+	pid=$!
 	# wait for violations appear in logs
 	tst_sleep 1s
 
@@ -177,7 +180,10 @@ test3()
 	validate $num_violations $count $search
 
 	# wait for ima_mmap to exit, so we can umount
-	tst_sleep 2s
+	wait $pid
+	if [ $? -ne 0 ]; then
+		tst_brk TBROK "failed to execute ima_mmap"
+	fi
 }
 
 test4()
-- 
2.54.0


^ permalink raw reply related

* [PATCH 2/2] ima_violations.sh: ima_mmap.c: Replace sleep with checkpoints
From: Petr Vorel @ 2026-04-28 16:10 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Cyril Hrubis, Avinesh Kumar, Wei Gao, Mimi Zohar,
	linux-integrity
In-Reply-To: <20260428161034.947614-1-pvorel@suse.cz>

Using checkpoints is a proper way in LTP new API [1] to avoid races and
waste of time.  It reduces 3 sec sleep in ima_mmap.c and 1 sec sleep in
ima_violations.sh with just checkpoints.

NOTE: tst_reinit() is really needed instead of .needs_checkpoints = 1
as documented in Shell-Test-API.asciidoc.

[1] https://people.kernel.org/metan/why-sleep-is-almost-never-acceptable-in-tests

Fixes: 0e4cbf753f ("security/ima: Rewrite tests into new API + fixes")
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 testcases/kernel/security/integrity/ima/src/ima_mmap.c     | 7 ++++---
 .../kernel/security/integrity/ima/tests/ima_violations.sh  | 6 +++++-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/testcases/kernel/security/integrity/ima/src/ima_mmap.c b/testcases/kernel/security/integrity/ima/src/ima_mmap.c
index 8596809ef4..09b22fd4f4 100644
--- a/testcases/kernel/security/integrity/ima/src/ima_mmap.c
+++ b/testcases/kernel/security/integrity/ima/src/ima_mmap.c
@@ -9,7 +9,6 @@
 
 #include "tst_test.h"
 
-#define SLEEP_AFTER_CLOSE 3
 #define MMAPSIZE 1024
 
 static char *filename;
@@ -35,8 +34,10 @@ static void run(void)
 	file = SAFE_MMAP(NULL, MMAPSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 	SAFE_CLOSE(fd);
 
-	tst_res(TINFO, "sleep %ds", SLEEP_AFTER_CLOSE);
-	sleep(SLEEP_AFTER_CLOSE);
+	tst_reinit();
+	TST_CHECKPOINT_WAIT(0);
+	/* keep running until ima_violations.sh open and close file */
+	TST_CHECKPOINT_WAKE_AND_WAIT(0);
 
 	tst_res(TPASS, "test completed");
 }
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
index 0c03c30786..d7dcd077b4 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
@@ -8,6 +8,7 @@
 # test[4-6] test 6.15 commit 5b3cd801155f ("ima: limit the number of open-writers integrity violations")
 # test[7-8] test 6.15 commit a414016218ca ("ima: limit the number of ToMToU integrity violations")
 
+TST_NEEDS_CHECKPOINTS=1
 TST_SETUP="setup"
 TST_CLEANUP="cleanup"
 TST_CNT=8
@@ -171,12 +172,15 @@ test3()
 
 	ima_mmap -f $FILE &
 	pid=$!
+
 	# wait for violations appear in logs
-	tst_sleep 1s
+	TST_CHECKPOINT_WAKE_AND_WAIT 0
 
 	open_file_read
 	close_file_read
 
+	TST_CHECKPOINT_WAKE 0
+
 	validate $num_violations $count $search
 
 	# wait for ima_mmap to exit, so we can umount
-- 
2.54.0


^ permalink raw reply related

* Re: [LTP] [PATCH 2/2] ima_violations.sh: ima_mmap.c: Replace sleep with checkpoints
From: Martin Doucha @ 2026-04-29 11:15 UTC (permalink / raw)
  To: Petr Vorel, ltp; +Cc: linux-integrity
In-Reply-To: <20260428161034.947614-2-pvorel@suse.cz>

Hi,
for both patches:

Reviewed-by: Martin Doucha <mdoucha@suse.cz>

On 4/28/26 18:10, Petr Vorel wrote:
> Using checkpoints is a proper way in LTP new API [1] to avoid races and
> waste of time.  It reduces 3 sec sleep in ima_mmap.c and 1 sec sleep in
> ima_violations.sh with just checkpoints.
> 
> NOTE: tst_reinit() is really needed instead of .needs_checkpoints = 1
> as documented in Shell-Test-API.asciidoc.
> 
> [1] https://people.kernel.org/metan/why-sleep-is-almost-never-acceptable-in-tests
> 
> Fixes: 0e4cbf753f ("security/ima: Rewrite tests into new API + fixes")
> Suggested-by: Cyril Hrubis <chrubis@suse.cz>
> Signed-off-by: Petr Vorel <pvorel@suse.cz>
> ---
>   testcases/kernel/security/integrity/ima/src/ima_mmap.c     | 7 ++++---
>   .../kernel/security/integrity/ima/tests/ima_violations.sh  | 6 +++++-
>   2 files changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/testcases/kernel/security/integrity/ima/src/ima_mmap.c b/testcases/kernel/security/integrity/ima/src/ima_mmap.c
> index 8596809ef4..09b22fd4f4 100644
> --- a/testcases/kernel/security/integrity/ima/src/ima_mmap.c
> +++ b/testcases/kernel/security/integrity/ima/src/ima_mmap.c
> @@ -9,7 +9,6 @@
>   
>   #include "tst_test.h"
>   
> -#define SLEEP_AFTER_CLOSE 3
>   #define MMAPSIZE 1024
>   
>   static char *filename;
> @@ -35,8 +34,10 @@ static void run(void)
>   	file = SAFE_MMAP(NULL, MMAPSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
>   	SAFE_CLOSE(fd);
>   
> -	tst_res(TINFO, "sleep %ds", SLEEP_AFTER_CLOSE);
> -	sleep(SLEEP_AFTER_CLOSE);
> +	tst_reinit();
> +	TST_CHECKPOINT_WAIT(0);
> +	/* keep running until ima_violations.sh open and close file */
> +	TST_CHECKPOINT_WAKE_AND_WAIT(0);
>   
>   	tst_res(TPASS, "test completed");
>   }
> diff --git a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
> index 0c03c30786..d7dcd077b4 100755
> --- a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
> +++ b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
> @@ -8,6 +8,7 @@
>   # test[4-6] test 6.15 commit 5b3cd801155f ("ima: limit the number of open-writers integrity violations")
>   # test[7-8] test 6.15 commit a414016218ca ("ima: limit the number of ToMToU integrity violations")
>   
> +TST_NEEDS_CHECKPOINTS=1
>   TST_SETUP="setup"
>   TST_CLEANUP="cleanup"
>   TST_CNT=8
> @@ -171,12 +172,15 @@ test3()
>   
>   	ima_mmap -f $FILE &
>   	pid=$!
> +
>   	# wait for violations appear in logs
> -	tst_sleep 1s
> +	TST_CHECKPOINT_WAKE_AND_WAIT 0
>   
>   	open_file_read
>   	close_file_read
>   
> +	TST_CHECKPOINT_WAKE 0
> +
>   	validate $num_violations $count $search
>   
>   	# wait for ima_mmap to exit, so we can umount


-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

^ permalink raw reply

* Re: [LTP] [PATCH 2/2] ima_violations.sh: ima_mmap.c: Replace sleep with checkpoints
From: Petr Vorel @ 2026-04-29 12:00 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp, linux-integrity, Mimi Zohar
In-Reply-To: <209b0327-64b4-4a58-9ee1-19ec693c8105@suse.cz>

Hi Martin, all,

> Hi,
> for both patches:

> Reviewed-by: Martin Doucha <mdoucha@suse.cz>

Thanks for review, patchset merged.

Kind regards,
Petr

> On 4/28/26 18:10, Petr Vorel wrote:
> > Using checkpoints is a proper way in LTP new API [1] to avoid races and
> > waste of time.  It reduces 3 sec sleep in ima_mmap.c and 1 sec sleep in
> > ima_violations.sh with just checkpoints.

> > NOTE: tst_reinit() is really needed instead of .needs_checkpoints = 1
> > as documented in Shell-Test-API.asciidoc.

> > [1] https://people.kernel.org/metan/why-sleep-is-almost-never-acceptable-in-tests

> > Fixes: 0e4cbf753f ("security/ima: Rewrite tests into new API + fixes")
> > Suggested-by: Cyril Hrubis <chrubis@suse.cz>
> > Signed-off-by: Petr Vorel <pvorel@suse.cz>
> > ---
> >   testcases/kernel/security/integrity/ima/src/ima_mmap.c     | 7 ++++---
> >   .../kernel/security/integrity/ima/tests/ima_violations.sh  | 6 +++++-
> >   2 files changed, 9 insertions(+), 4 deletions(-)

> > diff --git a/testcases/kernel/security/integrity/ima/src/ima_mmap.c b/testcases/kernel/security/integrity/ima/src/ima_mmap.c
> > index 8596809ef4..09b22fd4f4 100644
> > --- a/testcases/kernel/security/integrity/ima/src/ima_mmap.c
> > +++ b/testcases/kernel/security/integrity/ima/src/ima_mmap.c
> > @@ -9,7 +9,6 @@
> >   #include "tst_test.h"
> > -#define SLEEP_AFTER_CLOSE 3
> >   #define MMAPSIZE 1024
> >   static char *filename;
> > @@ -35,8 +34,10 @@ static void run(void)
> >   	file = SAFE_MMAP(NULL, MMAPSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> >   	SAFE_CLOSE(fd);
> > -	tst_res(TINFO, "sleep %ds", SLEEP_AFTER_CLOSE);
> > -	sleep(SLEEP_AFTER_CLOSE);
> > +	tst_reinit();
> > +	TST_CHECKPOINT_WAIT(0);
> > +	/* keep running until ima_violations.sh open and close file */
> > +	TST_CHECKPOINT_WAKE_AND_WAIT(0);
> >   	tst_res(TPASS, "test completed");
> >   }
> > diff --git a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
> > index 0c03c30786..d7dcd077b4 100755
> > --- a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
> > +++ b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
> > @@ -8,6 +8,7 @@
> >   # test[4-6] test 6.15 commit 5b3cd801155f ("ima: limit the number of open-writers integrity violations")
> >   # test[7-8] test 6.15 commit a414016218ca ("ima: limit the number of ToMToU integrity violations")
> > +TST_NEEDS_CHECKPOINTS=1
> >   TST_SETUP="setup"
> >   TST_CLEANUP="cleanup"
> >   TST_CNT=8
> > @@ -171,12 +172,15 @@ test3()
> >   	ima_mmap -f $FILE &
> >   	pid=$!
> > +
> >   	# wait for violations appear in logs
> > -	tst_sleep 1s
> > +	TST_CHECKPOINT_WAKE_AND_WAIT 0
> >   	open_file_read
> >   	close_file_read
> > +	TST_CHECKPOINT_WAKE 0
> > +
> >   	validate $num_violations $count $search
> >   	# wait for ima_mmap to exit, so we can umount

^ permalink raw reply

* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Roberto Sassu @ 2026-04-29 13:33 UTC (permalink / raw)
  To: Paul Moore, Mimi Zohar
  Cc: Yeoreum Yun, roberto.sassu, Jonathan McDowell,
	linux-security-module, linux-kernel, linux-integrity,
	linux-arm-kernel, kvmarm, jmorris, serge, dmitry.kasatkin,
	eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
	suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
	sebastianene
In-Reply-To: <CAHC9VhS_WgwhW_NDO91LoTeSzdieGqbwqnwPq8KpavH1_Lwi7g@mail.gmail.com>

On Mon, 2026-04-27 at 21:31 -0400, Paul Moore wrote:
> On Fri, Apr 24, 2026 at 6:49 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
> > On Fri, 2026-04-24 at 18:10 -0400, Paul Moore wrote:
> > > (I'm assuming you meant initcall and not syscall above, but if you're
> > > talking about something else, please let me know.)
> > > 
> > > Saying that you aren't comfortable moving IMA initialization to
> > > late-sync is inconsistent with allowing IMA initialization to be
> > > deferred to late-sync.  Either it is okay to initialize IMA in
> > > late-sync or it isn't.  You must pick one.
> > 
> > Yes, we're discussing late_initcall and late_initcall_sync.
> > 
> > I prefer to look at it as being pragmatic. I'd rather err on the side of caution
> > and not move the syscall to late_initcall_sync, than move it.
> 
> If you were truly erring on the side of caution you wouldn't allow
> late-sync initialization without knowing if it was safe or not.
> Determine whether IMA initialization is safe at late-sync.  If it is
> safe, move the init to late-sync; if not, keep it at late and figure
> out another mechanism to sync with the TPM availability.  If needed,
> you could probably use the LSM notifier to enable the TPM driver to
> signal when it is up and running.

Yes, I agree with you, or transition or not.

However, all of this looks very fragile and easy to be broken. If we
want to be on the safe side, we can use any notification mechanism that
is suitable, but at the same time from IMA side we need to deny any
file access that would require a measurement until the TPM comes up.

If you accept this, I don't have any problem to move to late_sync.

Roberto


^ permalink raw reply

* Re: [PATCH] hwrng: tpm: Do not enable by default
From: Niedermayr, BENEDIKT @ 2026-04-29 14:33 UTC (permalink / raw)
  To: Jarkko Sakkinen, Kiszka, Jan
  Cc: Peter Huewe, linux-integrity@vger.kernel.org,
	Linux Kernel Mailing List, Ilias Apalodimas, Jens Wiklander,
	OP-TEE TrustedFirmware, linux-crypto@vger.kernel.org, Bauer, Sven,
	Zeschg, Thomas, Gylstorff, Quirin
In-Reply-To: <aP_NN3HwO4Hp0-9T@kernel.org>

On 10/27/25 20:51, Jarkko Sakkinen wrote:
> On Tue, Oct 21, 2025 at 02:46:15PM +0200, Jan Kiszka wrote:
>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>
>> As seen with optee_ftpm, which uses ms-tpm-20-ref [1], a TPM may write
>> the current time epoch to its NV storage every 4 seconds if there are
>> commands sent to it. The 60 seconds periodic update of the entropy pool
>> that the hwrng kthread does triggers this, causing about 4 writes per
>> requests. Makes 2 millions per year for a 24/7 device, and that is a lot
>> for its backing NV storage.
>>
>> It is therefore better to make the user intentionally enable this,
>> providing a chance to read the warning.
>>
>> [1] https://github.com/Microsoft/ms-tpm-20-ref
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> 
> Looking at DRBG_* from [1] I don't see anything you describe. If OPTEE
> writes NVRAM,  then the implementation is broken.
> 
> Also AFAIK, it is pre-seeded per power cycle. There's nothing that even
> distantly relates on using NVRAM.
> 
> [1] https://trustedcomputinggroup.org/wp-content/uploads/TPM-2.0-1.83-Part-4-Supporting-Routines-Code.pdf

Hi all,

we recently also stumbled over this issue which led me here to this 
thread and maybe adding our observations helps to clarify things here a 
bit (hopefully) or at least augments the information related to firmware 
TPM based implementation based on ms-tpm-20-ref.

Based on the optee_ftpm repo, as Jan already described, which currently 
references commit 98b60a44aba7 of [1] suffers this exact issue because 
of the NV_CLOCK_UPDATE_INTERVAL [2] which is set to "12" and issues a 
write for each command after ~4 seconds have passed.

This config has been changed to "22" (on current master branch [3]) 
which is the allowed maximum when following the TPM spec (chapter 36.3.2 
in [4]) which leads to round about 70 minutes, but optee_ftpm didn't 
move ahead to this commit, yet.
This config exists for being able to adapt the write cycles to the 
specific wear conditions of the hardware.

Moreover the ms-tpm-20-ref repo seems to not be maintained anymore and 
one should rather switch to [6].

So there are currently firmware TPM implementations out there that lead 
to these frequent writes.

AFAIK since the tpm-20-ref implementation basically only supports a file 
on disk or RAM backing storage, the optee_ftpm repo [5] provides it's 
own _plat_NV* implementations that replace the default ones and finally 
call OP-TEE's TEE_* secure storage API, which then routes to whatever 
backend OP-TEE is configured with (REE-FS or RPMB) – In our case the RPMB.

Because there are currently implementations out there (e.g. start using 
optee_ftpm) it may make sense to add this information to the kernel 
config's help text at least?

We are currently trying to bump optee_ftpm to use the more recent v1.84, 
but since we're no TCG member the PRs on github could get a bit 
adventurous (PR's not upstream, yet).
Until then this is a valid issue that exists...


[2] 
https://github.com/microsoft/ms-tpm-20-ref/blob/98b60a44aba79b15fcce1c0d1e46cf5918400f6a/TPMCmd/tpm/include/TpmProfile.h#L199 


[3] 
https://github.com/microsoft/ms-tpm-20-ref/blob/98b60a44aba79b15fcce1c0d1e46cf5918400f6a/TPMCmd/tpm/include/TpmProfile.h#L200

[4] 
https://trustedcomputinggroup.org/wp-content/uploads/TPM-2.0-1.83-Part-1-Architecture.pdf

[5] https://github.com/OP-TEE/optee_ftpm

[6] https://github.com/TrustedComputingGroup/TPM

BR,
Benedikt


^ permalink raw reply

* [PATCH v5 00/13] ima: Introduce staging mechanism
From: Roberto Sassu @ 2026-04-29 16:03 UTC (permalink / raw)
  To: corbet, skhan, zohar, dmitry.kasatkin, eric.snowberg, paul,
	jmorris, serge
  Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
	gregorylumen, chenste, nramas, Roberto Sassu

From: Roberto Sassu <roberto.sassu@huawei.com>

Introduction
============

The IMA measurements list is currently stored in the kernel memory.
Memory occupation grows linearly with the number of entries, and can
become a problem especially in environments with reduced resources.

While there is an advantage in keeping the IMA measurements list in
kernel memory, so that it is always available for reading from the
securityfs interfaces, storing it elsewhere would make it possible to
free precious memory for other kernel components.

Storing the IMA measurements list outside the kernel does not introduce
security issues, since its integrity is anyway protected by the TPM.

Hence, the new IMA staging mechanism is introduced to allow user space
to remove the desired portion of the measurements list from the kernel.


Usage
=====

The IMA staging mechanism can be enabled from the kernel configuration
with the CONFIG_IMA_STAGING option.

If it is enabled, IMA duplicates the current measurements interfaces
(both binary and ASCII), by adding the _staged file suffix. Both the
original and the staging interfaces gain the write permission for the
root user and group, but require the process to have CAP_SYS_ADMIN set.

The staging mechanism supports two flavors.

Staging with prompt
~~~~~~~~~~~~~~~~~~~

The current measurements list is moved to a temporary staging area, and
staged measurements are deleted upon confirmation.

This staging process is achieved with the following steps.

  1.  echo A > <original interface>: the user requests IMA to stage the
      entire measurements list;
  2.  cat <_staged interface>: the user reads the staged measurements;
  3.  echo D > <_staged interface>: the user requests IMA to delete
      staged measurements.

Staging and deleting
~~~~~~~~~~~~~~~~~~~~

N measurements are staged to a temporary staging area, and immediately
deleted without further confirmation.

This staging process is achieved with the following steps.

  1.  cat <original interface>: the user reads the current measurements
      list and determines what the value N for staging should be;
  2.  echo N > <original interface>: the user requests IMA to delete N
      measurements from the current measurements list.


Management of Staged Measurements
=================================

Since with the staging mechanism measurement entries are removed from
the kernel, the user needs to save the staged ones in a storage and
concatenate them together, so that it can present them to remote
attestation agents as if staging was never done.


Patch set content
=================

Patches 1-8 are preparatory patches to quickly replace the hash table,
maintain separate counters for the different measurements list types,
mediate access to the measurements list interface, and simplify the staging
patches.

Patch 9 introduces the staging with prompt flavor. Patch 10 makes it
possible to flush the hash table when deleting all the staged measurements.
Patch 11 introduces the staging and deleting flavor. Patch 12 avoids
measurements entries to be stored twice if there is contention between the
measurements interfaces and kexec. Patch 13 adds the documentation of the
staging mechanism.


Changelog
=========

v4:
 - Add write permission to the original measurement interface, and move
   the A and N staging commands to that interface
 - Explain better the two staging flavors and highlight that the staging
   and delete only stages measurements internally
 - Rename ima_queue_staged_delete_partial() to ima_queue_delete_partial()
 - Replace ima_staged_measurements_prepended with per measurements list
   flag to avoid copying staged and active list measurements twice
 - Optimize the staging and deleting flavor by locklessly determining the
   cut position in the active list, and immediately deleting entries
   without explicit staging and splicing (suggested by Steven Chen)

v3:
 - Add Kconfig option to enable the staging mechanism (suggested by Mimi)
 - Change the meaning of BINARY_STAGED to be just the staged measurements
 - Separate the two staging flavors in two different functions:
   ima_queue_staged_delete_all() for staging with prompt,
   ima_queue_staged_delete_partial() for staging and deleting
 - Delete N entries without staging first (suggested by Mimi)
 - Avoid duplicate staged entries if there is contention between the
   measurements list interfaces and kexec

v2:
 - New patch to move measurements and violation counters outside the
   ima_h_table structure
 - New patch to quickly replace the hash table
 - Forbid partial deletion when flushing hash table (suggested by Mimi)
 - Ignore ima_flush_htable if CONFIG_IMA_DISABLE_HTABLE is enabled
 - BINARY_SIZE_* renamed to BINARY_* for better clarity
 - Removed ima_measurements_staged_exist and testing list empty instead
 - ima_queue_stage_trim() and ima_queue_delete_staged_trimmed() renamed to
   ima_queue_stage() and ima_queue_delete_staged()
 - New delete interval [1, ULONG_MAX - 1]
 - Rename ima_measure_lock to ima_measure_mutex
 - Move seq_open() and seq_release() outside the ima_measure_mutex lock
 - Drop ima_measurements_staged_read() and use seq_read() instead
 - Optimize create_securityfs_measurement_lists() changes
 - New file name format with _staged suffix at the end of the file name
 - Use _rcu list variant in ima_dump_measurement_list()
 - Remove support for direct trimming and splice the remaining entries to
   the active list (suggested by Mimi)
 - Hot swap the hash table if flushing is requested

v1:
 - Support for direct trimming without staging
 - Support unstaging on kexec (requested by Gregory Lumen)

Roberto Sassu (13):
  ima: Remove ima_h_table structure
  ima: Replace static htable queue with dynamically allocated array
  ima: Introduce per binary measurements list type ima_num_entries
    counter
  ima: Introduce per binary measurements list type binary_runtime_size
    value
  ima: Introduce _ima_measurements_start() and _ima_measurements_next()
  ima: Mediate open/release method of the measurements list
  ima: Use snprintf() in create_securityfs_measurement_lists
  ima: Introduce ima_dump_measurement()
  ima: Add support for staging measurements with prompt
  ima: Add support for flushing the hash table when staging measurements
  ima: Support staging and deleting N measurements entries
  ima: Return error on deleting measurements already copied during kexec
  doc: security: Add documentation of the IMA staging mechanism

 .../admin-guide/kernel-parameters.txt         |   4 +
 Documentation/security/IMA-staging.rst        | 163 +++++++++
 Documentation/security/index.rst              |   1 +
 MAINTAINERS                                   |   2 +
 security/integrity/ima/Kconfig                |  16 +
 security/integrity/ima/ima.h                  |  32 +-
 security/integrity/ima/ima_api.c              |   2 +-
 security/integrity/ima/ima_fs.c               | 315 ++++++++++++++++--
 security/integrity/ima/ima_init.c             |   5 +
 security/integrity/ima/ima_kexec.c            |  53 ++-
 security/integrity/ima/ima_queue.c            | 283 ++++++++++++++--
 11 files changed, 803 insertions(+), 73 deletions(-)
 create mode 100644 Documentation/security/IMA-staging.rst

-- 
2.43.0


^ permalink raw reply

* [PATCH v5 02/13] ima: Replace static htable queue with dynamically allocated array
From: Roberto Sassu @ 2026-04-29 16:03 UTC (permalink / raw)
  To: corbet, skhan, zohar, dmitry.kasatkin, eric.snowberg, paul,
	jmorris, serge
  Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
	gregorylumen, chenste, nramas, Roberto Sassu
In-Reply-To: <20260429160319.4162918-1-roberto.sassu@huaweicloud.com>

From: Roberto Sassu <roberto.sassu@huawei.com>

The IMA hash table is a fixed-size array of hlist_head buckets:

    struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE];

IMA_MEASURE_HTABLE_SIZE is (1 << IMA_HASH_BITS) = 1024 buckets, each a
struct hlist_head (one pointer, 8 bytes on 64-bit). That is 8 KiB allocated
in BSS for every kernel, regardless of whether IMA is ever used, and
regardless of how many measurements are actually made.

Replace the fixed-size array with a RCU-protected pointer to a dynamically
allocated array that is initialized in ima_init_htable(), which is called
from ima_init() during early boot. ima_init_htable() calls the static
function ima_alloc_replace_htable() which, other than initializing the hash
table the first time, can also hot-swap the existing hash table with a
blank one.

The allocation in ima_alloc_replace_htable() uses kcalloc() so the buckets
are zero-initialised (equivalent to HLIST_HEAD_INIT { .first = NULL }).
Callers of ima_alloc_replace_htable() must call synchronize_rcu() and free
the returned hash table.

Finally, access the hash table with rcu_dereference() in
ima_lookup_digest_entry() (reader side) and with
rcu_dereference_protected() in ima_add_digest_entry() (writer side).

No functional change: bucket count, hash function, and all locking remain
identical.

Link: https://github.com/linux-integrity/linux/issues/1
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima.h       |  3 +-
 security/integrity/ima/ima_init.c  |  5 ++++
 security/integrity/ima/ima_queue.c | 48 ++++++++++++++++++++++++++----
 3 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 51a8a582df56..94bf890628e5 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -311,6 +311,7 @@ bool ima_template_has_modsig(const struct ima_template_desc *ima_template);
 int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
 int ima_measurements_show(struct seq_file *m, void *v);
+int __init ima_init_htable(void);
 unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
 void ima_init_template_list(void);
@@ -326,7 +327,7 @@ extern spinlock_t ima_queue_lock;
 
 extern atomic_long_t ima_num_entries;
 extern atomic_long_t ima_num_violations;
-extern struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE];
+extern struct hlist_head __rcu *ima_htable;
 
 static inline unsigned int ima_hash_key(u8 *digest)
 {
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index a2f34f2d8ad7..7e0aa09a12e6 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -140,6 +140,11 @@ int __init ima_init(void)
 	rc = ima_init_digests();
 	if (rc != 0)
 		return rc;
+
+	rc = ima_init_htable();
+	if (rc != 0)
+		return rc;
+
 	rc = ima_add_boot_aggregate();	/* boot aggregate must be first entry */
 	if (rc != 0)
 		return rc;
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 1f6515f7d015..41f4941ceaad 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -38,9 +38,7 @@ atomic_long_t ima_num_entries = ATOMIC_LONG_INIT(0);
 atomic_long_t ima_num_violations = ATOMIC_LONG_INIT(0);
 
 /* key: inode (before secure-hashing a file) */
-struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE] = {
-	[0 ... IMA_MEASURE_HTABLE_SIZE - 1] = HLIST_HEAD_INIT
-};
+struct hlist_head __rcu *ima_htable;
 
 /* mutex protects atomicity of extending measurement list
  * and extending the TPM PCR aggregate. Since tpm_extend can take
@@ -54,17 +52,53 @@ static DEFINE_MUTEX(ima_extend_list_mutex);
  */
 static bool ima_measurements_suspended;
 
+/* Callers must call synchronize_rcu() and free the hash table. */
+static struct hlist_head *ima_alloc_replace_htable(void)
+{
+	struct hlist_head *old_htable, *new_htable;
+
+	/* Initializing to zeros is equivalent to call HLIST_HEAD_INIT. */
+	new_htable = kcalloc(IMA_MEASURE_HTABLE_SIZE, sizeof(struct hlist_head),
+			     GFP_KERNEL);
+	if (!new_htable)
+		return ERR_PTR(-ENOMEM);
+
+	old_htable = rcu_replace_pointer(ima_htable, new_htable,
+				lockdep_is_held(&ima_extend_list_mutex));
+
+	return old_htable;
+}
+
+int __init ima_init_htable(void)
+{
+	struct hlist_head *old_htable;
+
+	mutex_lock(&ima_extend_list_mutex);
+	old_htable = ima_alloc_replace_htable();
+	mutex_unlock(&ima_extend_list_mutex);
+
+	if (IS_ERR(old_htable))
+		return PTR_ERR(old_htable);
+
+	/* Synchronize_rcu() and kfree() not necessary, only for robustness. */
+	synchronize_rcu();
+	kfree(old_htable);
+	return 0;
+}
+
 /* lookup up the digest value in the hash table, and return the entry */
 static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value,
 						       int pcr)
 {
 	struct ima_queue_entry *qe, *ret = NULL;
+	struct hlist_head *htable;
 	unsigned int key;
 	int rc;
 
 	key = ima_hash_key(digest_value);
 	rcu_read_lock();
-	hlist_for_each_entry_rcu(qe, &ima_htable[key], hnext) {
+	htable = rcu_dereference(ima_htable);
+	hlist_for_each_entry_rcu(qe, &htable[key], hnext) {
 		rc = memcmp(qe->entry->digests[ima_hash_algo_idx].digest,
 			    digest_value, hash_digest_size[ima_hash_algo]);
 		if ((rc == 0) && (qe->entry->pcr == pcr)) {
@@ -104,6 +138,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
 				bool update_htable)
 {
 	struct ima_queue_entry *qe;
+	struct hlist_head *htable;
 	unsigned int key;
 
 	qe = kmalloc_obj(*qe);
@@ -116,10 +151,13 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
 	INIT_LIST_HEAD(&qe->later);
 	list_add_tail_rcu(&qe->later, &ima_measurements);
 
+	htable = rcu_dereference_protected(ima_htable,
+				lockdep_is_held(&ima_extend_list_mutex));
+
 	atomic_long_inc(&ima_num_entries);
 	if (update_htable) {
 		key = ima_hash_key(entry->digests[ima_hash_algo_idx].digest);
-		hlist_add_head_rcu(&qe->hnext, &ima_htable[key]);
+		hlist_add_head_rcu(&qe->hnext, &htable[key]);
 	}
 
 	if (binary_runtime_size != ULONG_MAX) {
-- 
2.43.0


^ permalink raw reply related

* [PATCH v5 03/13] ima: Introduce per binary measurements list type ima_num_entries counter
From: Roberto Sassu @ 2026-04-29 16:03 UTC (permalink / raw)
  To: corbet, skhan, zohar, dmitry.kasatkin, eric.snowberg, paul,
	jmorris, serge
  Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
	gregorylumen, chenste, nramas, Roberto Sassu
In-Reply-To: <20260429160319.4162918-1-roberto.sassu@huaweicloud.com>

From: Roberto Sassu <roberto.sassu@huawei.com>

Make ima_num_entries as an array, to have separate counters per binary
measurements list type. Currently, define the BINARY type for the existing
binary measurements list.

No functional change: the BINARY type is equivalent to the value without
the array.

Link: https://github.com/linux-integrity/linux/issues/1
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima.h       | 9 ++++++++-
 security/integrity/ima/ima_fs.c    | 3 +--
 security/integrity/ima/ima_kexec.c | 2 +-
 security/integrity/ima/ima_queue.c | 7 +++++--
 4 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 94bf890628e5..b417c9d792d8 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -28,6 +28,13 @@ enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
 		     IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII };
 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10 };
 
+/*
+ * BINARY: current binary measurements list
+ */
+enum binary_lists {
+	BINARY, BINARY__LAST
+};
+
 /* digest size for IMA, fits SHA1 or MD5 */
 #define IMA_DIGEST_SIZE		SHA1_DIGEST_SIZE
 #define IMA_EVENT_NAME_LEN_MAX	255
@@ -325,7 +332,7 @@ int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
  */
 extern spinlock_t ima_queue_lock;
 
-extern atomic_long_t ima_num_entries;
+extern atomic_long_t ima_num_entries[BINARY__LAST];
 extern atomic_long_t ima_num_violations;
 extern struct hlist_head __rcu *ima_htable;
 
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index aaa460d70ff7..79b0f287c668 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -63,8 +63,7 @@ static ssize_t ima_show_measurements_count(struct file *filp,
 					   char __user *buf,
 					   size_t count, loff_t *ppos)
 {
-	return ima_show_counter(buf, count, ppos, &ima_num_entries);
-
+	return ima_show_counter(buf, count, ppos, &ima_num_entries[BINARY]);
 }
 
 static const struct file_operations ima_measurements_count_ops = {
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 5801649fbbef..40962dc0ca86 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -43,7 +43,7 @@ void ima_measure_kexec_event(const char *event_name)
 	int n;
 
 	buf_size = ima_get_binary_runtime_size();
-	len = atomic_long_read(&ima_num_entries);
+	len = atomic_long_read(&ima_num_entries[BINARY]);
 
 	n = scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN,
 		      "kexec_segment_size=%lu;ima_binary_runtime_size=%lu;"
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 41f4941ceaad..952172a4905d 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -33,7 +33,10 @@ static unsigned long binary_runtime_size = ULONG_MAX;
 #endif
 
 /* num of stored measurements in the list */
-atomic_long_t ima_num_entries = ATOMIC_LONG_INIT(0);
+atomic_long_t ima_num_entries[BINARY__LAST] = {
+	[0 ... BINARY__LAST - 1] = ATOMIC_LONG_INIT(0)
+};
+
 /* num of violations in the list */
 atomic_long_t ima_num_violations = ATOMIC_LONG_INIT(0);
 
@@ -154,7 +157,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
 	htable = rcu_dereference_protected(ima_htable,
 				lockdep_is_held(&ima_extend_list_mutex));
 
-	atomic_long_inc(&ima_num_entries);
+	atomic_long_inc(&ima_num_entries[BINARY]);
 	if (update_htable) {
 		key = ima_hash_key(entry->digests[ima_hash_algo_idx].digest);
 		hlist_add_head_rcu(&qe->hnext, &htable[key]);
-- 
2.43.0


^ permalink raw reply related

* [PATCH v5 04/13] ima: Introduce per binary measurements list type binary_runtime_size value
From: Roberto Sassu @ 2026-04-29 16:03 UTC (permalink / raw)
  To: corbet, skhan, zohar, dmitry.kasatkin, eric.snowberg, paul,
	jmorris, serge
  Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
	gregorylumen, chenste, nramas, Roberto Sassu
In-Reply-To: <20260429160319.4162918-1-roberto.sassu@huaweicloud.com>

From: Roberto Sassu <roberto.sassu@huawei.com>

Make binary_runtime_size as an array, to have separate counters per binary
measurements list type. Currently, define the BINARY type for the existing
binary measurements list.

Introduce ima_update_binary_runtime_size() to facilitate updating a
binary_runtime_size value with a given binary measurement list type.

Also add the binary measurements list type parameter to
ima_get_binary_runtime_size(), to retrieve the desired value. Retrieving
the value is now done under the ima_extend_list_mutex, since there can be
concurrent updates.

No functional change (except for the mutex usage, that fixes the
concurrency issue): the BINARY array element is equivalent to the old
binary_runtime_size.

Link: https://github.com/linux-integrity/linux/issues/1
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima.h       |  2 +-
 security/integrity/ima/ima_kexec.c |  5 ++--
 security/integrity/ima/ima_queue.c | 40 +++++++++++++++++++++---------
 3 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index b417c9d792d8..f8ab6b604c0d 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -319,7 +319,7 @@ int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
 int ima_measurements_show(struct seq_file *m, void *v);
 int __init ima_init_htable(void);
-unsigned long ima_get_binary_runtime_size(void);
+unsigned long ima_get_binary_runtime_size(enum binary_lists binary_list);
 int ima_init_template(void);
 void ima_init_template_list(void);
 int __init ima_init_digests(void);
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 40962dc0ca86..44ebefbdcab0 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -42,7 +42,7 @@ void ima_measure_kexec_event(const char *event_name)
 	long len;
 	int n;
 
-	buf_size = ima_get_binary_runtime_size();
+	buf_size = ima_get_binary_runtime_size(BINARY);
 	len = atomic_long_read(&ima_num_entries[BINARY]);
 
 	n = scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN,
@@ -159,7 +159,8 @@ void ima_add_kexec_buffer(struct kimage *image)
 	else
 		extra_memory = CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB * 1024;
 
-	binary_runtime_size = ima_get_binary_runtime_size() + extra_memory;
+	binary_runtime_size = ima_get_binary_runtime_size(BINARY) +
+			      extra_memory;
 
 	if (binary_runtime_size >= ULONG_MAX - PAGE_SIZE)
 		kexec_segment_size = ULONG_MAX;
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 952172a4905d..b6d10dceb669 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -27,9 +27,11 @@ static struct tpm_digest *digests;
 
 LIST_HEAD(ima_measurements);	/* list of all measurements */
 #ifdef CONFIG_IMA_KEXEC
-static unsigned long binary_runtime_size;
+static unsigned long binary_runtime_size[BINARY__LAST];
 #else
-static unsigned long binary_runtime_size = ULONG_MAX;
+static unsigned long binary_runtime_size[BINARY__LAST] = {
+	[0 ... BINARY__LAST - 1] = ULONG_MAX
+};
 #endif
 
 /* num of stored measurements in the list */
@@ -131,6 +133,20 @@ static int get_binary_runtime_size(struct ima_template_entry *entry)
 	return size;
 }
 
+static void ima_update_binary_runtime_size(struct ima_template_entry *entry,
+					   enum binary_lists binary_list)
+{
+	int size;
+
+	if (binary_runtime_size[binary_list] == ULONG_MAX)
+		return;
+
+	size = get_binary_runtime_size(entry);
+	binary_runtime_size[binary_list] =
+		(binary_runtime_size[binary_list] < ULONG_MAX - size) ?
+		binary_runtime_size[binary_list] + size : ULONG_MAX;
+}
+
 /* ima_add_template_entry helper function:
  * - Add template entry to the measurement list and hash table, for
  *   all entries except those carried across kexec.
@@ -163,13 +179,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
 		hlist_add_head_rcu(&qe->hnext, &htable[key]);
 	}
 
-	if (binary_runtime_size != ULONG_MAX) {
-		int size;
-
-		size = get_binary_runtime_size(entry);
-		binary_runtime_size = (binary_runtime_size < ULONG_MAX - size) ?
-		     binary_runtime_size + size : ULONG_MAX;
-	}
+	ima_update_binary_runtime_size(entry, BINARY);
 	return 0;
 }
 
@@ -178,12 +188,18 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
  * entire binary_runtime_measurement list, including the ima_kexec_hdr
  * structure.
  */
-unsigned long ima_get_binary_runtime_size(void)
+unsigned long ima_get_binary_runtime_size(enum binary_lists binary_list)
 {
-	if (binary_runtime_size >= (ULONG_MAX - sizeof(struct ima_kexec_hdr)))
+	unsigned long val;
+
+	mutex_lock(&ima_extend_list_mutex);
+	val = binary_runtime_size[binary_list];
+	mutex_unlock(&ima_extend_list_mutex);
+
+	if (val >= (ULONG_MAX - sizeof(struct ima_kexec_hdr)))
 		return ULONG_MAX;
 	else
-		return binary_runtime_size + sizeof(struct ima_kexec_hdr);
+		return val + sizeof(struct ima_kexec_hdr);
 }
 
 static int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr)
-- 
2.43.0


^ permalink raw reply related

* [PATCH v5 05/13] ima: Introduce _ima_measurements_start() and _ima_measurements_next()
From: Roberto Sassu @ 2026-04-29 16:03 UTC (permalink / raw)
  To: corbet, skhan, zohar, dmitry.kasatkin, eric.snowberg, paul,
	jmorris, serge
  Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
	gregorylumen, chenste, nramas, Roberto Sassu
In-Reply-To: <20260429160319.4162918-1-roberto.sassu@huaweicloud.com>

From: Roberto Sassu <roberto.sassu@huawei.com>

Introduce _ima_measurements_start() and _ima_measurements_next(), renamed
from ima_measurements_start() and ima_measurements_next(), to include the
list head as an additional parameter, so that iteration on different lists
can be implemented by calling those functions.

No functional change: ima_measurements_start() and ima_measurements_next()
pass the ima_measurements list head, used before.

Link: https://github.com/linux-integrity/linux/issues/1
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_fs.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 79b0f287c668..9a8dba14d82a 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -72,14 +72,15 @@ static const struct file_operations ima_measurements_count_ops = {
 };
 
 /* returns pointer to hlist_node */
-static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
+static void *_ima_measurements_start(struct seq_file *m, loff_t *pos,
+				     struct list_head *head)
 {
 	loff_t l = *pos;
 	struct ima_queue_entry *qe;
 
 	/* we need a lock since pos could point beyond last element */
 	rcu_read_lock();
-	list_for_each_entry_rcu(qe, &ima_measurements, later) {
+	list_for_each_entry_rcu(qe, head, later) {
 		if (!l--) {
 			rcu_read_unlock();
 			return qe;
@@ -89,7 +90,13 @@ static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
 	return NULL;
 }
 
-static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
+static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
+{
+	return _ima_measurements_start(m, pos, &ima_measurements);
+}
+
+static void *_ima_measurements_next(struct seq_file *m, void *v, loff_t *pos,
+				    struct list_head *head)
 {
 	struct ima_queue_entry *qe = v;
 
@@ -101,7 +108,12 @@ static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
 	rcu_read_unlock();
 	(*pos)++;
 
-	return (&qe->later == &ima_measurements) ? NULL : qe;
+	return (&qe->later == head) ? NULL : qe;
+}
+
+static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	return _ima_measurements_next(m, v, pos, &ima_measurements);
 }
 
 static void ima_measurements_stop(struct seq_file *m, void *v)
-- 
2.43.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox