2019-11-13 19:24:58

by Lakshmi Ramasubramanian

[permalink] [raw]
Subject: [PATCH v6 0/3] KEYS: Measure keys when they are created or updated

Keys created or updated in the system are currently not measured.
Therefore an attestation service, for instance, would not be able to
attest whether or not the trusted keys keyring(s), for instance, contain
only known good (trusted) keys.

IMA measures system files, command line arguments passed to kexec,
boot aggregate, etc. It can be used to measure keys as well.
But there is no mechanism available in the kernel for IMA to
know when a key is created or updated.

This change aims to address measuring keys created or updated
in the system:

To achieve the above the following changes have been made:

- Added a new IMA hook namely, ima_post_key_create_or_update, which
measures the key. This IMA hook is called from key_create_or_update
function. The key measurement can be controlled through IMA policy.

A new IMA policy function KEY_CHECK has been added to measure keys.

# measure keys loaded onto any keyring
measure func=KEY_CHECK

Testing performed:

* Booted the kernel with this change.
* When KEY_CHECK policy is set IMA measures keys loaded
onto any keyring.
* Keys are not measured when KEY_CHECK is not set.
* Added a new key to a keyring.
=> Added keys to .ima and .evm keyrings.
* Added the same key again.
=> Add the same key to .ima and .evm keyrings.

Change Log:

v6:

=> Rebased the changes to v5.4-rc7
=> Renamed KEYRING_CHECK to KEY_CHECK per Mimi's suggestion.
=> Excluded the patches that add support for limiting key
measurement to specific keyrings ("keyrings=" option
for "measure func=KEY_CHECK" in the IMA policy).
Also, excluded the patches that add support for deferred
processing of keys (queue support).
These patches will be added in separate patch sets later.

v5:

=> Reorganized the patches to add measurement of keys through
the IMA hook without any queuing and then added queuing support.
=> Updated the queuing functions to minimize code executed inside mutex.
=> Process queued keys after custom IMA policies have been applied.

v4:

=> Rebased the changes to v5.4-rc3
=> Applied the following dependent patch set first
and then added new changes.
https://lore.kernel.org/linux-integrity/[email protected]
=> Refactored the patch set to separate out changes related to
func KEYRING_CHECK and options keyrings into different patches.
=> Moved the functions to queue and dequeue keys for measurement
from ima_queue.c to a new file ima_asymmetric_keys.c.
=> Added a new config namely CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
to compile ima_asymmetric_keys.c

v3:

=> Added KEYRING_CHECK for measuring keys. This can optionally specify
keyrings to measure.
=> Updated ima_get_action() and related functions to return
the keyrings if specified in the policy.
=> process_buffer_measurement() function is updated to take keyring
as a parameter. The key will be measured if the policy includes
the keyring in the list of measured keyrings. If the policy does not
specify any keyrings then all keys are measured.

v2:

=> Per suggestion from Mimi reordered the patch set to first
enable measuring keys added or updated in the system.
And, then scope the measurement to keys added to
builtin_trusted_keys keyring through ima policy.
=> Removed security_key_create_or_update function and instead
call ima hook, to measure the key, directly from
key_create_or_update function.

v1:

=> LSM function for key_create_or_update. It calls ima.
=> Added ima hook for measuring keys
=> ima measures keys based on ima policy.

v0:

=> Added LSM hook for key_create_or_update.
=> Measure keys added to builtin or secondary trusted keys keyring.

Lakshmi Ramasubramanian (3):
IMA: Add KEY_CHECK func to measure keys
IMA: Define an IMA hook to measure keys
KEYS: Call the IMA hook to measure keys

Documentation/ABI/testing/ima_policy | 6 ++-
include/linux/ima.h | 13 +++++
security/integrity/ima/Kconfig | 14 ++++++
security/integrity/ima/Makefile | 1 +
security/integrity/ima/ima.h | 1 +
security/integrity/ima/ima_asymmetric_keys.c | 51 ++++++++++++++++++++
security/integrity/ima/ima_main.c | 7 +++
security/integrity/ima/ima_policy.c | 4 +-
security/keys/key.c | 9 ++++
9 files changed, 104 insertions(+), 2 deletions(-)
create mode 100644 security/integrity/ima/ima_asymmetric_keys.c

--
2.17.1


2019-11-13 19:25:25

by Lakshmi Ramasubramanian

[permalink] [raw]
Subject: [PATCH v6 3/3] KEYS: Call the IMA hook to measure keys

Call the IMA hook from key_create_or_update function to measure
the key when a new key is created or an existing key is updated.

This patch adds the call to the IMA hook from key_create_or_update
function to measure the key on key create or update.

Signed-off-by: Lakshmi Ramasubramanian <[email protected]>
---
include/linux/ima.h | 13 +++++++++++++
security/keys/key.c | 9 +++++++++
2 files changed, 22 insertions(+)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index 6d904754d858..ec5afe319ab7 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -25,6 +25,12 @@ extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
extern void ima_post_path_mknod(struct dentry *dentry);
extern void ima_kexec_cmdline(const void *buf, int size);

+#ifdef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
+extern void ima_post_key_create_or_update(struct key *keyring,
+ struct key *key,
+ unsigned long flags, bool create);
+#endif
+
#ifdef CONFIG_IMA_KEXEC
extern void ima_add_kexec_buffer(struct kimage *image);
#endif
@@ -101,6 +107,13 @@ static inline void ima_add_kexec_buffer(struct kimage *image)
{}
#endif

+#ifndef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
+static inline void ima_post_key_create_or_update(struct key *keyring,
+ struct key *key,
+ unsigned long flags,
+ bool create) {}
+#endif
+
#ifdef CONFIG_IMA_APPRAISE
extern bool is_ima_appraise_enabled(void);
extern void ima_inode_post_setattr(struct dentry *dentry);
diff --git a/security/keys/key.c b/security/keys/key.c
index 764f4c57913e..9782d4d046fd 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -13,6 +13,7 @@
#include <linux/security.h>
#include <linux/workqueue.h>
#include <linux/random.h>
+#include <linux/ima.h>
#include <linux/err.h>
#include "internal.h"

@@ -936,6 +937,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
goto error_link_end;
}

+ /* let the ima module know about the created key. */
+ ima_post_key_create_or_update(keyring, key, flags, true);
+
key_ref = make_key_ref(key, is_key_possessed(keyring_ref));

error_link_end:
@@ -965,6 +969,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
}

key_ref = __key_update(key_ref, &prep);
+
+ /* let the ima module know about the updated key. */
+ if (!IS_ERR(key_ref))
+ ima_post_key_create_or_update(keyring, key, flags, false);
+
goto error_free_prep;
}
EXPORT_SYMBOL(key_create_or_update);
--
2.17.1

2019-11-13 20:11:04

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v6 3/3] KEYS: Call the IMA hook to measure keys

On Wed, 2019-11-13 at 10:46 -0800, Lakshmi Ramasubramanian wrote:
> Call the IMA hook from key_create_or_update function to measure
> the key when a new key is created or an existing key is updated.
>
> This patch adds the call to the IMA hook from key_create_or_update
> function to measure the key on key create or update.
>
> Signed-off-by: Lakshmi Ramasubramanian <[email protected]>
> ---
> include/linux/ima.h | 13 +++++++++++++
> security/keys/key.c | 9 +++++++++
> 2 files changed, 22 insertions(+)
>
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 6d904754d858..ec5afe319ab7 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -25,6 +25,12 @@ extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
> extern void ima_post_path_mknod(struct dentry *dentry);
> extern void ima_kexec_cmdline(const void *buf, int size);
>
> +#ifdef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
> +extern void ima_post_key_create_or_update(struct key *keyring,
> + struct key *key,
> + unsigned long flags, bool create);
> +#endif
> +
> #ifdef CONFIG_IMA_KEXEC
> extern void ima_add_kexec_buffer(struct kimage *image);
> #endif
> @@ -101,6 +107,13 @@ static inline void ima_add_kexec_buffer(struct kimage *image)
> {}
> #endif
>
> +#ifndef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
> +static inline void ima_post_key_create_or_update(struct key *keyring,
> + struct key *key,
> + unsigned long flags,
> + bool create) {}
> +#endif
> +
> #ifdef CONFIG_IMA_APPRAISE
> extern bool is_ima_appraise_enabled(void);
> extern void ima_inode_post_setattr(struct dentry *dentry);
> diff --git a/security/keys/key.c b/security/keys/key.c
> index 764f4c57913e..9782d4d046fd 100644
> --- a/security/keys/key.c
> +++ b/security/keys/key.c
> @@ -13,6 +13,7 @@
> #include <linux/security.h>
> #include <linux/workqueue.h>
> #include <linux/random.h>
> +#include <linux/ima.h>
> #include <linux/err.h>
> #include "internal.h"
>
> @@ -936,6 +937,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
> goto error_link_end;
> }
>
> + /* let the ima module know about the created key. */

This comment and the one below doesn't provide any additional
information.  Please remove them.

> + ima_post_key_create_or_update(keyring, key, flags, true);
> +
> key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
>
> error_link_end:
> @@ -965,6 +969,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
> }
>
> key_ref = __key_update(key_ref, &prep);
> +
> + /* let the ima module know about the updated key. */
> + if (!IS_ERR(key_ref))
> + ima_post_key_create_or_update(keyring, key, flags, false);
> +
> goto error_free_prep;
> }
> EXPORT_SYMBOL(key_create_or_update);

2019-11-13 22:05:31

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v6 0/3] KEYS: Measure keys when they are created or updated

On Wed, 2019-11-13 at 10:46 -0800, Lakshmi Ramasubramanian wrote:
> Keys created or updated in the system are currently not measured.
> Therefore an attestation service, for instance, would not be able to
> attest whether or not the trusted keys keyring(s), for instance, contain
> only known good (trusted) keys.
>
> IMA measures system files, command line arguments passed to kexec,
> boot aggregate, etc. It can be used to measure keys as well.
> But there is no mechanism available in the kernel for IMA to
> know when a key is created or updated.
>
> This change aims to address measuring keys created or updated
> in the system:
>
> To achieve the above the following changes have been made:
>
> - Added a new IMA hook namely, ima_post_key_create_or_update, which
> measures the key. This IMA hook is called from key_create_or_update
> function. The key measurement can be controlled through IMA policy.
>
> A new IMA policy function KEY_CHECK has been added to measure keys.
>
> # measure keys loaded onto any keyring
> measure func=KEY_CHECK

When re-posting this patch set, please include the support for
specifying the "keyrings=" policy option, as an additional patch.

Mimi

2019-11-13 22:06:51

by Lakshmi Ramasubramanian

[permalink] [raw]
Subject: Re: [PATCH v6 0/3] KEYS: Measure keys when they are created or updated

On 11/13/2019 2:02 PM, Mimi Zohar wrote:

>
> When re-posting this patch set, please include the support for
> specifying the "keyrings=" policy option, as an additional patch.
>
> Mimi

Sure - will do.

thanks,
-lakshmi