mbox series

[RFC,v4,0/9] ima: Integrate with Integrity Digest Cache

Message ID 20241119110103.2780453-1-roberto.sassu@huaweicloud.com (mailing list archive)
Headers show
Series ima: Integrate with Integrity Digest Cache | expand

Message

Roberto Sassu Nov. 19, 2024, 11 a.m. UTC
From: Roberto Sassu <roberto.sassu@huawei.com>

One of the IMA shortcomings over the years has been the availability of
reference digest values for appraisal. Recently, the situation improved
and some Linux distributions are including file signatures, such as
Fedora 39.

The Integrity Digest Cache takes a different approach. Instead of requiring
Linux distributions to include file signatures in their packages, it parses
the digests from signed RPM package headers and exposes an API for
integrity providers to query a digest.

That enables Linux distributions to immediately gain the ability to do
integrity checks with the existing packages, lowering the burden for
software vendors.

In addition, integrating IMA with the Integrity Digest Cache has even more
benefits.

First, it allows generating a new-style masurement list including the RPM
package headers and the unknown files, which improves system performance
due to the lower usage of the TPM. The cost is the less accuracy of the
information reported, which might not be suitable for everyone.

Second, performance improves for appraisal too. It has been found that
verifying the signatures of only the RPM package headers and doing a digest
lookup is much less computationally expensive than verifying individual
file signatures.

In the future, if RPM and other package formats include fsverity digests,
this would further improve the performance, due to verifying only the
portion of the file read.

For reference, a preliminary performance evaluation has been published
here:

https://lore.kernel.org/linux-integrity/20241119104922.2772571-15-roberto.sassu@huaweicloud.com/

Third, it makes a PCR predictable and suitable for TPM key sealing
policies.

Finally, it allows IMA to maintain a predictable PCR and to perform
appraisal from the very beginning of the boot, in the initial ram disk
(excluding auto-generated files).

Integration of IMA with the Integrity Digest Cache is straightforward.

Patch 1 lets IMA know when the Integrity Digest Cache is reading a digest
list, to populate a digest cache.

Patch 2 allows the usage of digest caches with the IMA policy.

Patch 3 introduces new boot-time built-in policies, to use digest caches
from the very beginning (it allows measurement/appraisal from the initial
ram disk).

Patch 4 modifies existing boot-time built-in policies if the Integrity
Digest Cache-specific policies have been selected at boot.

Patch 5 obtains a digest cache for a given file, stores it in the inode
integrity metadata, and notifies if the digest cache changed since last
file access.

Patches 6-7 store and load the integrity state of the digest list the
digest cache was populated from, to restrict the digest cache usage in case
an IMA action was not performed on the digest list.

Patches 8-9 enable the usage of digest caches respectively for measurement
and appraisal, at the condition that it is authorized with the IMA policy
and that the digest list itself was measured and appraised too.

Open points:
- Mimi prefers to extend flags in ima_iint_cache, rather than passing the
  parameter down to process_measurement() - will do in a next version
- Prefetching of digest lists should not be done if there is no
  measurement rule (not relevant for appraisal)


This patch set applies on top of:

https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git/log/?h=next-integrity

with commit 08ae3e5f5fc8 ("integrity: Use static_assert() to check struct
sizes").

and on top of the patch set at the URL:

https://lore.kernel.org/linux-integrity/20241119104922.2772571-1-roberto.sassu@huaweicloud.com/

Changelog

v3:
- Pass file descriptor to digest_cache_get()
- Retry digest_cache_lookup() if an error pointer is returned
- Drop patch 2/10 and use new function digest_cache_opened_fd() as argument
  of mutex_lock_nested()

v2:
- Rename Integrity Digest Cache to Integrity Digest Cache (suggested by Paul
  Moore)
- Add digest_cache member to ima_iint_cache structure
- Nest mutex only in process_measurement()
- Check IMA_DIGEST_CACHE_APPRAISE_DATA earlier in
  ima_appraise_measurement()
- Introduce ima_digest_cache_get_check() to detect changes, instead of
  using the notifier mechanism (removed from the Integrity Digest Cache)
- Rename ima_digest_cache_store_allowed_usage() to
  ima_digest_cache_store_verified_usage()
- Rename ima_digest_cache_update_allowed_usage() to
  ima_digest_cache_load_verified_usage(), but do the AND outside the
  function
- Check allowed IMA hooks with ima_digest_cache_func_allowed() also at
  run-time (when a policy is evaluated)

v1:
- Change digest_cache= policy keyword value from 'content' to 'data'
  (suggested by Mimi)
- Move Integrity Digest Cache integration code to ima_digest_cache.c (suggested
  by Mimi)
- Don't store digest cache pointer in integrity metadata
- Rename 'digest_cache_mask' parameter of ima_get_action() and
  ima_match_policy() to 'digest_cache_usage'
- Rename 'digest_cache_mask' parameter of ima_store_measurement() and
  ima_appraise_measurement() to 'allowed_usage'
- Try digest cache method as first in ima_appraise_measurement() (suggested
  by Mimi)
- Introduce ima_digest_cache_change() to be called on digest cache reset
- Subscribe to digest cache events
- Add forgotten modification in ima_iint_lockdep_annotate() (reported by
  Mimi)
- Replace 'digest_cache_mask' member of the ima_rule_entry structure with
  'digest_cache_usage' (suggested by Mimi)
- Split patch introducing Integrity Digest Cache-specific boot-time built-in
  policies and modifying existing rules
- Add Integrity Digest Cache-specific boot-time built-in policies if the
  Integrity Digest Cache is enabled in the kernel configuration
- Rename IMA_DIGEST_CACHE_MEASURE_CONTENT and
  IMA_DIGEST_CACHE_APPRAISE_CONTENT to IMA_DIGEST_CACHE_MEASURE_DATA and
  IMA_DIGEST_CACHE_APPRAISE_DATA

Roberto Sassu (9):
  ima: Introduce hook DIGEST_LIST_CHECK
  ima: Add digest_cache policy keyword
  ima: Add digest_cache_measure/appraise boot-time built-in policies
  ima: Modify existing boot-time built-in policies with digest cache
    policies
  ima: Retrieve digest cache and check if changed
  ima: Store verified usage in digest cache based on integrity metadata
    flags
  ima: Load verified usage from digest cache found from query
  ima: Use digest caches for measurement
  ima: Use digest caches for appraisal

 Documentation/ABI/testing/ima_policy          |   6 +-
 .../admin-guide/kernel-parameters.txt         |  15 +-
 security/integrity/ima/Kconfig                |  10 ++
 security/integrity/ima/Makefile               |   1 +
 security/integrity/ima/ima.h                  |  21 ++-
 security/integrity/ima/ima_api.c              |  21 ++-
 security/integrity/ima/ima_appraise.c         |  33 +++--
 security/integrity/ima/ima_digest_cache.c     | 126 +++++++++++++++++
 security/integrity/ima/ima_digest_cache.h     |  38 +++++
 security/integrity/ima/ima_iint.c             |   4 +
 security/integrity/ima/ima_main.c             |  33 +++--
 security/integrity/ima/ima_policy.c           | 133 +++++++++++++++++-
 12 files changed, 413 insertions(+), 28 deletions(-)
 create mode 100644 security/integrity/ima/ima_digest_cache.c
 create mode 100644 security/integrity/ima/ima_digest_cache.h