On 1/29/2026 12:20 AM, Roberto Sassu wrote:
On 1/28/2026 10:30 PM, steven chen wrote:
On 12/12/2025 9:19 AM, Roberto Sassu wrote:
From: Roberto Sassu <[email protected]>

Introduce the ability of staging the entire (or a portion of the) IMA
measurement list for deletion. Staging means moving the current content of the measurement list to a separate location, and allowing users to read and
delete it. This causes the measurement list to be atomically truncated
before new measurements can be added. Staging can be done only once at a time. In the event of kexec(), staging is reverted and staged entries will
be carried over to the new kernel.

User space is responsible to concatenate the staged IMA measurements list portions following the temporal order in which the operations were done, together with the current measurement list. Then, it can send the collected
data to the remote verifiers.

Also introduce the ability of trimming N measurements entries from the IMA measurements list, provided that user space has already read them. Trimming
combines staging and deletion in one operation.

The benefit of these solutions is the ability to free precious kernel
memory, in exchange of delegating user space to reconstruct the full
measurement list from the chunks. No trust needs to be given to user space,
since the integrity of the measurement list is protected by the TPM.

By default, staging/trimming the measurements list does not alter the hash
table. When staging/trimming are done, IMA is still able to detect
collisions on the staged and later deleted measurement entries, by keeping
the entry digests (only template data are freed).

However, since during the measurements list serialization only the SHA1
digest is passed, and since there are no template data to recalculate the other digests from, the hash table is currently not populated with digests
from staged/deleted entries after kexec().

Introduce the new kernel option ima_flush_htable to decide whether or not the digests of staged measurement entries are flushed from the hash table.

Then, introduce ascii_runtime_measurements_staged_<algo> and
binary_runtime_measurement_staged_<algo> interfaces to stage/trim/delete
the measurements. Use 'echo A > <IMA interface>' and
'echo D > <IMA interface>' to respectively stage and delete the entire
measurements list. Use 'echo N > <IMA interface>', with N between 1 and
LONG_MAX, to stage the selected portion of the measurements list, and
'echo -N > <IMA interface>' to trim N measurements entries.

The ima_measure_users counter (protected by the ima_measure_lock mutex) has been introduced to protect access to the measurements list and the staged part. The open method of all the measurement interfaces has been extended to allow only one writer at a time or, in alternative, multiple readers.
The write permission is used to stage/trim/delete the measurements, the
read permission to read them. Write requires also the CAP_SYS_ADMIN
capability.

Finally, introduce and maintain dedicate counters for the number of
measurement entries and binary size, for the current measurements list
(BINARY_SIZE), for the current measurements list plus staged entries
(BINARY_SIZE_STAGED) useful for kexec() segment allocation, and for the
entire measurement list without staging/trimming (BINARY_SIZE_FULL) useful
for the kexec-related critical data records.
Is the following possible race condition for staged list:

Agent A: create staged list            Staged list A1
          new measurement added    Measurement list M1
          Two lists in kernel: A1 and M1

Agent B: read staged list (A1) to do verification
          new measurement added    Measurement list M2
          Two lists in kernel: A1 and M2

Agent A: verified and remove staged list (A1)
          new measurement added    Measurement list M3
          One list in kernel: M3

Agent C: create staged list            Staged list C1
          new measurement added    Measurement list M4
          Two lists in kernel: C1 and M4

Agent B: remove staged list (?), C1 removed ---this will cause problem
          new measurement added    Measurement list M5
          One list in kernel: M5

Agent C: try to remove staged list(?)

If you remember the patch, we added a read-write protection to the measurements interfaces. As long as you keep the interface open for write no one else can make change on the staging. Sure, you can drop the write, and reopen for read, but then you should expect someone else to operate on the interface.

If you want to be sure no one else changes the staged measurements, just keep the interface open for write, read the staged measurements and delete them.

Roberto

For different use cases, we can compare lock time for both staged method and trim N method:

t1: user space measurement list lock time
t2: kernel measurement list lock time

    Stage approach use case 1:
              1. read PCR quote
              2. read list
              3. attestation
              4. get N from attestation response
---          5. hold the list in the user space
 ^   ---    6. hold the measurement list
       ^     7. stage the list
t1    t2   8. trim N
       v     9. put the rest of stage back to measurement list
 v   ---    10. release the measurement list
---          11. release the list in the user space
 For this case, agent race condition may happen

  Stage approach use case 2:
              1. read PCR quote
---          2. hold the list in the user space
 ^           3. stage the list
              4. read list
              5. attestation
t1    ---  6. hold the measurement list
         ^   7. get N from attestation response
         t2  8. trim N
         v    9. put the rest of stage back to measurement list
 v    ---   10. release the measurement list
---          11. release the list in the user space
 For this case, no agent race condition happen

the following use case for trim N method

   Trim N approach use case:
             1. read total trimmed T
             2. read PCR quote
             3. read list,
             4. attestation
             5. get N from attestation response
---         6. hold the list in the user space
 ^   ---   7. hold the measurement list
       ^
t1   t2   8. trim with format T:N, update T
       v
 v   ---    9 . release the measurement list
---          10. release the list in the user space
    no agent race condition happen

For all use cases, I think for both t1 and t2, trim N method has better result.

Steven

Possible solution?
   Save the total number trimmed T or tag

   Trim request sync this parameter to trim the staged list

Regards,

Steven

Note: This code derives from the Alt-IMA Huawei project, and is being
       released under the dual license model (GPL-2.0 OR MIT).

Link: https://github.com/linux-integrity/linux/issues/1
Signed-off-by: Roberto Sassu <[email protected]>
---


Reply via email to