@@ -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");
@@ -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*/
@@ -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;
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(+)