Linux-Integrity Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v9 0/6] KEYS: Measure keys when they are created or updated
@ 2019-11-27  1:56 Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 1/6] IMA: Check IMA policy flag Lakshmi Ramasubramanian
                   ` (5 more replies)
  0 siblings, 6 replies; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-27  1:56 UTC (permalink / raw)
  To: zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

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.
   "keyrings=" option can be specified for KEY_CHECK to limit
   measuring the keys loaded onto the specified keyrings only.

   # measure keys loaded onto any keyring
   measure func=KEY_CHECK

   # measure keys loaded onto the IMA keyring only
   measure func=KEY_CHECK keyring=".ima"

   # measure keys on the BUILTIN and IMA keyrings into a different PCR
   measure func=KEY_CHECK keyring=".builtin_trusted_keys|.ima" pcr=11

Testing performed:

  * Booted the kernel with this change.
  * When KEY_CHECK policy is set IMA measures keys loaded
    onto any keyring (keyrings= option not specified).
  * Keys are not measured when KEY_CHECK is not set.
  * When keyrings= option is specified for KEY_CHECK then only the keys
    loaded onto a keyring specified in the option is measured.
  * 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:

  v9:

  => Changed the measured key data from just the public key to
     the entire payload passed to key_create_or_update() function.
     This payload is the certificate from which the key is created
     or updated by key_create_or_update() function.
  => Added check in process_buffer_measurement() to return
     immediately if ima_policy_flag is set to zero.

  v8:

  => Updated ima_match_keyring() function to check for
     whole keyring name match.
  => Used CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE instead of
     CONFIG_KEYS to build ima_asymmetric_keys.c and enable
     the IMA hook to measure keys since this config handles
     the required build time dependencies better.
  => Updated patch description to illustrate verification
     of key measurement.

  v7:

  => Removed CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS option and used
     CONFIG_KEYS instead for ima_asymmetric_keys.c
  => Added the patches related to "keyrings=" option support to
     this patch set.

  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/1572492694-6520-1-git-send-email-zohar@linux.ibm.com
  => 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 (6):
  IMA: Check IMA policy flag
  IMA: Add KEY_CHECK func to measure keys
  IMA: Define an IMA hook to measure keys
  KEYS: Call the IMA hook to measure keys
  IMA: Add support to limit measuring keys
  IMA: Read keyrings= option from the IMA policy

 Documentation/ABI/testing/ima_policy         |  16 ++-
 include/linux/ima.h                          |  14 +++
 security/integrity/ima/Makefile              |   1 +
 security/integrity/ima/ima.h                 |   9 +-
 security/integrity/ima/ima_api.c             |   8 +-
 security/integrity/ima/ima_appraise.c        |   4 +-
 security/integrity/ima/ima_asymmetric_keys.c |  58 +++++++++++
 security/integrity/ima/ima_main.c            |  12 ++-
 security/integrity/ima/ima_policy.c          | 100 +++++++++++++++++--
 security/keys/key.c                          |  10 ++
 10 files changed, 212 insertions(+), 20 deletions(-)
 create mode 100644 security/integrity/ima/ima_asymmetric_keys.c

-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v9 1/6] IMA: Check IMA policy flag
  2019-11-27  1:56 [PATCH v9 0/6] KEYS: Measure keys when they are created or updated Lakshmi Ramasubramanian
@ 2019-11-27  1:56 ` Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 2/6] IMA: Add KEY_CHECK func to measure keys Lakshmi Ramasubramanian
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-27  1:56 UTC (permalink / raw)
  To: zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

Return immediately from process_buffer_measurement()
if the IMA policy flag is set to zero. Not doing this
can result in kernel panic when process_buffer_measurement()
is called before IMA is initialized (for instance, when
the IMA hook is called when a key is added to
the .builtin_trusted_keys keyring).

This change adds the check in process_buffer_measurement()
to return immediately if ima_policy_flag is set to zero.

Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
---
 security/integrity/ima/ima_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index d7e987baf127..9b35db2fc777 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -655,6 +655,9 @@ void process_buffer_measurement(const void *buf, int size,
 	int action = 0;
 	u32 secid;
 
+	if (!ima_policy_flag)
+		return;
+
 	/*
 	 * Both LSM hooks and auxilary based buffer measurements are
 	 * based on policy.  To avoid code duplication, differentiate
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v9 2/6] IMA: Add KEY_CHECK func to measure keys
  2019-11-27  1:56 [PATCH v9 0/6] KEYS: Measure keys when they are created or updated Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 1/6] IMA: Check IMA policy flag Lakshmi Ramasubramanian
@ 2019-11-27  1:56 ` Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 3/6] IMA: Define an IMA hook " Lakshmi Ramasubramanian
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-27  1:56 UTC (permalink / raw)
  To: zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

Measure keys loaded onto any keyring.

This patch defines a new IMA policy func namely KEY_CHECK to
measure keys. Updated ima_match_rules() to check for KEY_CHECK
and ima_parse_rule() to handle KEY_CHECK.

Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
---
 Documentation/ABI/testing/ima_policy | 6 +++++-
 security/integrity/ima/ima.h         | 1 +
 security/integrity/ima/ima_policy.c  | 4 +++-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 29aaedf33246..066d32797500 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -29,7 +29,7 @@ Description:
 		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
 				[FIRMWARE_CHECK]
 				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
-				[KEXEC_CMDLINE]
+				[KEXEC_CMDLINE] [KEY_CHECK]
 			mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
 			       [[^]MAY_EXEC]
 			fsmagic:= hex value
@@ -113,3 +113,7 @@ Description:
 		Example of appraise rule allowing modsig appended signatures:
 
 			appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig|modsig
+
+		Example of measure rule using KEY_CHECK to measure all keys:
+
+			measure func=KEY_CHECK
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index df4ca482fb53..fe6c698617bd 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -193,6 +193,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
 	hook(KEXEC_INITRAMFS_CHECK)	\
 	hook(POLICY_CHECK)		\
 	hook(KEXEC_CMDLINE)		\
+	hook(KEY_CHECK)			\
 	hook(MAX_CHECK)
 #define __ima_hook_enumify(ENUM)	ENUM,
 
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index f19a895ad7cd..1525a28fd705 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -373,7 +373,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
 {
 	int i;
 
-	if (func == KEXEC_CMDLINE) {
+	if ((func == KEXEC_CMDLINE) || (func == KEY_CHECK)) {
 		if ((rule->flags & IMA_FUNC) && (rule->func == func))
 			return true;
 		return false;
@@ -997,6 +997,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 				entry->func = POLICY_CHECK;
 			else if (strcmp(args[0].from, "KEXEC_CMDLINE") == 0)
 				entry->func = KEXEC_CMDLINE;
+			else if (strcmp(args[0].from, "KEY_CHECK") == 0)
+				entry->func = KEY_CHECK;
 			else
 				result = -EINVAL;
 			if (!result)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v9 3/6] IMA: Define an IMA hook to measure keys
  2019-11-27  1:56 [PATCH v9 0/6] KEYS: Measure keys when they are created or updated Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 1/6] IMA: Check IMA policy flag Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 2/6] IMA: Add KEY_CHECK func to measure keys Lakshmi Ramasubramanian
@ 2019-11-27  1:56 ` " Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 4/6] KEYS: Call the " Lakshmi Ramasubramanian
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-27  1:56 UTC (permalink / raw)
  To: zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

Measure asymmetric keys used for verifying file signatures,
certificates, etc.

This patch defines a new IMA hook namely ima_post_key_create_or_update()
to measure the payload used to create a new key or update an existing key.

The IMA hook is defined in a new file namely ima_asymmetric_keys.c
which is built only if CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is enabled.

Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
---
 security/integrity/ima/Makefile              |  1 +
 security/integrity/ima/ima_asymmetric_keys.c | 52 ++++++++++++++++++++
 2 files changed, 53 insertions(+)
 create mode 100644 security/integrity/ima/ima_asymmetric_keys.c

diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 31d57cdf2421..207a0a9eb72c 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -12,3 +12,4 @@ ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
 ima-$(CONFIG_IMA_APPRAISE_MODSIG) += ima_modsig.o
 ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
 obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
+obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += ima_asymmetric_keys.o
diff --git a/security/integrity/ima/ima_asymmetric_keys.c b/security/integrity/ima/ima_asymmetric_keys.c
new file mode 100644
index 000000000000..2308adcdeff3
--- /dev/null
+++ b/security/integrity/ima/ima_asymmetric_keys.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Microsoft Corporation
+ *
+ * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com)
+ *
+ * File: ima_asymmetric_keys.c
+ *       Defines an IMA hook to measure asymmetric keys on key
+ *       create or update.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <keys/asymmetric-type.h>
+#include "ima.h"
+
+/**
+ * ima_post_key_create_or_update - measure asymmetric keys
+ * @keyring: keyring to which the key is linked to
+ * @key: created or updated key
+ * @payload: The data used to instantiate or update the key.
+ * @plen: The length of @payload.
+ * @flags: key flags
+ * @create: flag indicating whether the key was created or updated
+ *
+ * Keys can only be measured, not appraised.
+ * The payload data used to instantiate or update the key is measured.
+ */
+void ima_post_key_create_or_update(struct key *keyring, struct key *key,
+				   const void *payload, size_t plen,
+				   unsigned long flags, bool create)
+{
+	/* Only asymmetric keys are handled by this hook. */
+	if (key->type != &key_type_asymmetric)
+		return;
+
+	if (!payload || (plen == 0))
+		return;
+
+	/*
+	 * keyring->description points to the name of the keyring
+	 * (such as ".builtin_trusted_keys", ".ima", etc.) to
+	 * which the given key is linked to.
+	 *
+	 * The name of the keyring is passed in the "eventname"
+	 * parameter to process_buffer_measurement() and is set
+	 * in the "eventname" field in ima_event_data for
+	 * the key measurement IMA event.
+	 */
+	process_buffer_measurement(payload, plen,
+				   keyring->description, KEY_CHECK, 0);
+}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v9 4/6] KEYS: Call the IMA hook to measure keys
  2019-11-27  1:56 [PATCH v9 0/6] KEYS: Measure keys when they are created or updated Lakshmi Ramasubramanian
                   ` (2 preceding siblings ...)
  2019-11-27  1:56 ` [PATCH v9 3/6] IMA: Define an IMA hook " Lakshmi Ramasubramanian
@ 2019-11-27  1:56 ` " Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 5/6] IMA: Add support to limit measuring keys Lakshmi Ramasubramanian
  2019-11-27  1:56 ` [PATCH v9 6/6] IMA: Read keyrings= option from the IMA policy Lakshmi Ramasubramanian
  5 siblings, 0 replies; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-27  1:56 UTC (permalink / raw)
  To: zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

Call the IMA hook from key_create_or_update() function to measure
the payload 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 <nramas@linux.microsoft.com>
---
 include/linux/ima.h | 14 ++++++++++++++
 security/keys/key.c | 10 ++++++++++
 2 files changed, 24 insertions(+)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index 6d904754d858..3b89136bc218 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -101,6 +101,20 @@ static inline void ima_add_kexec_buffer(struct kimage *image)
 {}
 #endif
 
+#if defined(CONFIG_IMA) && defined(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE)
+extern void ima_post_key_create_or_update(struct key *keyring,
+					  struct key *key,
+					  const void *payload, size_t plen,
+					  unsigned long flags, bool create);
+#else
+static inline void ima_post_key_create_or_update(struct key *keyring,
+						 struct key *key,
+						 const void *payload,
+						 size_t plen,
+						 unsigned long flags,
+						 bool create) {}
+#endif  /* CONFIG_IMA && CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE */
+
 #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..718bf7217420 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;
 	}
 
+	ima_post_key_create_or_update(keyring, key, payload, plen,
+				      flags, true);
+
 	key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
 
 error_link_end:
@@ -965,6 +969,12 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
 	}
 
 	key_ref = __key_update(key_ref, &prep);
+
+	if (!IS_ERR(key_ref))
+		ima_post_key_create_or_update(keyring, key,
+					      payload, plen,
+					      flags, false);
+
 	goto error_free_prep;
 }
 EXPORT_SYMBOL(key_create_or_update);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-11-27  1:56 [PATCH v9 0/6] KEYS: Measure keys when they are created or updated Lakshmi Ramasubramanian
                   ` (3 preceding siblings ...)
  2019-11-27  1:56 ` [PATCH v9 4/6] KEYS: Call the " Lakshmi Ramasubramanian
@ 2019-11-27  1:56 ` Lakshmi Ramasubramanian
  2019-11-27 18:52   ` Mimi Zohar
  2019-12-03 12:25   ` Mimi Zohar
  2019-11-27  1:56 ` [PATCH v9 6/6] IMA: Read keyrings= option from the IMA policy Lakshmi Ramasubramanian
  5 siblings, 2 replies; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-27  1:56 UTC (permalink / raw)
  To: zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

Limit measuring keys to those keys being loaded onto a given set of
keyrings only.

This patch defines a new IMA policy option namely "keyrings=" that
can be used to specify a set of keyrings. If this option is specified
in the policy for "measure func=KEY_CHECK" then only the keys
loaded onto a keyring given in the "keyrings=" option are measured.

Added a new parameter namely "keyring" (name of the keyring) to
process_buffer_measurement(). The keyring name is passed to
ima_get_action() to determine the required action.
ima_match_rules() is updated to check keyring in the policy, if
specified, for KEY_CHECK function.

Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
---
 Documentation/ABI/testing/ima_policy         | 10 ++-
 security/integrity/ima/ima.h                 |  8 ++-
 security/integrity/ima/ima_api.c             |  8 ++-
 security/integrity/ima/ima_appraise.c        |  4 +-
 security/integrity/ima/ima_asymmetric_keys.c |  8 ++-
 security/integrity/ima/ima_main.c            |  9 +--
 security/integrity/ima/ima_policy.c          | 67 ++++++++++++++++++--
 7 files changed, 96 insertions(+), 18 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 066d32797500..cd572912c593 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -25,7 +25,7 @@ Description:
 			lsm:	[[subj_user=] [subj_role=] [subj_type=]
 				 [obj_user=] [obj_role=] [obj_type=]]
 			option:	[[appraise_type=]] [template=] [permit_directio]
-				[appraise_flag=]
+				[appraise_flag=] [keyrings=]
 		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
 				[FIRMWARE_CHECK]
 				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
@@ -42,6 +42,9 @@ Description:
 			appraise_flag:= [check_blacklist]
 			Currently, blacklist check is only for files signed with appended
 			signature.
+			keyrings:= list of keyrings
+			(eg, .builtin_trusted_keys|.ima). Only valid
+			when action is "measure" and func is KEY_CHECK.
 			template:= name of a defined IMA template type
 			(eg, ima-ng). Only valid when action is "measure".
 			pcr:= decimal value
@@ -117,3 +120,8 @@ Description:
 		Example of measure rule using KEY_CHECK to measure all keys:
 
 			measure func=KEY_CHECK
+
+		Example of measure rule using KEY_CHECK to only measure
+		keys added to .builtin_trusted_keys or .ima keyring:
+
+			measure func=KEY_CHECK keyrings=.builtin_trusted_keys|.ima
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index fe6c698617bd..f06238e41a7c 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -208,7 +208,8 @@ struct modsig;
 /* LIM API function definitions */
 int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
 		   int mask, enum ima_hooks func, int *pcr,
-		   struct ima_template_desc **template_desc);
+		   struct ima_template_desc **template_desc,
+		   const char *keyring);
 int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
 			    struct file *file, void *buf, loff_t size,
@@ -220,7 +221,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
 			   struct ima_template_desc *template_desc);
 void process_buffer_measurement(const void *buf, int size,
 				const char *eventname, enum ima_hooks func,
-				int pcr);
+				int pcr, const char *keyring);
 void ima_audit_measurement(struct integrity_iint_cache *iint,
 			   const unsigned char *filename);
 int ima_alloc_init_template(struct ima_event_data *event_data,
@@ -235,7 +236,8 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
 /* IMA policy related functions */
 int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
 		     enum ima_hooks func, int mask, int flags, int *pcr,
-		     struct ima_template_desc **template_desc);
+		     struct ima_template_desc **template_desc,
+		     const char *keyring);
 void ima_init_policy(void);
 void ima_update_policy(void);
 void ima_update_policy_flag(void);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 610759fe63b8..f6bc00914aa5 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -169,12 +169,13 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
  * @func: caller identifier
  * @pcr: pointer filled in if matched measure policy sets pcr=
  * @template_desc: pointer filled in if matched measure policy sets template=
+ * @keyring: keyring name used to determine the action
  *
  * The policy is defined in terms of keypairs:
  *		subj=, obj=, type=, func=, mask=, fsmagic=
  *	subj,obj, and type: are LSM specific.
  *	func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK
- *	| KEXEC_CMDLINE
+ *	| KEXEC_CMDLINE | KEY_CHECK
  *	mask: contains the permission mask
  *	fsmagic: hex value
  *
@@ -183,14 +184,15 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
  */
 int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
 		   int mask, enum ima_hooks func, int *pcr,
-		   struct ima_template_desc **template_desc)
+		   struct ima_template_desc **template_desc,
+		   const char *keyring)
 {
 	int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH;
 
 	flags &= ima_policy_flag;
 
 	return ima_match_policy(inode, cred, secid, func, mask, flags, pcr,
-				template_desc);
+				template_desc, keyring);
 }
 
 /*
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 300c8d2943c5..a9649b04b9f1 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -55,7 +55,7 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
 
 	security_task_getsecid(current, &secid);
 	return ima_match_policy(inode, current_cred(), secid, func, mask,
-				IMA_APPRAISE | IMA_HASH, NULL, NULL);
+				IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL);
 }
 
 static int ima_fix_xattr(struct dentry *dentry,
@@ -330,7 +330,7 @@ int ima_check_blacklist(struct integrity_iint_cache *iint,
 		if ((rc == -EPERM) && (iint->flags & IMA_MEASURE))
 			process_buffer_measurement(digest, digestsize,
 						   "blacklisted-hash", NONE,
-						   pcr);
+						   pcr, NULL);
 	}
 
 	return rc;
diff --git a/security/integrity/ima/ima_asymmetric_keys.c b/security/integrity/ima/ima_asymmetric_keys.c
index 2308adcdeff3..ca895f9a6504 100644
--- a/security/integrity/ima/ima_asymmetric_keys.c
+++ b/security/integrity/ima/ima_asymmetric_keys.c
@@ -46,7 +46,13 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key,
 	 * parameter to process_buffer_measurement() and is set
 	 * in the "eventname" field in ima_event_data for
 	 * the key measurement IMA event.
+	 *
+	 * The name of the keyring is also passed in the "keyring"
+	 * parameter to process_buffer_measurement() to check
+	 * if the IMA policy is configured to measure a key linked
+	 * to the given keyring.
 	 */
 	process_buffer_measurement(payload, plen,
-				   keyring->description, KEY_CHECK, 0);
+				   keyring->description, KEY_CHECK, 0,
+				   keyring->description);
 }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 9b35db2fc777..2272c3255c7d 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -215,7 +215,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
 	 * Included is the appraise submask.
 	 */
 	action = ima_get_action(inode, cred, secid, mask, func, &pcr,
-				&template_desc);
+				&template_desc, NULL);
 	violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
 			   (ima_policy_flag & IMA_MEASURE));
 	if (!action && !violation_check)
@@ -632,12 +632,13 @@ int ima_load_data(enum kernel_load_data_id id)
  * @eventname: event name to be used for the buffer entry.
  * @func: IMA hook
  * @pcr: pcr to extend the measurement
+ * @keyring: keyring name to determine the action to be performed
  *
  * Based on policy, the buffer is measured into the ima log.
  */
 void process_buffer_measurement(const void *buf, int size,
 				const char *eventname, enum ima_hooks func,
-				int pcr)
+				int pcr, const char *keyring)
 {
 	int ret = 0;
 	struct ima_template_entry *entry = NULL;
@@ -668,7 +669,7 @@ void process_buffer_measurement(const void *buf, int size,
 	if (func) {
 		security_task_getsecid(current, &secid);
 		action = ima_get_action(NULL, current_cred(), secid, 0, func,
-					&pcr, &template);
+					&pcr, &template, keyring);
 		if (!(action & IMA_MEASURE))
 			return;
 	}
@@ -721,7 +722,7 @@ void ima_kexec_cmdline(const void *buf, int size)
 {
 	if (buf && size != 0)
 		process_buffer_measurement(buf, size, "kexec-cmdline",
-					   KEXEC_CMDLINE, 0);
+					   KEXEC_CMDLINE, 0, NULL);
 }
 
 static int __init init_ima(void)
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 1525a28fd705..d9400585fcda 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -79,6 +79,7 @@ struct ima_rule_entry {
 		int type;	/* audit type */
 	} lsm[MAX_LSM_RULES];
 	char *fsname;
+	char *keyrings; /* Measure keys added to these keyrings */
 	struct ima_template_desc *template;
 };
 
@@ -356,6 +357,55 @@ int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
 	return NOTIFY_OK;
 }
 
+/**
+ * ima_match_keyring - determine whether the keyring matches the measure rule
+ * @rule: a pointer to a rule
+ * @keyring: name of the keyring to match against the measure rule
+ *
+ * If the measure action for KEY_CHECK does not specify keyrings=
+ * option then return true (Measure all keys).
+ * Else, return true if the given keyring name is present in
+ * the keyrings= option. False, otherwise.
+ */
+static bool ima_match_keyring(struct ima_rule_entry *rule,
+			      const char *keyring)
+{
+	const char *p;
+
+	/* If "keyrings=" is not specified all keys are measured. */
+	if (!rule->keyrings)
+		return true;
+
+	if (!keyring)
+		return false;
+
+	/*
+	 * "keyrings=" is specified in the policy in the format below:
+	 *   keyrings=.builtin_trusted_keys|.ima|.evm
+	 *
+	 * Each keyring name in the option is separated by a '|' and
+	 * the last keyring name is null terminated.
+	 *
+	 * The given keyring is considered matched only if
+	 * the whole keyring name matched a keyring name specified
+	 * in the "keyrings=" option.
+	 */
+	p = strstr(rule->keyrings, keyring);
+	if (p) {
+		/*
+		 * Found a substring match. Check if the character
+		 * at the end of the keyring name is | (keyring name
+		 * separator) or is the terminating null character.
+		 * If yes, we have a whole string match.
+		 */
+		p += strlen(keyring);
+		if (*p == '|' || *p == '\0')
+			return true;
+	}
+
+	return false;
+}
+
 /**
  * ima_match_rules - determine whether an inode matches the measure rule.
  * @rule: a pointer to a rule
@@ -364,18 +414,23 @@ int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
  * @secid: the secid of the task to be validated
  * @func: LIM hook identifier
  * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
+ * @keyring: keyring name to check in policy for KEY_CHECK func
  *
  * Returns true on rule match, false on failure.
  */
 static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
 			    const struct cred *cred, u32 secid,
-			    enum ima_hooks func, int mask)
+			    enum ima_hooks func, int mask,
+			    const char *keyring)
 {
 	int i;
 
 	if ((func == KEXEC_CMDLINE) || (func == KEY_CHECK)) {
-		if ((rule->flags & IMA_FUNC) && (rule->func == func))
+		if ((rule->flags & IMA_FUNC) && (rule->func == func)) {
+			if (func == KEY_CHECK)
+				return ima_match_keyring(rule, keyring);
 			return true;
+		}
 		return false;
 	}
 	if ((rule->flags & IMA_FUNC) &&
@@ -479,6 +534,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
  * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
  * @pcr: set the pcr to extend
  * @template_desc: the template that should be used for this rule
+ * @keyring: the keyring name, if given, to be used to check in the policy.
+ *           keyring can be NULL if func is anything other than KEY_CHECK.
  *
  * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type)
  * conditions.
@@ -489,7 +546,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
  */
 int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
 		     enum ima_hooks func, int mask, int flags, int *pcr,
-		     struct ima_template_desc **template_desc)
+		     struct ima_template_desc **template_desc,
+		     const char *keyring)
 {
 	struct ima_rule_entry *entry;
 	int action = 0, actmask = flags | (flags << 1);
@@ -503,7 +561,8 @@ int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
 		if (!(entry->action & actmask))
 			continue;
 
-		if (!ima_match_rules(entry, inode, cred, secid, func, mask))
+		if (!ima_match_rules(entry, inode, cred, secid, func, mask,
+				     keyring))
 			continue;
 
 		action |= entry->flags & IMA_ACTION_FLAGS;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v9 6/6] IMA: Read keyrings= option from the IMA policy
  2019-11-27  1:56 [PATCH v9 0/6] KEYS: Measure keys when they are created or updated Lakshmi Ramasubramanian
                   ` (4 preceding siblings ...)
  2019-11-27  1:56 ` [PATCH v9 5/6] IMA: Add support to limit measuring keys Lakshmi Ramasubramanian
@ 2019-11-27  1:56 ` Lakshmi Ramasubramanian
  2019-11-27 19:32   ` Mimi Zohar
  5 siblings, 1 reply; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-27  1:56 UTC (permalink / raw)
  To: zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

Read "keyrings=" option, if specified in the IMA policy, and store in
the list of IMA rules when the configured IMA policy is read.

This patch defines a new policy token enum namely Opt_keyrings
and an option flag IMA_KEYRINGS for reading "keyrings=" option
from the IMA policy.

Updated ima_parse_rule() to parse "keyrings=" option in the policy.
Updated ima_policy_show() to display "keyrings=" option.

The following example illustrates how key measurement can be verified.

Sample IMA Policy entry to measure keys
(Added in the file /etc/ima/ima-policy):
measure func=KEY_CHECK keyrings=.ima|.evm template=ima-buf

Build the kernel with this patch set applied and reboot to that kernel.

Ensure the IMA policy is applied:

root@nramas:/home/nramas# cat /sys/kernel/security/ima/policy
measure func=KEY_CHECK keyrings=.ima|.evm template=ima-buf

View the initial IMA measurement log:

root@nramas:/home/nramas# cat /sys/kernel/security/ima/ascii_runtime_measurements
10 67ec... ima-ng sha1:b5466c508583f0e633df83aa58fc7c5b67ccf667 boot_aggregate

Now, add a certificate (for example, x509_ima.der) to the .ima keyring
using evmctl (IMA-EVM Utility)

root@nramas:/home/nramas# keyctl show %:.ima
Keyring
 547515640 ---lswrv      0     0  keyring: .ima

root@nramas:/home/nramas# evmctl import x509_ima.der 547515640

root@nramas:/home/nramas# keyctl show %:.ima
Keyring
 547515640 ---lswrv      0     0  keyring: .ima
 809678766 --als--v      0     0   \_ asymmetric: hostname: whoami signing key: 052dd247dc3c36...

View the updated IMA measurement log:

root@nramas:/home/nramas# cat /sys/kernel/security/ima/ascii_runtime_measurements
10 67ec... ima-ng sha1:b5466c508583f0e633df83aa58fc7c5b67ccf667 boot_aggregate
10 3adf... ima-buf sha256:27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b .ima 308202863082...4aee
root@nramas:/home/nramas#

For this sample, SHA256 should be selected as the hash algorithm
used by IMA.

The following command verifies if the SHA256 hash generated from
the payload in the IMA log entry (listed above) for the .ima key
matches the SHA256 hash in the IMA log entry. The output of this
command should match the SHA256 hash given in the IMA log entry
(In this case, it should be 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b)

root@nramas:/home/nramas# cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b | cut -d' ' -f 6 | xxd -r -p |tee ima-cert.der | sha256sum | cut -d' ' -f 1

The above command also creates a binary file namely ima-cert.der
using the payload in the IMA log entry. This file should be a valid
x509 certificate which can be verified using openssl as given below:

root@nramas:/home/nramas# openssl x509 -in ima-cert.der -inform DER -text

The above command should display the contents of the file ima-cert.der
as an x509 certificate.

The IMA policy used here allows measurement of keys added to
".ima" and ".evm" keyrings only. Add a key to any other keyring and
verify that the key is not measured.

Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
---
 security/integrity/ima/ima_policy.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index d9400585fcda..78b25f083fe1 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -34,6 +34,7 @@
 #define IMA_EUID	0x0080
 #define IMA_PCR		0x0100
 #define IMA_FSNAME	0x0200
+#define IMA_KEYRINGS	0x0400
 
 #define UNKNOWN		0
 #define MEASURE		0x0001	/* same as IMA_MEASURE */
@@ -825,7 +826,8 @@ enum {
 	Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
 	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
 	Opt_appraise_type, Opt_appraise_flag,
-	Opt_permit_directio, Opt_pcr, Opt_template, Opt_err
+	Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings,
+	Opt_err
 };
 
 static const match_table_t policy_tokens = {
@@ -861,6 +863,7 @@ static const match_table_t policy_tokens = {
 	{Opt_permit_directio, "permit_directio"},
 	{Opt_pcr, "pcr=%s"},
 	{Opt_template, "template=%s"},
+	{Opt_keyrings, "keyrings=%s"},
 	{Opt_err, NULL}
 };
 
@@ -1110,6 +1113,23 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			result = 0;
 			entry->flags |= IMA_FSNAME;
 			break;
+		case Opt_keyrings:
+			ima_log_string(ab, "keyrings", args[0].from);
+
+			if ((entry->keyrings) ||
+			    (entry->action != MEASURE) ||
+			    (entry->func != KEY_CHECK)) {
+				result = -EINVAL;
+				break;
+			}
+			entry->keyrings = kstrdup(args[0].from, GFP_KERNEL);
+			if (!entry->keyrings) {
+				result = -ENOMEM;
+				break;
+			}
+			result = 0;
+			entry->flags |= IMA_KEYRINGS;
+			break;
 		case Opt_fsuuid:
 			ima_log_string(ab, "fsuuid", args[0].from);
 
@@ -1485,6 +1505,13 @@ int ima_policy_show(struct seq_file *m, void *v)
 		seq_puts(m, " ");
 	}
 
+	if (entry->flags & IMA_KEYRINGS) {
+		if (entry->keyrings != NULL)
+			snprintf(tbuf, sizeof(tbuf), "%s", entry->keyrings);
+		seq_printf(m, pt(Opt_keyrings), tbuf);
+		seq_puts(m, " ");
+	}
+
 	if (entry->flags & IMA_PCR) {
 		snprintf(tbuf, sizeof(tbuf), "%d", entry->pcr);
 		seq_printf(m, pt(Opt_pcr), tbuf);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-11-27  1:56 ` [PATCH v9 5/6] IMA: Add support to limit measuring keys Lakshmi Ramasubramanian
@ 2019-11-27 18:52   ` Mimi Zohar
  2019-11-28  0:44     ` Lakshmi Ramasubramanian
  2019-12-03 12:25   ` Mimi Zohar
  1 sibling, 1 reply; 21+ messages in thread
From: Mimi Zohar @ 2019-11-27 18:52 UTC (permalink / raw)
  To: Lakshmi Ramasubramanian, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -79,6 +79,7 @@ struct ima_rule_entry {
>  		int type;	/* audit type */
>  	} lsm[MAX_LSM_RULES];
>  	char *fsname;
> +	char *keyrings; /* Measure keys added to these keyrings */
>  	struct ima_template_desc *template;
>  };
>  
> @@ -356,6 +357,55 @@ int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
>  	return NOTIFY_OK;
>  }
>  
> +/**
> + * ima_match_keyring - determine whether the keyring matches the measure rule
> + * @rule: a pointer to a rule
> + * @keyring: name of the keyring to match against the measure rule
> + *
> + * If the measure action for KEY_CHECK does not specify keyrings=
> + * option then return true (Measure all keys).
> + * Else, return true if the given keyring name is present in
> + * the keyrings= option. False, otherwise.

This is suppose to be a comment, not code or pseudo code.  Please
refer to the section "Comments" in Documentation/process/coding-
style.rst.
 
> + */
> +static bool ima_match_keyring(struct ima_rule_entry *rule,
> +			      const char *keyring)
> +{
> +	const char *p;
> +
> +	/* If "keyrings=" is not specified all keys are measured. */
> +	if (!rule->keyrings)
> +		return true;
> +
> +	if (!keyring)
> +		return false;
> +
> +	/*
> +	 * "keyrings=" is specified in the policy in the format below:
> +	 *   keyrings=.builtin_trusted_keys|.ima|.evm
> +	 *
> +	 * Each keyring name in the option is separated by a '|' and
> +	 * the last keyring name is null terminated.
> +	 *
> +	 * The given keyring is considered matched only if
> +	 * the whole keyring name matched a keyring name specified
> +	 * in the "keyrings=" option.
> +	 */
> +	p = strstr(rule->keyrings, keyring);
> +	if (p) {
> +		/*
> +		 * Found a substring match. Check if the character
> +		 * at the end of the keyring name is | (keyring name
> +		 * separator) or is the terminating null character.
> +		 * If yes, we have a whole string match.
> +		 */
> +		p += strlen(keyring);
> +		if (*p == '|' || *p == '\0')
> +			return true;
> +	}
> +

Using "while strsep()" would simplify this code, removing the need for
such a long comment.

Mimi

> +	return false;
> +}
> +


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 6/6] IMA: Read keyrings= option from the IMA policy
  2019-11-27  1:56 ` [PATCH v9 6/6] IMA: Read keyrings= option from the IMA policy Lakshmi Ramasubramanian
@ 2019-11-27 19:32   ` Mimi Zohar
  2019-11-27 22:05     ` Lakshmi Ramasubramanian
  0 siblings, 1 reply; 21+ messages in thread
From: Mimi Zohar @ 2019-11-27 19:32 UTC (permalink / raw)
  To: Lakshmi Ramasubramanian, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

On Tue, 2019-11-26 at 17:56 -0800, Lakshmi Ramasubramanian wrote:
> Read "keyrings=" option, if specified in the IMA policy, and store in
> the list of IMA rules when the configured IMA policy is read.
> 
> This patch defines a new policy token enum namely Opt_keyrings
> and an option flag IMA_KEYRINGS for reading "keyrings=" option
> from the IMA policy.
> 
> Updated ima_parse_rule() to parse "keyrings=" option in the policy.
> Updated ima_policy_show() to display "keyrings=" option.
> 
> The following example illustrates how key measurement can be verified.

The example is really too colloquial/verbose.  Please truncate it,
leaving just a sample "key" policy rule, with directions for verifying
the template data against the digest included in the measurement list.

> 
> Sample IMA Policy entry to measure keys
> (Added in the file /etc/ima/ima-policy):

Remove the above.

Sample "key" measurement rule:

> measure func=KEY_CHECK keyrings=.ima|.evm template=ima-buf
> 
> Build the kernel with this patch set applied and reboot to that kernel.
> 
> Ensure the IMA policy is applied:
> 
> root@nramas:/home/nramas# cat /sys/kernel/security/ima/policy
> measure func=KEY_CHECK keyrings=.ima|.evm template=ima-buf
> 
> View the initial IMA measurement log:
> 
> root@nramas:/home/nramas
> # cat /sys/kernel/security/ima/ascii_runtime_measurements
> 10 67ec... ima-ng sha1:b5466c508583f0e633df83aa58fc7c5b67ccf667 boot_aggregate
> 
> Now, add a certificate (for example, x509_ima.der) to the .ima keyring
> using evmctl (IMA-EVM Utility)
> 
> root@nramas:/home/nramas# keyctl show %:.ima
> Keyring
>  547515640 ---lswrv      0     0  keyring: .ima
> 
> root@nramas:/home/nramas# evmctl import x509_ima.der 547515640
> 
> root@nramas:/home/nramas# keyctl show %:.ima
> Keyring
>  547515640 ---lswrv      0     0  keyring: .ima
>  809678766 --als--v      0     0   \_ asymmetric: hostname: whoami signing key: 052dd247dc3c36...
> 
> View the updated IMA measurement log:
> 
> root@nramas:/home/nramas#

Remove everything up to here and simply say something like:

Display "key" measurement in the IMA measurement list:

> # cat /sys/kernel/security/ima/ascii_runtime_measurements

> 10 3adf... ima-buf
> sha256:27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3
> b7b .ima 308202863082...4aee


> root@nramas:/home/nramas#

Remove this string from all the commands.
> 
> For this sample, SHA256 should be selected as the hash algorithm
> used by IMA.
> 
> The following command verifies if the SHA256 hash generated from
> the payload in the IMA log entry (listed above) for the .ima key
> matches the SHA256 hash in the IMA log entry. The output of this
> command should match the SHA256 hash given in the IMA log entry
> (In this case, it should be
> 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b)

Previously you didn't use the hash value, but ".ima" to locate the
"key" measurement in the measurement list.  In each of the commands
above, it might be clearer.

> 
> root@nramas:/home/nramas

ditto

> # cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements
> | grep
> 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b | 

> cut -d' ' -f 6 | xxd -r -p |tee ima-cert.der | sha256sum | cut -d' '
> -f 1
> 
> The above command also creates a binary file namely ima-cert.der
> using the payload in the IMA log entry. This file should be a valid
> x509 certificate which can be verified using openssl as given below:
> 
> root@nramas:/home/nramas

ditto


> # openssl x509 -in ima-cert.der -inform DER -text
> 
> The above command should display the contents of the file ima-cert.der
> as an x509 certificate.

Either the comments should be above or below the commands, not both.

> 
> The IMA policy used here allows measurement of keys added to
> ".ima" and ".evm" keyrings only. Add a key to any other keyring and
> verify that the key is not measured.

This comment would be included, if desired, when defining the policy
rule, not here.

Mimi


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 6/6] IMA: Read keyrings= option from the IMA policy
  2019-11-27 19:32   ` Mimi Zohar
@ 2019-11-27 22:05     ` Lakshmi Ramasubramanian
  0 siblings, 0 replies; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-27 22:05 UTC (permalink / raw)
  To: Mimi Zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

On 11/27/19 11:32 AM, Mimi Zohar wrote:

> 
> The example is really too colloquial/verbose.  Please truncate it,
> leaving just a sample "key" policy rule, with directions for verifying
> the template data against the digest included in the measurement list.

I'll truncate the example and keep it to the point.

>> The following command verifies if the SHA256 hash generated from
>> the payload in the IMA log entry (listed above) for the .ima key
>> matches the SHA256 hash in the IMA log entry. The output of this
>> command should match the SHA256 hash given in the IMA log entry
>> (In this case, it should be
>> 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b)
> 
> Previously you didn't use the hash value, but ".ima" to locate the
> "key" measurement in the measurement list.  In each of the commands
> above, it might be clearer.

If the IMA measurement list has only one IMA key then locating it with 
".ima" would work - hash won't be needed for locating the entry.

But for describing key verification we can have just one IMA key. I'll 
change the description to locate the entry using ".ima".

>> # cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements
>> | grep
>> 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b |
> 
>> cut -d' ' -f 6 | xxd -r -p |tee ima-cert.der | sha256sum | cut -d' '
>> -f 1
>>
>> The above command also creates a binary file namely ima-cert.der
>> using the payload in the IMA log entry. This file should be a valid
>> x509 certificate which can be verified using openssl as given below:
>>
>> root@nramas:/home/nramas
> 
> ditto
> 
> 
>> # openssl x509 -in ima-cert.der -inform DER -text
>>
>> The above command should display the contents of the file ima-cert.der
>> as an x509 certificate.
> 
> Either the comments should be above or below the commands, not both.

I'll update the comment.

> 
>>
>> The IMA policy used here allows measurement of keys added to
>> ".ima" and ".evm" keyrings only. Add a key to any other keyring and
>> verify that the key is not measured.
> 
> This comment would be included, if desired, when defining the policy
> rule, not here.

Will remove the above from this patch description.

thanks,
  -lakshmi



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-11-27 18:52   ` Mimi Zohar
@ 2019-11-28  0:44     ` Lakshmi Ramasubramanian
  2019-12-02 18:18       ` Mimi Zohar
  0 siblings, 1 reply; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-11-28  0:44 UTC (permalink / raw)
  To: Mimi Zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

On 11/27/19 10:52 AM, Mimi Zohar wrote:

Hi Mimi,

>> +static bool ima_match_keyring(struct ima_rule_entry *rule,
>> +			      const char *keyring)
>> +{
>> +	/*
>> +	 * "keyrings=" is specified in the policy in the format below:
>> +	 *   keyrings=.builtin_trusted_keys|.ima|.evm
>> +	 *
>> +	 * Each keyring name in the option is separated by a '|' and
>> +	 * the last keyring name is null terminated.
>> +	 *
>> +	 * The given keyring is considered matched only if
>> +	 * the whole keyring name matched a keyring name specified
>> +	 * in the "keyrings=" option.
>> +	 */
>> +	p = strstr(rule->keyrings, keyring);
>> +	if (p) {
>> +		/*
>> +		 * Found a substring match. Check if the character
>> +		 * at the end of the keyring name is | (keyring name
>> +		 * separator) or is the terminating null character.
>> +		 * If yes, we have a whole string match.
>> +		 */
>> +		p += strlen(keyring);
>> +		if (*p == '|' || *p == '\0')
>> +			return true;
>> +	}
>> +
> 
> Using "while strsep()" would simplify this code, removing the need for
> such a long comment.
> 
> Mimi

strsep() modifies the source string (replaces the delimiter with '\0' 
and also updates the source string pointer). I am not sure it can be 
used for our scenario. Please correct me if I am wrong.

Initial IMA policy:
-------------------
measure func=KEY_CHECK 
keyrings=.ima|.evm|.builtin_trusted_keys|.blacklist template=ima-buf

Policy after adding a key to .ima keyring:
------------------------------------------
measure func=KEY_CHECK keyrings=.evm|.builtin_trusted_keys|.blacklist 
template=ima-buf

Policy after adding a key to a keyring that is not listed in the policy:
------------------------------------------------------------------------
measure func=KEY_CHECK keyrings= template=ima-buf

********************************************************************************

Please see the description from the man page for strsep():

http://man7.org/linux/man-pages/man3/strsep.3.html

char *strsep(char **stringp, const char *delim);

This function finds the first token in the string *stringp, that is 
delimited by one of the bytes in the string delim.  This token is 
terminated by overwriting the delimiter with a null byte ('\0'), and 
*stringp is updated to point past the token.

thanks,
  -lakshmi

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-11-28  0:44     ` Lakshmi Ramasubramanian
@ 2019-12-02 18:18       ` Mimi Zohar
  0 siblings, 0 replies; 21+ messages in thread
From: Mimi Zohar @ 2019-12-02 18:18 UTC (permalink / raw)
  To: Lakshmi Ramasubramanian, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

On Wed, 2019-11-27 at 16:44 -0800, Lakshmi Ramasubramanian wrote:
> On 11/27/19 10:52 AM, Mimi Zohar wrote:
> 
> Hi Mimi,
> 
> >> +static bool ima_match_keyring(struct ima_rule_entry *rule,
> >> +			      const char *keyring)
> >> +{
> >> +	/*
> >> +	 * "keyrings=" is specified in the policy in the format below:
> >> +	 *   keyrings=.builtin_trusted_keys|.ima|.evm
> >> +	 *
> >> +	 * Each keyring name in the option is separated by a '|' and
> >> +	 * the last keyring name is null terminated.
> >> +	 *
> >> +	 * The given keyring is considered matched only if
> >> +	 * the whole keyring name matched a keyring name specified
> >> +	 * in the "keyrings=" option.
> >> +	 */
> >> +	p = strstr(rule->keyrings, keyring);
> >> +	if (p) {
> >> +		/*
> >> +		 * Found a substring match. Check if the character
> >> +		 * at the end of the keyring name is | (keyring name
> >> +		 * separator) or is the terminating null character.
> >> +		 * If yes, we have a whole string match.
> >> +		 */
> >> +		p += strlen(keyring);
> >> +		if (*p == '|' || *p == '\0')
> >> +			return true;

This code checks that the keyring name isn't suffixed, but not
prefixed.

> >> +	}
> >> +
> > 
> > Using "while strsep()" would simplify this code, removing the need for
> > such a long comment.
> > 
> > Mimi
> 
> strsep() modifies the source string (replaces the delimiter with '\0' 
> and also updates the source string pointer). I am not sure it can be 
> used for our scenario. Please correct me if I am wrong.
> 
> Initial IMA policy:
> -------------------
> measure func=KEY_CHECK 
> keyrings=.ima|.evm|.builtin_trusted_keys|.blacklist template=ima-buf
> 
> Policy after adding a key to .ima keyring:
> ------------------------------------------
> measure func=KEY_CHECK keyrings=.evm|.builtin_trusted_keys|.blacklist 
> template=ima-buf
> 
> Policy after adding a key to a keyring that is not listed in the policy:
> ------------------------------------------------------------------------
> measure func=KEY_CHECK keyrings= template=ima-buf
> 
> ********************************************************************************
> 
> Please see the description from the man page for strsep():
> 
> http://man7.org/linux/man-pages/man3/strsep.3.html
> 
> char *strsep(char **stringp, const char *delim);
> 
> This function finds the first token in the string *stringp, that is 
> delimited by one of the bytes in the string delim.  This token is 
> terminated by overwriting the delimiter with a null byte ('\0'), and 
> *stringp is updated to point past the token.

Yes, you would have to make a copy of the string before using
strsep().  You could always use kstrdup(), remembering to free it, or
allocate the memory just once, and then just use memcpy.

Mimi


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-11-27  1:56 ` [PATCH v9 5/6] IMA: Add support to limit measuring keys Lakshmi Ramasubramanian
  2019-11-27 18:52   ` Mimi Zohar
@ 2019-12-03 12:25   ` Mimi Zohar
  2019-12-03 16:13     ` Lakshmi Ramasubramanian
  2019-12-03 19:45     ` Lakshmi Ramasubramanian
  1 sibling, 2 replies; 21+ messages in thread
From: Mimi Zohar @ 2019-12-03 12:25 UTC (permalink / raw)
  To: Lakshmi Ramasubramanian, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

Hi Lakshmi,

On Tue, 2019-11-26 at 17:56 -0800, Lakshmi Ramasubramanian wrote:
> Limit measuring keys to those keys being loaded onto a given set of
> keyrings only.
> 
> This patch defines a new IMA policy option namely "keyrings=" that
> can be used to specify a set of keyrings. If this option is specified
> in the policy for "measure func=KEY_CHECK" then only the keys
> loaded onto a keyring given in the "keyrings=" option are measured.
> 
> Added a new parameter namely "keyring" (name of the keyring) to
> process_buffer_measurement(). The keyring name is passed to
> ima_get_action() to determine the required action.
> ima_match_rules() is updated to check keyring in the policy, if
> specified, for KEY_CHECK function.
> 
> Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>

A keyring can be created by any user with any keyring name, other than
 ones dot prefixed, which are limited to the trusted builtin keyrings.
 With a policy of "func=KEY_CHECK template=ima-buf keyrings=foo", for
example, keys loaded onto any keyring named "foo" will be measured.
 For files, the IMA policy may be constrained to a particular uid/gid.
 An additional method of identifying or constraining keyring names
needs to be defined.

Mimi 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-12-03 12:25   ` Mimi Zohar
@ 2019-12-03 16:13     ` Lakshmi Ramasubramanian
  2019-12-03 16:47       ` Mimi Zohar
  2019-12-03 19:45     ` Lakshmi Ramasubramanian
  1 sibling, 1 reply; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-12-03 16:13 UTC (permalink / raw)
  To: Mimi Zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

On 12/3/2019 4:25 AM, Mimi Zohar wrote:

Hi Mimi,

> Hi Lakshmi,
> 
> A keyring can be created by any user with any keyring name, other than
>   ones dot prefixed, which are limited to the trusted builtin keyrings.
>   With a policy of "func=KEY_CHECK template=ima-buf keyrings=foo", for
> example, keys loaded onto any keyring named "foo" will be measured.
>   For files, the IMA policy may be constrained to a particular uid/gid.
>   An additional method of identifying or constraining keyring names
> needs to be defined.
> 

I agree - this is a good idea.

Do you think this can be added as a separate patch set - enhancement to 
the current one, or should this be addressed in the current set?

I was just about to send an update today that addresses your latest 
comments. Will hold it if you think the above change should be included 
now. Please let me know.

thanks,
  -lakshmi

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-12-03 16:13     ` Lakshmi Ramasubramanian
@ 2019-12-03 16:47       ` Mimi Zohar
  0 siblings, 0 replies; 21+ messages in thread
From: Mimi Zohar @ 2019-12-03 16:47 UTC (permalink / raw)
  To: Lakshmi Ramasubramanian, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

On Tue, 2019-12-03 at 08:13 -0800, Lakshmi Ramasubramanian wrote:
> On 12/3/2019 4:25 AM, Mimi Zohar wrote:
> 
> Hi Mimi,
> 
> > Hi Lakshmi,
> > 
> > A keyring can be created by any user with any keyring name, other than
> >   ones dot prefixed, which are limited to the trusted builtin keyrings.
> >   With a policy of "func=KEY_CHECK template=ima-buf keyrings=foo", for
> > example, keys loaded onto any keyring named "foo" will be measured.
> >   For files, the IMA policy may be constrained to a particular uid/gid.
> >   An additional method of identifying or constraining keyring names
> > needs to be defined.
> > 
> 
> I agree - this is a good idea.
> 
> Do you think this can be added as a separate patch set - enhancement to 
> the current one, or should this be addressed in the current set?
> 
> I was just about to send an update today that addresses your latest 
> comments. Will hold it if you think the above change should be included 
> now. Please let me know.

I'm hoping that it won't be all that difficult to implement and could
be included in this patch set as an additional patch.

Mimi


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-12-03 12:25   ` Mimi Zohar
  2019-12-03 16:13     ` Lakshmi Ramasubramanian
@ 2019-12-03 19:45     ` Lakshmi Ramasubramanian
  2019-12-03 20:06       ` Mimi Zohar
  1 sibling, 1 reply; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-12-03 19:45 UTC (permalink / raw)
  To: Mimi Zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

Hi Mimi,

On 12/3/2019 4:25 AM, Mimi Zohar wrote:

> 
> A keyring can be created by any user with any keyring name, other than
>   ones dot prefixed, which are limited to the trusted builtin keyrings.
>   With a policy of "func=KEY_CHECK template=ima-buf keyrings=foo", for
> example, keys loaded onto any keyring named "foo" will be measured.
>   For files, the IMA policy may be constrained to a particular uid/gid.
>   An additional method of identifying or constraining keyring names
> needs to be defined.
> 
> Mimi
> 

Are you expecting a functionality like the following?

  => Measure keys added to keyring "foo", but exclude certain keys 
(based on some key identifier)

Sample policy might look like below:

action=MEASURE func=KEY_CHECK keyrings=foo|bar
action=DONT_MEASURE key_magic=blah

So a key with key_magic "blah" will not be measured even though it is 
added to the keyring "foo". But any other key added to "foo" will be 
measured.

What would the constraining field in the key may be - Can it be SHA256 
hash of the public key? Or, some other unique identifier?

Could you please clarify?

thanks,
  -lakshmi

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-12-03 19:45     ` Lakshmi Ramasubramanian
@ 2019-12-03 20:06       ` Mimi Zohar
  2019-12-03 23:37         ` Lakshmi Ramasubramanian
  0 siblings, 1 reply; 21+ messages in thread
From: Mimi Zohar @ 2019-12-03 20:06 UTC (permalink / raw)
  To: Lakshmi Ramasubramanian, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

On Tue, 2019-12-03 at 11:45 -0800, Lakshmi Ramasubramanian wrote:
> Hi Mimi,
> 
> On 12/3/2019 4:25 AM, Mimi Zohar wrote:
> 
> > 
> > A keyring can be created by any user with any keyring name, other than
> >   ones dot prefixed, which are limited to the trusted builtin keyrings.
> >   With a policy of "func=KEY_CHECK template=ima-buf keyrings=foo", for
> > example, keys loaded onto any keyring named "foo" will be measured.
> >   For files, the IMA policy may be constrained to a particular uid/gid.
> >   An additional method of identifying or constraining keyring names
> > needs to be defined.
> > 
> > Mimi
> > 
> 
> Are you expecting a functionality like the following?
> 
>   => Measure keys added to keyring "foo", but exclude certain keys 
> (based on some key identifier)
> 
> Sample policy might look like below:
> 
> action=MEASURE func=KEY_CHECK keyrings=foo|bar
> action=DONT_MEASURE key_magic=blah
> 
> So a key with key_magic "blah" will not be measured even though it is 
> added to the keyring "foo". But any other key added to "foo" will be 
> measured.
> 
> What would the constraining field in the key may be - Can it be SHA256 
> hash of the public key? Or, some other unique identifier?
> 
> Could you please clarify?

Suppose both root and uid 1000 define a keyring named "foo".  The
current "keyrings=foo" will measure all keys added to either keyring
named "foo".  There needs to be a way to limit measuring keys to a
particular keyring named "foo".

Mimi


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-12-03 20:06       ` Mimi Zohar
@ 2019-12-03 23:37         ` Lakshmi Ramasubramanian
  2019-12-04 11:16           ` Mimi Zohar
  0 siblings, 1 reply; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-12-03 23:37 UTC (permalink / raw)
  To: Mimi Zohar, linux-integrity
  Cc: eric.snowberg, dhowells, matthewgarrett, sashal, jamorris,
	linux-kernel, keyrings

On 12/3/2019 12:06 PM, Mimi Zohar wrote:

> Suppose both root and uid 1000 define a keyring named "foo".  The
> current "keyrings=foo" will measure all keys added to either keyring
> named "foo".  There needs to be a way to limit measuring keys to a
> particular keyring named "foo".
> 
> Mimi

Thanks for clarifying.

Suppose two different non-root users create keyring with the same name 
"foo" and, say, both are measured, how would we know which keyring 
measurement belongs to which user?

Wouldn't it be sufficient to include only keyrings created by "root" 
(UID value 0) in the key measurement? This will include all the builtin 
trusted keyrings (such as .builtin_trusted_keys, 
.secondary_trusted_keys, .ima, .evm, etc.).

What would be the use case for including keyrings created by non-root 
users in key measurement?

Also, since the UID for non-root users can be any integer value (greater 
than 0), can an an administrator craft a generic IMA policy that would 
be applicable to all clients in an enterprise?

thanks,
  -lakshmi



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-12-03 23:37         ` Lakshmi Ramasubramanian
@ 2019-12-04 11:16           ` Mimi Zohar
  2019-12-04 22:43             ` Lakshmi Ramasubramanian
  2019-12-04 23:25             ` Mat Martineau
  0 siblings, 2 replies; 21+ messages in thread
From: Mimi Zohar @ 2019-12-04 11:16 UTC (permalink / raw)
  To: Lakshmi Ramasubramanian, linux-integrity
  Cc: Mat Martineau, eric.snowberg, dhowells, matthewgarrett, sashal,
	jamorris, linux-kernel, keyrings, Mat Martineau

[Cc'ing Mat Martineau]

On Tue, 2019-12-03 at 15:37 -0800, Lakshmi Ramasubramanian wrote:
> On 12/3/2019 12:06 PM, Mimi Zohar wrote:
> 
> > Suppose both root and uid 1000 define a keyring named "foo".  The
> > current "keyrings=foo" will measure all keys added to either keyring
> > named "foo".  There needs to be a way to limit measuring keys to a
> > particular keyring named "foo".
> > 
> > Mimi
> 
> Thanks for clarifying.
> 
> Suppose two different non-root users create keyring with the same name 
> "foo" and, say, both are measured, how would we know which keyring 
> measurement belongs to which user?
> 
> Wouldn't it be sufficient to include only keyrings created by "root" 
> (UID value 0) in the key measurement? This will include all the builtin 
> trusted keyrings (such as .builtin_trusted_keys, 
> .secondary_trusted_keys, .ima, .evm, etc.).
> 
> What would be the use case for including keyrings created by non-root 
> users in key measurement?
> 
> Also, since the UID for non-root users can be any integer value (greater 
> than 0), can an an administrator craft a generic IMA policy that would 
> be applicable to all clients in an enterprise?

The integrity subsystem, and other concepts upstreamed to support it,
are being used by different people/companies in different ways.  I
know some of the ways, but not all, as how it is being used.  For
example, Mat Martineau gave an LSS2019-NA talk titled "Using and
Implementing Keyring Restrictions for Userspace".  I don't know if he
would be interested in measuring keys on these restricted userspace
keyrings, but before we limit how a new feature works, we should at
least look to see if that limitation is really necessary.

Mimi


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-12-04 11:16           ` Mimi Zohar
@ 2019-12-04 22:43             ` Lakshmi Ramasubramanian
  2019-12-04 23:25             ` Mat Martineau
  1 sibling, 0 replies; 21+ messages in thread
From: Lakshmi Ramasubramanian @ 2019-12-04 22:43 UTC (permalink / raw)
  To: Mimi Zohar, linux-integrity
  Cc: Mat Martineau, eric.snowberg, dhowells, matthewgarrett, sashal,
	jamorris, linux-kernel, keyrings

On 12/4/19 3:16 AM, Mimi Zohar wrote:

Hi Mimi,

> 
> The integrity subsystem, and other concepts upstreamed to support it,
> are being used by different people/companies in different ways.  I
> know some of the ways, but not all, as how it is being used.  For
> example, Mat Martineau gave an LSS2019-NA talk titled "Using and
> Implementing Keyring Restrictions for Userspace".  I don't know if he
> would be interested in measuring keys on these restricted userspace
> keyrings, but before we limit how a new feature works, we should at
> least look to see if that limitation is really necessary.
> 
> Mimi

I have updated the patch per your suggestion - if uid is specified in 
the policy for key measurement, then it is checked against the current 
user's credential.

Please review the updated patch set (v10).

thanks,
  -lakshmi



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v9 5/6] IMA: Add support to limit measuring keys
  2019-12-04 11:16           ` Mimi Zohar
  2019-12-04 22:43             ` Lakshmi Ramasubramanian
@ 2019-12-04 23:25             ` Mat Martineau
  1 sibling, 0 replies; 21+ messages in thread
From: Mat Martineau @ 2019-12-04 23:25 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: Lakshmi Ramasubramanian, linux-integrity, eric.snowberg,
	dhowells, matthewgarrett, sashal, jamorris, linux-kernel,
	keyrings

[-- Attachment #1: Type: text/plain, Size: 2605 bytes --]


On Wed, 4 Dec 2019, Mimi Zohar wrote:

> [Cc'ing Mat Martineau]
>
> On Tue, 2019-12-03 at 15:37 -0800, Lakshmi Ramasubramanian wrote:
>> On 12/3/2019 12:06 PM, Mimi Zohar wrote:
>>
>>> Suppose both root and uid 1000 define a keyring named "foo".  The
>>> current "keyrings=foo" will measure all keys added to either keyring
>>> named "foo".  There needs to be a way to limit measuring keys to a
>>> particular keyring named "foo".
>>>
>>> Mimi
>>
>> Thanks for clarifying.
>>
>> Suppose two different non-root users create keyring with the same name
>> "foo" and, say, both are measured, how would we know which keyring
>> measurement belongs to which user?
>>
>> Wouldn't it be sufficient to include only keyrings created by "root"
>> (UID value 0) in the key measurement? This will include all the builtin
>> trusted keyrings (such as .builtin_trusted_keys,
>> .secondary_trusted_keys, .ima, .evm, etc.).
>>
>> What would be the use case for including keyrings created by non-root
>> users in key measurement?
>>
>> Also, since the UID for non-root users can be any integer value (greater
>> than 0), can an an administrator craft a generic IMA policy that would
>> be applicable to all clients in an enterprise?
>
> The integrity subsystem, and other concepts upstreamed to support it,
> are being used by different people/companies in different ways.  I
> know some of the ways, but not all, as how it is being used.  For
> example, Mat Martineau gave an LSS2019-NA talk titled "Using and
> Implementing Keyring Restrictions for Userspace".  I don't know if he
> would be interested in measuring keys on these restricted userspace
> keyrings, but before we limit how a new feature works, we should at
> least look to see if that limitation is really necessary.

The use cases I'm most familiar with could have a use for key measurement 
for something like enterprise Wi-Fi root certificates. I'm not sure of the 
best way to uniquely identify a key to measure in that scenario, it could 
be anchored in various ways (process, session, thread, or user keyrings, 
for example) and may be owned by a non-root user. As Lakshmi noted above, 
key names are not unique, and I'll add that namespace considerations may 
come in to play too.

Keys (including keyrings like .builtin_trusted_keys, .ima, etc) can be 
linked to multiple keyrings, maybe you could create a system-level 
.ima_measured keyring. You could measure keys that are accessible from 
that keyring, and opt in more keys for measurement by linking them to 
.ima_measured or a keyring nested within .ima_measured.

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, back to index

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-27  1:56 [PATCH v9 0/6] KEYS: Measure keys when they are created or updated Lakshmi Ramasubramanian
2019-11-27  1:56 ` [PATCH v9 1/6] IMA: Check IMA policy flag Lakshmi Ramasubramanian
2019-11-27  1:56 ` [PATCH v9 2/6] IMA: Add KEY_CHECK func to measure keys Lakshmi Ramasubramanian
2019-11-27  1:56 ` [PATCH v9 3/6] IMA: Define an IMA hook " Lakshmi Ramasubramanian
2019-11-27  1:56 ` [PATCH v9 4/6] KEYS: Call the " Lakshmi Ramasubramanian
2019-11-27  1:56 ` [PATCH v9 5/6] IMA: Add support to limit measuring keys Lakshmi Ramasubramanian
2019-11-27 18:52   ` Mimi Zohar
2019-11-28  0:44     ` Lakshmi Ramasubramanian
2019-12-02 18:18       ` Mimi Zohar
2019-12-03 12:25   ` Mimi Zohar
2019-12-03 16:13     ` Lakshmi Ramasubramanian
2019-12-03 16:47       ` Mimi Zohar
2019-12-03 19:45     ` Lakshmi Ramasubramanian
2019-12-03 20:06       ` Mimi Zohar
2019-12-03 23:37         ` Lakshmi Ramasubramanian
2019-12-04 11:16           ` Mimi Zohar
2019-12-04 22:43             ` Lakshmi Ramasubramanian
2019-12-04 23:25             ` Mat Martineau
2019-11-27  1:56 ` [PATCH v9 6/6] IMA: Read keyrings= option from the IMA policy Lakshmi Ramasubramanian
2019-11-27 19:32   ` Mimi Zohar
2019-11-27 22:05     ` Lakshmi Ramasubramanian

Linux-Integrity Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-integrity/0 linux-integrity/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-integrity linux-integrity/ https://lore.kernel.org/linux-integrity \
		linux-integrity@vger.kernel.org
	public-inbox-index linux-integrity

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-integrity


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git