[PATCH v8 8/8] selinux: include a consumer of the new IMA critical data hook

Lakshmi Ramasubramanian nramas at linux.microsoft.com
Sat Dec 12 00:33:56 UTC 2020


On 12/11/20 4:32 PM, Tyler Hicks wrote:
> On 2020-12-11 15:58:07, Tushar Sugandhi wrote:
>> From: Lakshmi Ramasubramanian <nramas at linux.microsoft.com>
>>
>> SELinux stores the active policy in memory, so the changes to this data
>> at runtime would have an impact on the security guarantees provided
>> by SELinux. Measuring in-memory SELinux policy through IMA subsystem
>> provides a secure way for the attestation service to remotely validate
>> the policy contents at runtime.
>>
>> Measure the hash of the loaded policy by calling the IMA hook
>> ima_measure_critical_data(). Since the size of the loaded policy can
>> be large (several MB), measure the hash of the policy instead of
>> the entire policy to avoid bloating the IMA log entry.
>>
>> Add "selinux" to the list of supported data sources maintained by IMA
>> to enable measuring SELinux data.
>>
>> To enable SELinux data measurement, the following steps are required:
>>
>> 1, Add "ima_policy=critical_data" to the kernel command line arguments
>>     to enable measuring SELinux data at boot time.
>> For example,
>>    BOOT_IMAGE=/boot/vmlinuz-5.10.0-rc1+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset security=selinux ima_policy=critical_data
>>
>> 2, Add the following rule to /etc/ima/ima-policy
>>     measure func=CRITICAL_DATA data_source=selinux
>>
>> Sample measurement of the hash of SELinux policy:
>>
>> 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 "selinux-policy-hash" /sys/kernel/security/integrity/ima/ascii_runtime_measurements | tail -1 | cut -d' ' -f 6
>>
>> Note that the actual verification of SELinux policy would require loading
>> the expected policy into an identical kernel on a pristine/known-safe
>> system and run the sha256sum /sys/kernel/selinux/policy there to get
>> the expected hash.
>>
>> Signed-off-by: Lakshmi Ramasubramanian <nramas at linux.microsoft.com>
>> Suggested-by: Stephen Smalley <stephen.smalley.work at gmail.com>
> 
> This looks good but I've got one small suggestion below if you roll a
> v9. Feel free to add:
> 
> Reviewed-by: Tyler Hicks <tyhicks at linux.microsoft.com>
> 
>> diff --git a/security/selinux/measure.c b/security/selinux/measure.c
>> new file mode 100644
>> index 000000000000..a070d8dae403
>> --- /dev/null
>> +++ b/security/selinux/measure.c
>> @@ -0,0 +1,81 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Measure SELinux state using IMA subsystem.
>> + */
>> +#include <linux/vmalloc.h>
>> +#include <linux/ktime.h>
>> +#include <linux/ima.h>
>> +#include "security.h"
>> +
>> +/*
>> + * This function creates a unique name by appending the timestamp to
>> + * the given string. This string is passed as "event_name" to the IMA
>> + * hook to measure the given SELinux data.
>> + *
>> + * The data provided by SELinux to the IMA subsystem for measuring may have
>> + * already been measured (for instance the same state existed earlier).
>> + * But for SELinux the current data represents a state change and hence
>> + * needs to be measured again. To enable this, pass a unique "event_name"
>> + * to the IMA hook so that IMA subsystem will always measure the given data.
>> + *
>> + * For example,
>> + * At time T0 SELinux data to be measured is "foo". IMA measures it.
>> + * At time T1 the data is changed to "bar". IMA measures it.
>> + * At time T2 the data is changed to "foo" again. IMA will not measure it
>> + * (since it was already measured) unless the event_name, for instance,
>> + * is different in this call.
>> + */
>> +static char *selinux_event_name(const char *name_prefix)
>> +{
>> +	char *event_name = NULL;
>> +	struct timespec64 cur_time;
>> +
>> +	ktime_get_real_ts64(&cur_time);
>> +	event_name = kasprintf(GFP_KERNEL, "%s-%lld:%09ld", name_prefix,
>> +			       cur_time.tv_sec, cur_time.tv_nsec);
>> +	return event_name;
> 
> There's no longer a need to store the return of kasprintf() in a
> variable. Just 'return kasprint(...);' and get rid of the event_name
> variable.
> 

Sure - I'll make the change.

  -lakshmi




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