diff mbox series

[RFC,3/7] dm: measure data on device remove

Message ID 20210526005954.31564-4-tusharsu@linux.microsoft.com (mailing list archive)
State Changes Requested, archived
Delegated to: Mike Snitzer
Headers show
Series device mapper target measurements using IMA | expand

Commit Message

Tushar Sugandhi May 26, 2021, 12:59 a.m. UTC
Presence of an active block-device, configured with expected parameters,
is important for an external attestation service to determine if a system
meets the attestation requirements.  Therefore it is important for DM to
measure the device remove events.

Measure device parameters, and table hashes when the device is removed.

Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
---
 drivers/md/dm-ima.c   | 56 +++++++++++++++++++++++++++++++++++++++++++
 drivers/md/dm-ima.h   |  1 +
 drivers/md/dm-ioctl.c |  2 ++
 3 files changed, 59 insertions(+)
diff mbox series

Patch

diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c
index b244a7fd58fe..a93387beda9e 100644
--- a/drivers/md/dm-ima.c
+++ b/drivers/md/dm-ima.c
@@ -257,9 +257,65 @@  void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap)
 	kfree(device_table_data);
 }
 
+/*
+ * Measure IMA data on remove
+ */
+void dm_ima_measure_on_device_remove(struct mapped_device *md)
+{
+	unsigned int noio_flag, l;
+	char *dev_table_data;
+	char active[] = "active_table_hash=";
+	char inactive[] = "inactive_table_hash=";
+	unsigned int active_len = strlen(active);
+	unsigned int inactive_len = strlen(inactive);
+
+	noio_flag = memalloc_noio_save();
+	dev_table_data = kzalloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL);
+	memalloc_noio_restore(noio_flag);
+
+	if (!dev_table_data)
+		goto bad;
+	l = strlen(md->ima.device_data);
+	memcpy(dev_table_data, md->ima.device_data, l);
+
+	if (md->ima.active_table_hash) {
+		memcpy(dev_table_data + l, active, active_len);
+		l += active_len;
+
+		memcpy(dev_table_data + l,
+		md->ima.active_table_hash,
+		md->ima.active_table_hash_len);
+		l += md->ima.active_table_hash_len;
+
+		memcpy(dev_table_data + l, ";", 1);
+		l++;
+	}
+
+	if (md->ima.inactive_table_hash) {
+		memcpy(dev_table_data + l, inactive, inactive_len);
+		l += inactive_len;
+
+		memcpy(dev_table_data + l,
+		md->ima.inactive_table_hash,
+		md->ima.inactive_table_hash_len);
+
+		l += md->ima.inactive_table_hash_len;
+
+		memcpy(dev_table_data + l, ";", 1);
+		l++;
+	}
+
+	dm_ima_measure_data("device_remove", dev_table_data, l);
+
+	kfree(dev_table_data);
+bad:
+	kfree(md->ima.device_data);
+}
+
 #else
 void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags) {}
 void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) {}
+void dm_ima_measure_on_device_remove(struct mapped_device *md) {}
 #endif
 MODULE_AUTHOR("Tushar Sugandhi <tusharsu@linux.microsoft.com>");
 MODULE_DESCRIPTION("Enables IMA measurements for DM targets");
diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h
index 1cd0c76e0379..974b14361958 100644
--- a/drivers/md/dm-ima.h
+++ b/drivers/md/dm-ima.h
@@ -34,4 +34,5 @@  struct dm_ima_measurements {
 
 void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags);
 void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap);
+void dm_ima_measure_on_device_remove(struct mapped_device *md);
 #endif /*DM_IMA_H*/
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index e06e256d1a7e..cb6392c156c2 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -984,6 +984,8 @@  static int dev_remove(struct file *filp, struct dm_ioctl *param, size_t param_si
 
 	param->flags &= ~DM_DEFERRED_REMOVE;
 
+	dm_ima_measure_on_device_remove(md);
+
 	if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr))
 		param->flags |= DM_UEVENT_GENERATED_FLAG;