[RFC v1 0/1] Implement IMA Event Log Trimming

Anirudh Venkataramanan anirudhve at linux.microsoft.com
Wed Nov 19 21:33:17 UTC 2025


==========================================================================
| A. Introduction                                                        |
==========================================================================

IMA events are kept in kernel memory and preserved across kexec soft
reboots. This can lead to increased kernel memory usage over time,
especially with aggressive IMA policies that measure everything. To reduce
memory pressure, it becomes necessary to discard IMA events but given that
IMA events are extended into PCRs in the TPM, just discarding events will
break the PCR extension chain, making future verification of the IMA event
log impossible.

This patch series proposes a method to discard IMA events while keeping the
log verifiable. While reducing memory pressure is the primary objective,
the second order benefit of trimming the IMA log is that IMA log verifiers
(local userspace daemon or a remote cloud service) can process smaller IMA
logs on a rolling basis, thus avoiding re-verification of previously
verified events.

The method has other advantages too:

 1. It provides a userspace interface that can be used to precisely control
    trim point, allowing for trim points to be optionally aligned with
    userspace IMA event log validation.

 2. It ensures that all necessary information required for continued IMA
    log validation is made available via the userspace interface at all
    times.

 3. It provides a simple mechanism for userspace applications to determine
    if the event log has been unexpectedly trimmed.

 4. The duration for which the IMA Measurement list mutex must be held (for
    trimming) is minimal.

==========================================================================
| B. Solution                                                            |
==========================================================================

--------------------------------------------------------------------------
| B.1 Overview                                                           |
--------------------------------------------------------------------------

The kernel trims the IMA event log based on PCR values supplied by userspace.
The core principles leveraged are as follows:

 - Given an IMA event log, PCR values for each IMA event can be obtained by
   recalulating the PCR extension for each event. Thus processing N events
   from the start will yield PCR values as of event N. This is referred to
   as "IMA event log replay".

 - To get the PCR value for event N + 1, only the PCR value as of event N
   is needed. If this can be known, events till and including N can be
   safely purged.

Putting it all together, we get the following userspace + kernel flow:

 1. A userspace application replays the IMA event log to generate PCR
    values and then triggers a trim by providing these values to the kernel
    (by writing to a pseudo file). 

    Optionally, the userspace application may verify these PCR values
    against the corresponding TPM quote, and trigger trimming only if
    the calculated PCR values match up to the expectations in the quote's
    PCR digest.

 2. The kernel uses the userspace supplied PCR values to trim the IMA
    measurements list at a specific point, and so these are referred to as
    "trim-to PCR values" in this context.

    Note that the kernel doesn't really understand what these userspace
    provided PCR values mean or what IMA event they correspond to, and so
    it does its own IMA event replay till either the replayed PCR values
    match with the userspace provided ones, or it runs out of events.

    If a match is found, the kernel can proceed with trimming the IMA
    measurements list. This is done in two steps, to keep locking context
    minimal.

    step 1: Find and return the list entry (as a count from head) of exact
            match. This does not lock the measurements list mutex, ensuring
            new events can be appended to the log.

    step 2: Lock the measurements list mutex and trim the measurements list
            at the previously identified list entry.

   If the trim is successful, the trim-to PCR values are saved as "starting
   PCR values". The next time userspace wants to replay the IMA event log,
   it will use the starting PCR values as the base for the IMA event log
   replay.

--------------------------------------------------------------------------
| B.2 Kernel Interfaces                                                  |
--------------------------------------------------------------------------

A new configfs pseudo file /sys/kernel/config/ima/pcrs that supports the
following operations is exposed.

  read: returns starting PCR values stored in the kernel (within IMA
        specifically).

 write: writes trim-to PCR values to trigger trimming. If trimming is
        successful, trim-to PCR values are stored as starting PCR values.
        requires root privileges.

--------------------------------------------------------------------------
| B.3 Walk-through with a real example                                   |
--------------------------------------------------------------------------

This is a real example from a test run.

Suppose this IMA policy is deployed:

  measure func=FILE_CHECK mask=MAY_READ pcr=10
  measure func=FILE_CHECK mask=MAY_WRITE pcr=11

When the policy is deployed, a zero digest starting PCR value will be set
for each PCR used. If the TPM supports multiple hashbanks, there will be
one starting PCR value per PCR, per TPM hashbank. This can be seen in the
following hexdump:

$ sudo hexdump -vC /sys/kernel/config/ima/pcrs
00000000  70 63 72 31 30 3a 73 68  61 31 3a 00 00 00 00 00  |pcr10:sha1:.....|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 70  |...............p|
00000020  63 72 31 31 3a 73 68 61  31 3a 00 00 00 00 00 00  |cr11:sha1:......|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 70 63  |..............pc|
00000040  72 31 30 3a 73 68 61 32  35 36 3a 00 00 00 00 00  |r10:sha256:.....|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 70 63 72 31 31  |...........pcr11|
00000070  3a 73 68 61 32 35 36 3a  00 00 00 00 00 00 00 00  |:sha256:........|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000090  00 00 00 00 00 00 00 00  70 63 72 31 30 3a 73 68  |........pcr10:sh|
000000a0  61 33 38 34 3a 00 00 00  00 00 00 00 00 00 00 00  |a384:...........|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000d0  00 00 00 00 00 70 63 72  31 31 3a 73 68 61 33 38  |.....pcr11:sha38|
000000e0  34 3a 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |4:..............|
000000f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000100  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000110  00 00                                             |..|
00000112

Let's say that a userspace utility replays the IMA event log, and triggers
trimming by writing the following PCR values (i.e. trim-to PCR values) to the
pseudo file:

pcr10:sha256:8268782906555cf3aefc179f815c878527dd4e67eaa836572ebabab31977922c
pcr11:sha256:4c7f31927183eacb53d51d95b0162916fd3fca51a8d1efc6dde3805eb891fe41

The trim is successful, 

1. Some number of entries from the measurements log will disappear. This
   can be verified by reading out the ASCII or binary IMA measurements
   file.

2. The trim-to PCR values are saved as starting PCR values. This can be
   verified by reading out the pseudo file again as shown below. Note that
   even through only sha256 PCR values were written, the kernel populated
   sha1 and sha384 starting values as well.

$ sudo hexdump -vC /sys/kernel/config/ima/pcrs

00000000  70 63 72 31 30 3a 73 68  61 31 3a c4 7f 9d 00 68  |pcr10:sha1:....h|
00000010  e4 86 71 bf bc ae f0 10  12 ff 68 e2 9e 74 e4 70  |..q.......h..t.p|
00000020  63 72 31 31 3a 73 68 61  31 3a 90 d7 17 ac 60 4d  |cr11:sha1:....`M|
00000030  c8 25 ce 77 7d 9d 94 cf  44 7b b2 2e 2e e2 70 63  |.%.w}...D{....pc|
00000040  72 31 30 3a 73 68 61 32  35 36 3a 82 68 78 29 06  |r10:sha256:.hx).|
00000050  55 5c f3 ae fc 17 9f 81  5c 87 85 27 dd 4e 67 ea  |U\......\..'.Ng.|
00000060  a8 36 57 2e ba ba b3 19  77 92 2c 70 63 72 31 31  |.6W.....w.,pcr11|
00000070  3a 73 68 61 32 35 36 3a  4c 7f 31 92 71 83 ea cb  |:sha256:L.1.q...|
00000080  53 d5 1d 95 b0 16 29 16  fd 3f ca 51 a8 d1 ef c6  |S.....)..?.Q....|
00000090  dd e3 80 5e b8 91 fe 41  70 63 72 31 30 3a 73 68  |...^...Apcr10:sh|
000000a0  61 33 38 34 3a 8e d6 12  18 b1 d6 cd 95 16 98 33  |a384:..........3|
000000b0  2b 7d a2 d6 d9 05 c7 e8  5b 15 b0 91 c5 fc 23 d1  |+}......[.....#.|
000000c0  f9 a8 8d 60 50 5c e9 64  5f d7 b3 b2 f1 9c 90 0a  |...`P\.d_.......|
000000d0  45 53 5d b2 57 70 63 72  31 31 3a 73 68 61 33 38  |ES].Wpcr11:sha38|
000000e0  34 3a 25 fc 21 28 31 5a  f7 c6 fb 0f 40 c9 06 e6  |4:%.!(1Z.... at ...|
000000f0  c5 da ed 20 61 a1 03 54  4f 67 18 88 82 0f 48 d1  |... a..TOg....H.|
00000100  2f e0 3d 36 46 5e 94 a4  88 51 f8 91 39 7e e5 97  |/.=6F^...Q..9~..|
00000110  2c c5                                             |,.|
00000112

--------------------------------------------------------------------------
| C. Footnotes                                                           |
--------------------------------------------------------------------------

1. The 'pcrs' pseudo file is currently part of configfs. This was due to
   some early internal feedback in a different context. This can as well be
   in securityfs with the rest of the IMA pseudo files.

2. PCR values are never read out of the TPM at any point. All PCR values
   used are derived from IMA event log replay.

3. Code is "RFC quality". Refinements can be made if the method is accepted.

4. For functional validation, base kernel version was 6.17 stable, with the
   most recent tested version being 6.17.8.

5. Code has been validated to some degree using a python-based internal test
   tool. This can be published if there is community interest. 

Steven Chen (1):
  ima: Implement IMA event log trimming

 drivers/Kconfig                       |   2 +
 drivers/Makefile                      |   1 +
 drivers/ima/Kconfig                   |  13 +
 drivers/ima/Makefile                  |   2 +
 drivers/ima/ima_config_pcrs.c         | 291 ++++++++++++++++++
 include/linux/ima.h                   |  27 ++
 security/integrity/ima/Makefile       |   4 +
 security/integrity/ima/ima.h          |   8 +
 security/integrity/ima/ima_init.c     |  44 +++
 security/integrity/ima/ima_log_trim.c | 421 ++++++++++++++++++++++++++
 security/integrity/ima/ima_policy.c   |   7 +-
 security/integrity/ima/ima_queue.c    |   5 +-
 12 files changed, 821 insertions(+), 4 deletions(-)
 create mode 100644 drivers/ima/Kconfig
 create mode 100644 drivers/ima/Makefile
 create mode 100644 drivers/ima/ima_config_pcrs.c
 create mode 100644 security/integrity/ima/ima_log_trim.c

-- 
2.43.0




More information about the Linux-security-module-archive mailing list