dm ima: measure data on device rename
authorTushar Sugandhi <tusharsu@linux.microsoft.com>
Tue, 13 Jul 2021 00:49:02 +0000 (17:49 -0700)
committerMike Snitzer <snitzer@redhat.com>
Tue, 10 Aug 2021 17:34:23 +0000 (13:34 -0400)
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.

Update the device data with the new values for IMA measurements.  Measure
both old and new device name/UUID parameters in the same IMA measurement
event, so that the old and the new values can be connected later.

Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-ima.c
drivers/md/dm-ima.h
drivers/md/dm-ioctl.c

index 1a22860888fa58e1bf4bcebdad96e4c2070b0258..91ea4a7202abbd13f9c0c037c7b58384d37d9f2a 100644 (file)
@@ -655,3 +655,51 @@ error2:
 error1:
        kfree(device_table_data);
 }
+
+/*
+ * 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, *capacity_str = NULL;
+       bool noio = true;
+       int r;
+
+       if (dm_ima_alloc_and_copy_device_data(md, &new_device_data,
+                                             md->ima.active_table.num_targets, noio))
+               return;
+
+       if (dm_ima_alloc_and_copy_name_uuid(md, &new_dev_name, &new_dev_uuid, noio))
+               goto error;
+
+       combined_device_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN * 2, GFP_KERNEL, noio);
+       if (!combined_device_data)
+               goto error;
+
+       r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio);
+       if (r)
+               goto error;
+
+       old_device_data = md->ima.active_table.device_metadata;
+
+       md->ima.active_table.device_metadata = new_device_data;
+       md->ima.active_table.device_metadata_len = strlen(new_device_data);
+
+       scnprintf(combined_device_data, DM_IMA_DEVICE_BUF_LEN * 2, "%snew_name=%s,new_uuid=%s;%s",
+                 old_device_data, new_dev_name, new_dev_uuid, capacity_str);
+
+       dm_ima_measure_data("device_rename", combined_device_data, strlen(combined_device_data),
+                           noio);
+
+       goto exit;
+
+error:
+       kfree(new_device_data);
+exit:
+       kfree(capacity_str);
+       kfree(combined_device_data);
+       kfree(old_device_data);
+       kfree(new_dev_name);
+       kfree(new_dev_uuid);
+}
index caa5c84017b1dc23a0c0f0392d3a07db7a6ef987..6e6f18bf05b42809e386515f8dc05cad676b9b4c 100644 (file)
@@ -52,6 +52,7 @@ 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, bool remove_all);
 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);
 
 #else
 
@@ -60,6 +61,7 @@ static inline void dm_ima_measure_on_table_load(struct dm_table *table, unsigned
 static inline void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) {}
 static inline void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all) {}
 static inline void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map) {}
+static inline void dm_ima_measure_on_device_rename(struct mapped_device *md) {}
 
 #endif /* CONFIG_IMA */
 
index 7c902e67cd1088709ae050809acc1753da31c208..21fe8652b095bd1f517aa43c31ce50bd5a572b67 100644 (file)
@@ -485,6 +485,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);