A given block device is identified by it's name and UUID.  However, both
these parameters can be renamed.  For an external attestation service to
correctly attest a given device, it needs to keep track of these rename
events.

Fix if there are any separator characters in the new name/UUID. Update 
the device data for IMA with the new values. Measure both old device
data and the new device name/UUID parameters in the same IMA measurement
event, so that the old and new values can be connected later.

Signed-off-by: Tushar Sugandhi <[email protected]>
---
 drivers/md/dm-ima.c   | 70 +++++++++++++++++++++++++++++++++++++++++++
 drivers/md/dm-ima.h   |  1 +
 drivers/md/dm-ioctl.c |  3 ++
 3 files changed, 74 insertions(+)

diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c
index 6670b5f74004..511d471648a1 100644
--- a/drivers/md/dm-ima.c
+++ b/drivers/md/dm-ima.c
@@ -361,11 +361,81 @@ void dm_ima_measure_on_table_clear(struct mapped_device 
*md, bool new_map)
        return;
 }
 
+/*
+ * Measure IMA data on device rename
+ */
+void dm_ima_measure_on_device_rename(struct mapped_device *md)
+{
+       char *old_device_data = NULL, *new_device_data = NULL, 
*combined_device_data = NULL;
+       char *new_dev_name = NULL, *new_dev_uuid = NULL;
+       unsigned int noio_flag;
+       sector_t capacity;
+
+       noio_flag = memalloc_noio_save();
+       new_device_data = kzalloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL);
+       memalloc_noio_restore(noio_flag);
+
+       if (!new_device_data)
+               return;
+
+       noio_flag = memalloc_noio_save();
+       new_dev_name = kzalloc(DM_NAME_LEN*2, GFP_KERNEL);
+       memalloc_noio_restore(noio_flag);
+       if (!new_dev_name)
+               goto error;
+
+       memalloc_noio_restore(noio_flag);
+       new_dev_uuid = kzalloc(DM_UUID_LEN*2, GFP_KERNEL);
+       memalloc_noio_restore(noio_flag);
+       if (!new_dev_uuid)
+               goto error;
+
+       if (dm_copy_name_and_uuid(md, new_dev_name, new_dev_uuid))
+               goto error;
+
+       fix_separator_chars(&new_dev_name);
+       fix_separator_chars(&new_dev_uuid);
+
+       noio_flag = memalloc_noio_save();
+       combined_device_data = kzalloc(DM_IMA_DEVICE_BUF_LEN * 2, GFP_KERNEL);
+       memalloc_noio_restore(noio_flag);
+
+       if (!combined_device_data)
+               goto error;
+
+       capacity = get_capacity(md->disk);
+
+       old_device_data = md->ima.device_data;
+
+       scnprintf(new_device_data, DM_IMA_DEVICE_BUF_LEN,
+                 
"name=%s;uuid=%s;capacity=%llu;major=%d;minor=%d;minor_count=%d;num_targets=%u;",
+                 new_dev_name, new_dev_uuid, capacity, md->disk->major, 
md->disk->first_minor,
+                 md->disk->minors, md->ima.num_targets);
+       md->ima.device_data = new_device_data;
+       md->ima.device_data_len = strlen(new_device_data);
+
+       scnprintf(combined_device_data, DM_IMA_DEVICE_BUF_LEN * 2, 
"%snew_name=%s;new_uuid=%s;",
+                 old_device_data, new_dev_name, new_dev_uuid);
+
+       dm_ima_measure_data("device_rename", combined_device_data, 
strlen(combined_device_data));
+
+       goto exit;
+
+error:
+       kfree(new_device_data);
+exit:
+       kfree(combined_device_data);
+       kfree(old_device_data);
+       kfree(new_dev_name);
+       kfree(new_dev_uuid);
+}
+
 #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) {}
 void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map) {}
+void dm_ima_measure_on_device_rename(struct mapped_device *md) {}
 #endif
 MODULE_AUTHOR("Tushar Sugandhi <[email protected]>");
 MODULE_DESCRIPTION("Enables IMA measurements for DM targets");
diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h
index ed633e031a18..340032f1d07f 100644
--- a/drivers/md/dm-ima.h
+++ b/drivers/md/dm-ima.h
@@ -36,5 +36,6 @@ void dm_ima_measure_on_table_load(struct dm_table *table, 
unsigned int status_fl
 void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap);
 void dm_ima_measure_on_device_remove(struct mapped_device *md);
 void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map);
+void dm_ima_measure_on_device_rename(struct mapped_device *md);
 
 #endif /*DM_IMA_H*/
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index b4f47d596985..9d8258dd014e 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -486,6 +486,9 @@ static struct mapped_device *dm_hash_rename(struct dm_ioctl 
*param,
                param->flags |= DM_UEVENT_GENERATED_FLAG;
 
        md = hc->md;
+
+       dm_ima_measure_on_device_rename(md);
+
        up_write(&_hash_lock);
        kfree(old_name);
 
-- 
2.17.1

--
dm-devel mailing list
[email protected]
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to