IMA measures files and buffer data such as keys, command-line arguments
passed to the kernel on kexec system call, etc. While these measurements
are necessary for monitoring and validating the integrity of the system,
they are not sufficient. Various data structures, policies, and states
stored in kernel memory also impact the integrity of the system.
Several kernel subsystems contain such integrity critical data -
e.g. LSMs like SELinux, AppArmor etc. or device-mapper targets like
dm-crypt, dm-verity, dm-integrity etc. These kernel subsystems help
protect the integrity of a system. Their integrity critical data is not
expected to change frequently during run-time. Some of these structures
cannot be defined as __ro_after_init, because they are initialized later.
For a given system, various external services/infrastructure tools
(including the attestation service) interact with it - both during the
setup and during rest of the system run-time. They share sensitive data
and/or execute critical workload on that system. The external services
may want to verify the current run-time state of the relevant kernel
subsystems before fully trusting the system with business critical
data/workload. For instance, verifying that SELinux is in "enforce" mode
along with the expected policy, disks are encrypted with a certain
configuration, secure boot is enabled etc.
This series provides the necessary IMA functionality for kernel
subsystems to ensure their configuration can be measured:
- by kernel subsystems themselves,
- in a tamper resistant way,
- and re-measured - triggered on state/configuration change.
This patch set:
- defines a new IMA hook ima_measure_critical_data() to measure
integrity critical data,
- limits the critical data being measured based on a label,
- defines a builtin critical data measurement policy,
- and includes an SELinux consumer of the new IMA critical data hook.
This series is based on the following repo/branch:
repo: https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
branch: next-integrity
commit 207cdd565dfc ("ima: Don't modify file descriptor mode on the fly")
Change Log v10:
Incorporated feedback from Mimi on v9 of this series.
- Updated function description comments to simplify language and remove
unnecessary text.
- Changed references to variable names and policy documentation from
"data_source" to "label".
- Updated patch descriptions to simplify language and remove unnecessary
text.
- Updated function names and file name related to SELinux IMA
measurements per feedback from Paul Moore.
- Updated patch description for adding a built-in IMA policy for
measuring kernel critical data.
Change Log v9:
Incorporated feedback from Tyler on v8 of this series.
- Moved rule->data_source logic from Patch #4 to Patch #5.
- Removed unnecessary variable event_name from selinux_event_name()
in Patch #8.
Change Log v8:
Incorporated feedback from Tyler on v7 of this series.
- Removed unnecessary 'else' clauses in ima_match_rule_data().
- Fixed ima_store_template() to pass the buffer hash in case the
buffer is large.
- fixed function description for ima_measure_critical_data().
- Moved some usage of CRITICAL_DATA from Patch #3 to Patch #4.
- Moved IMA_DATA_SOURCE from Patch #4 to Patch #5.
- Removed unnecessary pr_err() from ima_measure_critical_data()
and selinux_event_name().
- Fixed log formatting in selinux_measure_state() to be consistent
with other messages in that file.
Change Log v7:
Incorporated feedback from Mimi on v6 of this series.
- Updated cover letter and patch descriptions as per Mimi's feedback.
- Changed references to variable names and policy documentation from
plural "data_sources" to singular "data_source".
- Updated SELinux patch to measure only policy, instead of policy and
state. The state measurement will be upstreamed through a separate
patch.
- Updated admin-guide/kernel-parameters.txt to document support for
critical_data in builtin policy.
Change Log v6:
Incorporated feedback from Mimi on v5 of this series.
- Got rid of patch 5 from the v5 of the series.(the allow list for data
sources)
- Updated function descriptions, changed variable names etc.
- Moved the input param event_data_source in ima_measure_critical_data()
to a new patch. (patch 6/8 of this series)
- Split patch 4 from v5 of the series into two patches (patch 4/8 and
patch 5/8)
- Updated cover letter and patch descriptions as per feedback.
Change Log v5:
(1) Incorporated feedback from Stephen on the last SeLinux patch.
SeLinux Patch: https://patchwork.kernel.org/patch/11801585/
- Freed memory in the reverse order of allocation in
selinux_measure_state().
- Used scnprintf() instead of snprintf() to create the string for
selinux state.
- Allocated event name passed to ima_measure_critical_data() before
gathering selinux state and policy information for measuring.
(2) Incorporated feedback from Mimi on v4 of this series.
V4 of this Series: https://patchwork.kernel.org/project/linux-integrity/list/?series=354437
- Removed patch "[v4,2/6] IMA: conditionally allow empty rule data"
- Reversed the order of following patches.
[v4,4/6] IMA: add policy to measure critical data from kernel components
[v4,5/6] IMA: add hook to measure critical data from kernel components
and renamed them to remove "from kernel components"
- Added a new patch to this series -
IMA: add critical_data to built-in policy rules
- Added the next version of SeLinux patch (mentioned above) to this
series
selinux: measure state and hash of the policy using IMA
- Updated cover-letter description to give broader perspective of the
feature, rearranging paragraphs, removing unnecessary info, clarifying
terms etc.
- Got rid of opt_list param from ima_match_rule_data().
- Updated the documentation to remove sources that don't yet exist.
- detailed IMA hook description added to ima_measure_critical_data(),
as well as elaborating terms event_name, event_data_source.
- "data_sources:=" is not a mandatory policy option for
func=CRITICAL_DATA anymore. If not present, all the data sources
specified in __ima_supported_kernel_data_sources will be measured.
Lakshmi Ramasubramanian (2):
IMA: define a builtin critical data measurement policy
selinux: include a consumer of the new IMA critical data hook
Tushar Sugandhi (6):
IMA: generalize keyring specific measurement constructs
IMA: add support to measure buffer data hash
IMA: define a hook to measure kernel integrity critical data
IMA: add policy rule to measure critical data
IMA: limit critical data measurement based on a label
IMA: extend critical data hook to limit the measurement based on a
label
Documentation/ABI/testing/ima_policy | 5 +-
.../admin-guide/kernel-parameters.txt | 5 +-
include/linux/ima.h | 10 ++
security/integrity/ima/ima.h | 8 +-
security/integrity/ima/ima_api.c | 8 +-
security/integrity/ima/ima_appraise.c | 2 +-
security/integrity/ima/ima_asymmetric_keys.c | 2 +-
security/integrity/ima/ima_main.c | 59 +++++++--
security/integrity/ima/ima_policy.c | 115 ++++++++++++++----
security/integrity/ima/ima_queue_keys.c | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++
security/selinux/include/ima.h | 24 ++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++--
15 files changed, 324 insertions(+), 50 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
--
2.17.1
A new IMA policy rule is needed for the IMA hook
ima_measure_critical_data() and the corresponding func CRITICAL_DATA for
measuring the input buffer. The policy rule should ensure the buffer
would get measured only when the policy rule allows the action. The
policy rule should also support the necessary constraints (flags etc.)
for integrity critical buffer data measurements.
Add policy rule support for measuring integrity critical data.
Signed-off-by: Tushar Sugandhi <redacted>
Reviewed-by: Tyler Hicks <redacted>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
---
Documentation/ABI/testing/ima_policy | 2 +-
security/integrity/ima/ima_policy.c | 29 ++++++++++++++++++++++++----
2 files changed, 26 insertions(+), 5 deletions(-)
The original IMA buffer data measurement sizes were small (e.g. boot
command line), but the new buffer data measurement use cases have data
sizes that are a lot larger. Just as IMA measures the file data hash,
not the file data, IMA should similarly support the option for measuring
buffer data hash.
Introduce a boolean parameter to support measuring buffer data hash,
which would be much smaller, instead of the buffer itself.
Signed-off-by: Tushar Sugandhi <redacted>
Reviewed-by: Tyler Hicks <redacted>
---
security/integrity/ima/ima.h | 3 +-
security/integrity/ima/ima_appraise.c | 2 +-
security/integrity/ima/ima_asymmetric_keys.c | 2 +-
security/integrity/ima/ima_main.c | 29 ++++++++++++++++----
security/integrity/ima/ima_queue_keys.c | 3 +-
5 files changed, 30 insertions(+), 9 deletions(-)
IMA provides capabilities to measure file and buffer data. However,
various data structures, policies, and states stored in kernel memory
also impact the integrity of the system. Several kernel subsystems
contain such integrity critical data. These kernel subsystems help
protect the integrity of the system. Currently, IMA does not provide a
generic function for measuring kernel integrity critical data.
Define ima_measure_critical_data, a new IMA hook, to measure kernel
integrity critical data.
Signed-off-by: Tushar Sugandhi <redacted>
Reviewed-by: Tyler Hicks <redacted>
---
include/linux/ima.h | 7 +++++++
security/integrity/ima/ima.h | 1 +
security/integrity/ima/ima_api.c | 2 +-
security/integrity/ima/ima_main.c | 24 ++++++++++++++++++++++++
4 files changed, 33 insertions(+), 1 deletion(-)
IMA functions such as ima_match_keyring(), process_buffer_measurement(),
ima_match_policy() etc. handle data specific to keyrings. Currently,
these constructs are not generic to handle any func specific data.
This makes it harder to extend them without code duplication.
Refactor the keyring specific measurement constructs to be generic and
reusable in other measurement scenarios.
Signed-off-by: Tushar Sugandhi <redacted>
Reviewed-by: Tyler Hicks <redacted>
---
security/integrity/ima/ima.h | 6 ++--
security/integrity/ima/ima_api.c | 6 ++--
security/integrity/ima/ima_main.c | 6 ++--
security/integrity/ima/ima_policy.c | 43 +++++++++++++++++------------
4 files changed, 35 insertions(+), 26 deletions(-)
The IMA hook ima_measure_critical_data() does not support a way to
specify the source of the critical data provider. Thus, the data
measurement cannot be constrained based on the data source label
in the IMA policy.
Extend the IMA hook ima_measure_critical_data() to support passing
the data source label as an input parameter, so that the policy rule can
be used to limit the measurements based on the label.
Signed-off-by: Tushar Sugandhi <redacted>
Reviewed-by: Tyler Hicks <redacted>
---
include/linux/ima.h | 7 +++++--
security/integrity/ima/ima_main.c | 8 +++++---
2 files changed, 10 insertions(+), 5 deletions(-)
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
@@ -52,8 +52,9 @@ Description: template:= name of a defined IMA template type (eg, ima-ng). Only valid when action is "measure". pcr:= decimal value- label:= [data_label]+ label:= [selinux]|[data_label] data_label:= a unique string used for grouping and limiting critical data.+ For example, "selinux" to measure critical data for SELinux. default policy: # PROC_SUPER_MAGIC
@@ -0,0 +1,64 @@+// SPDX-License-Identifier: GPL-2.0++/*+*Copyright(C)2021MicrosoftCorporation+*+*Author:LakshmiRamasubramanian(nramas@linux.microsoft.com)+*+*MeasurecriticaldatastructuresmaintaintedbySELinux+*usingIMAsubsystem.+*/+#include<linux/vmalloc.h>+#include<linux/ktime.h>+#include<linux/ima.h>+#include"security.h"+#include"ima.h"++/*+*selinux_ima_measure_state-MeasurehashoftheSELinuxpolicy+*+*@state:selinuxstatestruct+*+*NOTE:Thisfunctionmustbecalledwithpolicy_mutexheld.+*/+voidselinux_ima_measure_state(structselinux_state*state)+{+structtimespec64cur_time;+void*policy=NULL;+char*policy_event_name=NULL;+size_tpolicy_len;+intrc=0;++/*+*MeasureSELinuxpolicyonlyafterinitializationiscompleted.+*/+if(!selinux_initialized(state))+return;++/*+*Passaunique"event_name"totheIMAhooksothatIMAsubsystem+*willalwaysmeasurethegivendata.+*/+ktime_get_real_ts64(&cur_time);+policy_event_name=kasprintf(GFP_KERNEL,"%s-%lld:%09ld",+"selinux-policy-hash",+cur_time.tv_sec,cur_time.tv_nsec);+if(!policy_event_name){+pr_err("SELinux: %s: event name for policy not allocated.\n",+__func__);+gotoout;+}++rc=security_read_state_kernel(state,&policy,&policy_len);+if(rc){+pr_err("SELinux: %s: failed to read policy %d.\n",__func__,rc);+gotoout;+}++ima_measure_critical_data("selinux",policy_event_name,+policy,policy_len,true);++vfree(policy);++out:+kfree(policy_event_name);+}
Integrity critical data may belong to a single subsystem or it may
arise from cross subsystem interaction. Currently there is no mechanism
to group or limit the data based on certain label. Limiting and
grouping critical data based on a label would make it flexible and
configurable to measure.
Define "label:=", a new IMA policy condition, for the IMA func
CRITICAL_DATA to allow grouping and limiting measurement of integrity
critical data.
Limit the measurement to the labels that are specified in the IMA
policy - CRITICAL_DATA+"label:=". If "label:=" is not provided with
the func CRITICAL_DATA, measure all the input integrity critical data.
Signed-off-by: Tushar Sugandhi <redacted>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 2 ++
security/integrity/ima/ima_policy.c | 37 +++++++++++++++++++++++++---
2 files changed, 36 insertions(+), 3 deletions(-)
@@ -52,6 +52,8 @@ Description: template:= name of a defined IMA template type (eg, ima-ng). Only valid when action is "measure". pcr:= decimal value+ label:= [data_label]+ data_label:= a unique string used for grouping and limiting critical data. default policy: # PROC_SUPER_MAGIC
@@ -85,6 +86,7 @@ struct ima_rule_entry {}lsm[MAX_LSM_RULES];char*fsname;structima_rule_opt_list*keyrings;/* Measure keys added to these keyrings */+structima_rule_opt_list*label;/* Measure data grouped under this label */structima_template_desc*template;};
From: Lakshmi Ramasubramanian <redacted>
Define a new critical data builtin policy to allow measuring
early kernel integrity critical data before a custom IMA policy
is loaded.
Update the documentation on kernel parameters to document
the new critical data builtin policy.
Signed-off-by: Lakshmi Ramasubramanian <redacted>
Reviewed-by: Tyler Hicks <redacted>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
---
Documentation/admin-guide/kernel-parameters.txt | 5 ++++-
security/integrity/ima/ima_policy.c | 12 ++++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
@@ -1746,7 +1746,7 @@ ima_policy= [IMA] The builtin policies to load during IMA setup. Format: "tcb | appraise_tcb | secure_boot |- fail_securely"+ fail_securely | critical_data" The "tcb" policy measures all programs exec'd, files mmap'd for exec, and all files opened with the read
@@ -1765,6 +1765,9 @@ filesystems with the SB_I_UNVERIFIABLE_SIGNATURE flag.+ The "critical_data" policy measures kernel integrity+ critical data.+ ima_tcb [IMA] Deprecated. Use ima_policy= instead. Load a policy which meets the needs of the Trusted Computing Base. This means IMA will measure all
From: Paul Moore <paul@paul-moore.com> Date: 2021-01-12 16:28:15
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
@@ -52,8 +52,9 @@ Description: template:= name of a defined IMA template type (eg, ima-ng). Only valid when action is "measure". pcr:= decimal value- label:= [data_label]+ label:= [selinux]|[data_label] data_label:= a unique string used for grouping and limiting critical data.+ For example, "selinux" to measure critical data for SELinux. default policy: # PROC_SUPER_MAGIC
@@ -0,0 +1,64 @@+// SPDX-License-Identifier: GPL-2.0++/*+*Copyright(C)2021MicrosoftCorporation+*+*Author:LakshmiRamasubramanian(nramas@linux.microsoft.com)+*+*MeasurecriticaldatastructuresmaintaintedbySELinux+*usingIMAsubsystem.+*/+#include<linux/vmalloc.h>+#include<linux/ktime.h>+#include<linux/ima.h>+#include"security.h"+#include"ima.h"++/*+*selinux_ima_measure_state-MeasurehashoftheSELinuxpolicy+*+*@state:selinuxstatestruct+*+*NOTE:Thisfunctionmustbecalledwithpolicy_mutexheld.+*/+voidselinux_ima_measure_state(structselinux_state*state)+{+structtimespec64cur_time;+void*policy=NULL;+char*policy_event_name=NULL;+size_tpolicy_len;+intrc=0;++/*+*MeasureSELinuxpolicyonlyafterinitializationiscompleted.+*/+if(!selinux_initialized(state))+return;++/*+*Passaunique"event_name"totheIMAhooksothatIMAsubsystem+*willalwaysmeasurethegivendata.+*/+ktime_get_real_ts64(&cur_time);+policy_event_name=kasprintf(GFP_KERNEL,"%s-%lld:%09ld",+"selinux-policy-hash",+cur_time.tv_sec,cur_time.tv_nsec);+if(!policy_event_name){+pr_err("SELinux: %s: event name for policy not allocated.\n",+__func__);+gotoout;+}++rc=security_read_state_kernel(state,&policy,&policy_len);+if(rc){+pr_err("SELinux: %s: failed to read policy %d.\n",__func__,rc);+gotoout;+}++ima_measure_critical_data("selinux",policy_event_name,+policy,policy_len,true);++vfree(policy);++out:+kfree(policy_event_name);+}
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
quoted
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
On Tue, 2021-01-12 at 11:27 -0500, Paul Moore wrote:
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
quoted
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
Thanks, Paul.
Including any unique string would cause the buffer hash to change,
forcing a new measurement. Perhaps they were concerned with
overflowing a counter.
Mimi
quoted
+/*+ * selinux_ima_measure_state - Measure hash of the SELinux policy+ *+ * @state: selinux state struct+ *+ * NOTE: This function must be called with policy_mutex held.+ */+void selinux_ima_measure_state(struct selinux_state *state)+{+ struct timespec64 cur_time;+ void *policy = NULL;+ char *policy_event_name = NULL;+ size_t policy_len;+ int rc = 0;++ /*+ * Measure SELinux policy only after initialization is completed.+ */+ if (!selinux_initialized(state))+ return;++ /*+ * Pass a unique "event_name" to the IMA hook so that IMA subsystem+ * will always measure the given data.+ */+ ktime_get_real_ts64(&cur_time);+ policy_event_name = kasprintf(GFP_KERNEL, "%s-%lld:%09ld",+ "selinux-policy-hash",+ cur_time.tv_sec, cur_time.tv_nsec);+ if (!policy_event_name) {+ pr_err("SELinux: %s: event name for policy not allocated.\n",+ __func__);+ goto out;+ }+
From: Paul Moore <paul@paul-moore.com> Date: 2021-01-13 19:20:35
On Wed, Jan 13, 2021 at 2:13 PM Mimi Zohar [off-list ref] wrote:
On Tue, 2021-01-12 at 11:27 -0500, Paul Moore wrote:
quoted
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
quoted
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
Thanks, Paul.
Including any unique string would cause the buffer hash to change,
forcing a new measurement. Perhaps they were concerned with
overflowing a counter.
My understanding is that Lakshmi wanted to force a new measurement
each time and felt using a timestamp would be the best way to do that.
A counter, even if it wraps, would have a different value each time
whereas a timestamp is vulnerable to time adjustments. While a
properly controlled and audited system could be configured and
monitored to detect such an event (I *think*), why rely on that if it
isn't necessary?
--
paul moore
www.paul-moore.com
On Wed, 2021-01-13 at 17:10 -0500, Paul Moore wrote:
On Wed, Jan 13, 2021 at 4:11 PM Mimi Zohar [off-list ref] wrote:
quoted
On Wed, 2021-01-13 at 14:19 -0500, Paul Moore wrote:
quoted
On Wed, Jan 13, 2021 at 2:13 PM Mimi Zohar [off-list ref] wrote:
quoted
On Tue, 2021-01-12 at 11:27 -0500, Paul Moore wrote:
quoted
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
quoted
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
Thanks, Paul.
Including any unique string would cause the buffer hash to change,
forcing a new measurement. Perhaps they were concerned with
overflowing a counter.
My understanding is that Lakshmi wanted to force a new measurement
each time and felt using a timestamp would be the best way to do that.
A counter, even if it wraps, would have a different value each time
whereas a timestamp is vulnerable to time adjustments. While a
properly controlled and audited system could be configured and
monitored to detect such an event (I *think*), why rely on that if it
isn't necessary?
Why are you saying that even if the counter wraps a new measurement is
guaranteed. I agree with the rest of what you said.
I was assuming that the IMA code simply compares the passed
"policy_event_name" value to the previous value, if they are different
a new measurement is taken, if they are the same the measurement
request is ignored. If this is the case the counter value is only
important in as much as that it is different from the previous value,
even simply toggling a single bit back and forth would suffice in this
case. IMA doesn't keep a record of every previous "policy_event_name"
value does it? Am I misunderstanding how
ima_measure_critical_data(...) works?
Originally, there was quite a bit of discussion as to how much or how
little should be measured for a number of reasons. One reason is that
the TPM is relatively slow. Another reason is to limit the size of the
measurement list. For this reason, duplicate hashes aren't added to
the measurement list or extended into the TPM.
When a dentry is removed from cache, its also removed from IMA's iint
cache. A subsequent file read would result in adding the measurement
and extending the TPM again. ima_lookup_digest_entry() is called to
prevent adding the duplicate entry.
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Mimi
On Thu, 2021-01-07 at 20:07 -0800, Tushar Sugandhi wrote:
Integrity critical data may belong to a single subsystem or it may
arise from cross subsystem interaction. Currently there is no mechanism
to group or limit the data based on certain label. Limiting and
grouping critical data based on a label would make it flexible and
configurable to measure.
Define "label:=", a new IMA policy condition, for the IMA func
CRITICAL_DATA to allow grouping and limiting measurement of integrity
critical data.
Limit the measurement to the labels that are specified in the IMA
policy - CRITICAL_DATA+"label:=". If "label:=" is not provided with
the func CRITICAL_DATA, measure all the input integrity critical data.
Signed-off-by: Tushar Sugandhi <redacted>
Reviewed-by: Tyler Hicks <redacted>
From: Paul Moore <paul@paul-moore.com> Date: 2021-01-14 02:12:21
On Wed, Jan 13, 2021 at 4:11 PM Mimi Zohar [off-list ref] wrote:
On Wed, 2021-01-13 at 14:19 -0500, Paul Moore wrote:
quoted
On Wed, Jan 13, 2021 at 2:13 PM Mimi Zohar [off-list ref] wrote:
quoted
On Tue, 2021-01-12 at 11:27 -0500, Paul Moore wrote:
quoted
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
quoted
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
Thanks, Paul.
Including any unique string would cause the buffer hash to change,
forcing a new measurement. Perhaps they were concerned with
overflowing a counter.
My understanding is that Lakshmi wanted to force a new measurement
each time and felt using a timestamp would be the best way to do that.
A counter, even if it wraps, would have a different value each time
whereas a timestamp is vulnerable to time adjustments. While a
properly controlled and audited system could be configured and
monitored to detect such an event (I *think*), why rely on that if it
isn't necessary?
Why are you saying that even if the counter wraps a new measurement is
guaranteed. I agree with the rest of what you said.
I was assuming that the IMA code simply compares the passed
"policy_event_name" value to the previous value, if they are different
a new measurement is taken, if they are the same the measurement
request is ignored. If this is the case the counter value is only
important in as much as that it is different from the previous value,
even simply toggling a single bit back and forth would suffice in this
case. IMA doesn't keep a record of every previous "policy_event_name"
value does it? Am I misunderstanding how
ima_measure_critical_data(...) works?
--
paul moore
www.paul-moore.com
On Wed, 2021-01-13 at 14:19 -0500, Paul Moore wrote:
On Wed, Jan 13, 2021 at 2:13 PM Mimi Zohar [off-list ref] wrote:
quoted
On Tue, 2021-01-12 at 11:27 -0500, Paul Moore wrote:
quoted
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
quoted
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
Thanks, Paul.
Including any unique string would cause the buffer hash to change,
forcing a new measurement. Perhaps they were concerned with
overflowing a counter.
My understanding is that Lakshmi wanted to force a new measurement
each time and felt using a timestamp would be the best way to do that.
A counter, even if it wraps, would have a different value each time
whereas a timestamp is vulnerable to time adjustments. While a
properly controlled and audited system could be configured and
monitored to detect such an event (I *think*), why rely on that if it
isn't necessary?
Why are you saying that even if the counter wraps a new measurement is
guaranteed. I agree with the rest of what you said.
Mimi
From: Paul Moore <paul@paul-moore.com> Date: 2021-01-14 02:42:11
On Wed, Jan 13, 2021 at 6:11 PM Mimi Zohar [off-list ref] wrote:
On Wed, 2021-01-13 at 17:10 -0500, Paul Moore wrote:
quoted
On Wed, Jan 13, 2021 at 4:11 PM Mimi Zohar [off-list ref] wrote:
quoted
On Wed, 2021-01-13 at 14:19 -0500, Paul Moore wrote:
quoted
On Wed, Jan 13, 2021 at 2:13 PM Mimi Zohar [off-list ref] wrote:
quoted
On Tue, 2021-01-12 at 11:27 -0500, Paul Moore wrote:
quoted
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
quoted
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
Thanks, Paul.
Including any unique string would cause the buffer hash to change,
forcing a new measurement. Perhaps they were concerned with
overflowing a counter.
My understanding is that Lakshmi wanted to force a new measurement
each time and felt using a timestamp would be the best way to do that.
A counter, even if it wraps, would have a different value each time
whereas a timestamp is vulnerable to time adjustments. While a
properly controlled and audited system could be configured and
monitored to detect such an event (I *think*), why rely on that if it
isn't necessary?
Why are you saying that even if the counter wraps a new measurement is
guaranteed. I agree with the rest of what you said.
I was assuming that the IMA code simply compares the passed
"policy_event_name" value to the previous value, if they are different
a new measurement is taken, if they are the same the measurement
request is ignored. If this is the case the counter value is only
important in as much as that it is different from the previous value,
even simply toggling a single bit back and forth would suffice in this
case. IMA doesn't keep a record of every previous "policy_event_name"
value does it? Am I misunderstanding how
ima_measure_critical_data(...) works?
Originally, there was quite a bit of discussion as to how much or how
little should be measured for a number of reasons. One reason is that
the TPM is relatively slow. Another reason is to limit the size of the
measurement list. For this reason, duplicate hashes aren't added to
the measurement list or extended into the TPM.
When a dentry is removed from cache, its also removed from IMA's iint
cache. A subsequent file read would result in adding the measurement
and extending the TPM again. ima_lookup_digest_entry() is called to
prevent adding the duplicate entry.
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Perhaps it is just the end of the day and I'm a bit tired, but I just
read all of the above and I have no idea what your current thoughts
are regarding this patch.
--
paul moore
www.paul-moore.com
On Wed, 2021-01-13 at 21:40 -0500, Paul Moore wrote:
On Wed, Jan 13, 2021 at 6:11 PM Mimi Zohar [off-list ref] wrote:
quoted
On Wed, 2021-01-13 at 17:10 -0500, Paul Moore wrote:
quoted
On Wed, Jan 13, 2021 at 4:11 PM Mimi Zohar [off-list ref] wrote:
quoted
On Wed, 2021-01-13 at 14:19 -0500, Paul Moore wrote:
quoted
On Wed, Jan 13, 2021 at 2:13 PM Mimi Zohar [off-list ref] wrote:
quoted
On Tue, 2021-01-12 at 11:27 -0500, Paul Moore wrote:
quoted
On Thu, Jan 7, 2021 at 11:07 PM Tushar Sugandhi
[off-list ref] wrote:
quoted
From: Lakshmi Ramasubramanian <redacted>
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.
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 label=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 <redacted>
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Tyler Hicks <redacted>
---
Documentation/ABI/testing/ima_policy | 3 +-
security/selinux/Makefile | 2 +
security/selinux/ima.c | 64 ++++++++++++++++++++++++++++
security/selinux/include/ima.h | 24 +++++++++++
security/selinux/include/security.h | 3 +-
security/selinux/ss/services.c | 64 ++++++++++++++++++++++++----
6 files changed, 149 insertions(+), 11 deletions(-)
create mode 100644 security/selinux/ima.c
create mode 100644 security/selinux/include/ima.h
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
Thanks, Paul.
Including any unique string would cause the buffer hash to change,
forcing a new measurement. Perhaps they were concerned with
overflowing a counter.
My understanding is that Lakshmi wanted to force a new measurement
each time and felt using a timestamp would be the best way to do that.
A counter, even if it wraps, would have a different value each time
whereas a timestamp is vulnerable to time adjustments. While a
properly controlled and audited system could be configured and
monitored to detect such an event (I *think*), why rely on that if it
isn't necessary?
Why are you saying that even if the counter wraps a new measurement is
guaranteed. I agree with the rest of what you said.
I was assuming that the IMA code simply compares the passed
"policy_event_name" value to the previous value, if they are different
a new measurement is taken, if they are the same the measurement
request is ignored. If this is the case the counter value is only
important in as much as that it is different from the previous value,
even simply toggling a single bit back and forth would suffice in this
case. IMA doesn't keep a record of every previous "policy_event_name"
value does it? Am I misunderstanding how
ima_measure_critical_data(...) works?
Originally, there was quite a bit of discussion as to how much or how
little should be measured for a number of reasons. One reason is that
the TPM is relatively slow. Another reason is to limit the size of the
measurement list. For this reason, duplicate hashes aren't added to
the measurement list or extended into the TPM.
When a dentry is removed from cache, its also removed from IMA's iint
cache. A subsequent file read would result in adding the measurement
and extending the TPM again. ima_lookup_digest_entry() is called to
prevent adding the duplicate entry.
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Perhaps it is just the end of the day and I'm a bit tired, but I just
read all of the above and I have no idea what your current thoughts
are regarding this patch.
Other than appending the timestamp, which is a hack, the patch is fine.
Support for re-measuring an event can be upstreamed independently.
Mimi
I remain concerned about the possibility of bypassing a measurement by
tampering with the time, but I appear to be the only one who is
worried about this so I'm not going to block this patch on those
grounds.
Acked-by: Paul Moore <paul@paul-moore.com>
Thanks, Paul.
Including any unique string would cause the buffer hash to change,
forcing a new measurement. Perhaps they were concerned with
overflowing a counter.
My understanding is that Lakshmi wanted to force a new measurement
each time and felt using a timestamp would be the best way to do that.
A counter, even if it wraps, would have a different value each time
whereas a timestamp is vulnerable to time adjustments. While a
properly controlled and audited system could be configured and
monitored to detect such an event (I *think*), why rely on that if it
isn't necessary?
Why are you saying that even if the counter wraps a new measurement is
guaranteed. I agree with the rest of what you said.
I was assuming that the IMA code simply compares the passed
"policy_event_name" value to the previous value, if they are different
a new measurement is taken, if they are the same the measurement
request is ignored. If this is the case the counter value is only
important in as much as that it is different from the previous value,
even simply toggling a single bit back and forth would suffice in this
case. IMA doesn't keep a record of every previous "policy_event_name"
value does it? Am I misunderstanding how
ima_measure_critical_data(...) works?
Originally, there was quite a bit of discussion as to how much or how
little should be measured for a number of reasons. One reason is that
the TPM is relatively slow. Another reason is to limit the size of the
measurement list. For this reason, duplicate hashes aren't added to
the measurement list or extended into the TPM.
When a dentry is removed from cache, its also removed from IMA's iint
cache. A subsequent file read would result in adding the measurement
and extending the TPM again. ima_lookup_digest_entry() is called to
prevent adding the duplicate entry.
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Perhaps it is just the end of the day and I'm a bit tired, but I just
read all of the above and I have no idea what your current thoughts
are regarding this patch.
Other than appending the timestamp, which is a hack, the patch is fine.
Support for re-measuring an event can be upstreamed independently.
Thanks for clarifying the details related to duplicate measurement detection and re-measuring.
I will keep the timestamp for the time being, even though its a hack, as it helps with re-measuring state changes in SELinux. We will add support for "policy driven" re-measurement as a subsequent patch series.
thanks,
-lakshmi
[Cc'ing Sasha]
Hi Lakshmi,
On Thu, 2021-01-14 at 08:22 -0800, Lakshmi Ramasubramanian wrote:
On 1/13/21 6:49 PM, Mimi Zohar wrote:
quoted
quoted
quoted
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Perhaps it is just the end of the day and I'm a bit tired, but I just
read all of the above and I have no idea what your current thoughts
are regarding this patch.
Other than appending the timestamp, which is a hack, the patch is fine.
Support for re-measuring an event can be upstreamed independently.
Thanks for clarifying the details related to duplicate measurement
detection and re-measuring.
I will keep the timestamp for the time being, even though its a hack, as
it helps with re-measuring state changes in SELinux. We will add support
for "policy driven" re-measurement as a subsequent patch series.
Once including the timestamp is upstreamed, removing it will be
difficult, especially if different userspace applications are dependent
on it. Unless everyone is on board that removing the timestamp
wouldn't be considered a regression, it cannot be upstreamed.
thanks,
Mimi
On Thu, 2021-01-14 at 11:44 -0500, Mimi Zohar wrote:
[Cc'ing Sasha]
Hi Lakshmi,
On Thu, 2021-01-14 at 08:22 -0800, Lakshmi Ramasubramanian wrote:
quoted
On 1/13/21 6:49 PM, Mimi Zohar wrote:
quoted
quoted
quoted
quoted
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Perhaps it is just the end of the day and I'm a bit tired, but I just
read all of the above and I have no idea what your current thoughts
are regarding this patch.
Other than appending the timestamp, which is a hack, the patch is fine.
Support for re-measuring an event can be upstreamed independently.
Thanks for clarifying the details related to duplicate measurement
detection and re-measuring.
I will keep the timestamp for the time being, even though its a hack, as
it helps with re-measuring state changes in SELinux. We will add support
for "policy driven" re-measurement as a subsequent patch series.
Once including the timestamp is upstreamed, removing it will be
difficult, especially if different userspace applications are dependent
on it. Unless everyone is on board that removing the timestamp
wouldn't be considered a regression, it cannot be upstreamed.
Feel free to just re-post just this one patch. Otherwise the patch set
looks good.
thanks,
Mimi
From: Paul Moore <paul@paul-moore.com> Date: 2021-01-14 16:52:08
On Thu, Jan 14, 2021 at 11:44 AM Mimi Zohar [off-list ref] wrote:
[Cc'ing Sasha]
Hi Lakshmi,
On Thu, 2021-01-14 at 08:22 -0800, Lakshmi Ramasubramanian wrote:
quoted
On 1/13/21 6:49 PM, Mimi Zohar wrote:
quoted
quoted
quoted
quoted
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Perhaps it is just the end of the day and I'm a bit tired, but I just
read all of the above and I have no idea what your current thoughts
are regarding this patch.
Other than appending the timestamp, which is a hack, the patch is fine.
Support for re-measuring an event can be upstreamed independently.
Thanks for clarifying the details related to duplicate measurement
detection and re-measuring.
I will keep the timestamp for the time being, even though its a hack, as
it helps with re-measuring state changes in SELinux. We will add support
for "policy driven" re-measurement as a subsequent patch series.
Once including the timestamp is upstreamed, removing it will be
difficult, especially if different userspace applications are dependent
on it. Unless everyone is on board that removing the timestamp
wouldn't be considered a regression, it cannot be upstreamed.
I'm not a fan of merging things which are known to be broken only with
the promise of fixing it later. That goes double when the proper fix
will result in a user visible breaking change.
--
paul moore
www.paul-moore.com
On Thu, 2021-01-14 at 11:44 -0500, Mimi Zohar wrote:
quoted
[Cc'ing Sasha]
Hi Lakshmi,
On Thu, 2021-01-14 at 08:22 -0800, Lakshmi Ramasubramanian wrote:
quoted
On 1/13/21 6:49 PM, Mimi Zohar wrote:
quoted
quoted
quoted
quoted
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Perhaps it is just the end of the day and I'm a bit tired, but I just
read all of the above and I have no idea what your current thoughts
are regarding this patch.
Other than appending the timestamp, which is a hack, the patch is fine.
Support for re-measuring an event can be upstreamed independently.
Thanks for clarifying the details related to duplicate measurement
detection and re-measuring.
I will keep the timestamp for the time being, even though its a hack, as
it helps with re-measuring state changes in SELinux. We will add support
for "policy driven" re-measurement as a subsequent patch series.
Once including the timestamp is upstreamed, removing it will be
difficult, especially if different userspace applications are dependent
on it. Unless everyone is on board that removing the timestamp
wouldn't be considered a regression, it cannot be upstreamed.
Feel free to just re-post just this one patch. Otherwise the patch set
looks good.
thanks,
Sounds good Mimi - I will remove the timestamp and re-post the selinux patch.
thanks,
-lakshmi
On Thu, 2021-01-07 at 20:07 -0800, Tushar Sugandhi wrote:
quoted
Integrity critical data may belong to a single subsystem or it may
arise from cross subsystem interaction. Currently there is no mechanism
to group or limit the data based on certain label. Limiting and
grouping critical data based on a label would make it flexible and
configurable to measure.
Define "label:=", a new IMA policy condition, for the IMA func
CRITICAL_DATA to allow grouping and limiting measurement of integrity
critical data.
Limit the measurement to the labels that are specified in the IMA
policy - CRITICAL_DATA+"label:=". If "label:=" is not provided with
the func CRITICAL_DATA, measure all the input integrity critical data.
Signed-off-by: Tushar Sugandhi <redacted>
Reviewed-by: Tyler Hicks <redacted>
This is looking a lot better.
thanks,
Mimi
Thanks a lot for the feedback Mimi.
Appreciate it. :)
~Tushar
On 1/14/21 9:48 AM, Lakshmi Ramasubramanian wrote:
On 1/14/21 8:50 AM, Mimi Zohar wrote:
quoted
On Thu, 2021-01-14 at 11:44 -0500, Mimi Zohar wrote:
quoted
[Cc'ing Sasha]
Hi Lakshmi,
On Thu, 2021-01-14 at 08:22 -0800, Lakshmi Ramasubramanian wrote:
quoted
On 1/13/21 6:49 PM, Mimi Zohar wrote:
quoted
quoted
quoted
quoted
Lakshmi is trying to address the situation where an event changes a
value, but then is restored to the original value. The original and
subsequent events are measured, but restoring to the original value
isn't re-measured. This isn't any different than when a file is
modified and then reverted.
Instead of changing the name like this, which doesn't work for files,
allowing duplicate measurements should be generic, based on policy.
Perhaps it is just the end of the day and I'm a bit tired, but I just
read all of the above and I have no idea what your current thoughts
are regarding this patch.
Other than appending the timestamp, which is a hack, the patch is fine.
Support for re-measuring an event can be upstreamed independently.
Thanks for clarifying the details related to duplicate measurement
detection and re-measuring.
I will keep the timestamp for the time being, even though its a hack, as
it helps with re-measuring state changes in SELinux. We will add support
for "policy driven" re-measurement as a subsequent patch series.
Once including the timestamp is upstreamed, removing it will be
difficult, especially if different userspace applications are dependent
on it. Unless everyone is on board that removing the timestamp
wouldn't be considered a regression, it cannot be upstreamed.
Feel free to just re-post just this one patch. Otherwise the patch set
looks good.
thanks,
Sounds good Mimi - I will remove the timestamp and re-post the selinux patch.
I have removed the timestamp in the event name and have posted the selinux patch alone.
Thanks a lot for reviewing the changes.
-lakshmi
On Thu, 2021-01-07 at 20:07 -0800, Tushar Sugandhi wrote:
IMA measures files and buffer data such as keys, command-line arguments
passed to the kernel on kexec system call, etc. While these measurements
are necessary for monitoring and validating the integrity of the system,
they are not sufficient. Various data structures, policies, and states
stored in kernel memory also impact the integrity of the system.
Several kernel subsystems contain such integrity critical data -
e.g. LSMs like SELinux, AppArmor etc. or device-mapper targets like
dm-crypt, dm-verity, dm-integrity etc. These kernel subsystems help
protect the integrity of a system. Their integrity critical data is not
expected to change frequently during run-time. Some of these structures
cannot be defined as __ro_after_init, because they are initialized later.
For a given system, various external services/infrastructure tools
(including the attestation service) interact with it - both during the
setup and during rest of the system run-time. They share sensitive data
and/or execute critical workload on that system. The external services
may want to verify the current run-time state of the relevant kernel
subsystems before fully trusting the system with business critical
data/workload. For instance, verifying that SELinux is in "enforce" mode
along with the expected policy, disks are encrypted with a certain
configuration, secure boot is enabled etc.
This series provides the necessary IMA functionality for kernel
subsystems to ensure their configuration can be measured:
- by kernel subsystems themselves,
- in a tamper resistant way,
- and re-measured - triggered on state/configuration change.
This patch set:
- defines a new IMA hook ima_measure_critical_data() to measure
integrity critical data,
- limits the critical data being measured based on a label,
- defines a builtin critical data measurement policy,
- and includes an SELinux consumer of the new IMA critical data hook.
Thanks Tushar, Lakshmi. This patch set is queued in the next-
integrity-testing branch.
Mimi
On Thu, 2021-01-07 at 20:07 -0800, Tushar Sugandhi wrote:
quoted
IMA measures files and buffer data such as keys, command-line arguments
passed to the kernel on kexec system call, etc. While these measurements
are necessary for monitoring and validating the integrity of the system,
they are not sufficient. Various data structures, policies, and states
stored in kernel memory also impact the integrity of the system.
Several kernel subsystems contain such integrity critical data -
e.g. LSMs like SELinux, AppArmor etc. or device-mapper targets like
dm-crypt, dm-verity, dm-integrity etc. These kernel subsystems help
protect the integrity of a system. Their integrity critical data is not
expected to change frequently during run-time. Some of these structures
cannot be defined as __ro_after_init, because they are initialized later.
For a given system, various external services/infrastructure tools
(including the attestation service) interact with it - both during the
setup and during rest of the system run-time. They share sensitive data
and/or execute critical workload on that system. The external services
may want to verify the current run-time state of the relevant kernel
subsystems before fully trusting the system with business critical
data/workload. For instance, verifying that SELinux is in "enforce" mode
along with the expected policy, disks are encrypted with a certain
configuration, secure boot is enabled etc.
This series provides the necessary IMA functionality for kernel
subsystems to ensure their configuration can be measured:
- by kernel subsystems themselves,
- in a tamper resistant way,
- and re-measured - triggered on state/configuration change.
This patch set:
- defines a new IMA hook ima_measure_critical_data() to measure
integrity critical data,
- limits the critical data being measured based on a label,
- defines a builtin critical data measurement policy,
- and includes an SELinux consumer of the new IMA critical data hook.
Thanks Tushar, Lakshmi. This patch set is queued in the next-
integrity-testing branch.
Mimi
Hello Mimi, Paul, Stephen, Tyler,
Thanks a lot for reviewing this series and providing all the valuable feedback over the last few months.
We really really appreciate it.
Thanks,
Tushar