summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-ima.c60
-rw-r--r--drivers/md/dm-ima.h9
2 files changed, 57 insertions, 12 deletions
diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c
index d4184ff28cca..22faf0698d09 100644
--- a/drivers/md/dm-ima.c
+++ b/drivers/md/dm-ima.c
@@ -168,6 +168,7 @@ static int dm_ima_alloc_and_copy_capacity_str(struct mapped_device *md, char **c
void dm_ima_reset_data(struct mapped_device *md)
{
memset(&(md->ima), 0, sizeof(md->ima));
+ md->ima.dm_version_str_len = strlen(DM_IMA_VERSION_STR);
}
/*
@@ -223,6 +224,9 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl
if (r)
goto error;
+ memcpy(ima_buf + l, DM_IMA_VERSION_STR, table->md->ima.dm_version_str_len);
+ l += table->md->ima.dm_version_str_len;
+
device_data_buf_len = strlen(device_data_buf);
memcpy(ima_buf + l, device_data_buf, device_data_buf_len);
l += device_data_buf_len;
@@ -280,6 +284,9 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl
* prefix, so that multiple records from the same table_load for
* a given device can be linked together.
*/
+ memcpy(ima_buf + l, DM_IMA_VERSION_STR, table->md->ima.dm_version_str_len);
+ l += table->md->ima.dm_version_str_len;
+
memcpy(ima_buf + l, device_data_buf, device_data_buf_len);
l += device_data_buf_len;
@@ -367,6 +374,7 @@ void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap)
unsigned int active_len = strlen(active), capacity_len = 0;
unsigned int l = 0;
bool noio = true;
+ bool nodata = true;
int r;
device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio);
@@ -377,6 +385,9 @@ void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap)
if (r)
goto error;
+ memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len);
+ l += md->ima.dm_version_str_len;
+
if (swap) {
if (md->ima.active_table.hash != md->ima.inactive_table.hash)
kfree(md->ima.active_table.hash);
@@ -412,8 +423,11 @@ void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap)
}
if (md->ima.active_table.device_metadata) {
- l = md->ima.active_table.device_metadata_len;
- memcpy(device_table_data, md->ima.active_table.device_metadata, l);
+ memcpy(device_table_data + l, md->ima.active_table.device_metadata,
+ md->ima.active_table.device_metadata_len);
+ l += md->ima.active_table.device_metadata_len;
+
+ nodata = false;
}
if (md->ima.active_table.hash) {
@@ -426,16 +440,18 @@ void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap)
memcpy(device_table_data + l, ";", 1);
l++;
+
+ nodata = false;
}
- if (!l) {
+ if (nodata) {
r = dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio);
if (r)
goto error;
scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN,
- "name=%s,uuid=%s;device_resume=no_data;",
- dev_name, dev_uuid);
+ "%sname=%s,uuid=%s;device_resume=no_data;",
+ DM_IMA_VERSION_STR, dev_name, dev_uuid);
l += strlen(device_table_data);
}
@@ -472,6 +488,7 @@ void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all)
unsigned int capacity_len = 0;
unsigned int l = 0;
bool noio = true;
+ bool nodata = true;
int r;
device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN*2, GFP_KERNEL, noio);
@@ -484,6 +501,9 @@ void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all)
goto exit;
}
+ memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len);
+ l += md->ima.dm_version_str_len;
+
if (md->ima.active_table.device_metadata) {
memcpy(device_table_data + l, device_active_str, device_active_len);
l += device_active_len;
@@ -491,6 +511,8 @@ void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all)
memcpy(device_table_data + l, md->ima.active_table.device_metadata,
md->ima.active_table.device_metadata_len);
l += md->ima.active_table.device_metadata_len;
+
+ nodata = false;
}
if (md->ima.inactive_table.device_metadata) {
@@ -500,6 +522,8 @@ void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all)
memcpy(device_table_data + l, md->ima.inactive_table.device_metadata,
md->ima.inactive_table.device_metadata_len);
l += md->ima.inactive_table.device_metadata_len;
+
+ nodata = false;
}
if (md->ima.active_table.hash) {
@@ -512,6 +536,8 @@ void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all)
memcpy(device_table_data + l, ",", 1);
l++;
+
+ nodata = false;
}
if (md->ima.inactive_table.hash) {
@@ -524,19 +550,21 @@ void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all)
memcpy(device_table_data + l, ",", 1);
l++;
+
+ nodata = false;
}
/*
* In case both active and inactive tables, and corresponding
* device metadata is cleared/missing - record the name and uuid
* in IMA measurements.
*/
- if (!l) {
+ if (nodata) {
if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio))
goto error;
scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN,
- "name=%s,uuid=%s;device_remove=no_data;",
- dev_name, dev_uuid);
+ "%sname=%s,uuid=%s;device_remove=no_data;",
+ DM_IMA_VERSION_STR, dev_name, dev_uuid);
l += strlen(device_table_data);
}
@@ -582,6 +610,7 @@ void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map)
char inactive_str[] = "inactive_table_hash=";
unsigned int inactive_len = strlen(inactive_str);
bool noio = true;
+ bool nodata = true;
int r;
device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio);
@@ -592,6 +621,9 @@ void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map)
if (r)
goto error1;
+ memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len);
+ l += md->ima.dm_version_str_len;
+
if (md->ima.inactive_table.device_metadata_len &&
md->ima.inactive_table.hash_len) {
memcpy(device_table_data + l, md->ima.inactive_table.device_metadata,
@@ -608,14 +640,17 @@ void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map)
memcpy(device_table_data + l, ";", 1);
l++;
+
+ nodata = false;
}
- if (!l) {
+ if (nodata) {
if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio))
goto error2;
scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN,
- "name=%s,uuid=%s;table_clear=no_data;", dev_name, dev_uuid);
+ "%sname=%s,uuid=%s;table_clear=no_data;",
+ DM_IMA_VERSION_STR, dev_name, dev_uuid);
l += strlen(device_table_data);
}
@@ -694,8 +729,9 @@ void dm_ima_measure_on_device_rename(struct mapped_device *md)
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);
+ scnprintf(combined_device_data, DM_IMA_DEVICE_BUF_LEN * 2,
+ "%s%snew_name=%s,new_uuid=%s;%s", DM_IMA_VERSION_STR, 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);
diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h
index 0731a51565d6..b8c3b614670b 100644
--- a/drivers/md/dm-ima.h
+++ b/drivers/md/dm-ima.h
@@ -18,6 +18,14 @@
#define DM_IMA_DEVICE_CAPACITY_BUF_LEN 128
#define DM_IMA_TABLE_HASH_ALG "sha256"
+#define __dm_ima_stringify(s) #s
+#define __dm_ima_str(s) __dm_ima_stringify(s)
+
+#define DM_IMA_VERSION_STR "dm_version=" \
+ __dm_ima_str(DM_VERSION_MAJOR) "." \
+ __dm_ima_str(DM_VERSION_MINOR) "." \
+ __dm_ima_str(DM_VERSION_PATCHLEVEL) ";"
+
#ifdef CONFIG_IMA
struct dm_ima_device_table_metadata {
@@ -46,6 +54,7 @@ struct dm_ima_device_table_metadata {
struct dm_ima_measurements {
struct dm_ima_device_table_metadata active_table;
struct dm_ima_device_table_metadata inactive_table;
+ unsigned int dm_version_str_len;
};
void dm_ima_reset_data(struct mapped_device *md);