From: Tushar Sugandhi <tusharsu@linux.microsoft.com> To: dm-devel@redhat.com, agk@redhat.com, snitzer@redhat.com Cc: zohar@linux.ibm.com, linux-integrity@vger.kernel.org, nramas@linux.microsoft.com, tusharsu@linux.microsoft.com Subject: [PATCH 2/7] dm: measure data on device resume Date: Mon, 12 Jul 2021 17:48:59 -0700 [thread overview] Message-ID: <20210713004904.8808-3-tusharsu@linux.microsoft.com> (raw) In-Reply-To: <20210713004904.8808-1-tusharsu@linux.microsoft.com> A given block device can load a table multiple times, with different input parameters, before eventually resuming it. Further, a device may be suspended and then resumed. The device may never resume after a table-load. Because of the above valid scenarios for a given device, it is important to measure and log the device resume event using IMA. Also, if the table is large, measuring it in clear-text each time the device changes state, will unnecessarily increase the size of IMA log. Since the table clear-text is already measured during table-load event, measuring the hash during resume should be sufficient to validate the table contents. Measure the device parameters, and hash of the active table, when the device is resumed. Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> --- drivers/md/dm-ima.c | 118 ++++++++++++++++++++++++++++++++++++++++++ drivers/md/dm-ima.h | 2 + drivers/md/dm-ioctl.c | 8 ++- 3 files changed, 126 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c index b752517380c3..1c545717adf4 100644 --- a/drivers/md/dm-ima.c +++ b/drivers/md/dm-ima.c @@ -145,6 +145,27 @@ static void dm_ima_measure_data(const char *event_name, const void *buf, size_t memalloc_noio_restore(noio_flag); } +/* + * Internal function to allocate and copy current device capacity for IMA measurements. + */ + +static int dm_ima_alloc_and_copy_capacity_str(struct mapped_device *md, char **capacity_str, + bool noio) +{ + sector_t capacity; + + capacity = get_capacity(md->disk); + + *capacity_str = dm_ima_alloc(DM_IMA_DEVICE_CAPACITY_BUF_LEN, GFP_KERNEL, noio); + if (!(*capacity_str)) + return -ENOMEM; + + scnprintf(*capacity_str, DM_IMA_DEVICE_BUF_LEN, "current_device_capacity=%llu;", + capacity); + + return 0; +} + /* * Initialize the dm ima related data structure variables. */ @@ -336,9 +357,106 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl kfree(target_data_buf); } +/* + * Measure IMA data on device resume. + */ +void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) +{ + char *device_table_data, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL; + char active[] = "active_table_hash="; + unsigned int active_len = strlen(active), capacity_len = 0; + unsigned int l = 0; + bool noio = true; + int r; + + device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio); + if (!device_table_data) + return; + + r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); + if (r) + goto error; + + if (swap) { + if (md->ima.active_table.hash != md->ima.inactive_table.hash) + kfree(md->ima.active_table.hash); + + md->ima.active_table.hash = NULL; + md->ima.active_table.hash_len = 0; + + if (md->ima.active_table.device_metadata != + md->ima.inactive_table.device_metadata) + kfree(md->ima.active_table.device_metadata); + + md->ima.active_table.device_metadata = NULL; + md->ima.active_table.device_metadata_len = 0; + md->ima.active_table.num_targets = 0; + + if (md->ima.inactive_table.hash) { + md->ima.active_table.hash = md->ima.inactive_table.hash; + md->ima.active_table.hash_len = md->ima.inactive_table.hash_len; + md->ima.inactive_table.hash = NULL; + md->ima.inactive_table.hash_len = 0; + } + + if (md->ima.inactive_table.device_metadata) { + md->ima.active_table.device_metadata = + md->ima.inactive_table.device_metadata; + md->ima.active_table.device_metadata_len = + md->ima.inactive_table.device_metadata_len; + md->ima.active_table.num_targets = md->ima.inactive_table.num_targets; + md->ima.inactive_table.device_metadata = NULL; + md->ima.inactive_table.device_metadata_len = 0; + md->ima.inactive_table.num_targets = 0; + } + } + + 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); + } + + if (md->ima.active_table.hash) { + memcpy(device_table_data + l, active, active_len); + l += active_len; + + memcpy(device_table_data + l, md->ima.active_table.hash, + md->ima.active_table.hash_len); + l += md->ima.active_table.hash_len; + + memcpy(device_table_data + l, ";", 1); + l++; + } + + if (!l) { + 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); + l += strlen(device_table_data); + + } + + capacity_len = strlen(capacity_str); + memcpy(device_table_data + l, capacity_str, capacity_len); + l += capacity_len; + + dm_ima_measure_data("device_resume", device_table_data, l, noio); + + kfree(dev_name); + kfree(dev_uuid); +error: + kfree(capacity_str); + kfree(device_table_data); +} + #else void dm_ima_reset_data(struct mapped_device *md) {} 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) {} #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 3c92a2523284..cafdcf5064c7 100644 --- a/drivers/md/dm-ima.h +++ b/drivers/md/dm-ima.h @@ -15,6 +15,7 @@ #define DM_IMA_DEVICE_BUF_LEN 1024 #define DM_IMA_TARGET_METADATA_BUF_LEN 128 #define DM_IMA_TARGET_DATA_BUF_LEN 2048 +#define DM_IMA_DEVICE_CAPACITY_BUF_LEN 128 struct dm_ima_device_table_metadata { /* @@ -47,4 +48,5 @@ struct dm_ima_measurements { void dm_ima_reset_data(struct mapped_device *md); 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); #endif /*DM_IMA_H*/ diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index e6e9fe74baf9..11af40f9b9c0 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1160,8 +1160,12 @@ static int do_resume(struct dm_ioctl *param) if (dm_suspended_md(md)) { r = dm_resume(md); - if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr)) - param->flags |= DM_UEVENT_GENERATED_FLAG; + if (!r) { + dm_ima_measure_on_device_resume(md, new_map ? true : false); + + if (!dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr)) + param->flags |= DM_UEVENT_GENERATED_FLAG; + } } /* -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Tushar Sugandhi <tusharsu@linux.microsoft.com> To: dm-devel@redhat.com, agk@redhat.com, snitzer@redhat.com Cc: tusharsu@linux.microsoft.com, nramas@linux.microsoft.com, linux-integrity@vger.kernel.org, zohar@linux.ibm.com Subject: [dm-devel] [PATCH 2/7] dm: measure data on device resume Date: Mon, 12 Jul 2021 17:48:59 -0700 [thread overview] Message-ID: <20210713004904.8808-3-tusharsu@linux.microsoft.com> (raw) In-Reply-To: <20210713004904.8808-1-tusharsu@linux.microsoft.com> A given block device can load a table multiple times, with different input parameters, before eventually resuming it. Further, a device may be suspended and then resumed. The device may never resume after a table-load. Because of the above valid scenarios for a given device, it is important to measure and log the device resume event using IMA. Also, if the table is large, measuring it in clear-text each time the device changes state, will unnecessarily increase the size of IMA log. Since the table clear-text is already measured during table-load event, measuring the hash during resume should be sufficient to validate the table contents. Measure the device parameters, and hash of the active table, when the device is resumed. Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> --- drivers/md/dm-ima.c | 118 ++++++++++++++++++++++++++++++++++++++++++ drivers/md/dm-ima.h | 2 + drivers/md/dm-ioctl.c | 8 ++- 3 files changed, 126 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c index b752517380c3..1c545717adf4 100644 --- a/drivers/md/dm-ima.c +++ b/drivers/md/dm-ima.c @@ -145,6 +145,27 @@ static void dm_ima_measure_data(const char *event_name, const void *buf, size_t memalloc_noio_restore(noio_flag); } +/* + * Internal function to allocate and copy current device capacity for IMA measurements. + */ + +static int dm_ima_alloc_and_copy_capacity_str(struct mapped_device *md, char **capacity_str, + bool noio) +{ + sector_t capacity; + + capacity = get_capacity(md->disk); + + *capacity_str = dm_ima_alloc(DM_IMA_DEVICE_CAPACITY_BUF_LEN, GFP_KERNEL, noio); + if (!(*capacity_str)) + return -ENOMEM; + + scnprintf(*capacity_str, DM_IMA_DEVICE_BUF_LEN, "current_device_capacity=%llu;", + capacity); + + return 0; +} + /* * Initialize the dm ima related data structure variables. */ @@ -336,9 +357,106 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl kfree(target_data_buf); } +/* + * Measure IMA data on device resume. + */ +void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) +{ + char *device_table_data, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL; + char active[] = "active_table_hash="; + unsigned int active_len = strlen(active), capacity_len = 0; + unsigned int l = 0; + bool noio = true; + int r; + + device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio); + if (!device_table_data) + return; + + r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); + if (r) + goto error; + + if (swap) { + if (md->ima.active_table.hash != md->ima.inactive_table.hash) + kfree(md->ima.active_table.hash); + + md->ima.active_table.hash = NULL; + md->ima.active_table.hash_len = 0; + + if (md->ima.active_table.device_metadata != + md->ima.inactive_table.device_metadata) + kfree(md->ima.active_table.device_metadata); + + md->ima.active_table.device_metadata = NULL; + md->ima.active_table.device_metadata_len = 0; + md->ima.active_table.num_targets = 0; + + if (md->ima.inactive_table.hash) { + md->ima.active_table.hash = md->ima.inactive_table.hash; + md->ima.active_table.hash_len = md->ima.inactive_table.hash_len; + md->ima.inactive_table.hash = NULL; + md->ima.inactive_table.hash_len = 0; + } + + if (md->ima.inactive_table.device_metadata) { + md->ima.active_table.device_metadata = + md->ima.inactive_table.device_metadata; + md->ima.active_table.device_metadata_len = + md->ima.inactive_table.device_metadata_len; + md->ima.active_table.num_targets = md->ima.inactive_table.num_targets; + md->ima.inactive_table.device_metadata = NULL; + md->ima.inactive_table.device_metadata_len = 0; + md->ima.inactive_table.num_targets = 0; + } + } + + 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); + } + + if (md->ima.active_table.hash) { + memcpy(device_table_data + l, active, active_len); + l += active_len; + + memcpy(device_table_data + l, md->ima.active_table.hash, + md->ima.active_table.hash_len); + l += md->ima.active_table.hash_len; + + memcpy(device_table_data + l, ";", 1); + l++; + } + + if (!l) { + 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); + l += strlen(device_table_data); + + } + + capacity_len = strlen(capacity_str); + memcpy(device_table_data + l, capacity_str, capacity_len); + l += capacity_len; + + dm_ima_measure_data("device_resume", device_table_data, l, noio); + + kfree(dev_name); + kfree(dev_uuid); +error: + kfree(capacity_str); + kfree(device_table_data); +} + #else void dm_ima_reset_data(struct mapped_device *md) {} 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) {} #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 3c92a2523284..cafdcf5064c7 100644 --- a/drivers/md/dm-ima.h +++ b/drivers/md/dm-ima.h @@ -15,6 +15,7 @@ #define DM_IMA_DEVICE_BUF_LEN 1024 #define DM_IMA_TARGET_METADATA_BUF_LEN 128 #define DM_IMA_TARGET_DATA_BUF_LEN 2048 +#define DM_IMA_DEVICE_CAPACITY_BUF_LEN 128 struct dm_ima_device_table_metadata { /* @@ -47,4 +48,5 @@ struct dm_ima_measurements { void dm_ima_reset_data(struct mapped_device *md); 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); #endif /*DM_IMA_H*/ diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index e6e9fe74baf9..11af40f9b9c0 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1160,8 +1160,12 @@ static int do_resume(struct dm_ioctl *param) if (dm_suspended_md(md)) { r = dm_resume(md); - if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr)) - param->flags |= DM_UEVENT_GENERATED_FLAG; + if (!r) { + dm_ima_measure_on_device_resume(md, new_map ? true : false); + + if (!dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr)) + param->flags |= DM_UEVENT_GENERATED_FLAG; + } } /* -- 2.25.1 -- dm-devel mailing list dm-devel@redhat.com https://listman.redhat.com/mailman/listinfo/dm-devel
next prev parent reply other threads:[~2021-07-13 0:49 UTC|newest] Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-07-13 0:48 [PATCH 0/7] device mapper target measurements using IMA Tushar Sugandhi 2021-07-13 0:48 ` [dm-devel] " Tushar Sugandhi 2021-07-13 0:48 ` [PATCH 1/7] dm: measure data on table load Tushar Sugandhi 2021-07-13 0:48 ` [dm-devel] " Tushar Sugandhi 2021-07-21 2:12 ` Mimi Zohar 2021-07-21 2:12 ` [dm-devel] " Mimi Zohar 2021-07-21 15:42 ` Mike Snitzer 2021-07-21 15:42 ` [dm-devel] " Mike Snitzer 2021-07-21 16:07 ` Mimi Zohar 2021-07-21 16:07 ` [dm-devel] " Mimi Zohar 2021-07-21 21:17 ` Mimi Zohar 2021-07-21 21:17 ` [dm-devel] " Mimi Zohar 2021-07-29 19:58 ` Tushar Sugandhi 2021-07-29 19:58 ` [dm-devel] " Tushar Sugandhi 2021-07-13 0:48 ` Tushar Sugandhi [this message] 2021-07-13 0:48 ` [dm-devel] [PATCH 2/7] dm: measure data on device resume Tushar Sugandhi 2021-07-13 0:49 ` [PATCH 3/7] dm: measure data on device remove Tushar Sugandhi 2021-07-13 0:49 ` [dm-devel] " Tushar Sugandhi 2021-07-13 0:49 ` [PATCH 4/7] dm: measure data on table clear Tushar Sugandhi 2021-07-13 0:49 ` [dm-devel] " Tushar Sugandhi 2021-07-13 0:49 ` [PATCH 5/7] dm: measure data on device rename Tushar Sugandhi 2021-07-13 0:49 ` [dm-devel] " Tushar Sugandhi 2021-07-13 0:49 ` [PATCH 6/7] dm: update target specific status functions to measure data Tushar Sugandhi 2021-07-13 0:49 ` [dm-devel] " Tushar Sugandhi 2021-07-13 1:06 ` Alasdair G Kergon 2021-07-13 1:06 ` [dm-devel] " Alasdair G Kergon 2021-07-14 20:23 ` Tushar Sugandhi 2021-07-14 20:23 ` [dm-devel] " Tushar Sugandhi 2021-07-13 0:49 ` [PATCH 7/7] dm: add documentation for IMA measurement support Tushar Sugandhi 2021-07-13 0:49 ` [dm-devel] " Tushar Sugandhi 2021-07-21 2:33 ` Mimi Zohar 2021-07-21 2:33 ` [dm-devel] " Mimi Zohar 2021-07-24 7:25 ` Tushar Sugandhi 2021-07-24 7:25 ` [dm-devel] " Tushar Sugandhi 2021-07-26 16:33 ` Mimi Zohar 2021-07-26 16:33 ` [dm-devel] " Mimi Zohar 2021-07-26 18:28 ` Tushar Sugandhi 2021-07-26 18:28 ` [dm-devel] " Tushar Sugandhi 2021-07-14 11:32 ` [dm-devel] [PATCH 0/7] device mapper target measurements using IMA Thore Sommer 2021-07-14 11:32 ` Thore Sommer 2021-07-14 20:20 ` Tushar Sugandhi 2021-07-14 20:20 ` Tushar Sugandhi 2021-07-27 10:18 ` Thore Sommer 2021-07-27 10:18 ` Thore Sommer 2021-07-27 20:33 ` Alasdair G Kergon 2021-07-27 20:33 ` Alasdair G Kergon 2021-07-28 3:10 ` Tushar Sugandhi 2021-07-28 3:10 ` Tushar Sugandhi 2021-07-28 17:14 ` Thore Sommer 2021-07-28 17:14 ` Thore Sommer 2021-07-29 17:32 ` Tushar Sugandhi 2021-07-29 17:32 ` Tushar Sugandhi 2021-07-28 17:34 ` Thore Sommer 2021-07-28 17:34 ` Thore Sommer 2021-07-28 21:33 ` Alasdair G Kergon 2021-07-28 21:33 ` Alasdair G Kergon 2021-08-02 10:45 ` Thore Sommer 2021-08-02 10:45 ` Thore Sommer 2021-07-29 19:24 ` Tushar Sugandhi 2021-07-29 19:24 ` Tushar Sugandhi 2021-08-02 10:38 ` Thore Sommer 2021-08-02 10:38 ` Thore Sommer 2021-07-20 21:27 ` Mike Snitzer 2021-07-20 21:27 ` [dm-devel] " Mike Snitzer 2021-07-24 6:57 ` Tushar Sugandhi
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210713004904.8808-3-tusharsu@linux.microsoft.com \ --to=tusharsu@linux.microsoft.com \ --cc=agk@redhat.com \ --cc=dm-devel@redhat.com \ --cc=linux-integrity@vger.kernel.org \ --cc=nramas@linux.microsoft.com \ --cc=snitzer@redhat.com \ --cc=zohar@linux.ibm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.