linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Roberto Sassu <roberto.sassu@huawei.com>
To: <linux-integrity@vger.kernel.org>
Cc: <linux-security-module@vger.kernel.org>,
	<linux-fsdevel@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <silviu.vlasceanu@huawei.com>,
	Roberto Sassu <roberto.sassu@huawei.com>
Subject: [PATCH v2 10/15] ima: disable digest lookup if digest lists are not checked
Date: Tue, 7 Nov 2017 11:37:05 +0100	[thread overview]
Message-ID: <20171107103710.10883-11-roberto.sassu@huawei.com> (raw)
In-Reply-To: <20171107103710.10883-1-roberto.sassu@huawei.com>

This patch introduces two new hooks DIGEST_LIST_METADATA_CHECK and
DIGEST_LIST_CHECK, which are called respectively when parsing digest list
metadata and digest lists.

It also checks that rules for these two hooks are always specified in the
current policy. Without them, digest lists could be uploaded to IMA without
adding a new entry to the measurement list, without verifying the
signature, or without auditing the operation. Digest lookup is disabled for
each missing policy action (measure, appraise, audit).

Digest lookup is also disabled if CONFIG_IMA_DIGEST_LIST is not defined.

Changelog

v1:
- clear IMA_MEASURE action flag only if it was in the policy
- check if at least one action is allowed before searching the file digest
- retrieve ima_digest structure
- set IMA action flags in ima_disable_digest_lookup
- added DIGEST_LIST_METADATA_CHECK hook
- update MEASURE/APPRAISE policies

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima.h        |  2 ++
 security/integrity/ima/ima_main.c   | 38 +++++++++++++++++++++++++++++++++++--
 security/integrity/ima/ima_policy.c | 16 ++++++++++++++++
 3 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 1f43284788eb..4b3b1ca5c09a 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -204,6 +204,8 @@ static inline unsigned long ima_hash_key(u8 *digest)
 	hook(KEXEC_KERNEL_CHECK)	\
 	hook(KEXEC_INITRAMFS_CHECK)	\
 	hook(POLICY_CHECK)		\
+	hook(DIGEST_LIST_METADATA_CHECK)		\
+	hook(DIGEST_LIST_CHECK)		\
 	hook(MAX_CHECK)
 #define __ima_hook_enumify(ENUM)	ENUM,
 
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 766fe2e77419..840362734f91 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -29,6 +29,12 @@
 
 int ima_initialized;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
+static int ima_disable_digest_lookup;
+#else
+static int ima_disable_digest_lookup = IMA_DO_MASK & ~IMA_APPRAISE_SUBMASK;
+#endif
+
 #ifdef CONFIG_IMA_APPRAISE
 int ima_appraise = IMA_APPRAISE_ENFORCE;
 #else
@@ -168,12 +174,20 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
 	char *pathbuf = NULL;
 	char filename[NAME_MAX];
 	const char *pathname = NULL;
-	int rc = -ENOMEM, action, must_appraise;
+	int rc = -ENOMEM, action, action_done, must_appraise, digest_lookup;
 	int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+	struct ima_digest *found_digest = NULL;
 	struct evm_ima_xattr_data *xattr_value = NULL;
 	int xattr_len = 0;
 	bool violation_check;
 	enum hash_algo hash_algo;
+	int disable_mask = (func == DIGEST_LIST_CHECK) ?
+			   IMA_DO_MASK & ~IMA_APPRAISE_SUBMASK :
+			   IMA_DO_MASK & ~(IMA_APPRAISE | IMA_APPRAISE_SUBMASK);
+
+	if ((func == DIGEST_LIST_METADATA_CHECK || func == DIGEST_LIST_CHECK) &&
+	    !ima_policy_flag)
+		ima_disable_digest_lookup = disable_mask;
 
 	if (!ima_policy_flag || !S_ISREG(inode->i_mode))
 		return 0;
@@ -185,6 +199,9 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
 	action = ima_get_action(inode, mask, func, &pcr);
 	violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
 			   (ima_policy_flag & IMA_MEASURE));
+	if (func == DIGEST_LIST_METADATA_CHECK || func == DIGEST_LIST_CHECK)
+		ima_disable_digest_lookup |= (~action & disable_mask);
+
 	if (!action && !violation_check)
 		return 0;
 
@@ -242,6 +259,21 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
 	if (rc != 0 && rc != -EBADF && rc != -EINVAL)
 		goto out_digsig;
 
+	digest_lookup = action & ~ima_disable_digest_lookup;
+	if (digest_lookup) {
+		found_digest = ima_lookup_loaded_digest(iint->ima_hash->digest);
+		if (found_digest) {
+			action_done = digest_lookup & (IMA_MEASURE | IMA_AUDIT);
+			action &= ~action_done;
+			iint->flags |= (action_done << 1);
+
+			if (!(digest_lookup & IMA_APPRAISE))
+				found_digest = NULL;
+			if (digest_lookup & IMA_MEASURE)
+				iint->measured_pcrs |= (0x1 << pcr);
+		}
+	}
+
 	if (!pathbuf)	/* ima_rdwr_violation possibly pre-fetched */
 		pathname = ima_d_path(&file->f_path, &pathbuf, filename);
 
@@ -378,7 +410,9 @@ static int read_idmap[READING_MAX_ID] = {
 	[READING_MODULE] = MODULE_CHECK,
 	[READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
 	[READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
-	[READING_POLICY] = POLICY_CHECK
+	[READING_POLICY] = POLICY_CHECK,
+	[READING_DIGEST_LIST_METADATA] = DIGEST_LIST_METADATA_CHECK,
+	[READING_DIGEST_LIST] = DIGEST_LIST_CHECK
 };
 
 /**
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index ee4613fa5840..2767f7901f94 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -127,9 +127,20 @@ static struct ima_rule_entry default_measurement_rules[] __ro_after_init = {
 	{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC},
+#ifdef CONFIG_IMA_DIGEST_LIST
+	{.action = MEASURE, .func = DIGEST_LIST_METADATA_CHECK,
+	 .flags = IMA_FUNC},
+	{.action = MEASURE, .func = DIGEST_LIST_CHECK, .flags = IMA_FUNC},
+#endif
 };
 
 static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
+#ifdef CONFIG_IMA_DIGEST_LIST
+	{.action = APPRAISE, .func = DIGEST_LIST_METADATA_CHECK,
+	 .flags = IMA_FUNC},
+	{.action = APPRAISE, .func = DIGEST_LIST_CHECK,
+	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
+#endif
 	{.action = DONT_APPRAISE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_APPRAISE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_APPRAISE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC},
@@ -699,6 +710,11 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 				entry->func = KEXEC_INITRAMFS_CHECK;
 			else if (strcmp(args[0].from, "POLICY_CHECK") == 0)
 				entry->func = POLICY_CHECK;
+			else if (strcmp(args[0].from, "DIGEST_LIST_CHECK") == 0)
+				entry->func = DIGEST_LIST_CHECK;
+			else if (strcmp(args[0].from,
+				 "DIGEST_LIST_METADATA_CHECK") == 0)
+				entry->func = DIGEST_LIST_METADATA_CHECK;
 			else
 				result = -EINVAL;
 			if (!result)
-- 
2.11.0

  parent reply	other threads:[~2017-11-07 10:44 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-07 10:36 [PATCH v2 00/15] ima: digest list feature Roberto Sassu
2017-11-07 10:36 ` [PATCH v2 01/15] ima: generalize ima_read_policy() Roberto Sassu
2017-11-07 10:36 ` [PATCH v2 02/15] ima: generalize ima_write_policy() Roberto Sassu
2017-11-07 10:36 ` [PATCH v2 03/15] ima: generalize policy file operations Roberto Sassu
2017-11-07 10:36 ` [PATCH v2 04/15] ima: use ima_show_htable_value to show hash table data Roberto Sassu
2017-11-07 10:37 ` [PATCH v2 05/15] ima: add functions to manage digest lists Roberto Sassu
2017-11-07 10:37 ` [PATCH v2 06/15] ima: add parser of digest lists metadata Roberto Sassu
2017-11-18  4:20   ` Serge E. Hallyn
2017-11-18 23:23     ` Mimi Zohar
2017-11-20  9:40       ` Roberto Sassu
2017-11-20 13:53         ` Mimi Zohar
2017-11-20 16:52           ` Serge E. Hallyn
2017-11-07 10:37 ` [PATCH v2 07/15] ima: add parser of compact digest list Roberto Sassu
2017-11-07 10:37 ` [PATCH v2 08/15] ima: add parser of RPM package headers Roberto Sassu
2017-11-07 10:37 ` [PATCH v2 09/15] ima: introduce securityfs interfaces for digest lists Roberto Sassu
2017-11-07 10:37 ` Roberto Sassu [this message]
2017-11-07 10:37 ` [PATCH v2 11/15] ima: add policy action digest_list Roberto Sassu
2017-11-07 10:37 ` [PATCH v2 12/15] ima: do not update security.ima if appraisal status is not INTEGRITY_PASS Roberto Sassu
2017-11-18  4:25   ` Serge E. Hallyn
2017-11-07 10:37 ` [PATCH v2 13/15] evm: add kernel command line option to select protected xattrs Roberto Sassu
2017-11-07 10:37 ` [PATCH v2 14/15] ima: add support for appraisal with digest lists Roberto Sassu
2017-11-07 10:37 ` [PATCH v2 15/15] ima: add Documentation/security/IMA-digest-lists.txt Roberto Sassu
2017-11-07 13:37 ` [PATCH v2 00/15] ima: digest list feature Mimi Zohar
2017-11-07 16:45   ` Roberto Sassu
2017-11-17  1:08     ` Kees Cook
2017-11-17  8:55       ` Roberto Sassu
2017-11-17 12:21         ` Mimi Zohar
2017-11-07 14:49 ` Matthew Garrett
2017-11-07 17:53   ` Roberto Sassu
2017-11-07 18:06     ` Matthew Garrett
2017-11-08 12:00       ` Roberto Sassu
2017-11-08 15:48         ` Matthew Garrett
2017-11-09  9:51           ` Roberto Sassu
2017-11-09 14:47             ` Matthew Garrett
2017-11-09 16:13               ` Roberto Sassu
2017-11-09 16:46                 ` Matthew Garrett
2017-11-09 17:23                   ` Roberto Sassu
2017-11-09 16:17               ` Mimi Zohar
2017-11-07 18:03 ` Safford, David (GE Global Research, US)
2017-11-08 10:16   ` Roberto Sassu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171107103710.10883-11-roberto.sassu@huawei.com \
    --to=roberto.sassu@huawei.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=silviu.vlasceanu@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).