Skip to contentSkip to conversation

IMA: Measure kernel version in early boot

PATCH Superseded Raphael Gianotti 2 participants 2 messages Jan 22, 2021 – Jan 24, 2021

Subsystems (4)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 IMA: Measure kernel version in early boot

The integrity of a kernel can be verified by the boot loader on cold boot, and during kexec, by the current running kernel, before it is loaded. However, it is still possible that the new kernel being loaded is older than the current kernel, and/or has known vulnerabilities. Therefore, it is imperative that an attestation service be able to verify the version of the kernel being loaded on the client, from cold boot and subsequent kexec system calls, ensuring that only kernels with versions known to be good are loaded.

Measure the kernel version using ima_measure_critical_data() early on in the boot sequence, reducing the chances of known kernel vulnerabilities being exploited. With IMA being part of the kernel, this overall approach makes the measurement itself more trustworthy.

To enable measuring the kernel version "ima_policy=critical_data" needs to be added to the kernel command line arguments. For example,

	BOOT_IMAGE=/boot/vmlinuz-5.11.0-rc3+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset ima_policy=critical_data

If runtime measurement of the kernel version is ever needed, the following should be added to /etc/ima/ima-policy:

measure func=CRITICAL_DATA label=kernel_version

To extract the measured data after boot, the following command can be used:

        grep -m 1 "kernel_version" \
        /sys/kernel/security/integrity/ima/ascii_runtime_measurements

Sample output from the command above:

	10 a8297d408e9d5155728b619761d0dd4cedf5ef5f ima-buf
	sha256:5660e19945be0119bc19cbbf8d9c33a09935ab5d30dad48aa11f879c67d70988
	kernel_version 352e31312e302d7263332d31363138372d676564623634666537383234342d6469727479

The above corresponds to the following (decoded) version string:

	5.11.0-rc3-16187-gedb64fe78244-dirty

This patch is based on
commit e58bb688f2e4 "Merge branch 'measure-critical-data' into next-integrity" in "next-integrity-testing" branch

Change Log v2:
- Changed the measurement to align with the latest version of ima_measure_critical_data(), without the need for queueing
- Scoped the measurement to only measure the kernel version, found in UTS_RELEASE, instead of the entire linux_banner string

---
 security/integrity/ima/ima_main.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
security/integrity/ima/ima_main.c +5 -1
index 6a429846f90a..0a33f570725c 100644
@@ -26,6 +26,7 @@
 #include <linux/ima.h>
 #include <linux/iversion.h>
 #include <linux/fs.h>
+#include <generated/utsrelease.h>
 
 #include "ima.h"
 
@@ -994,8 +995,11 @@ static int __init init_ima(void)
 	if (error)
 		pr_warn("Couldn't register LSM notifier, error %d\n", error);
 
-	if (!error)
+	if (!error) {
 		ima_update_policy_flag();
+		ima_measure_critical_data("kernel_version", "kernel_version",
+					  UTS_RELEASE, strlen(UTS_RELEASE), false);
+	}
 
 	return error;
 }
Signature · 1 line
2.28.0
maintainer
#1 lore raw
Quoted 70 lines · Raphael Gianotti

The integrity of a kernel can be verified by the boot loader on cold boot, and during kexec, by the current running kernel, before it is loaded. However, it is still possible that the new kernel being loaded is older than the current kernel, and/or has known vulnerabilities. Therefore, it is imperative that an attestation service be able to verify the version of the kernel being loaded on the client, from cold boot and subsequent kexec system calls, ensuring that only kernels with versions known to be good are loaded.

Measure the kernel version using ima_measure_critical_data() early on in the boot sequence, reducing the chances of known kernel vulnerabilities being exploited. With IMA being part of the kernel, this overall approach makes the measurement itself more trustworthy.

To enable measuring the kernel version "ima_policy=critical_data" needs to be added to the kernel command line arguments. For example,

	BOOT_IMAGE=/boot/vmlinuz-5.11.0-rc3+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset ima_policy=critical_data

If runtime measurement of the kernel version is ever needed, the following should be added to /etc/ima/ima-policy:

measure func=CRITICAL_DATA label=kernel_version

To extract the measured data after boot, the following command can be used:

        grep -m 1 "kernel_version" \
        /sys/kernel/security/integrity/ima/ascii_runtime_measurements

Sample output from the command above:

	10 a8297d408e9d5155728b619761d0dd4cedf5ef5f ima-buf
	sha256:5660e19945be0119bc19cbbf8d9c33a09935ab5d30dad48aa11f879c67d70988
	kernel_version 352e31312e302d7263332d31363138372d676564623634666537383234342d6469727479

The above corresponds to the following (decoded) version string:

	5.11.0-rc3-16187-gedb64fe78244-dirty

This patch is based on
commit e58bb688f2e4 "Merge branch 'measure-critical-data' into next-integrity" in "next-integrity-testing" branch

Change Log v2:
- Changed the measurement to align with the latest version of ima_measure_critical_data(), without the need for queueing
- Scoped the measurement to only measure the kernel version, found in UTS_RELEASE, instead of the entire linux_banner string

---
 security/integrity/ima/ima_main.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
security/integrity/ima/ima_main.c +1 -0
index 6a429846f90a..0a33f570725c 100644
@@ -26,6 +26,7 @@
 #include <linux/ima.h>
 #include <linux/iversion.h>
 #include <linux/fs.h>
+#include <generated/utsrelease.h>
 
 #include "ima.h"
 
@@ -994,8 +995,11 @@ static int __init init_ima(void)
 	if (error)
 		pr_warn("Couldn't register LSM notifier, error %d\n", error);

security/integrity/ima/ima_main.c static int __init init_ima(void) · line 1005

Quoted 10 lines
security/integrity/ima/ima_main.c +4 -1
 
-	if (!error)
+	if (!error) {
 		ima_update_policy_flag();
+		ima_measure_critical_data("kernel_version", "kernel_version",
+					  UTS_RELEASE, strlen(UTS_RELEASE), false);
+	}
 
 	return error;
 }

Consider defining a new critical data label grouping (e.g. "kernel_info", ...).

Please move ima_measure_critical_data() to ima_init() and update the critical data "label:=" in Documentation/ABI/testing/ima_policy.

thanks,

Mimi