mbox series

[0/7] device mapper target measurements using IMA

Message ID 20210713004904.8808-1-tusharsu@linux.microsoft.com (mailing list archive)
Headers show
Series device mapper target measurements using IMA | expand

Message

Tushar Sugandhi July 13, 2021, 12:48 a.m. UTC
For a given system, various external services/infrastructure tools
(including the attestation service) interact with it - both during the
setup and during rest of the system run-time.  They share sensitive data
and/or execute critical workload on that system.  The external services
may want to verify the current run-time state of the relevant kernel
subsystems before fully trusting the system with business-critical
data/workload.

Device mapper is one such kernel subsystem that plays a critical role on
a given system by providing various important functionalities to the
block devices with various target types like crypt, verity, integrity 
etc.  Each of these target types’ functionalities can be configured with
various attributes.  The attributes chosen to configure these target types
can significantly impact the security profile of the block device,
and in-turn, of the system itself.  For instance, the type of encryption
algorithm and the key size determines the strength of encryption for a
given block device.

Therefore, verifying the current state of various block devices as well
as their various target attributes is crucial for external services
before fully trusting the system with business-critical data/workload.

IMA provides the necessary functionality for device mapper to measure the
state and configuration of various block devices -
  - BY device mapper itself, from within the kernel,
  - in a tamper resistant way,
  - and re-measured - triggered on state/configuration change.

This patch series uses this IMA functionality, by calling the function
ima_measure_critical_data(), when a block device state is changed (e.g.
on device create, resume, rename, remove etc.)  It measures the device
state and configuration and stores it in IMA logs, so that it can be
used by external services for managing the system.


Tushar Sugandhi (7):
  dm: measure data on table load
  dm: measure data on device resume
  dm: measure data on device remove
  dm: measure data on table clear
  dm: measure data on device rename
  dm: update target specific status functions to measure data
  dm: add documentation for IMA measurement support

 .../admin-guide/device-mapper/dm-ima.rst      | 306 ++++++++
 .../admin-guide/device-mapper/index.rst       |   1 +
 drivers/md/Makefile                           |   2 +
 drivers/md/dm-cache-target.c                  |  24 +
 drivers/md/dm-clone-target.c                  |   7 +
 drivers/md/dm-core.h                          |   5 +
 drivers/md/dm-crypt.c                         |  29 +
 drivers/md/dm-delay.c                         |   4 +
 drivers/md/dm-dust.c                          |   4 +
 drivers/md/dm-ebs-target.c                    |   3 +
 drivers/md/dm-era-target.c                    |   4 +
 drivers/md/dm-flakey.c                        |   4 +
 drivers/md/dm-ima.c                           | 725 ++++++++++++++++++
 drivers/md/dm-ima.h                           |  56 ++
 drivers/md/dm-integrity.c                     |  24 +
 drivers/md/dm-ioctl.c                         |  24 +-
 drivers/md/dm-linear.c                        |   8 +
 drivers/md/dm-log-userspace-base.c            |   3 +
 drivers/md/dm-log-writes.c                    |   4 +
 drivers/md/dm-log.c                           |  10 +
 drivers/md/dm-mpath.c                         |  29 +
 drivers/md/dm-ps-historical-service-time.c    |   3 +
 drivers/md/dm-ps-io-affinity.c                |   3 +
 drivers/md/dm-ps-queue-length.c               |   3 +
 drivers/md/dm-ps-round-robin.c                |   4 +
 drivers/md/dm-ps-service-time.c               |   3 +
 drivers/md/dm-raid.c                          |  39 +
 drivers/md/dm-raid1.c                         |  18 +
 drivers/md/dm-snap-persistent.c               |   4 +
 drivers/md/dm-snap-transient.c                |   4 +
 drivers/md/dm-snap.c                          |  13 +
 drivers/md/dm-stripe.c                        |  16 +
 drivers/md/dm-switch.c                        |   4 +
 drivers/md/dm-thin.c                          |   8 +
 drivers/md/dm-unstripe.c                      |   4 +
 drivers/md/dm-verity-target.c                 |  45 ++
 drivers/md/dm-writecache.c                    |   3 +
 drivers/md/dm-zoned-target.c                  |   3 +
 drivers/md/dm.c                               |   3 +
 include/linux/device-mapper.h                 |   6 +-
 include/uapi/linux/dm-ioctl.h                 |   6 +
 41 files changed, 1464 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/admin-guide/device-mapper/dm-ima.rst
 create mode 100644 drivers/md/dm-ima.c
 create mode 100644 drivers/md/dm-ima.h

Comments

Thore Sommer July 14, 2021, 11:32 a.m. UTC | #1
Thank you for bringing IMA support to device mapper. The addition of dm-verity
to IMA is very useful for the project I'm working on where we boot
our distribution from removable USB media.

One of our goals is to detect tampering of the root file system remotely.
Therefore we enabled dm-verity support but implementing remote attestation for
dm-verity from userland is not ideal which was our initial plan.

This patch set enables us to leverage to already implemented IMA attestation
infrastructure by the remote attestation service that we are using (Keylime)
without trying to roll a custom solution.

We tested the initial RFC patch set and will continue testing with this one to
see if it fully works in our environment and with our use case.

Thore Sommer

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Tushar Sugandhi July 14, 2021, 8:20 p.m. UTC | #2
Hello Thore,
On 7/14/21 4:32 AM, Thore Sommer wrote:
> Thank you for bringing IMA support to device mapper. The addition of dm-verity
> to IMA is very useful for the project I'm working on where we boot
> our distribution from removable USB media.
Thank you for the positive ack. Appreciate it.
> One of our goals is to detect tampering of the root file system remotely.
> Therefore we enabled dm-verity support but implementing remote attestation for
> dm-verity from userland is not ideal which was our initial plan.
Yes, remote attestation from userland is not ideal.
> This patch set enables us to leverage to already implemented IMA attestation
> infrastructure by the remote attestation service that we are using (Keylime)
> without trying to roll a custom solution.
I am glad that DM-IMA functionality is useful for your scenario.
> We tested the initial RFC patch set and will continue testing with 
> this one to see if it fully works in our environment and with our use 
> case. 
Thank you for testing the RFC patch set.
Please let me know if you discover any bugs in this one, or have any 
other feedback.

Thanks again.

Regards,
Tushar
> Thore Sommer 

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Mike Snitzer July 20, 2021, 9:27 p.m. UTC | #3
On Mon, Jul 12 2021 at  8:48P -0400,
Tushar Sugandhi <tusharsu@linux.microsoft.com> wrote:

> For a given system, various external services/infrastructure tools
> (including the attestation service) interact with it - both during the
> setup and during rest of the system run-time.  They share sensitive data
> and/or execute critical workload on that system.  The external services
> may want to verify the current run-time state of the relevant kernel
> subsystems before fully trusting the system with business-critical
> data/workload.
> 
> Device mapper is one such kernel subsystem that plays a critical role on
> a given system by providing various important functionalities to the
> block devices with various target types like crypt, verity, integrity 
> etc.  Each of these target types’ functionalities can be configured with
> various attributes.  The attributes chosen to configure these target types
> can significantly impact the security profile of the block device,
> and in-turn, of the system itself.  For instance, the type of encryption
> algorithm and the key size determines the strength of encryption for a
> given block device.
> 
> Therefore, verifying the current state of various block devices as well
> as their various target attributes is crucial for external services
> before fully trusting the system with business-critical data/workload.
> 
> IMA provides the necessary functionality for device mapper to measure the
> state and configuration of various block devices -
>   - BY device mapper itself, from within the kernel,
>   - in a tamper resistant way,
>   - and re-measured - triggered on state/configuration change.
> 
> This patch series uses this IMA functionality, by calling the function
> ima_measure_critical_data(), when a block device state is changed (e.g.
> on device create, resume, rename, remove etc.)  It measures the device
> state and configuration and stores it in IMA logs, so that it can be
> used by external services for managing the system.

I needed to EXPORT_SYMBOL_GPL(ima_measure_critical_data); otherwise I
couldn't compile.. not sure but I can only imagine you compile DM
(and all targets) to be builtin?

In addition to fixing that (in first table load patch) I changed
various things along the way while I reviewed each patch.

Things that I recall are:
- moved #ifdef CONFIG_IMA from dm-ima.c to dm-ima.h
- fixed various typos and whitespace
- consistently prepend "," in STATUSTYPE_IMA's DMEMIT()s as opposed to
  having a mix or pre and postfix throughout targets
- fixed what seemed like malformed STATUSTYPE_IMA handling for
  dm-multipath -- it was DMEMIT(";") for each dm-mpath's pathgroup
- added some fields to dm-mpath, renamed some IMA names in name=value
  pairs to be more clear.

I've staged the result in linux-next via linux-dm.git's dm-5.15
branch, see:
https://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git/log/?h=dm-5.15

I've compiled tested both with and without CONFIG_IMA set.  But
haven't actually tested the code.

Please send any incremental fixes relative to the dm-5.15 branch and
I'll get them folded in where appropriate.

Thanks,
Mike

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Tushar Sugandhi July 24, 2021, 6:57 a.m. UTC | #4
Hi Mike,

On 7/20/21 2:27 PM, Mike Snitzer wrote:
> On Mon, Jul 12 2021 at  8:48P -0400,
> Tushar Sugandhi <tusharsu@linux.microsoft.com> wrote:
>
>> For a given system, various external services/infrastructure tools
>> (including the attestation service) interact with it - both during the
>> setup and during rest of the system run-time.  They share sensitive data
>> and/or execute critical workload on that system.  The external services
>> may want to verify the current run-time state of the relevant kernel
>> subsystems before fully trusting the system with business-critical
>> data/workload.
>>
>> Device mapper is one such kernel subsystem that plays a critical role on
>> a given system by providing various important functionalities to the
>> block devices with various target types like crypt, verity, integrity
>> etc.  Each of these target types’ functionalities can be configured with
>> various attributes.  The attributes chosen to configure these target types
>> can significantly impact the security profile of the block device,
>> and in-turn, of the system itself.  For instance, the type of encryption
>> algorithm and the key size determines the strength of encryption for a
>> given block device.
>>
>> Therefore, verifying the current state of various block devices as well
>> as their various target attributes is crucial for external services
>> before fully trusting the system with business-critical data/workload.
>>
>> IMA provides the necessary functionality for device mapper to measure the
>> state and configuration of various block devices -
>>    - BY device mapper itself, from within the kernel,
>>    - in a tamper resistant way,
>>    - and re-measured - triggered on state/configuration change.
>>
>> This patch series uses this IMA functionality, by calling the function
>> ima_measure_critical_data(), when a block device state is changed (e.g.
>> on device create, resume, rename, remove etc.)  It measures the device
>> state and configuration and stores it in IMA logs, so that it can be
>> used by external services for managing the system.
> I needed to EXPORT_SYMBOL_GPL(ima_measure_critical_data); otherwise I
> couldn't compile.. not sure but I can only imagine you compile DM
> (and all targets) to be builtin?

I believe the EXPORT_SYMBOL_GPL(ima_measure_critical_data) is now needed 
because of the move “#ifdef CONFIG_IMA from dm-ima.c to dm-ima.h”, and 
the associated change in the Makefile
+ifeq ($(CONFIG_IMA),y)
dm-mod-objs += dm-ima.o
+endif
Earlier I needed to export symbol only if I was calling 
ima_measure_critical_data() directly from various dm-*.c files.
With my earlier implementation, it wasn’t needed when it was called from 
the wrapper dm_ima_measure_data() in dm-ima.c.

> In addition to fixing that (in first table load patch) I changed
> various things along the way while I reviewed each patch.

Thank you so much for making the necessary changes Mike. Really 
appreciate it.

> Things that I recall are:
> - moved #ifdef CONFIG_IMA from dm-ima.c to dm-ima.h
> - fixed various typos and whitespace
> - consistently prepend "," in STATUSTYPE_IMA's DMEMIT()s as opposed to
>    having a mix or pre and postfix throughout targets
> - fixed what seemed like malformed STATUSTYPE_IMA handling for
>    dm-multipath -- it was DMEMIT(";") for each dm-mpath's pathgroup
> - added some fields to dm-mpath, renamed some IMA names in name=value
>    pairs to be more clear.

I went through the changes you made. They look fine. In addition to the 
above changes, you also fixed a warning in dm-raid.c. (initializing the 
recovery variable)
Thanks again. :)

> I've staged the result in linux-next via linux-dm.git's dm-5.15
> branch, see:
> https://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git/log/?h=dm-5.15
>
> I've compiled tested both with and without CONFIG_IMA set.  But
> haven't actually tested the code.

No worries. I will test the changesthoroughly again.

> Please send any incremental fixes relative to the dm-5.15 branch and
> I'll get them folded in where appropriate.

Ok. I will send incremental patches against dm-5.15 as you've suggested. 
Thanks again for the review and all the help so far. Really appreciate 
it. ~Tushar

> Thanks,
> Mike
--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Thore Sommer July 27, 2021, 10:18 a.m. UTC | #5
Hello Tushar,

I've now tested your patches more in depth. I've used the latest changes from
the dm-5.15 branch. Here are some things that I noticed during testing with
dm-verity. I'm relative new to IMA and device mapper, so there are also some
more general questions.

No new IMA measurement is generated if dm-verity verification fails. This is
unfortunate because to make the dm-verity measurements useful we need to be
notified when hash_failed is set to true. We will need something like
"device_update" where we remeasure the device state if it has changed.

Creating a dm-verity device with mount then removing it and now if you create it
again no measurement is generated. Is that the expected behavior?  
I would expect that new measurements for "table_load" and "device_resume" are
created even if the entries are identical the other ones before.

There is no way to verify if the root hash was verified against a signature. We
have "root_hash_sig_key_desc SIGNATURE_DESCRIPTION" in the dm table.
"SIGNATURE_DESCRIPTION" itself is not really useful because it seems that we
cannot map it back to the certificate that was used for verification but the
presence of "root_hash_sig_key_desc" might be enough in combination with
measuring the keyring.

Is there a reason that suspend is not measured?

How is the measured uuid created? The format seems to be
"CRYPT-VERITY-UUID-NAME" where UUID is uuid from the verity device and NAME is
the device mapper name. Does this naming come from the kernel or libcryptsetup?

What can happen in between a "table_load" and "device_resume" that is security
relevant?

For remote attestation services it would be nice if we have clear indicator from
what component the "ima-buf" entry was generated. Prefixing all "n-ng" field
entries with something like "dm_" would make it easier for us to add different
validators for different measurements that use the "ima-buf" template. The
keyring measurements already use "ima-buf" and using some kind of naming scheme
to easily differentiate the entries would be nice.

Not directly device mapper related, but it would be nice to also measure the
mount points and a mapping to the device IDs. The reasoning is that we can
measure if the target is correct but not if it was mounted correctly.  
In our case we can verify the trust of our initramfs that creates the dm-verity
device and then mounts it and if this fails refuses to boot, but that might not
always be the case.

Regards, 
Thore

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Alasdair G Kergon July 27, 2021, 8:33 p.m. UTC | #6
On Tue, Jul 27, 2021 at 12:18:02PM +0200, Thore Sommer wrote:
> No new IMA measurement is generated if dm-verity verification fails. This is
> unfortunate because to make the dm-verity measurements useful we need to be
> notified when hash_failed is set to true. We will need something like
> "device_update" where we remeasure the device state if it has changed.
 
Measurements in the current patchset are only triggered by ioctl calls
initiated by userspace.

Having other triggering mechanisms - such as hooking into internal
events when something unexpected happens - could be considered for
follow-on patches.

> Creating a dm-verity device with mount then removing it and now if you create it
> again no measurement is generated. Is that the expected behavior?  

Each of the relevant dm ioctls should be logged separately each time.  If that's
not happening it might need fixing.

> Is there a reason that suspend is not measured?

A suspend doesn't change the configuration so falls outside the criteria
for this patch set.  (If there is some need for it, it would be covered
by the need to measure internal events that I mentioned above.)
 
> What can happen in between a "table_load" and "device_resume" that is security
> relevant?

The table prepared by the load can be cleared.  That would change the
effect of the resume.
 
> Not directly device mapper related, but it would be nice to also measure the
> mount points and a mapping to the device IDs. 

Again, that would be for future patches building on these ones.

Alasdair

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Tushar Sugandhi July 28, 2021, 3:10 a.m. UTC | #7
Hi Thore,

On 7/27/21 1:33 PM, Alasdair G Kergon wrote:
>> Creating a dm-verity device with mount then removing it and now if you create it
>> again no measurement is generated. Is that the expected behavior?
> Each of the relevant dm ioctls should be logged separately each time.  If that's
> not happening it might need fixing.
> 
Most likely this is because you haven't set CONFIG_IMA_DISABLE_HTABLE=y.

See "IMA: support for duplicate measurement records" [1] for details.

Please let us know if you still see this behavior after setting
CONFIG_IMA_DISABLE_HTABLE=y.

Thanks,
Tushar

[1] 
https://github.com/torvalds/linux/commit/52c208397c246f0c31d031eb8c41f9c7e9fdec0e

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Thore Sommer July 28, 2021, 5:14 p.m. UTC | #8
Hi Tushar,

> Most likely this is because you haven't set CONFIG_IMA_DISABLE_HTABLE=y.
Yes, that was the case. 

With CONFIG_IMA_DISABLE_HTABLE=y the behavior is as expected. Now a new
measurement is created if I create the same device twice.

Regards,
Thore

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Thore Sommer July 28, 2021, 5:34 p.m. UTC | #9
Hi Alasdair,

thank you for answering my questions. The answers helped a lot.

> Having other triggering mechanisms - such as hooking into internal
> events when something unexpected happens - could be considered for
> follow-on patches.

I've written [1] a proof of concept implementation that provides a hook for
targets to remeasure their state. This was my first attempt at writing kernel
code, so there might be some serious bugs. With something like this implemented
remote attestation for state of dm-verity should be possible.

The output if a target calls that hook is:
device_update DEVICE_METADATA;TARGET_METADATA,TARGET_STATUS

Regards,
Thore

[1]
diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c
index 2d796e439bee..b743a2e9add4 100644
--- a/drivers/md/dm-ima.c
+++ b/drivers/md/dm-ima.c
@@ -703,3 +703,84 @@ void dm_ima_measure_on_device_rename(struct mapped_device *md)
 	kfree(new_dev_name);
 	kfree(new_dev_uuid);
 }
+
+/*
+ * Give the option for targets to remeasure on state change.
+ */
+void dm_ima_measure_on_target_update(struct dm_target *ti){
+	char *ima_buf = NULL, *target_metadata_buf = NULL, *target_data_buf= NULL;
+	status_type_t type = STATUSTYPE_IMA;
+	size_t target_metadata_buf_len, target_data_buf_len;
+	unsigned int num_targets, i;
+	struct dm_table *table = ti->table;
+	struct mapped_device *md = table->md;
+	unsigned int  target_num = -1;
+	bool noio = true;
+	int l = 0;
+
+	ima_buf = dm_ima_alloc(DM_IMA_MEASUREMENT_BUF_LEN, GFP_KERNEL, noio);
+	if (!ima_buf)
+		return;
+
+	target_metadata_buf = dm_ima_alloc(DM_IMA_TARGET_METADATA_BUF_LEN, GFP_KERNEL, noio);
+	if (!target_metadata_buf)
+		goto exit;
+
+	target_data_buf = dm_ima_alloc(DM_IMA_TARGET_DATA_BUF_LEN, GFP_KERNEL, noio);
+	if (!target_data_buf)
+		goto exit;
+
+
+	num_targets = dm_table_get_num_targets(table);
+
+	// Get target number
+	for (i = 0; i < num_targets; i++){
+		struct dm_target *ti2 = dm_table_get_target(table, i);
+		if (!ti)
+			goto exit;
+		if (ti == ti2){
+			target_num = i;
+			break;
+		}
+	}
+	if (target_num == -1)
+		goto exit;
+
+	/*
+	 * First retrieve the target metadata.
+	 */
+	scnprintf(target_metadata_buf, DM_IMA_TARGET_METADATA_BUF_LEN,
+			  "target_index=%d,target_begin=%llu,target_len=%llu,",
+			  target_num, ti->begin, ti->len);
+	target_metadata_buf_len = strlen(target_metadata_buf);
+
+	/*
+	 * Then retrieve the actual target data.
+	 */
+	if (ti->type->status)
+		ti->type->status(ti, type, STATUSTYPE_IMA, target_data_buf,
+					DM_IMA_TARGET_DATA_BUF_LEN);
+	else
+		target_data_buf[0] = '\0';
+	target_data_buf_len = strlen(target_data_buf);
+
+	// Add the device metadata
+	memcpy(ima_buf + l, md->ima.active_table.device_metadata, md->ima.active_table.device_metadata_len);
+	l += md->ima.active_table.device_metadata_len;
+
+	// Add the target metadata
+	memcpy(ima_buf + l, target_metadata_buf, target_metadata_buf_len);
+	l += target_metadata_buf_len;
+
+	// Add the new target state
+	memcpy(ima_buf + l, target_data_buf, target_data_buf_len);
+
+	dm_ima_measure_data("device_update", ima_buf, strlen(ima_buf), noio);
+
+exit:
+	kfree(ima_buf);
+	kfree(target_data_buf);
+	kfree(target_metadata_buf);
+}
+
+EXPORT_SYMBOL_GPL(dm_ima_measure_on_target_update);
\ No newline at end of file
diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h
index 6e6f18bf05b4..f90c4147277a 100644
--- a/drivers/md/dm-ima.h
+++ b/drivers/md/dm-ima.h
@@ -53,6 +53,7 @@ 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);
+void dm_ima_measure_on_target_update(struct dm_target *ti);
 
 #else
 
@@ -62,6 +63,7 @@ static inline void dm_ima_measure_on_device_resume(struct mapped_device *md, boo
 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) {}
+static inline void dm_ima_measure_on_target_update(struct dm_target *ti) {}
 
 #endif /* CONFIG_IMA */
 
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index bfefa100c265..f0764dd8bd4d 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -16,6 +16,7 @@
 #include "dm-verity.h"
 #include "dm-verity-fec.h"
 #include "dm-verity-verify-sig.h"
+#include "dm-ima.h"
 #include <linux/module.h>
 #include <linux/reboot.h>
 
@@ -217,10 +218,15 @@ static int verity_handle_err(struct dm_verity *v, enum verity_block_type type,
 	char *envp[] = { verity_env, NULL };
 	const char *type_str = "";
 	struct mapped_device *md = dm_table_get_md(v->ti->table);
+	int old_hash_failed = v->hash_failed;
 
 	/* Corruption should be visible in device status in all modes */
 	v->hash_failed = 1;
 
+	if (!old_hash_failed){
+		dm_ima_measure_on_target_update(v->ti);
+	}
+
 	if (v->corrupted_errs >= DM_VERITY_MAX_CORRUPTED_ERRS)
 		goto out;
Alasdair G Kergon July 28, 2021, 9:33 p.m. UTC | #10
On Tue, Jul 27, 2021 at 12:18:02PM +0200, Thore Sommer wrote:
> How is the measured uuid created? The format seems to be
> "CRYPT-VERITY-UUID-NAME" where UUID is uuid from the verity device and NAME is
> the device mapper name. Does this naming come from the kernel or libcryptsetup?

See libdevmapper.h:
/*
 * Configure default UUID prefix string.
 * Conventionally this is a short capitalised prefix indicating the subsystem
 * that is managing the devices, e.g. "LVM-" or "MPATH-".
 * To support stacks of devices from different subsystems, recursive functions
 * stop recursing if they reach a device with a different prefix.
 */
int dm_set_uuid_prefix(const char *uuid_prefix);


Each device-mapper device may have a uuid of up to 128 characters plus
trailing NUL.  Whichever piece software activates the device assigns the
uuid (so userspace or kernel boot parameters).  By convention each such
piece of software uses a short prefix ending with a hyphen that
identifies that software as the "owner" (manager) of that dm device.
This means each piece of software can easily filter out the devices for
which it is responsible and ignore all the others etc.  It can use the
remainder of the UUID to identify the device uniquely to itself.
Another convention is that when one device is a 'wrapper' of some sort
around another, it may create the uuid by adding its prefix to the uuid
of the device it is wrapping - this might give you stacked prefixes.
When there's a complex one-composed-from-many device structure, suffices
may be used to identify the components.

Think of the 'name' as the human-friendly device name and the uuid as
a software-friendly internal name.

Alasdair

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Tushar Sugandhi July 29, 2021, 5:32 p.m. UTC | #11
On 7/28/21 10:14 AM, Thore Sommer wrote:
> Hi Tushar,
> 
>> Most likely this is because you haven't set CONFIG_IMA_DISABLE_HTABLE=y.
> Yes, that was the case.
> 
> With CONFIG_IMA_DISABLE_HTABLE=y the behavior is as expected. Now a new
> measurement is created if I create the same device twice.
> 
> Regards,
> Thore
> 
Thanks for confirming Thore. :)

Regards,
Tushar

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Tushar Sugandhi July 29, 2021, 7:24 p.m. UTC | #12
Hi Thore,
Replying to a few questions which were not already answered by me/Alasdair.


On 7/27/21 3:18 AM, Thore Sommer wrote:

> There is no way to verify if the root hash was verified against a signature. We
> have "root_hash_sig_key_desc SIGNATURE_DESCRIPTION" in the dm table.
> "SIGNATURE_DESCRIPTION" itself is not really useful because it seems that we
> cannot map it back to the certificate that was used for verification but the
> presence of "root_hash_sig_key_desc" might be enough in combination with
> measuring the keyring.

Thanks for the suggestion Thore.
I can update the verity_status() to measure if v->signature_key_desc is 
set.

Something like:
DMEMIT("signature_key_desc_present=%c,", v->signature_key_desc ? 'y' :
'n');

Alasdair, Mike,
Can you tell if this is needed and/or sufficient?
If it is needed, should we log the full string  v->signature_key_desc?
I am concerned about logging the full string as it is an unbounded
buffer (a char*) coming from UM. And at the same time, not sure if just
logging the presence is sufficient. Thoughts?

Thore,
Please note – even if we measure signature_key_desc (full string or just
its presence): in order to use it with the keyrings, the IMA policy also
needs to be set to measure key rings (using “measure func=KEY_CHECK
...”). It is independent from measuring the device mapper data (which is
measured when the policy is set to “measure func=CRITICAL_DATA
label=device-mapper ...”).

Therefore measuring keyrings together (i.e. in the same IMA log) with DM
data  is not always guaranteed, since it is dictated by how the IMA
policy is configured.

Just FYI.

> For remote attestation services it would be nice if we have clear indicator from
> what component the "ima-buf" entry was generated. Prefixing all "n-ng" field
> entries with something like "dm_" would make it easier for us to add different
> validators for different measurements that use the "ima-buf" template. The
> keyring measurements already use "ima-buf" and using some kind of naming scheme
> to easily differentiate the entries would be nice.
The event names typically come from kernel components that are doing the
measurement of critical data. So any duplicates should be caught in the
upstream review of the kernel patch.

But thanks for the suggestion. I will prefix the event names in this 
patch series with “dm_” to indicate they are related to device mapper.

Thanks,
Tushar
> Regards,
> Thore
> 


--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Thore Sommer Aug. 2, 2021, 10:38 a.m. UTC | #13
Hi Tushar,

thank you for answering my questions and looking at my suggestions.

> I can update the verity_status() to measure if v->signature_key_desc is 
> set.
> 
> Something like:
> DMEMIT("signature_key_desc_present=%c,", v->signature_key_desc ? 'y' :
> 'n');

If my understanding that this entry is only set if the signature was validated
is correct then this should work.

> Please note – even if we measure signature_key_desc (full string or just
> its presence): in order to use it with the keyrings, the IMA policy also
> needs to be set to measure key rings (using "measure func=KEY_CHECK
> ..."). It is independent from measuring the device mapper data (which is
> measured when the policy is set to “measure func=CRITICAL_DATA
> label=device-mapper ...").
> 
> Therefore measuring keyrings together (i.e. in the same IMA log) with DM
> data  is not always guaranteed, since it is dictated by how the IMA
> policy is configured.

Thanks for pointing that out. Currently we don't measure the keyrings but when
we enable remote attestation for dm-verity we'll make sure that our IMA policy
also measures the keyrings.

Regards,
Thore

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Thore Sommer Aug. 2, 2021, 10:45 a.m. UTC | #14
Hi Alasdair,

thank you for the explanation and pointing me into the right direction.  
I was wondering how we can differentiate the different devices in the remote
attestation service and now I think that I understand the format of the uuids,
so that we can implement a parser/validator for that.

Regards,
Thore

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel