Thread (12 messages) flat view 12 messages, 4 authors, 2020-08-31

Re: [PATCH] SELinux: Measure state and hash of policy using IMA

From: Stephen Smalley <stephen.smalley.work@gmail.com>
Date: 2020-08-24 14:00:27
Also in: linux-integrity, lkml, selinux

On Fri, Aug 21, 2020 at 9:00 PM Lakshmi Ramasubramanian
[off-list ref] wrote:
Critical data structures of security modules are currently not measured.
Therefore an attestation service, for instance, would not be able to
attest whether the security modules are always operating with the policies
and configuration that the system administrator had setup. The policies
and configuration for the security modules could be tampered with by
rogue user mode agents or modified through some inadvertent actions on
the system. Measuring such critical data would enable an attestation
service to reliably assess the security configuration of the system.

SELinux configuration and policy are some of the critical data for this
security module that needs to be measured. This measurement can be used
by an attestation service, for instance, to verify if the configuration
and policies have been setup correctly and that they haven't been tampered
with at runtime.

Measure SELinux configuration, policy capabilities settings, and the hash
of the loaded policy by calling the IMA hook ima_measure_critical_data().
Since the size of the loaded policy can be quite large, hash of the policy
is measured instead of the entire policy to avoid bloating the IMA log.

Enable early boot measurement for SELinux in IMA since SELinux
initializes its state and policy before custom IMA policy is loaded.

Sample measurement of SELinux state and hash of the policy:

10 e32e...5ac3 ima-buf sha256:86e8...4594 selinux-state-1595389364:287899386 696e697469616c697a65643d313b656e61626c65643d313b656e666f7263696e673d303b636865636b72657170726f743d313b6e6574776f726b5f706565725f636f6e74726f6c733d313b6f70656e5f7065726d733d313b657874656e6465645f736f636b65745f636c6173733d313b616c776179735f636865636b5f6e6574776f726b3d303b6367726f75705f7365636c6162656c3d313b6e6e705f6e6f737569645f7472616e736974696f6e3d313b67656e66735f7365636c6162656c5f73796d6c696e6b733d303
10 9e81...0857 ima-buf sha256:4941...68fc selinux-policy-hash-1597335667:462051628 8d1d...1834

To verify the measurement check the following:

Execute the following command to extract the measured data
from the IMA log for SELinux configuration (selinux-state).

  grep -m 1 "selinux-state" /sys/kernel/security/integrity/ima/ascii_runtime_measurements | cut -d' ' -f 6 | xxd -r -p

The output should be the list of key-value pairs. For example,
 initialized=1;enabled=1;enforcing=0;checkreqprot=1;network_peer_controls=1;open_perms=1;extended_socket_class=1;always_check_network=0;cgroup_seclabel=1;nnp_nosuid_transition=1;genfs_seclabel_symlinks=0;

To verify the measured data with the current SELinux state:

 => enabled should be set to 1 if /sys/fs/selinux folder exists,
    0 otherwise

For other entries, compare the integer value in the files
 => /sys/fs/selinux/enforce
 => /sys/fs/selinux/checkreqprot
And, each of the policy capabilities files under
 => /sys/fs/selinux/policy_capabilities

For selinux-policy-hash, the hash of SELinux policy is included
in the IMA log entry.

To verify the measured data with the current SELinux policy run
the following commands and verify the output hash values match.

  sha256sum /sys/fs/selinux/policy | cut -d' ' -f 1

  grep -m 1 "selinux-policy-hash" /sys/kernel/security/integrity/ima/ascii_runtime_measurements | cut -d' ' -f 6

This patch is dependent on the following patch series:
        https://patchwork.kernel.org/patch/11709527/
        https://patchwork.kernel.org/patch/11730193/
        https://patchwork.kernel.org/patch/11730757/

Signed-off-by: Lakshmi Ramasubramanian <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reported-by: kernel test robot <redacted> # error: implicit declaration of function 'vfree'
Reported-by: kernel test robot <redacted> # error: implicit declaration of function 'crypto_alloc_shash'
Reported-by: kernel test robot <redacted> # sparse: symbol 'security_read_selinux_policy' was not declared. Should it be static?
---
+int security_read_policy_kernel(struct selinux_state *state,
+                               void **data, size_t *len)
+{
+       int rc;
+
+       rc = security_read_policy_len(state, len);
+       if (rc)
+               return rc;
+
+       *data = vmalloc(*len);
+       if (!*data)
+               return -ENOMEM;

+       return security_read_selinux_policy(state, data, len);
 }
See the discussion here:
https://lore.kernel.org/selinux/20200824113015.1375857-1-omosnace@redhat.com/T/#t (local)

In order for this to be safe, you need to ensure that all callers of
security_read_policy_kernel() have taken fsi->mutex in selinuxfs and
any use of security_read_policy_len() occurs while holding the mutex.
Otherwise, the length can change between security_read_policy_len()
and security_read_selinux_policy() if policy is reloaded.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help