linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/12] ima: measure digest lists instead of individual files
@ 2017-07-25 15:44 Roberto Sassu
  2017-07-25 15:44 ` [PATCH 01/12] ima: generalize ima_read_policy() Roberto Sassu
                   ` (12 more replies)
  0 siblings, 13 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch set applies on top of kernel v4.13-rc2.

IMA, for each file matching policy rules, calculates a digest, creates
a new entry in the measurement list and extends a TPM PCR with the digest
of entry data. The last step causes a noticeable performance reduction.

Since systems likely access the same files, repeating the above tasks at
every boot can be avoided by replacing individual measurements of likely
accessed files with only one measurement of their digests: the advantage
is that the system performance significantly improves due to less PCR
extend operations; on the other hand, the information about which files
have exactly been accessed and in which sequence is lost.

If this new measurement reports only good digests (e.g. those of
files included in a Linux distribution), and if verifiers only check
that a system executed good software and didn't access malicious data,
the disadvantages reported earlier would be acceptable.

The Trusted Computing paradigm measure & load is still respected by IMA
with the proposed optimization. If a file being accessed is not in a
measured digest list, a measurement will be recorded as before. If it is,
the list has already been measured, and the verifier must assume that
files with digest in the list have been accessed.

Measuring digest lists gives the following benefits:

- boot time reduction
  For a minimal Linux installation with 1400 measurements, the boot time
  decreases from 1 minute 30 seconds to 15 seconds, after loading to IMA
  the digest of all files packaged by the distribution (32000). The new
  list contains 92 entries. Without IMA, the boot time is 8.5 seconds.

- lower network and CPU requirements for remote attestation
  With the IMA optimization, both the measurement and digest lists
  must be verified for a complete evaluation. However, since the lists
  are fixed, they could be sent to and checked by the verifier only once.
  Then, during a remote attestation, the only remaining task is to verify
  the short measurement list.

- signature-based remote attestation
  Digest list signature can be used as a proof of the provenance for the
  files whose digest is in the list. Then, if verifiers trust the signer
  and only check provenance, remote attestation verification would simply
  consist on checking digest lists signatures and that the measurement
  list only contain list metadata digests (reference measurement databases
  would be no longer required). An example of a signed digest list,
  that can be parsed with this patch set, is the RPM package header.

Digest lists are loaded in two stages by IMA through the new securityfs
interface called 'digest_lists'. Users supply metadata, for the digest
lists they want to load: path, format, digest, signature and algorithm
of the digest.

Then, after the metadata digest is added to the measurement list, IMA
reads the digest lists at the path specified and loads the digests in
a hash table (digest lists are not measured, since their digest is already
included in the metadata). With metadata measurement instead of digest list
measurement, it is possible to avoid a performance reduction that would
occur by measuring many digest lists (e.g. RPM headers) individually.
If, alternatively, digest lists are loaded together, their signature
cannot be verified.

Lastly, when a file is accessed, IMA searches the calculated digest in
the hash table. Only if the digest is not found a new entry is added
to the measurement list.


Roberto Sassu (12):
  ima: generalize ima_read_policy()
  ima: generalize ima_write_policy()
  ima: generalize policy file operations
  ima: use ima_show_htable_value to show hash table data
  ima: add functions to manage digest lists
  ima: added parser of digest lists metadata
  ima: added parser for compact digest list
  ima: added parser for RPM data type
  ima: introduce securityfs interfaces for digest lists
  ima: disable digest lookup if digest lists are not measured
  ima: don't report measurements if digests are included in the loaded
    lists
  ima: added Documentation/security/IMA-digest-lists.txt

 Documentation/security/IMA-digest-lists.txt | 150 +++++++++++++++++
 include/linux/fs.h                          |   1 +
 security/integrity/ima/Kconfig              |  11 ++
 security/integrity/ima/Makefile             |   1 +
 security/integrity/ima/ima.h                |  17 ++
 security/integrity/ima/ima_digest_list.c    | 247 ++++++++++++++++++++++++++++
 security/integrity/ima/ima_fs.c             | 178 ++++++++++++--------
 security/integrity/ima/ima_main.c           |  23 ++-
 security/integrity/ima/ima_policy.c         |   1 +
 security/integrity/ima/ima_queue.c          |  39 +++++
 10 files changed, 602 insertions(+), 66 deletions(-)
 create mode 100644 Documentation/security/IMA-digest-lists.txt
 create mode 100644 security/integrity/ima/ima_digest_list.c

-- 
2.9.3

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

* [PATCH 01/12] ima: generalize ima_read_policy()
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-25 15:44 ` [PATCH 02/12] ima: generalize ima_write_policy() Roberto Sassu
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

Rename ima_read_policy() to ima_read_file(), and add file_id as new
parameter. If file_id is equal to READING_POLICY, ima_read_file()
behavior is the same of that without the patch.

ima_read_file() will be used to read digest lists, to avoid reporting
measurements when the file digest is known.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_fs.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index ad491c5..058d3c1 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -272,7 +272,7 @@ static const struct file_operations ima_ascii_measurements_ops = {
 	.release = seq_release,
 };
 
-static ssize_t ima_read_policy(char *path)
+static ssize_t ima_read_file(char *path, enum kernel_read_file_id file_id)
 {
 	void *data;
 	char *datap;
@@ -285,16 +285,22 @@ static ssize_t ima_read_policy(char *path)
 	datap = path;
 	strsep(&datap, "\n");
 
-	rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
+	rc = kernel_read_file_from_path(path, &data, &size, 0, file_id);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
 		return rc;
 	}
 
 	datap = data;
-	while (size > 0 && (p = strsep(&datap, "\n"))) {
-		pr_debug("rule: %s\n", p);
-		rc = ima_parse_add_rule(p);
+	while (size > 0) {
+		if (file_id == READING_POLICY) {
+			p = strsep(&datap, "\n");
+			if (p == NULL)
+				break;
+
+			pr_debug("rule: %s\n", p);
+			rc = ima_parse_add_rule(p);
+		}
 		if (rc < 0)
 			break;
 		size -= rc;
@@ -334,7 +340,7 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
 		goto out_free;
 
 	if (data[0] == '/') {
-		result = ima_read_policy(data);
+		result = ima_read_file(data, READING_POLICY);
 	} else if (ima_appraise & IMA_APPRAISE_POLICY) {
 		pr_err("IMA: signed policy file (specified as an absolute pathname) required\n");
 		integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
-- 
2.9.3

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

* [PATCH 02/12] ima: generalize ima_write_policy()
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
  2017-07-25 15:44 ` [PATCH 01/12] ima: generalize ima_read_policy() Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-25 15:44 ` [PATCH 03/12] ima: generalize policy file operations Roberto Sassu
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch renames ima_write_policy() to ima_write_data(). Also,
it determines the kernel_read_file_id from the dentry associated
to the file, and passes it to ima_read_file().

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_fs.c | 55 ++++++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 20 deletions(-)

diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 058d3c1..e375206 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -28,6 +28,21 @@
 
 static DEFINE_MUTEX(ima_write_mutex);
 
+static struct dentry *ima_dir;
+static struct dentry *binary_runtime_measurements;
+static struct dentry *ascii_runtime_measurements;
+static struct dentry *runtime_measurements_count;
+static struct dentry *violations;
+static struct dentry *ima_policy;
+
+static enum kernel_read_file_id ima_get_file_id(struct dentry *dentry)
+{
+	if (dentry == ima_policy)
+		return READING_POLICY;
+
+	return READING_UNKNOWN;
+}
+
 bool ima_canonical_fmt;
 static int __init default_canonical_fmt_setup(char *str)
 {
@@ -315,11 +330,12 @@ static ssize_t ima_read_file(char *path, enum kernel_read_file_id file_id)
 		return pathlen;
 }
 
-static ssize_t ima_write_policy(struct file *file, const char __user *buf,
-				size_t datalen, loff_t *ppos)
+static ssize_t ima_write_data(struct file *file, const char __user *buf,
+			      size_t datalen, loff_t *ppos)
 {
 	char *data;
 	ssize_t result;
+	enum kernel_read_file_id file_id = ima_get_file_id(file->f_path.dentry);
 
 	if (datalen >= PAGE_SIZE)
 		datalen = PAGE_SIZE - 1;
@@ -340,34 +356,33 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
 		goto out_free;
 
 	if (data[0] == '/') {
-		result = ima_read_file(data, READING_POLICY);
-	} else if (ima_appraise & IMA_APPRAISE_POLICY) {
-		pr_err("IMA: signed policy file (specified as an absolute pathname) required\n");
-		integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
-				    "policy_update", "signed policy required",
-				    1, 0);
-		if (ima_appraise & IMA_APPRAISE_ENFORCE)
-			result = -EACCES;
+		result = ima_read_file(data, file_id);
+	} else if (file_id == READING_POLICY) {
+		if (ima_appraise & IMA_APPRAISE_POLICY) {
+			pr_err("IMA: signed policy file (specified "
+			       "as an absolute pathname) required\n");
+			integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
+				"policy_update", "signed policy required",
+				1, 0);
+			if (ima_appraise & IMA_APPRAISE_ENFORCE)
+				result = -EACCES;
+		} else {
+			result = ima_parse_add_rule(data);
+		}
 	} else {
-		result = ima_parse_add_rule(data);
+		pr_err("Unknown data type\n");
+		result = -EINVAL;
 	}
 	mutex_unlock(&ima_write_mutex);
 out_free:
 	kfree(data);
 out:
-	if (result < 0)
+	if (file_id == READING_POLICY && result < 0)
 		valid_policy = 0;
 
 	return result;
 }
 
-static struct dentry *ima_dir;
-static struct dentry *binary_runtime_measurements;
-static struct dentry *ascii_runtime_measurements;
-static struct dentry *runtime_measurements_count;
-static struct dentry *violations;
-static struct dentry *ima_policy;
-
 enum ima_fs_flags {
 	IMA_FS_BUSY,
 };
@@ -446,7 +461,7 @@ static int ima_release_policy(struct inode *inode, struct file *file)
 
 static const struct file_operations ima_measure_policy_ops = {
 	.open = ima_open_policy,
-	.write = ima_write_policy,
+	.write = ima_write_data,
 	.read = seq_read,
 	.release = ima_release_policy,
 	.llseek = generic_file_llseek,
-- 
2.9.3

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

* [PATCH 03/12] ima: generalize policy file operations
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
  2017-07-25 15:44 ` [PATCH 01/12] ima: generalize ima_read_policy() Roberto Sassu
  2017-07-25 15:44 ` [PATCH 02/12] ima: generalize ima_write_policy() Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-25 15:44 ` [PATCH 04/12] ima: use ima_show_htable_value to show hash table data Roberto Sassu
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch renames ima_open_policy() and ima_release_policy() respectively
to ima_open_data_upload() and ima_release_data_upload(). They will be used
to implement file operations for interfaces allowing to upload and read
provided data.

Also, the new flag IMA_POLICY_BUSY has been defined specifically for
the policy, as it might not be cleared at file release. This would prevent
userspace applications from uploading files after a policy has been loaded.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_fs.c | 46 ++++++++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index e375206..f4199f2 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -384,6 +384,7 @@ static ssize_t ima_write_data(struct file *file, const char __user *buf,
 }
 
 enum ima_fs_flags {
+	IMA_POLICY_BUSY,
 	IMA_FS_BUSY,
 };
 
@@ -399,22 +400,33 @@ static const struct seq_operations ima_policy_seqops = {
 #endif
 
 /*
- * ima_open_policy: sequentialize access to the policy file
+ * ima_open_data_upload: sequentialize access to the data upload interface
  */
-static int ima_open_policy(struct inode *inode, struct file *filp)
+static int ima_open_data_upload(struct inode *inode, struct file *filp)
 {
+	enum kernel_read_file_id file_id = ima_get_file_id(filp->f_path.dentry);
+	const struct seq_operations *seq_ops = NULL;
+	enum ima_fs_flags flag = IMA_FS_BUSY;
+	bool read_allowed = false;
+
+	if (file_id == READING_POLICY) {
+		flag = IMA_POLICY_BUSY;
+#ifdef	CONFIG_IMA_READ_POLICY
+		read_allowed = true;
+		seq_ops = &ima_policy_seqops;
+#endif
+	}
+
 	if (!(filp->f_flags & O_WRONLY)) {
-#ifndef	CONFIG_IMA_READ_POLICY
-		return -EACCES;
-#else
+		if (!read_allowed)
+			return -EACCES;
 		if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
 			return -EACCES;
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		return seq_open(filp, &ima_policy_seqops);
-#endif
+		return seq_open(filp, seq_ops);
 	}
-	if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
+	if (test_and_set_bit(flag, &ima_fs_flags))
 		return -EBUSY;
 	return 0;
 }
@@ -426,13 +438,19 @@ static int ima_open_policy(struct inode *inode, struct file *filp)
  * point to the new policy rules, and remove the securityfs policy file,
  * assuming a valid policy.
  */
-static int ima_release_policy(struct inode *inode, struct file *file)
+static int ima_release_data_upload(struct inode *inode, struct file *file)
 {
+	enum kernel_read_file_id file_id = ima_get_file_id(file->f_path.dentry);
 	const char *cause = valid_policy ? "completed" : "failed";
 
 	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
 		return seq_release(inode, file);
 
+	if (file_id != READING_POLICY) {
+		clear_bit(IMA_FS_BUSY, &ima_fs_flags);
+		return 0;
+	}
+
 	if (valid_policy && ima_check_policy() < 0) {
 		cause = "failed";
 		valid_policy = 0;
@@ -454,16 +472,16 @@ static int ima_release_policy(struct inode *inode, struct file *file)
 	securityfs_remove(ima_policy);
 	ima_policy = NULL;
 #else
-	clear_bit(IMA_FS_BUSY, &ima_fs_flags);
+	clear_bit(IMA_POLICY_BUSY, &ima_fs_flags);
 #endif
 	return 0;
 }
 
-static const struct file_operations ima_measure_policy_ops = {
-	.open = ima_open_policy,
+static const struct file_operations ima_data_upload_ops = {
+	.open = ima_open_data_upload,
 	.write = ima_write_data,
 	.read = seq_read,
-	.release = ima_release_policy,
+	.release = ima_release_data_upload,
 	.llseek = generic_file_llseek,
 };
 
@@ -502,7 +520,7 @@ int __init ima_fs_init(void)
 
 	ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
 					    ima_dir, NULL,
-					    &ima_measure_policy_ops);
+					    &ima_data_upload_ops);
 	if (IS_ERR(ima_policy))
 		goto out;
 
-- 
2.9.3

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

* [PATCH 04/12] ima: use ima_show_htable_value to show hash table data
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (2 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 03/12] ima: generalize policy file operations Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-25 15:44 ` [PATCH 05/12] ima: add functions to manage digest lists Roberto Sassu
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch removes ima_show_htable_violations() and
ima_show_measurements_count(). ima_show_htable_value(), called
by those functions, determines which hash table data should be
copied to the buffer depending on the dentry of the file passed
as argument.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_fs.c | 38 ++++++++++++--------------------------
 1 file changed, 12 insertions(+), 26 deletions(-)

diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index f4199f2..ad3d674 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -55,38 +55,24 @@ __setup("ima_canonical_fmt", default_canonical_fmt_setup);
 
 static int valid_policy = 1;
 #define TMPBUFLEN 12
-static ssize_t ima_show_htable_value(char __user *buf, size_t count,
-				     loff_t *ppos, atomic_long_t *val)
+static ssize_t ima_show_htable_value(struct file *filp, char __user *buf,
+				     size_t count, loff_t *ppos)
 {
+	atomic_long_t *val = NULL;
 	char tmpbuf[TMPBUFLEN];
 	ssize_t len;
 
+	if (filp->f_path.dentry == violations)
+		val = &ima_htable.violations;
+	else if (filp->f_path.dentry == runtime_measurements_count)
+		val = &ima_htable.len;
+
 	len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val));
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
 }
 
-static ssize_t ima_show_htable_violations(struct file *filp,
-					  char __user *buf,
-					  size_t count, loff_t *ppos)
-{
-	return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
-}
-
-static const struct file_operations ima_htable_violations_ops = {
-	.read = ima_show_htable_violations,
-	.llseek = generic_file_llseek,
-};
-
-static ssize_t ima_show_measurements_count(struct file *filp,
-					   char __user *buf,
-					   size_t count, loff_t *ppos)
-{
-	return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
-
-}
-
-static const struct file_operations ima_measurements_count_ops = {
-	.read = ima_show_measurements_count,
+static const struct file_operations ima_htable_value_ops = {
+	.read = ima_show_htable_value,
 	.llseek = generic_file_llseek,
 };
 
@@ -508,13 +494,13 @@ int __init ima_fs_init(void)
 	runtime_measurements_count =
 	    securityfs_create_file("runtime_measurements_count",
 				   S_IRUSR | S_IRGRP, ima_dir, NULL,
-				   &ima_measurements_count_ops);
+				   &ima_htable_value_ops);
 	if (IS_ERR(runtime_measurements_count))
 		goto out;
 
 	violations =
 	    securityfs_create_file("violations", S_IRUSR | S_IRGRP,
-				   ima_dir, NULL, &ima_htable_violations_ops);
+				   ima_dir, NULL, &ima_htable_value_ops);
 	if (IS_ERR(violations))
 		goto out;
 
-- 
2.9.3

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

* [PATCH 05/12] ima: add functions to manage digest lists
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (3 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 04/12] ima: use ima_show_htable_value to show hash table data Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-25 15:44 ` [PATCH 06/12] ima: added parser of digest lists metadata Roberto Sassu
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch first introduces a new structure called ima_digest, which will
contain a digest parsed from the digest list. It has been preferred to
ima_queue_entry, as the existing structure includes an additional member
(a list head), which is not necessary for digest lookup.

Then, this patch introduces functions to lookup and add a digest to
a hash table, which will be used by the parsers.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima.h       |  8 ++++++++
 security/integrity/ima/ima_queue.c | 39 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index d52b487..a0c6808 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -107,6 +107,11 @@ struct ima_queue_entry {
 };
 extern struct list_head ima_measurements;	/* list of all measurements */
 
+struct ima_digest {
+	struct hlist_node hnext;
+	u8 digest[0];
+};
+
 /* Some details preceding the binary serialized measurement list */
 struct ima_kexec_hdr {
 	u16 version;
@@ -150,6 +155,8 @@ void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
 struct ima_template_desc *ima_template_desc_current(void);
 int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
+struct ima_digest *ima_lookup_loaded_digest(u8 *digest);
+int ima_add_digest_data_entry(u8 *digest);
 int ima_measurements_show(struct seq_file *m, void *v);
 unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
@@ -166,6 +173,7 @@ struct ima_h_table {
 	struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE];
 };
 extern struct ima_h_table ima_htable;
+extern struct ima_h_table ima_digests_htable;
 
 static inline unsigned long ima_hash_key(u8 *digest)
 {
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index a02a86d..d1a3d3f 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -42,6 +42,11 @@ struct ima_h_table ima_htable = {
 	.queue[0 ... IMA_MEASURE_HTABLE_SIZE - 1] = HLIST_HEAD_INIT
 };
 
+struct ima_h_table ima_digests_htable = {
+	.len = ATOMIC_LONG_INIT(0),
+	.queue[0 ... IMA_MEASURE_HTABLE_SIZE - 1] = HLIST_HEAD_INIT
+};
+
 /* mutex protects atomicity of extending measurement list
  * and extending the TPM PCR aggregate. Since tpm_extend can take
  * long (and the tpm driver uses a mutex), we can't use the spinlock.
@@ -212,3 +217,37 @@ int ima_restore_measurement_entry(struct ima_template_entry *entry)
 	mutex_unlock(&ima_extend_list_mutex);
 	return result;
 }
+
+struct ima_digest *ima_lookup_loaded_digest(u8 *digest)
+{
+	struct ima_digest *d = NULL;
+	int digest_len = hash_digest_size[ima_hash_algo];
+	unsigned int key = ima_hash_key(digest);
+
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(d, &ima_digests_htable.queue[key], hnext) {
+		if (memcmp(d->digest, digest, digest_len) == 0)
+			break;
+	}
+	rcu_read_unlock();
+	return d;
+}
+
+int ima_add_digest_data_entry(u8 *digest)
+{
+	struct ima_digest *d = ima_lookup_loaded_digest(digest);
+	int digest_len = hash_digest_size[ima_hash_algo];
+	unsigned int key = ima_hash_key(digest);
+
+	if (d)
+		return -EEXIST;
+
+	d = kmalloc(sizeof(*d) + digest_len, GFP_KERNEL);
+	if (d == NULL)
+		return -ENOMEM;
+
+	memcpy(d->digest, digest, digest_len);
+	hlist_add_head_rcu(&d->hnext, &ima_digests_htable.queue[key]);
+	atomic_long_inc(&ima_digests_htable.len);
+	return 0;
+}
-- 
2.9.3

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

* [PATCH 06/12] ima: added parser of digest lists metadata
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (4 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 05/12] ima: add functions to manage digest lists Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-27  5:15   ` kbuild test robot
  2017-08-01 10:17   ` [PATCH, RESEND " Roberto Sassu
  2017-07-25 15:44 ` [PATCH 07/12] ima: added parser for compact digest list Roberto Sassu
                   ` (6 subsequent siblings)
  12 siblings, 2 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

Userspace applications will be able to load digest lists by supplying
their metadata.

Digest list metadata are:

- DATA_ALGO: algorithm of the digests to be uploaded
- DATA_DIGEST: digest of the file containing the digest list
- DATA_SIGNATURE: signature of the file containing the digest list
- DATA_FILE_PATH: pathname
- DATA_REF_ID: reference ID of the digest list
- DATA_TYPE: type of digest list

The new function ima_parse_digest_list_metadata() parses the metadata
and load each file individually. Then, it parses the data according
to the data type specified.

Since digest lists are measured, their digest is added to the hash table
so that IMA does not create a measurement entry for them (which would
affect the performance). The only measurement entry created will be
for the metadata.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/fs.h                       |   1 +
 security/integrity/ima/Kconfig           |  11 ++++
 security/integrity/ima/Makefile          |   1 +
 security/integrity/ima/ima.h             |   8 +++
 security/integrity/ima/ima_digest_list.c | 105 +++++++++++++++++++++++++++++++
 5 files changed, 126 insertions(+)
 create mode 100644 security/integrity/ima/ima_digest_list.c

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6e1fd5d..2eb6e7c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2751,6 +2751,7 @@ extern int do_pipe_flags(int *, int);
 	id(KEXEC_IMAGE, kexec-image)		\
 	id(KEXEC_INITRAMFS, kexec-initramfs)	\
 	id(POLICY, security-policy)		\
+	id(DIGEST_LIST, security-digest-list)	\
 	id(MAX_ID, )
 
 #define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 35ef693..8965dcc 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -227,3 +227,14 @@ config IMA_APPRAISE_SIGNED_INIT
 	default n
 	help
 	   This option requires user-space init to be signed.
+
+config IMA_DIGEST_LIST
+	bool "Measure files depending on uploaded digest lists"
+	depends on IMA
+	default n
+	help
+	   This option allows users to load digest lists. If a measured
+	   file has the same digest of one from loaded lists, IMA will
+	   not create a new measurement entry. A measurement entry will
+	   be created only when digest lists are loaded (this entry
+	   contains the digest of digest lists metadata).
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 29f198b..00dbe3a 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -9,4 +9,5 @@ ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
 	 ima_policy.o ima_template.o ima_template_lib.o
 ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
 ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
+ima-$(CONFIG_IMA_DIGEST_LIST) += ima_digest_list.o
 obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index a0c6808..77dd4d0 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -157,6 +157,14 @@ int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
 struct ima_digest *ima_lookup_loaded_digest(u8 *digest);
 int ima_add_digest_data_entry(u8 *digest);
+#ifdef CONFIG_IMA_DIGEST_LIST
+ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf);
+#else
+static inline ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf)
+{
+	return -ENOTSUP;
+}
+#endif
 int ima_measurements_show(struct seq_file *m, void *v);
 unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c
new file mode 100644
index 0000000..3e1ff69b
--- /dev/null
+++ b/security/integrity/ima/ima_digest_list.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 Huawei Technologies Co. Ltd.
+ *
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * File: ima_digest_list.c
+ *      Functions to manage digest lists.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/vmalloc.h>
+
+#include "ima.h"
+#include "ima_template_lib.h"
+
+enum digest_metadata_fields {DATA_ALGO, DATA_DIGEST, DATA_SIGNATURE,
+			     DATA_FILE_PATH, DATA_REF_ID, DATA_TYPE,
+			     DATA__LAST};
+
+static int ima_parse_digest_list_data(struct ima_field_data *data)
+{
+	void *digest_list;
+	loff_t digest_list_size;
+	u16 data_algo = le16_to_cpu(*(u16 *)data[DATA_ALGO].data);
+	u16 data_type = le16_to_cpu(*(u16 *)data[DATA_TYPE].data);
+	int ret;
+
+	if (data_algo != ima_hash_algo) {
+		pr_err("Incompatible digest algorithm, expected %s\n",
+		       hash_algo_name[ima_hash_algo]);
+		return -EINVAL;
+	}
+
+	ret = kernel_read_file_from_path(data[DATA_FILE_PATH].data,
+					 &digest_list, &digest_list_size,
+					 0, READING_DIGEST_LIST);
+	if (ret < 0) {
+		pr_err("Unable to open file: %s (%d)",
+		       data[DATA_FILE_PATH].data, ret);
+		return ret;
+	}
+
+	switch (data_type) {
+	default:
+		pr_err("Parser for data type %d not implemented\n", data_type);
+		ret = -EINVAL;
+	}
+
+	if (ret < 0) {
+		pr_err("Error parsing file: %s (%d)\n",
+		       data[DATA_FILE_PATH].data, ret);
+		return ret;
+	}
+
+	vfree(digest_list);
+	return ret;
+}
+
+ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf)
+{
+	struct ima_field_data entry;
+
+	struct ima_field_data entry_data[DATA__LAST] = {
+		[DATA_ALGO] = {.len = sizeof(u16)},
+		[DATA_TYPE] = {.len = sizeof(u16)},
+	};
+
+	DECLARE_BITMAP(data_mask, DATA__LAST);
+	void *bufp = buf, *bufendp = buf + size;
+	int ret;
+
+	bitmap_zero(data_mask, DATA__LAST);
+	bitmap_set(data_mask, DATA_ALGO, 1);
+	bitmap_set(data_mask, DATA_TYPE, 1);
+
+	ret = ima_parse_buf(bufp, bufendp, &bufp, 1, &entry, NULL, NULL,
+			    ENFORCE_FIELDS, "metadata list entry");
+	if (ret < 0)
+		return ret;
+
+	ret = ima_parse_buf(entry.data, entry.data + entry.len, NULL,
+			    DATA__LAST, entry_data, NULL, data_mask,
+			    ENFORCE_FIELDS | ENFORCE_BUFEND,
+			    "metadata entry data");
+	if (ret < 0)
+		goto out;
+
+	ret = ima_add_digest_data_entry(entry_data[DATA_DIGEST].data);
+	if (ret < 0) {
+		if (ret == -EEXIST)
+			ret = 0;
+
+		goto out;
+	}
+
+	ret = ima_parse_digest_list_data(entry_data);
+out:
+	return ret < 0 ? ret : bufp - buf;
+}
-- 
2.9.3

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

* [PATCH 07/12] ima: added parser for compact digest list
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (5 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 06/12] ima: added parser of digest lists metadata Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-25 15:44 ` [PATCH 08/12] ima: added parser for RPM data type Roberto Sassu
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch introduces the parser for the compact digest list.
Its format is:

entry_id[2] count[4] data_len[4]
data[data_len]
entry_id[2] count[4] data_len[4]
data[data_len]
...

The parser supports the COMPACT_LIST_ID_DIGEST entry ID.

This format is suitable to store a large number of digests, as there is
no metadata provided for each. Digests (which have all the same size) are
concatenated together and placed after the header.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_digest_list.c | 60 ++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c
index 3e1ff69b..c1ef79a 100644
--- a/security/integrity/ima/ima_digest_list.c
+++ b/security/integrity/ima/ima_digest_list.c
@@ -23,6 +23,63 @@ enum digest_metadata_fields {DATA_ALGO, DATA_DIGEST, DATA_SIGNATURE,
 			     DATA_FILE_PATH, DATA_REF_ID, DATA_TYPE,
 			     DATA__LAST};
 
+enum digest_data_types {DATA_TYPE_COMPACT_LIST};
+
+enum compact_list_entry_ids {COMPACT_LIST_ID_DIGEST};
+
+struct compact_list_hdr {
+	u16 entry_id;
+	u32 count;
+	u32 datalen;
+} __packed;
+
+static int ima_parse_compact_list(loff_t size, void *buf)
+{
+	void *bufp = buf, *bufendp = buf + size;
+	int digest_len = hash_digest_size[ima_hash_algo];
+	struct compact_list_hdr *hdr;
+	int ret, i;
+
+	while (bufp < bufendp) {
+		if (bufp + sizeof(*hdr) > bufendp) {
+			pr_err("compact list, missing header\n");
+			return -EINVAL;
+		}
+
+		hdr = bufp;
+
+		if (ima_canonical_fmt) {
+			hdr->entry_id = le16_to_cpu(hdr->entry_id);
+			hdr->count = le32_to_cpu(hdr->count);
+			hdr->datalen = le32_to_cpu(hdr->datalen);
+		}
+
+		if (hdr->entry_id != COMPACT_LIST_ID_DIGEST) {
+			pr_err("compact list, invalid data type\n");
+			return -EINVAL;
+		}
+
+		bufp += sizeof(*hdr);
+
+		for (i = 0; i < hdr->count &&
+		     bufp + digest_len <= bufendp; i++) {
+			ret = ima_add_digest_data_entry(bufp);
+			if (ret < 0 && ret != -EEXIST)
+				return ret;
+
+			bufp += digest_len;
+		}
+
+		if (i != hdr->count ||
+		    bufp != (void *)hdr + sizeof(*hdr) + hdr->datalen) {
+			pr_err("compact list, invalid data\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int ima_parse_digest_list_data(struct ima_field_data *data)
 {
 	void *digest_list;
@@ -47,6 +104,9 @@ static int ima_parse_digest_list_data(struct ima_field_data *data)
 	}
 
 	switch (data_type) {
+	case DATA_TYPE_COMPACT_LIST:
+		ret = ima_parse_compact_list(digest_list_size, digest_list);
+		break;
 	default:
 		pr_err("Parser for data type %d not implemented\n", data_type);
 		ret = -EINVAL;
-- 
2.9.3

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

* [PATCH 08/12] ima: added parser for RPM data type
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (6 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 07/12] ima: added parser for compact digest list Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-27  5:03   ` kbuild test robot
  2017-08-01 10:20   ` [PATCH, RESEND " Roberto Sassu
  2017-07-25 15:44 ` [PATCH 09/12] ima: introduce securityfs interfaces for digest lists Roberto Sassu
                   ` (4 subsequent siblings)
  12 siblings, 2 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch introduces a parser for RPM packages. It extracts the digests
from the RPMTAG_FILEDIGESTS header section and converts them to binary data
before adding them to the hash table.

The advantage of this data type is that verifiers can determine who
produced that data, as headers are signed by Linux distributions vendors.
RPM headers signatures can be provided as digest list metadata.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_digest_list.c | 84 +++++++++++++++++++++++++++++++-
 1 file changed, 83 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c
index c1ef79a..11ee77e 100644
--- a/security/integrity/ima/ima_digest_list.c
+++ b/security/integrity/ima/ima_digest_list.c
@@ -19,11 +19,13 @@
 #include "ima.h"
 #include "ima_template_lib.h"
 
+#define RPMTAG_FILEDIGESTS 1035
+
 enum digest_metadata_fields {DATA_ALGO, DATA_DIGEST, DATA_SIGNATURE,
 			     DATA_FILE_PATH, DATA_REF_ID, DATA_TYPE,
 			     DATA__LAST};
 
-enum digest_data_types {DATA_TYPE_COMPACT_LIST};
+enum digest_data_types {DATA_TYPE_COMPACT_LIST, DATA_TYPE_RPM};
 
 enum compact_list_entry_ids {COMPACT_LIST_ID_DIGEST};
 
@@ -33,6 +35,20 @@ struct compact_list_hdr {
 	u32 datalen;
 } __packed;
 
+struct rpm_hdr {
+	u32 magic;
+	u32 reserved;
+	u32 tags;
+	u32 datasize;
+} __packed;
+
+struct rpm_entryinfo {
+	int32_t tag;
+	u32 type;
+	int32_t offset;
+	u32 count;
+} __packed;
+
 static int ima_parse_compact_list(loff_t size, void *buf)
 {
 	void *bufp = buf, *bufendp = buf + size;
@@ -80,6 +96,69 @@ static int ima_parse_compact_list(loff_t size, void *buf)
 	return 0;
 }
 
+static int ima_parse_rpm(loff_t size, void *buf)
+{
+	void *bufp = buf, *bufendp = buf + size;
+	struct rpm_hdr *hdr = bufp;
+	u32 tags = be32_to_cpu(hdr->tags);
+	struct rpm_entryinfo *entry;
+	void *datap = bufp + sizeof(*hdr) + tags * sizeof(struct rpm_entryinfo);
+	int digest_len = hash_digest_size[ima_hash_algo];
+	u8 digest[digest_len];
+	int ret, i, j;
+
+	const unsigned char rpm_header_magic[8] = {
+		0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
+	};
+
+	if (size < sizeof(*hdr)) {
+		pr_err("Missing RPM header\n");
+		return -EINVAL;
+	}
+
+	if (memcmp(bufp, rpm_header_magic, sizeof(rpm_header_magic))) {
+		pr_err("Invalid RPM header\n");
+		return -EINVAL;
+	}
+
+	bufp += sizeof(*hdr);
+
+	for (i = 0; i < tags && (bufp + sizeof(*entry)) <= bufendp;
+	     i++, bufp += sizeof(*entry)) {
+		entry = bufp;
+
+		if (be32_to_cpu(entry->tag) != RPMTAG_FILEDIGESTS)
+			continue;
+
+		datap += be32_to_cpu(entry->offset);
+
+		for (j = 0; j < be32_to_cpu(entry->count) &&
+		     datap < bufendp; j++) {
+			if (strlen(datap) == 0) {
+				datap++;
+				continue;
+			}
+
+			if (datap + digest_len * 2 + 1 > bufendp) {
+				pr_err("RPM header read at invalid offset\n");
+				return -EINVAL;
+			}
+
+			hex2bin(digest, datap, digest_len);
+
+			ret = ima_add_digest_data_entry(digest);
+			if (ret < 0 && ret != -EEXIST)
+				return ret;
+
+			datap += digest_len * 2 + 1;
+		}
+
+		break;
+	}
+
+	return 0;
+}
+
 static int ima_parse_digest_list_data(struct ima_field_data *data)
 {
 	void *digest_list;
@@ -107,6 +186,9 @@ static int ima_parse_digest_list_data(struct ima_field_data *data)
 	case DATA_TYPE_COMPACT_LIST:
 		ret = ima_parse_compact_list(digest_list_size, digest_list);
 		break;
+	case DATA_TYPE_RPM:
+		ret = ima_parse_rpm(digest_list_size, digest_list);
+		break;
 	default:
 		pr_err("Parser for data type %d not implemented\n", data_type);
 		ret = -EINVAL;
-- 
2.9.3

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

* [PATCH 09/12] ima: introduce securityfs interfaces for digest lists
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (7 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 08/12] ima: added parser for RPM data type Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-27  5:38   ` kbuild test robot
  2017-07-25 15:44 ` [PATCH 10/12] ima: disable digest lookup if digest lists are not measured Roberto Sassu
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch introduces the file 'digest_lists' in the securityfs
filesystem, to load digest lists metadata. IMA will parse the metadata
and loads the digest lists from the path provided.

It also introduces 'digests_count', to show the number of digests
stored in the digest hash table.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_fs.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index ad3d674..08174c1 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -34,11 +34,15 @@ static struct dentry *ascii_runtime_measurements;
 static struct dentry *runtime_measurements_count;
 static struct dentry *violations;
 static struct dentry *ima_policy;
+static struct dentry *digest_lists;
+static struct dentry *digests_count;
 
 static enum kernel_read_file_id ima_get_file_id(struct dentry *dentry)
 {
 	if (dentry == ima_policy)
 		return READING_POLICY;
+	else if (dentry == digest_lists)
+		return READING_DIGEST_LIST;
 
 	return READING_UNKNOWN;
 }
@@ -66,6 +70,8 @@ static ssize_t ima_show_htable_value(struct file *filp, char __user *buf,
 		val = &ima_htable.violations;
 	else if (filp->f_path.dentry == runtime_measurements_count)
 		val = &ima_htable.len;
+	else if (filp->f_path.dentry == digests_count)
+		val = &ima_digests_htable.len;
 
 	len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val));
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
@@ -301,6 +307,9 @@ static ssize_t ima_read_file(char *path, enum kernel_read_file_id file_id)
 
 			pr_debug("rule: %s\n", p);
 			rc = ima_parse_add_rule(p);
+		} else if (file_id == READING_DIGEST_LIST) {
+			rc = ima_parse_digest_list_metadata(size, datap);
+			datap += rc;
 		}
 		if (rc < 0)
 			break;
@@ -510,8 +519,22 @@ int __init ima_fs_init(void)
 	if (IS_ERR(ima_policy))
 		goto out;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
+	digest_lists = securityfs_create_file("digest_lists", S_IWUSR, ima_dir,
+					      NULL, &ima_data_upload_ops);
+	if (IS_ERR(digest_lists))
+		goto out;
+
+	digests_count = securityfs_create_file("digests_count",
+					       S_IRUSR | S_IRGRP, ima_dir,
+					       NULL, &ima_htable_value_ops);
+	if (IS_ERR(digests_count))
+		goto out;
+#endif
 	return 0;
 out:
+	securityfs_remove(digests_count);
+	securityfs_remove(digest_lists);
 	securityfs_remove(violations);
 	securityfs_remove(runtime_measurements_count);
 	securityfs_remove(ascii_runtime_measurements);
-- 
2.9.3

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

* [PATCH 10/12] ima: disable digest lookup if digest lists are not measured
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (8 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 09/12] ima: introduce securityfs interfaces for digest lists Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-25 15:44 ` [PATCH 11/12] ima: don't report measurements if digests are included in the loaded lists Roberto Sassu
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

Loading digest lists affects the behavior of IMA, as files whose digest
has been uploaded will not be displayed in the measurement list.
If the digest lists loading event is not reported, verifiers would believe
that the files with uploaded digests have not been accessed.

To prevent this, the DIGEST_CHECK hook has been defined and a new rule
to measure files accessed by the new hook has been added to the default
policy. If the currently loaded policy does not contain that rule,
digest lookup is disabled.

Digest lookup is also disabled if CONFIG_IMA_DIGEST_LIST is not defined.

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

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 77dd4d0..2a558ee 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -199,6 +199,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
 	hook(KEXEC_KERNEL_CHECK)	\
 	hook(KEXEC_INITRAMFS_CHECK)	\
 	hook(POLICY_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 2aebb79..c329549 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_check;
+#else
+static int ima_disable_digest_check = 1;
+#endif
+
 #ifdef CONFIG_IMA_APPRAISE
 int ima_appraise = IMA_APPRAISE_ENFORCE;
 #else
@@ -171,6 +177,9 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
 	bool violation_check;
 	enum hash_algo hash_algo;
 
+	if (func == DIGEST_LIST_CHECK && !ima_policy_flag)
+		ima_disable_digest_check = 1;
+
 	if (!ima_policy_flag || !S_ISREG(inode->i_mode))
 		return 0;
 
@@ -181,6 +190,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_CHECK && !(action & IMA_MEASURE))
+		ima_disable_digest_check = 1;
+
 	if (!action && !violation_check)
 		return 0;
 
@@ -375,7 +387,8 @@ 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] = DIGEST_LIST_CHECK
 };
 
 /**
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 95209a5..b5c004d 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -127,6 +127,7 @@ 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},
+	{.action = MEASURE, .func = DIGEST_LIST_CHECK, .flags = IMA_FUNC},
 };
 
 static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
-- 
2.9.3

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

* [PATCH 11/12] ima: don't report measurements if digests are included in the loaded lists
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (9 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 10/12] ima: disable digest lookup if digest lists are not measured Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-08-09 20:36   ` [Linux-ima-devel] " Ken Goldman
  2017-07-25 15:44 ` [PATCH 12/12] ima: added Documentation/security/IMA-digest-lists.txt Roberto Sassu
  2017-07-26 21:54 ` [PATCH 00/12] ima: measure digest lists instead of individual files Mimi Zohar
  12 siblings, 1 reply; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

Don't report measurements if the file digest has been included in
an uploaded digest list.

The advantage of this solution is that the boot time overhead, when
a TPM is available, is very small because a PCR is extended only
for unknown files. The disadvantage is that verifiers do not know
anymore which and when files are accessed (they must assume that
the worst case happened, i.e. all files have been accessed).

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_main.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index c329549..e289b7c 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -253,6 +253,14 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
 		goto out_digsig;
 	}
 
+	if (!ima_disable_digest_check) {
+		if (ima_lookup_loaded_digest(iint->ima_hash->digest)) {
+			action ^= IMA_MEASURE;
+			iint->flags |= IMA_MEASURED;
+			iint->measured_pcrs |= (0x1 << pcr);
+		}
+	}
+
 	if (!pathbuf)	/* ima_rdwr_violation possibly pre-fetched */
 		pathname = ima_d_path(&file->f_path, &pathbuf, filename);
 
-- 
2.9.3

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

* [PATCH 12/12] ima: added Documentation/security/IMA-digest-lists.txt
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (10 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 11/12] ima: don't report measurements if digests are included in the loaded lists Roberto Sassu
@ 2017-07-25 15:44 ` Roberto Sassu
  2017-07-26 21:54 ` [PATCH 00/12] ima: measure digest lists instead of individual files Mimi Zohar
  12 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-07-25 15:44 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch adds the documentation of the new IMA feature, to load
and measure file digest lists.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 Documentation/security/IMA-digest-lists.txt | 150 ++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)
 create mode 100644 Documentation/security/IMA-digest-lists.txt

diff --git a/Documentation/security/IMA-digest-lists.txt b/Documentation/security/IMA-digest-lists.txt
new file mode 100644
index 0000000..f9eed21
--- /dev/null
+++ b/Documentation/security/IMA-digest-lists.txt
@@ -0,0 +1,150 @@
+                            File Digest Lists
+
+==== INTRODUCTION ====
+
+IMA, for each file matching policy rules, calculates a digest, creates
+a new entry in the measurement list and extends a TPM PCR with the digest
+of entry data. The last step causes a noticeable performance reduction.
+
+Since systems likely access the same files, repeating the above tasks at
+every boot can be avoided by replacing individual measurements of likely
+accessed files with only one measurement of their digests: the advantage
+is that the system performance significantly improves due to less PCR
+extend operations; on the other hand, the information about which files
+have exactly been accessed and in which sequence is lost.
+
+If this new measurement reports only good digests (e.g. those of
+files included in a Linux distribution), and if verifiers only check
+that a system executed good software and didn't access malicious data,
+the disadvantages reported earlier would be acceptable.
+
+The Trusted Computing paradigm measure & load is still respected by IMA
+with the proposed optimization. If a file being accessed is not in a
+measured digest list, a measurement will be recorded as before. If it is,
+the list has already been measured, and the verifier must assume that
+files with digest in the list have been accessed.
+
+Measuring digest lists gives the following benefits:
+
+- boot time reduction
+  For a minimal Linux installation with 1400 measurements, the boot time
+  decreases from 1 minute 30 seconds to 15 seconds, after loading to IMA
+  the digest of all files packaged by the distribution (32000). The new
+  list contains 92 entries. Without IMA, the boot time is 8.5 seconds.
+
+- lower network and CPU requirements for remote attestation
+  With the IMA optimization, both the measurement and digest lists
+  must be verified for a complete evaluation. However, since the lists
+  are fixed, they could be sent to and checked by the verifier only once.
+  Then, during a remote attestation, the only remaining task is to verify
+  the short measurement list.
+
+- signature-based remote attestation
+  Digest list signature can be used as a proof of the provenance for the
+  files whose digest is in the list. Then, if verifiers trust the signer
+  and only check provenance, remote attestation verification would simply
+  consist on checking digest lists signatures and that the measurement
+  list only contain list metadata digests (reference measurement databases
+  would be no longer required). An example of a signed digest list,
+  that can be parsed with this patch set, is the RPM package header.
+
+Digest lists are loaded in two stages by IMA through the new securityfs
+interface called 'digest_lists'. Users supply metadata, for the digest
+lists they want to load: path, format, digest, signature and algorithm
+of the digest.
+
+Then, after the metadata digest is added to the measurement list, IMA
+reads the digest lists at the path specified and loads the digests in
+a hash table (digest lists are not measured, since their digest is already
+included in the metadata). With metadata measurement instead of digest list
+measurement, it is possible to avoid a performance reduction that would
+occur by measuring many digest lists (e.g. RPM headers) individually.
+If, alternatively, digest lists are loaded together, their signature
+cannot be verified.
+
+Lastly, when a file is accessed, IMA searches the calculated digest in
+the hash table. Only if the digest is not found a new entry is added
+to the measurement list.
+
+
+
+==== FORMAT ====
+
+The format of digest list metadata is:
+
+algo[2] digest_len[4] digest[digest_len]
+        signature_len[4] signature[signature_len]
+        path_len[4] path[path_len]
+        ref_id_len[4] ref_id[ref_id_len]
+        list_type_len[4] list_type[list_type_len]
+
+algo, list_type and _len are little endian.
+
+
+algo values are defined in include/uapi/linux/hash_info.h. The algorithms
+in the list metadata must be the same of ima_hash_algo (algorithm used
+by IMA to calculate the file digest).
+
+list type values:
+
+0: compact digest list
+1: RPM package header
+
+
+The format of the compact digest list is:
+
+entry_id[2] count[4] data_len[4]
+data[data_len]
+[...]
+entry_id[2] count[4] data_len[4]
+data[data_len]
+
+entry_id, count and data_len are little endian.
+
+At the moment, entry_id can have value 0, which means that 'data' contains
+'count' digests concatenated together. For example, a compact digest list
+with 10 SHA256 digests will look like:
+
+0 10 320
+digest1..digest10
+
+
+
+==== MEASUREMENT LIST ====
+
+systemd has been modified to load the path of files containing digest list
+metadata to the new securityfs interface. Paths must be stored in
+/etc/ima/digest-lists. If digest lists, metadata and systemd configuration
+file are included in the initial ram disk, a typical measurement list
+will look like:
+
+10 <template digest> ima-ng sha1:<digest> boot_aggregate
+10 <template digest> ima-ng sha256:<digest> /usr/lib/systemd/systemd
+10 <template digest> ima-ng sha256:<digest> /usr/lib64/ld-2.17.so
+[...]
+10 <template digest> ima-ng sha256:<digest> /etc/ima/digest-lists
+10 <template digest> ima-ng sha256:<digest> /digests/headers
+[...]
+
+systemd executable and libraries still appear in the measurement list,
+even if they are in a digest list, because digests lists have not been
+loaded yet.
+
+Then, the next measurement should be for /etc/ima/digest-lists.
+At verification time, the file digest can be verified by calculating
+the digest of the path of list metadata (/digests/headers). If multiple
+metadata files are specified in /etc/ima/digest-lists, it is task of the
+system administrator to use appropriate names, so that a verifier can
+recognize them from the measurement list.
+
+The last measurement to verify is of /digests/headers. During remote
+attestation, the content of this file should be sent to the verifier,
+together with the digest lists (unless a reference ID is provided,
+so that lists can be fetched from a repository).
+
+A verifier should check if:
+
+1) the digest of received metadata matches that in the measurement list
+2) the digest of digest lists matches the digests in the list metadata
+3a) each file digest in the digest list is acceptable
+3b) the signature of the digest list is valid and the signer is trusted
-- 
2.9.3

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

* Re: [PATCH 00/12] ima: measure digest lists instead of individual files
  2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
                   ` (11 preceding siblings ...)
  2017-07-25 15:44 ` [PATCH 12/12] ima: added Documentation/security/IMA-digest-lists.txt Roberto Sassu
@ 2017-07-26 21:54 ` Mimi Zohar
  12 siblings, 0 replies; 30+ messages in thread
From: Mimi Zohar @ 2017-07-26 21:54 UTC (permalink / raw)
  To: Roberto Sassu, linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	tpmdd-devel

Hi Roberto,

[cc'ing tpmdd-devel]

On Tue, 2017-07-25 at 17:44 +0200, Roberto Sassu wrote:
> This patch set applies on top of kernel v4.13-rc2.
> 
> IMA, for each file matching policy rules, calculates a digest, creates
> a new entry in the measurement list and extends a TPM PCR with the digest
> of entry data. The last step causes a noticeable performance reduction.
> 
> Since systems likely access the same files, repeating the above tasks at
> every boot can be avoided by replacing individual measurements of likely
> accessed files with only one measurement of their digests: the advantage
> is that the system performance significantly improves due to less PCR
> extend operations; on the other hand, the information about which files
> have exactly been accessed and in which sequence is lost.
> 
> If this new measurement reports only good digests (e.g. those of
> files included in a Linux distribution), and if verifiers only check
> that a system executed good software and didn't access malicious data,
> the disadvantages reported earlier would be acceptable.
> 
> The Trusted Computing paradigm measure & load is still respected by IMA
> with the proposed optimization. If a file being accessed is not in a
> measured digest list, a measurement will be recorded as before. If it is,
> the list has already been measured, and the verifier must assume that
> files with digest in the list have been accessed.
> 
> Measuring digest lists gives the following benefits:
> 
> - boot time reduction
>   For a minimal Linux installation with 1400 measurements, the boot time
>   decreases from 1 minute 30 seconds to 15 seconds, after loading to IMA
>   the digest of all files packaged by the distribution (32000). The new
>   list contains 92 entries. Without IMA, the boot time is 8.5 seconds.

Before we "fix" a TPM performance problem in IMA, we need to really
understand the performance problem first.  We've added a "TPM
peformance" topic to the Linux Plumber Conference TPM microconference
- http://wiki.linuxplumbersconf.org/2017:tpms.

We've benchmarked a couple of different TPMs on different systems with
TPMs on LPC, I2C, and STI.  Originally we were seeing even worse
performance than your 1 minute 30 seconds for 1400 measurements.
  Fortunately, we were able to bring it down to about 17 seconds for
a 1000 TPM extends.  Refer to commits a233a0289cf9 "tpm: msleep()
delays - replace with usleep_range() in i2c nuvoton driver" and
0afb7118ae02 "tpm: add sleep only for retry in
i2c_nuvoton_write_status()" for the details.

Hamza Attak posted a similar patch to the tpmdd-devel mailing list
replacing msleep() with usleep_range() calls.  Unfortunately, we're
seeing really poor performance with another TPM for other reasons.

Mimi

> 
> - lower network and CPU requirements for remote attestation
>   With the IMA optimization, both the measurement and digest lists
>   must be verified for a complete evaluation. However, since the lists
>   are fixed, they could be sent to and checked by the verifier only once.
>   Then, during a remote attestation, the only remaining task is to verify
>   the short measurement list.
> 
> - signature-based remote attestation
>   Digest list signature can be used as a proof of the provenance for the
>   files whose digest is in the list. Then, if verifiers trust the signer
>   and only check provenance, remote attestation verification would simply
>   consist on checking digest lists signatures and that the measurement
>   list only contain list metadata digests (reference measurement databases
>   would be no longer required). An example of a signed digest list,
>   that can be parsed with this patch set, is the RPM package header.
> 
> Digest lists are loaded in two stages by IMA through the new securityfs
> interface called 'digest_lists'. Users supply metadata, for the digest
> lists they want to load: path, format, digest, signature and algorithm
> of the digest.
> 
> Then, after the metadata digest is added to the measurement list, IMA
> reads the digest lists at the path specified and loads the digests in
> a hash table (digest lists are not measured, since their digest is already
> included in the metadata). With metadata measurement instead of digest list
> measurement, it is possible to avoid a performance reduction that would
> occur by measuring many digest lists (e.g. RPM headers) individually.
> If, alternatively, digest lists are loaded together, their signature
> cannot be verified.
> 
> Lastly, when a file is accessed, IMA searches the calculated digest in
> the hash table. Only if the digest is not found a new entry is added
> to the measurement list.
> 
> 
> Roberto Sassu (12):
>   ima: generalize ima_read_policy()
>   ima: generalize ima_write_policy()
>   ima: generalize policy file operations
>   ima: use ima_show_htable_value to show hash table data
>   ima: add functions to manage digest lists
>   ima: added parser of digest lists metadata
>   ima: added parser for compact digest list
>   ima: added parser for RPM data type
>   ima: introduce securityfs interfaces for digest lists
>   ima: disable digest lookup if digest lists are not measured
>   ima: don't report measurements if digests are included in the loaded
>     lists
>   ima: added Documentation/security/IMA-digest-lists.txt
> 
>  Documentation/security/IMA-digest-lists.txt | 150 +++++++++++++++++
>  include/linux/fs.h                          |   1 +
>  security/integrity/ima/Kconfig              |  11 ++
>  security/integrity/ima/Makefile             |   1 +
>  security/integrity/ima/ima.h                |  17 ++
>  security/integrity/ima/ima_digest_list.c    | 247 ++++++++++++++++++++++++++++
>  security/integrity/ima/ima_fs.c             | 178 ++++++++++++--------
>  security/integrity/ima/ima_main.c           |  23 ++-
>  security/integrity/ima/ima_policy.c         |   1 +
>  security/integrity/ima/ima_queue.c          |  39 +++++
>  10 files changed, 602 insertions(+), 66 deletions(-)
>  create mode 100644 Documentation/security/IMA-digest-lists.txt
>  create mode 100644 security/integrity/ima/ima_digest_list.c
> 

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

* Re: [PATCH 08/12] ima: added parser for RPM data type
  2017-07-25 15:44 ` [PATCH 08/12] ima: added parser for RPM data type Roberto Sassu
@ 2017-07-27  5:03   ` kbuild test robot
  2017-08-01 10:20   ` [PATCH, RESEND " Roberto Sassu
  1 sibling, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2017-07-27  5:03 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: kbuild-all, linux-ima-devel, linux-security-module,
	linux-fsdevel, linux-doc, linux-kernel, Roberto Sassu

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

Hi Roberto,

[auto build test WARNING on integrity/next]
[also build test WARNING on v4.13-rc2 next-20170726]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Roberto-Sassu/ima-measure-digest-lists-instead-of-individual-files/20170727-123131
base:   https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

All warnings (new ones prefixed by >>):

   security/integrity/ima/ima_digest_list.c: In function 'ima_parse_rpm':
>> security/integrity/ima/ima_digest_list.c:147:4: warning: ignoring return value of 'hex2bin', declared with attribute warn_unused_result [-Wunused-result]
       hex2bin(digest, datap, digest_len);
       ^

vim +/hex2bin +147 security/integrity/ima/ima_digest_list.c

    98	
    99	static int ima_parse_rpm(loff_t size, void *buf)
   100	{
   101		void *bufp = buf, *bufendp = buf + size;
   102		struct rpm_hdr *hdr = bufp;
   103		u32 tags = be32_to_cpu(hdr->tags);
   104		struct rpm_entryinfo *entry;
   105		void *datap = bufp + sizeof(*hdr) + tags * sizeof(struct rpm_entryinfo);
   106		int digest_len = hash_digest_size[ima_hash_algo];
   107		u8 digest[digest_len];
   108		int ret, i, j;
   109	
   110		const unsigned char rpm_header_magic[8] = {
   111			0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
   112		};
   113	
   114		if (size < sizeof(*hdr)) {
   115			pr_err("Missing RPM header\n");
   116			return -EINVAL;
   117		}
   118	
   119		if (memcmp(bufp, rpm_header_magic, sizeof(rpm_header_magic))) {
   120			pr_err("Invalid RPM header\n");
   121			return -EINVAL;
   122		}
   123	
   124		bufp += sizeof(*hdr);
   125	
   126		for (i = 0; i < tags && (bufp + sizeof(*entry)) <= bufendp;
   127		     i++, bufp += sizeof(*entry)) {
   128			entry = bufp;
   129	
   130			if (be32_to_cpu(entry->tag) != RPMTAG_FILEDIGESTS)
   131				continue;
   132	
   133			datap += be32_to_cpu(entry->offset);
   134	
   135			for (j = 0; j < be32_to_cpu(entry->count) &&
   136			     datap < bufendp; j++) {
   137				if (strlen(datap) == 0) {
   138					datap++;
   139					continue;
   140				}
   141	
   142				if (datap + digest_len * 2 + 1 > bufendp) {
   143					pr_err("RPM header read at invalid offset\n");
   144					return -EINVAL;
   145				}
   146	
 > 147				hex2bin(digest, datap, digest_len);
   148	
   149				ret = ima_add_digest_data_entry(digest);
   150				if (ret < 0 && ret != -EEXIST)
   151					return ret;
   152	
   153				datap += digest_len * 2 + 1;
   154			}
   155	
   156			break;
   157		}
   158	
   159		return 0;
   160	}
   161	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 50308 bytes --]

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

* Re: [PATCH 06/12] ima: added parser of digest lists metadata
  2017-07-25 15:44 ` [PATCH 06/12] ima: added parser of digest lists metadata Roberto Sassu
@ 2017-07-27  5:15   ` kbuild test robot
  2017-08-01 10:17   ` [PATCH, RESEND " Roberto Sassu
  1 sibling, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2017-07-27  5:15 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: kbuild-all, linux-ima-devel, linux-security-module,
	linux-fsdevel, linux-doc, linux-kernel, Roberto Sassu

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

Hi Roberto,

[auto build test ERROR on integrity/next]
[also build test ERROR on v4.13-rc2 next-20170726]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Roberto-Sassu/ima-measure-digest-lists-instead-of-individual-files/20170727-123131
base:   https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next
config: x86_64-randconfig-x000-201730 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from security/integrity/ima/ima_fs.c:27:0:
   security/integrity/ima/ima.h: In function 'ima_parse_digest_list_metadata':
>> security/integrity/ima/ima.h:165:10: error: 'ENOTSUP' undeclared (first use in this function)
     return -ENOTSUP;
             ^~~~~~~
   security/integrity/ima/ima.h:165:10: note: each undeclared identifier is reported only once for each function it appears in

vim +/ENOTSUP +165 security/integrity/ima/ima.h

   135	
   136	/* Internal IMA function definitions */
   137	int ima_init(void);
   138	int ima_fs_init(void);
   139	int ima_add_template_entry(struct ima_template_entry *entry, int violation,
   140				   const char *op, struct inode *inode,
   141				   const unsigned char *filename);
   142	int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
   143	int ima_calc_buffer_hash(const void *buf, loff_t len,
   144				 struct ima_digest_data *hash);
   145	int ima_calc_field_array_hash(struct ima_field_data *field_data,
   146				      struct ima_template_desc *desc, int num_fields,
   147				      struct ima_digest_data *hash);
   148	int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
   149	void ima_add_violation(struct file *file, const unsigned char *filename,
   150			       struct integrity_iint_cache *iint,
   151			       const char *op, const char *cause);
   152	int ima_init_crypto(void);
   153	void ima_putc(struct seq_file *m, void *data, int datalen);
   154	void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
   155	struct ima_template_desc *ima_template_desc_current(void);
   156	int ima_restore_measurement_entry(struct ima_template_entry *entry);
   157	int ima_restore_measurement_list(loff_t bufsize, void *buf);
   158	struct ima_digest *ima_lookup_loaded_digest(u8 *digest);
   159	int ima_add_digest_data_entry(u8 *digest);
   160	#ifdef CONFIG_IMA_DIGEST_LIST
   161	ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf);
   162	#else
   163	static inline ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf)
   164	{
 > 165		return -ENOTSUP;
   166	}
   167	#endif
   168	int ima_measurements_show(struct seq_file *m, void *v);
   169	unsigned long ima_get_binary_runtime_size(void);
   170	int ima_init_template(void);
   171	void ima_init_template_list(void);
   172	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27483 bytes --]

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

* Re: [PATCH 09/12] ima: introduce securityfs interfaces for digest lists
  2017-07-25 15:44 ` [PATCH 09/12] ima: introduce securityfs interfaces for digest lists Roberto Sassu
@ 2017-07-27  5:38   ` kbuild test robot
  0 siblings, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2017-07-27  5:38 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: kbuild-all, linux-ima-devel, linux-security-module,
	linux-fsdevel, linux-doc, linux-kernel, Roberto Sassu

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

Hi Roberto,

[auto build test WARNING on integrity/next]
[also build test WARNING on v4.13-rc2 next-20170726]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Roberto-Sassu/ima-measure-digest-lists-instead-of-individual-files/20170727-123131
base:   https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next
config: x86_64-randconfig-x000-201730 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   In file included from security/integrity/ima/ima_fs.c:27:0:
   security/integrity/ima/ima.h: In function 'ima_parse_digest_list_metadata':
   security/integrity/ima/ima.h:165:10: error: 'ENOTSUP' undeclared (first use in this function)
     return -ENOTSUP;
             ^~~~~~~
   security/integrity/ima/ima.h:165:10: note: each undeclared identifier is reported only once for each function it appears in
>> security/integrity/ima/ima.h:166:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^

vim +166 security/integrity/ima/ima.h

d68a6fe9f Mimi Zohar      2016-12-19  135  
3323eec92 Mimi Zohar      2009-02-04  136  /* Internal IMA function definitions */
3323eec92 Mimi Zohar      2009-02-04  137  int ima_init(void);
bab739378 Mimi Zohar      2009-02-04  138  int ima_fs_init(void);
3323eec92 Mimi Zohar      2009-02-04  139  int ima_add_template_entry(struct ima_template_entry *entry, int violation,
9803d413f Roberto Sassu   2013-06-07  140  			   const char *op, struct inode *inode,
9803d413f Roberto Sassu   2013-06-07  141  			   const unsigned char *filename);
c7c8bb237 Dmitry Kasatkin 2013-04-25  142  int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
11d7646df Dmitry Kasatkin 2014-04-17  143  int ima_calc_buffer_hash(const void *buf, loff_t len,
11d7646df Dmitry Kasatkin 2014-04-17  144  			 struct ima_digest_data *hash);
b6f8f16f4 Roberto Sassu   2013-11-08  145  int ima_calc_field_array_hash(struct ima_field_data *field_data,
b6f8f16f4 Roberto Sassu   2013-11-08  146  			      struct ima_template_desc *desc, int num_fields,
c7c8bb237 Dmitry Kasatkin 2013-04-25  147  			      struct ima_digest_data *hash);
09ef54359 Dmitry Kasatkin 2013-06-07  148  int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
7d802a227 Roberto Sassu   2013-06-07  149  void ima_add_violation(struct file *file, const unsigned char *filename,
8d94eb9b5 Roberto Sassu   2015-04-11  150  		       struct integrity_iint_cache *iint,
3323eec92 Mimi Zohar      2009-02-04  151  		       const char *op, const char *cause);
76bb28f61 Dmitry Kasatkin 2012-06-08  152  int ima_init_crypto(void);
3ce1217d6 Roberto Sassu   2013-06-07  153  void ima_putc(struct seq_file *m, void *data, int datalen);
45b26133b Mimi Zohar      2015-06-11  154  void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
a71dc65d3 Roberto Sassu   2013-06-07  155  struct ima_template_desc *ima_template_desc_current(void);
94c3aac56 Mimi Zohar      2016-12-19  156  int ima_restore_measurement_entry(struct ima_template_entry *entry);
94c3aac56 Mimi Zohar      2016-12-19  157  int ima_restore_measurement_list(loff_t bufsize, void *buf);
4b1c19b3d Roberto Sassu   2017-07-25  158  struct ima_digest *ima_lookup_loaded_digest(u8 *digest);
4b1c19b3d Roberto Sassu   2017-07-25  159  int ima_add_digest_data_entry(u8 *digest);
3580b2df6 Roberto Sassu   2017-07-25  160  #ifdef CONFIG_IMA_DIGEST_LIST
3580b2df6 Roberto Sassu   2017-07-25  161  ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf);
3580b2df6 Roberto Sassu   2017-07-25  162  #else
3580b2df6 Roberto Sassu   2017-07-25  163  static inline ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf)
3580b2df6 Roberto Sassu   2017-07-25  164  {
3580b2df6 Roberto Sassu   2017-07-25 @165  	return -ENOTSUP;
3580b2df6 Roberto Sassu   2017-07-25 @166  }
3580b2df6 Roberto Sassu   2017-07-25  167  #endif
7b8589cc2 Mimi Zohar      2016-12-19  168  int ima_measurements_show(struct seq_file *m, void *v);
d158847ae Mimi Zohar      2016-12-19  169  unsigned long ima_get_binary_runtime_size(void);
a71dc65d3 Roberto Sassu   2013-06-07  170  int ima_init_template(void);
3f23d624d Mimi Zohar      2016-12-19  171  void ima_init_template_list(void);
3323eec92 Mimi Zohar      2009-02-04  172  

:::::: The code at line 166 was first introduced by commit
:::::: 3580b2df63c2ec47030a481fea2d2c865124aff4 ima: added parser of digest lists metadata

:::::: TO: Roberto Sassu <roberto.sassu@huawei.com>
:::::: CC: 0day robot <fengguang.wu@intel.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27483 bytes --]

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

* [PATCH, RESEND 06/12] ima: added parser of digest lists metadata
  2017-07-25 15:44 ` [PATCH 06/12] ima: added parser of digest lists metadata Roberto Sassu
  2017-07-27  5:15   ` kbuild test robot
@ 2017-08-01 10:17   ` Roberto Sassu
  1 sibling, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-08-01 10:17 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

Userspace applications will be able to load digest lists by supplying
their metadata.

Digest list metadata are:

- DATA_ALGO: algorithm of the digests to be uploaded
- DATA_DIGEST: digest of the file containing the digest list
- DATA_SIGNATURE: signature of the file containing the digest list
- DATA_FILE_PATH: pathname
- DATA_REF_ID: reference ID of the digest list
- DATA_TYPE: type of digest list

The new function ima_parse_digest_list_metadata() parses the metadata
and load each file individually. Then, it parses the data according
to the data type specified.

Since digest lists are measured, their digest is added to the hash table
so that IMA does not create a measurement entry for them (which would
affect the performance). The only measurement entry created will be
for the metadata.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/fs.h                       |   1 +
 security/integrity/ima/Kconfig           |  11 ++++
 security/integrity/ima/Makefile          |   1 +
 security/integrity/ima/ima.h             |   8 +++
 security/integrity/ima/ima_digest_list.c | 105 +++++++++++++++++++++++++++++++
 5 files changed, 126 insertions(+)
 create mode 100644 security/integrity/ima/ima_digest_list.c

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6e1fd5d..2eb6e7c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2751,6 +2751,7 @@ extern int do_pipe_flags(int *, int);
 	id(KEXEC_IMAGE, kexec-image)		\
 	id(KEXEC_INITRAMFS, kexec-initramfs)	\
 	id(POLICY, security-policy)		\
+	id(DIGEST_LIST, security-digest-list)	\
 	id(MAX_ID, )
 
 #define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 35ef693..8965dcc 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -227,3 +227,14 @@ config IMA_APPRAISE_SIGNED_INIT
 	default n
 	help
 	   This option requires user-space init to be signed.
+
+config IMA_DIGEST_LIST
+	bool "Measure files depending on uploaded digest lists"
+	depends on IMA
+	default n
+	help
+	   This option allows users to load digest lists. If a measured
+	   file has the same digest of one from loaded lists, IMA will
+	   not create a new measurement entry. A measurement entry will
+	   be created only when digest lists are loaded (this entry
+	   contains the digest of digest lists metadata).
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 29f198b..00dbe3a 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -9,4 +9,5 @@ ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
 	 ima_policy.o ima_template.o ima_template_lib.o
 ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
 ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
+ima-$(CONFIG_IMA_DIGEST_LIST) += ima_digest_list.o
 obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index a0c6808..9ecb7cc 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -157,6 +157,14 @@ int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
 struct ima_digest *ima_lookup_loaded_digest(u8 *digest);
 int ima_add_digest_data_entry(u8 *digest);
+#ifdef CONFIG_IMA_DIGEST_LIST
+ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf);
+#else
+static inline ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf)
+{
+	return -ENOTSUPP;
+}
+#endif
 int ima_measurements_show(struct seq_file *m, void *v);
 unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c
new file mode 100644
index 0000000..3e1ff69b
--- /dev/null
+++ b/security/integrity/ima/ima_digest_list.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 Huawei Technologies Co. Ltd.
+ *
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * File: ima_digest_list.c
+ *      Functions to manage digest lists.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/vmalloc.h>
+
+#include "ima.h"
+#include "ima_template_lib.h"
+
+enum digest_metadata_fields {DATA_ALGO, DATA_DIGEST, DATA_SIGNATURE,
+			     DATA_FILE_PATH, DATA_REF_ID, DATA_TYPE,
+			     DATA__LAST};
+
+static int ima_parse_digest_list_data(struct ima_field_data *data)
+{
+	void *digest_list;
+	loff_t digest_list_size;
+	u16 data_algo = le16_to_cpu(*(u16 *)data[DATA_ALGO].data);
+	u16 data_type = le16_to_cpu(*(u16 *)data[DATA_TYPE].data);
+	int ret;
+
+	if (data_algo != ima_hash_algo) {
+		pr_err("Incompatible digest algorithm, expected %s\n",
+		       hash_algo_name[ima_hash_algo]);
+		return -EINVAL;
+	}
+
+	ret = kernel_read_file_from_path(data[DATA_FILE_PATH].data,
+					 &digest_list, &digest_list_size,
+					 0, READING_DIGEST_LIST);
+	if (ret < 0) {
+		pr_err("Unable to open file: %s (%d)",
+		       data[DATA_FILE_PATH].data, ret);
+		return ret;
+	}
+
+	switch (data_type) {
+	default:
+		pr_err("Parser for data type %d not implemented\n", data_type);
+		ret = -EINVAL;
+	}
+
+	if (ret < 0) {
+		pr_err("Error parsing file: %s (%d)\n",
+		       data[DATA_FILE_PATH].data, ret);
+		return ret;
+	}
+
+	vfree(digest_list);
+	return ret;
+}
+
+ssize_t ima_parse_digest_list_metadata(loff_t size, void *buf)
+{
+	struct ima_field_data entry;
+
+	struct ima_field_data entry_data[DATA__LAST] = {
+		[DATA_ALGO] = {.len = sizeof(u16)},
+		[DATA_TYPE] = {.len = sizeof(u16)},
+	};
+
+	DECLARE_BITMAP(data_mask, DATA__LAST);
+	void *bufp = buf, *bufendp = buf + size;
+	int ret;
+
+	bitmap_zero(data_mask, DATA__LAST);
+	bitmap_set(data_mask, DATA_ALGO, 1);
+	bitmap_set(data_mask, DATA_TYPE, 1);
+
+	ret = ima_parse_buf(bufp, bufendp, &bufp, 1, &entry, NULL, NULL,
+			    ENFORCE_FIELDS, "metadata list entry");
+	if (ret < 0)
+		return ret;
+
+	ret = ima_parse_buf(entry.data, entry.data + entry.len, NULL,
+			    DATA__LAST, entry_data, NULL, data_mask,
+			    ENFORCE_FIELDS | ENFORCE_BUFEND,
+			    "metadata entry data");
+	if (ret < 0)
+		goto out;
+
+	ret = ima_add_digest_data_entry(entry_data[DATA_DIGEST].data);
+	if (ret < 0) {
+		if (ret == -EEXIST)
+			ret = 0;
+
+		goto out;
+	}
+
+	ret = ima_parse_digest_list_data(entry_data);
+out:
+	return ret < 0 ? ret : bufp - buf;
+}
-- 
2.9.3

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

* [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-07-25 15:44 ` [PATCH 08/12] ima: added parser for RPM data type Roberto Sassu
  2017-07-27  5:03   ` kbuild test robot
@ 2017-08-01 10:20   ` Roberto Sassu
  2017-08-01 10:27     ` Christoph Hellwig
  1 sibling, 1 reply; 30+ messages in thread
From: Roberto Sassu @ 2017-08-01 10:20 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-security-module, linux-fsdevel, linux-doc, linux-kernel,
	Roberto Sassu

This patch introduces a parser for RPM packages. It extracts the digests
from the RPMTAG_FILEDIGESTS header section and converts them to binary data
before adding them to the hash table.

The advantage of this data type is that verifiers can determine who
produced that data, as headers are signed by Linux distributions vendors.
RPM headers signatures can be provided as digest list metadata.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima_digest_list.c | 86 +++++++++++++++++++++++++++++++-
 1 file changed, 85 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c
index c1ef79a..0b5916d 100644
--- a/security/integrity/ima/ima_digest_list.c
+++ b/security/integrity/ima/ima_digest_list.c
@@ -19,11 +19,13 @@
 #include "ima.h"
 #include "ima_template_lib.h"
 
+#define RPMTAG_FILEDIGESTS 1035
+
 enum digest_metadata_fields {DATA_ALGO, DATA_DIGEST, DATA_SIGNATURE,
 			     DATA_FILE_PATH, DATA_REF_ID, DATA_TYPE,
 			     DATA__LAST};
 
-enum digest_data_types {DATA_TYPE_COMPACT_LIST};
+enum digest_data_types {DATA_TYPE_COMPACT_LIST, DATA_TYPE_RPM};
 
 enum compact_list_entry_ids {COMPACT_LIST_ID_DIGEST};
 
@@ -33,6 +35,20 @@ struct compact_list_hdr {
 	u32 datalen;
 } __packed;
 
+struct rpm_hdr {
+	u32 magic;
+	u32 reserved;
+	u32 tags;
+	u32 datasize;
+} __packed;
+
+struct rpm_entryinfo {
+	int32_t tag;
+	u32 type;
+	int32_t offset;
+	u32 count;
+} __packed;
+
 static int ima_parse_compact_list(loff_t size, void *buf)
 {
 	void *bufp = buf, *bufendp = buf + size;
@@ -80,6 +96,71 @@ static int ima_parse_compact_list(loff_t size, void *buf)
 	return 0;
 }
 
+static int ima_parse_rpm(loff_t size, void *buf)
+{
+	void *bufp = buf, *bufendp = buf + size;
+	struct rpm_hdr *hdr = bufp;
+	u32 tags = be32_to_cpu(hdr->tags);
+	struct rpm_entryinfo *entry;
+	void *datap = bufp + sizeof(*hdr) + tags * sizeof(struct rpm_entryinfo);
+	int digest_len = hash_digest_size[ima_hash_algo];
+	u8 digest[digest_len];
+	int ret, i, j;
+
+	const unsigned char rpm_header_magic[8] = {
+		0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
+	};
+
+	if (size < sizeof(*hdr)) {
+		pr_err("Missing RPM header\n");
+		return -EINVAL;
+	}
+
+	if (memcmp(bufp, rpm_header_magic, sizeof(rpm_header_magic))) {
+		pr_err("Invalid RPM header\n");
+		return -EINVAL;
+	}
+
+	bufp += sizeof(*hdr);
+
+	for (i = 0; i < tags && (bufp + sizeof(*entry)) <= bufendp;
+	     i++, bufp += sizeof(*entry)) {
+		entry = bufp;
+
+		if (be32_to_cpu(entry->tag) != RPMTAG_FILEDIGESTS)
+			continue;
+
+		datap += be32_to_cpu(entry->offset);
+
+		for (j = 0; j < be32_to_cpu(entry->count) &&
+		     datap < bufendp; j++) {
+			if (strlen(datap) == 0) {
+				datap++;
+				continue;
+			}
+
+			if (datap + digest_len * 2 + 1 > bufendp) {
+				pr_err("RPM header read at invalid offset\n");
+				return -EINVAL;
+			}
+
+			ret = hex2bin(digest, datap, digest_len);
+			if (ret < 0)
+				return -EINVAL;
+
+			ret = ima_add_digest_data_entry(digest);
+			if (ret < 0 && ret != -EEXIST)
+				return ret;
+
+			datap += digest_len * 2 + 1;
+		}
+
+		break;
+	}
+
+	return 0;
+}
+
 static int ima_parse_digest_list_data(struct ima_field_data *data)
 {
 	void *digest_list;
@@ -107,6 +188,9 @@ static int ima_parse_digest_list_data(struct ima_field_data *data)
 	case DATA_TYPE_COMPACT_LIST:
 		ret = ima_parse_compact_list(digest_list_size, digest_list);
 		break;
+	case DATA_TYPE_RPM:
+		ret = ima_parse_rpm(digest_list_size, digest_list);
+		break;
 	default:
 		pr_err("Parser for data type %d not implemented\n", data_type);
 		ret = -EINVAL;
-- 
2.9.3

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

* Re: [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-01 10:20   ` [PATCH, RESEND " Roberto Sassu
@ 2017-08-01 10:27     ` Christoph Hellwig
  2017-08-01 10:58       ` Roberto Sassu
  0 siblings, 1 reply; 30+ messages in thread
From: Christoph Hellwig @ 2017-08-01 10:27 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: linux-ima-devel, linux-security-module, linux-fsdevel, linux-doc,
	linux-kernel

On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
> This patch introduces a parser for RPM packages. It extracts the digests
> from the RPMTAG_FILEDIGESTS header section and converts them to binary data
> before adding them to the hash table.
> 
> The advantage of this data type is that verifiers can determine who
> produced that data, as headers are signed by Linux distributions vendors.
> RPM headers signatures can be provided as digest list metadata.

Err, parsing arbitrary file formats has no business in the kernel.

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

* Re: [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-01 10:27     ` Christoph Hellwig
@ 2017-08-01 10:58       ` Roberto Sassu
  2017-08-02  7:22         ` [Linux-ima-devel] " James Morris
  0 siblings, 1 reply; 30+ messages in thread
From: Roberto Sassu @ 2017-08-01 10:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-ima-devel, linux-security-module, linux-fsdevel, linux-doc,
	linux-kernel, keyrings

On 8/1/2017 12:27 PM, Christoph Hellwig wrote:
> On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
>> This patch introduces a parser for RPM packages. It extracts the digests
>> from the RPMTAG_FILEDIGESTS header section and converts them to binary data
>> before adding them to the hash table.
>>
>> The advantage of this data type is that verifiers can determine who
>> produced that data, as headers are signed by Linux distributions vendors.
>> RPM headers signatures can be provided as digest list metadata.
>
> Err, parsing arbitrary file formats has no business in the kernel.

The benefit of this choice is that no actions are required for
Linux distribution vendors to support the solution I'm proposing,
because they already provide signed digest lists (RPM headers).

Since the proof of loading a digest list is the digest of the
digest list (included in the list metadata), if RPM headers are
converted to a different format, remote attestation verifiers
cannot check the signature.

If the concern is security, it would be possible to prevent unsigned
RPM headers from being parsed, if the PGP key type is upstreamed
(adding in CC keyrings@vger.kernel.org).

Roberto

-- 
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Qiuen PENG, Shengli WANG

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

* Re: [Linux-ima-devel] [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-01 10:58       ` Roberto Sassu
@ 2017-08-02  7:22         ` James Morris
  2017-08-02 11:22           ` Roberto Sassu
  2017-08-09  9:15           ` Roberto Sassu
  0 siblings, 2 replies; 30+ messages in thread
From: James Morris @ 2017-08-02  7:22 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: Christoph Hellwig, linux-doc, linux-kernel, linux-fsdevel,
	linux-security-module, keyrings, linux-ima-devel

On Tue, 1 Aug 2017, Roberto Sassu wrote:

> On 8/1/2017 12:27 PM, Christoph Hellwig wrote:
> > On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
> > > This patch introduces a parser for RPM packages. It extracts the digests
> > > from the RPMTAG_FILEDIGESTS header section and converts them to binary
> > > data
> > > before adding them to the hash table.
> > >
> > > The advantage of this data type is that verifiers can determine who
> > > produced that data, as headers are signed by Linux distributions vendors.
> > > RPM headers signatures can be provided as digest list metadata.
> >
> > Err, parsing arbitrary file formats has no business in the kernel.
> 
> The benefit of this choice is that no actions are required for
> Linux distribution vendors to support the solution I'm proposing,
> because they already provide signed digest lists (RPM headers).
> 
> Since the proof of loading a digest list is the digest of the
> digest list (included in the list metadata), if RPM headers are
> converted to a different format, remote attestation verifiers
> cannot check the signature.
> 
> If the concern is security, it would be possible to prevent unsigned
> RPM headers from being parsed, if the PGP key type is upstreamed
> (adding in CC keyrings@vger.kernel.org).

It's a security concern and also a layering violation, there should be no 
need to parse package file formats in the kernel.

I'm not really clear on exactly how this patch series works.  Can you 
provide a more concrete explanation of what steps would occur during boot 
and attestation? 

-- 
James Morris
<jmorris@namei.org>

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

* Re: [Linux-ima-devel] [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-02  7:22         ` [Linux-ima-devel] " James Morris
@ 2017-08-02 11:22           ` Roberto Sassu
  2017-08-09  9:15           ` Roberto Sassu
  1 sibling, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-08-02 11:22 UTC (permalink / raw)
  To: James Morris
  Cc: Christoph Hellwig, linux-doc, linux-kernel, linux-fsdevel,
	linux-security-module, keyrings, linux-ima-devel

On 8/2/2017 9:22 AM, James Morris wrote:
> On Tue, 1 Aug 2017, Roberto Sassu wrote:
>
>> On 8/1/2017 12:27 PM, Christoph Hellwig wrote:
>>> On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
>>>> This patch introduces a parser for RPM packages. It extracts the digests
>>>> from the RPMTAG_FILEDIGESTS header section and converts them to binary
>>>> data
>>>> before adding them to the hash table.
>>>>
>>>> The advantage of this data type is that verifiers can determine who
>>>> produced that data, as headers are signed by Linux distributions vendors.
>>>> RPM headers signatures can be provided as digest list metadata.
>>>
>>> Err, parsing arbitrary file formats has no business in the kernel.
>>
>> The benefit of this choice is that no actions are required for
>> Linux distribution vendors to support the solution I'm proposing,
>> because they already provide signed digest lists (RPM headers).
>>
>> Since the proof of loading a digest list is the digest of the
>> digest list (included in the list metadata), if RPM headers are
>> converted to a different format, remote attestation verifiers
>> cannot check the signature.
>>
>> If the concern is security, it would be possible to prevent unsigned
>> RPM headers from being parsed, if the PGP key type is upstreamed
>> (adding in CC keyrings@vger.kernel.org).
>
> It's a security concern and also a layering violation, there should be no
> need to parse package file formats in the kernel.
>
> I'm not really clear on exactly how this patch series works.  Can you
> provide a more concrete explanation of what steps would occur during boot
> and attestation?

The main idea of this patch set is that, if a system executes
or reads good files (e.g. those from a Linux distribution),
the difference between the assertion 'a file could have possibly
been accessed' and 'a file has been accessed' is not relevant
for verifiers that only check the provenance of software.

Then, for those verifiers, a measurement representing the list of
good files which could have possibly been accessed gives the same
guarantees of individual file measurements.

The patch set introduces two data types:

- digest list: contains the digests of good files
- list metadata: contains the digest, the signature and the path
                  of each digest list to load (why loading many
                  lists instead of one will be clear after I explain
                  the remote attestation verification process)

Steps at boot:

1) systemd reads the path of list metadata from /etc/ima/digest-lists
    and writes it to a new securityfs file created by IMA
2) IMA reads and parses the list metadata (same mechanism for
    loading a policy, already upstreamed)
3) for each list metadata, IMA reads and parses the digest list
    and adds the file digests to a hash table
4) when a file is accessed, IMA calculates the digest as before
    and searches the file digest in the new hash table; if the
    digest is found, IMA sets the IMA_MEASURED flag in the inode
    metadata and clears the IMA_MEASURE action

Notes:

- list metadata and digest lists are measured before IMA reads them
- the digest of digest lists is also added to the hash table, otherwise
   there would be a measurement for each digest list

The measurement list looks like:

10 <template digest> ima-ng <digest> boot_aggregate
10 <template digest> ima-ng <digest> systemd (exe + libs)
10 <template digest> ima-ng <digest> /etc/ima/digest-lists
10 <template digest> ima-ng <digest> <list metadata>
10 <template digest> ima-ng <digest> <unknown files>


Steps during the verification:

Case 1: list metadata and digest lists are provided to verifiers

This is necessary when:
- digest lists are not signed
- verifiers do not trust the signer
- verifiers want to perform more checks on digest lists
   (digest lists may contain digest of outdated software)

Verifiers:

1) parse the list metadata received
2) for each digest list received, calculate the digest and
    compare it with the digest included in the list metadata
3) calculate the digest of list metadata and compare it with
    the digest in the measurement list
4) calculate the digest of the path of list metadata and compare
    it with the digest of /etc/ima/digest-lists in the measurement list
5) check boot_aggregate, systemd exe and libs, and unknown files
6) check the digest lists


Case 2: only list metadata is provided to verifiers

Verifiers:

1) parse the list metadata received
2) for each digest list, verify the signature
3) calculate the digest of the path of list metadata and compare
    it with the digest of /etc/ima/digest-lists in the measurement list
4) check boot_aggregate, systemd exe and libs, and unknown files

In Case 2, the verification process is simplified, because if
the signature of digest lists is valid, this means that possibly
accessed files are provided by the signer.

The problem here is that verifiers know the digest of possibly
accessed files from the measurement done by IMA at the time
digest lists are read. If IMA cannot parse the original (signed)
digest list, it would measure something that cannot be verified
with the signature.

RPM-based distributions already provide signed digest lists
(the RPM headers) for each package. To avoid the performance
penalty due to extending a PCR for each digest list, only
an entry for the list metadata is added to the measurement list.

For RPM-based Linux distributions, the full lifecycle for configuring
IMA can be implemented with very low effort. The tasks are:

1) systemd patch to load list metadata: just extend the existing
    patch to load the policy
2) userspace tools to parse the RPM database: done
3) dracut module to generate and include the digest lists and
    metadata into the initial ram disk: at the moment this is done
    from the dracut command line
4) plugin for the software management that executes the tool
    to generate the digest list for updated packages: to be implemented

Roberto

-- 
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Qiuen PENG, Shengli WANG

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

* Re: [Linux-ima-devel] [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-02  7:22         ` [Linux-ima-devel] " James Morris
  2017-08-02 11:22           ` Roberto Sassu
@ 2017-08-09  9:15           ` Roberto Sassu
  2017-08-09 14:30             ` Mimi Zohar
  1 sibling, 1 reply; 30+ messages in thread
From: Roberto Sassu @ 2017-08-09  9:15 UTC (permalink / raw)
  To: James Morris
  Cc: Christoph Hellwig, linux-doc, linux-kernel, linux-fsdevel,
	linux-security-module, keyrings, linux-ima-devel

On 8/2/2017 9:22 AM, James Morris wrote:
> On Tue, 1 Aug 2017, Roberto Sassu wrote:
>
>> On 8/1/2017 12:27 PM, Christoph Hellwig wrote:
>>> On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
>>>> This patch introduces a parser for RPM packages. It extracts the digests
>>>> from the RPMTAG_FILEDIGESTS header section and converts them to binary
>>>> data
>>>> before adding them to the hash table.
>>>>
>>>> The advantage of this data type is that verifiers can determine who
>>>> produced that data, as headers are signed by Linux distributions vendors.
>>>> RPM headers signatures can be provided as digest list metadata.
>>>
>>> Err, parsing arbitrary file formats has no business in the kernel.
>>
>> The benefit of this choice is that no actions are required for
>> Linux distribution vendors to support the solution I'm proposing,
>> because they already provide signed digest lists (RPM headers).
>>
>> Since the proof of loading a digest list is the digest of the
>> digest list (included in the list metadata), if RPM headers are
>> converted to a different format, remote attestation verifiers
>> cannot check the signature.
>>
>> If the concern is security, it would be possible to prevent unsigned
>> RPM headers from being parsed, if the PGP key type is upstreamed
>> (adding in CC keyrings@vger.kernel.org).
>
> It's a security concern and also a layering violation, there should be no
> need to parse package file formats in the kernel.

Parsing RPMs is not strictly necessary. Digests from the headers
can be extracted and written to a new file using the compact data
format (introduced with patch 7/12).

At boot time, IMA measures this file before digests are uploaded to the
kernel. At this point, only files with unknown digest will be added
to the measurement list. At verification time, verifiers recreate the
measurement list by merging together the digests uploaded to the
kernel with the unknown digests. Then, they verify the obtained list.

There are two ways to verify the digests: searching them in a reference
database, or checking a signature. With the 'ima-sig' measurement list
template, it is possible to verify signatures for each accessed file.
With this patch set, it is possible to verify the signature of
the file containing the digests uploaded to the kernel. If the data
format changes, the signature cannot be verified.

To avoid this limitation, the parsers could be moved to a userspace
tool which then uploads the parsed digests to the kernel. IMA would
measure the original files. But, if the tool is compromised, it could
load digests not included in the parsed files. With the current solution
this problem does not arise because no changes can be done by userspace
applications to the uploaded data while digests are parsed by IMA.

I could remove the RPM parser from the patch set for now.

Is the remaining part of the patch set ok, and is the explanation of
what it does clear?

Thanks

Roberto


> I'm not really clear on exactly how this patch series works.  Can you
> provide a more concrete explanation of what steps would occur during boot
> and attestation?
>

-- 
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Qiuen PENG, Shengli WANG

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

* Re: [Linux-ima-devel] [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-09  9:15           ` Roberto Sassu
@ 2017-08-09 14:30             ` Mimi Zohar
  2017-08-09 17:18               ` Roberto Sassu
  0 siblings, 1 reply; 30+ messages in thread
From: Mimi Zohar @ 2017-08-09 14:30 UTC (permalink / raw)
  To: Roberto Sassu, James Morris
  Cc: Christoph Hellwig, linux-doc, linux-kernel, linux-fsdevel,
	linux-security-module, keyrings, linux-ima-devel,
	Jarkko Sakkinen

On Wed, 2017-08-09 at 11:15 +0200, Roberto Sassu wrote:
> On 8/2/2017 9:22 AM, James Morris wrote:
> > On Tue, 1 Aug 2017, Roberto Sassu wrote:
> >
> >> On 8/1/2017 12:27 PM, Christoph Hellwig wrote:
> >>> On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
> >>>> This patch introduces a parser for RPM packages. It extracts the digests
> >>>> from the RPMTAG_FILEDIGESTS header section and converts them to binary
> >>>> data
> >>>> before adding them to the hash table.
> >>>>
> >>>> The advantage of this data type is that verifiers can determine who
> >>>> produced that data, as headers are signed by Linux distributions vendors.
> >>>> RPM headers signatures can be provided as digest list metadata.
> >>>
> >>> Err, parsing arbitrary file formats has no business in the kernel.
> >>
> >> The benefit of this choice is that no actions are required for
> >> Linux distribution vendors to support the solution I'm proposing,
> >> because they already provide signed digest lists (RPM headers).
> >>
> >> Since the proof of loading a digest list is the digest of the
> >> digest list (included in the list metadata), if RPM headers are
> >> converted to a different format, remote attestation verifiers
> >> cannot check the signature.
> >>
> >> If the concern is security, it would be possible to prevent unsigned
> >> RPM headers from being parsed, if the PGP key type is upstreamed
> >> (adding in CC keyrings@vger.kernel.org).
> >
> > It's a security concern and also a layering violation, there should be no
> > need to parse package file formats in the kernel.
> 
> Parsing RPMs is not strictly necessary. Digests from the headers
> can be extracted and written to a new file using the compact data
> format (introduced with patch 7/12).
> 
> At boot time, IMA measures this file before digests are uploaded to the
> kernel. At this point, only files with unknown digest will be added
> to the measurement list. At verification time, verifiers recreate the
> measurement list by merging together the digests uploaded to the
> kernel with the unknown digests. Then, they verify the obtained list.
> 
> There are two ways to verify the digests: searching them in a reference
> database, or checking a signature. With the 'ima-sig' measurement list
> template, it is possible to verify signatures for each accessed file.
> With this patch set, it is possible to verify the signature of
> the file containing the digests uploaded to the kernel. If the data
> format changes, the signature cannot be verified.
> 
> To avoid this limitation, the parsers could be moved to a userspace
> tool which then uploads the parsed digests to the kernel. IMA would
> measure the original files. But, if the tool is compromised, it could
> load digests not included in the parsed files. With the current solution
> this problem does not arise because no changes can be done by userspace
> applications to the uploaded data while digests are parsed by IMA.
> 
> I could remove the RPM parser from the patch set for now.
> 
> Is the remaining part of the patch set ok, and is the explanation of
> what it does clear?

>From a trusted boot perspective, file measurements are added to the
measurement list, before access to the file is given.  The measurement
list contains ALL measurements, as defined by policy.  This patch set
changes that meaning to be all measurements, as defined by policy,
with the exception of those in a white list.

Changing the fundamental meaning of the measurement list is not
acceptable.  You could define a new securityfs file to differentiate
between the full measurement list and this abbreviated one.  But
before making this sort of change, I would prefer to address the
underlying problem - TPM peformance.

There are a couple of things that could be done to improve the TPM
driver performance, itself.  Once all of these options have been
pursued, we could then consider batching the measurements to the TPM,
meaning that the measurement list would still contain all the file
measurements, but instead of extending the TPM for each measurement, a
batched hash - a hash of a group of file measurements - would be
extended into the TPM.

Mimi

> > I'm not really clear on exactly how this patch series works.  Can you
> > provide a more concrete explanation of what steps would occur during boot
> > and attestation?
> >

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

* Re: [Linux-ima-devel] [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-09 14:30             ` Mimi Zohar
@ 2017-08-09 17:18               ` Roberto Sassu
  2017-08-10 13:12                 ` Mimi Zohar
  0 siblings, 1 reply; 30+ messages in thread
From: Roberto Sassu @ 2017-08-09 17:18 UTC (permalink / raw)
  To: Mimi Zohar, James Morris
  Cc: Christoph Hellwig, linux-doc, linux-kernel, linux-fsdevel,
	linux-security-module, keyrings, linux-ima-devel,
	Jarkko Sakkinen

On 8/9/2017 4:30 PM, Mimi Zohar wrote:
> On Wed, 2017-08-09 at 11:15 +0200, Roberto Sassu wrote:
>> On 8/2/2017 9:22 AM, James Morris wrote:
>>> On Tue, 1 Aug 2017, Roberto Sassu wrote:
>>>
>>>> On 8/1/2017 12:27 PM, Christoph Hellwig wrote:
>>>>> On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
>>>>>> This patch introduces a parser for RPM packages. It extracts the digests
>>>>>> from the RPMTAG_FILEDIGESTS header section and converts them to binary
>>>>>> data
>>>>>> before adding them to the hash table.
>>>>>>
>>>>>> The advantage of this data type is that verifiers can determine who
>>>>>> produced that data, as headers are signed by Linux distributions vendors.
>>>>>> RPM headers signatures can be provided as digest list metadata.
>>>>>
>>>>> Err, parsing arbitrary file formats has no business in the kernel.
>>>>
>>>> The benefit of this choice is that no actions are required for
>>>> Linux distribution vendors to support the solution I'm proposing,
>>>> because they already provide signed digest lists (RPM headers).
>>>>
>>>> Since the proof of loading a digest list is the digest of the
>>>> digest list (included in the list metadata), if RPM headers are
>>>> converted to a different format, remote attestation verifiers
>>>> cannot check the signature.
>>>>
>>>> If the concern is security, it would be possible to prevent unsigned
>>>> RPM headers from being parsed, if the PGP key type is upstreamed
>>>> (adding in CC keyrings@vger.kernel.org).
>>>
>>> It's a security concern and also a layering violation, there should be no
>>> need to parse package file formats in the kernel.
>>
>> Parsing RPMs is not strictly necessary. Digests from the headers
>> can be extracted and written to a new file using the compact data
>> format (introduced with patch 7/12).
>>
>> At boot time, IMA measures this file before digests are uploaded to the
>> kernel. At this point, only files with unknown digest will be added
>> to the measurement list. At verification time, verifiers recreate the
>> measurement list by merging together the digests uploaded to the
>> kernel with the unknown digests. Then, they verify the obtained list.
>>
>> There are two ways to verify the digests: searching them in a reference
>> database, or checking a signature. With the 'ima-sig' measurement list
>> template, it is possible to verify signatures for each accessed file.
>> With this patch set, it is possible to verify the signature of
>> the file containing the digests uploaded to the kernel. If the data
>> format changes, the signature cannot be verified.
>>
>> To avoid this limitation, the parsers could be moved to a userspace
>> tool which then uploads the parsed digests to the kernel. IMA would
>> measure the original files. But, if the tool is compromised, it could
>> load digests not included in the parsed files. With the current solution
>> this problem does not arise because no changes can be done by userspace
>> applications to the uploaded data while digests are parsed by IMA.
>>
>> I could remove the RPM parser from the patch set for now.
>>
>> Is the remaining part of the patch set ok, and is the explanation of
>> what it does clear?
>
> From a trusted boot perspective, file measurements are added to the
> measurement list, before access to the file is given.  The measurement
> list contains ALL measurements, as defined by policy.  This patch set
> changes that meaning to be all measurements, as defined by policy,
> with the exception of those in a white list.

The digest list is also measured, so the measurement list is complete.
Verifiers have to check the digest of digest lists. Otherwise, they
would get an unknown digest and conclude that the system being verified
has been compromised.

If you prefer, I could add a new policy rule option to avoid file
measurements if the digest is in the digest list.


> Changing the fundamental meaning of the measurement list is not
> acceptable.  You could define a new securityfs file to differentiate
> between the full measurement list and this abbreviated one.  But

There cannot be two measurement lists at the same time. Providing the
full measurement list (containing the digest of files being accessed)
implies that its integrity must be protected with PCR extends, making
the optimization done by this patch set useless.


> before making this sort of change, I would prefer to address the
> underlying problem - TPM peformance.

Even if the TPM driver performance improves significantly (17 seconds
for 1000 extends), the boot time delay would be still noticeable
(8.5 seconds for normal boot + 24 seconds for 1400 PCR extends).

In my opinion, this patch set is useful without considering the
performance improvement: reduced size of measurement lists and
verification of digest list signatures, instead of file signatures,
where signatures are already provided by Linux distributions.


> There are a couple of things that could be done to improve the TPM
> driver performance, itself.  Once all of these options have been
> pursued, we could then consider batching the measurements to the TPM,
> meaning that the measurement list would still contain all the file
> measurements, but instead of extending the TPM for each measurement, a
> batched hash - a hash of a group of file measurements - would be
> extended into the TPM.

Probably, I didn't explain clearly that this patch set does not decrease
the security of IMA.

Extending the PCR for a group of file measurements means that the system
can be compromised between two PCR extends without detection because
a malicious binary could alter IMA before the next extend.

This patch set extends the PCR with the digest of digest lists, before
files are accessed. No actions happen before either the digest lists
have been measured or the file measurement is added to the measurement
list, if the file digest is not included in the digest list.

Roberto


> Mimi
>
>>> I'm not really clear on exactly how this patch series works.  Can you
>>> provide a more concrete explanation of what steps would occur during boot
>>> and attestation?
>>>
>

-- 
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Qiuen PENG, Shengli WANG

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

* Re: [Linux-ima-devel] [PATCH 11/12] ima: don't report measurements if digests are included in the loaded lists
  2017-07-25 15:44 ` [PATCH 11/12] ima: don't report measurements if digests are included in the loaded lists Roberto Sassu
@ 2017-08-09 20:36   ` Ken Goldman
  2017-08-17  8:32     ` Roberto Sassu
  0 siblings, 1 reply; 30+ messages in thread
From: Ken Goldman @ 2017-08-09 20:36 UTC (permalink / raw)
  To: linux-ima-devel
  Cc: linux-fsdevel, linux-security-module, linux-kernel, linux-doc

On 7/25/2017 11:44 AM, Roberto Sassu wrote:
> Don't report measurements if the file digest has been included in
> an uploaded digest list.
> 
> The advantage of this solution is that the boot time overhead, when
> a TPM is available, is very small because a PCR is extended only
> for unknown files. The disadvantage is that verifiers do not know
> anymore which and when files are accessed (they must assume that
> the worst case happened, i.e. all files have been accessed).

Am I reading this correctly that you want to measure certain files, but 
not ones that have been included in a "digest list", which sounds like a 
white list of sorts.

If so, I have two concerns:

1 - How would the client get this digest list?  Shouldn't it be up to 
the relying party to decide what is trusted and not trusted, not the client?

What of the case with two different relying parties that have a 
different list of trusted applications?  E.g., one trusts any version of 
program X, while the other trusts only version 3.1 and up?

2 - What about files on the digest list that were not run?  The relying 
party may want to know if a program wasn't run?  E.g., antivirus or a 
firewall.

If the rule is "don't measure if it's on the digest list", how does the 
relying party know if it was run?

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

* Re: [Linux-ima-devel] [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-09 17:18               ` Roberto Sassu
@ 2017-08-10 13:12                 ` Mimi Zohar
  2017-08-17  9:15                   ` Roberto Sassu
  0 siblings, 1 reply; 30+ messages in thread
From: Mimi Zohar @ 2017-08-10 13:12 UTC (permalink / raw)
  To: Roberto Sassu, James Morris
  Cc: Christoph Hellwig, linux-doc, linux-kernel, linux-fsdevel,
	linux-security-module, keyrings, linux-ima-devel,
	Jarkko Sakkinen

On Wed, 2017-08-09 at 19:18 +0200, Roberto Sassu wrote:
> On 8/9/2017 4:30 PM, Mimi Zohar wrote:
> > On Wed, 2017-08-09 at 11:15 +0200, Roberto Sassu wrote:
> >> On 8/2/2017 9:22 AM, James Morris wrote:
> >>> On Tue, 1 Aug 2017, Roberto Sassu wrote:
> >>>
> >>>> On 8/1/2017 12:27 PM, Christoph Hellwig wrote:
> >>>>> On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
> >>>>>> This patch introduces a parser for RPM packages. It extracts the digests
> >>>>>> from the RPMTAG_FILEDIGESTS header section and converts them to binary
> >>>>>> data
> >>>>>> before adding them to the hash table.
> >>>>>>
> >>>>>> The advantage of this data type is that verifiers can determine who
> >>>>>> produced that data, as headers are signed by Linux distributions vendors.
> >>>>>> RPM headers signatures can be provided as digest list metadata.
> >>>>>
> >>>>> Err, parsing arbitrary file formats has no business in the kernel.
> >>>>
> >>>> The benefit of this choice is that no actions are required for
> >>>> Linux distribution vendors to support the solution I'm proposing,
> >>>> because they already provide signed digest lists (RPM headers).
> >>>>
> >>>> Since the proof of loading a digest list is the digest of the
> >>>> digest list (included in the list metadata), if RPM headers are
> >>>> converted to a different format, remote attestation verifiers
> >>>> cannot check the signature.
> >>>>
> >>>> If the concern is security, it would be possible to prevent unsigned
> >>>> RPM headers from being parsed, if the PGP key type is upstreamed
> >>>> (adding in CC keyrings@vger.kernel.org).
> >>>
> >>> It's a security concern and also a layering violation, there should be no
> >>> need to parse package file formats in the kernel.
> >>
> >> Parsing RPMs is not strictly necessary. Digests from the headers
> >> can be extracted and written to a new file using the compact data
> >> format (introduced with patch 7/12).
> >>
> >> At boot time, IMA measures this file before digests are uploaded to the
> >> kernel. At this point, only files with unknown digest will be added
> >> to the measurement list. At verification time, verifiers recreate the
> >> measurement list by merging together the digests uploaded to the
> >> kernel with the unknown digests. Then, they verify the obtained list.
> >>
> >> There are two ways to verify the digests: searching them in a reference
> >> database, or checking a signature. With the 'ima-sig' measurement list
> >> template, it is possible to verify signatures for each accessed file.
> >> With this patch set, it is possible to verify the signature of
> >> the file containing the digests uploaded to the kernel. If the data
> >> format changes, the signature cannot be verified.
> >>
> >> To avoid this limitation, the parsers could be moved to a userspace
> >> tool which then uploads the parsed digests to the kernel. IMA would
> >> measure the original files. But, if the tool is compromised, it could
> >> load digests not included in the parsed files. With the current solution
> >> this problem does not arise because no changes can be done by userspace
> >> applications to the uploaded data while digests are parsed by IMA.
> >>
> >> I could remove the RPM parser from the patch set for now.
> >>
> >> Is the remaining part of the patch set ok, and is the explanation of
> >> what it does clear?
> >
> > From a trusted boot perspective, file measurements are added to the
> > measurement list, before access to the file is given.  The measurement
> > list contains ALL measurements, as defined by policy.  This patch set
> > changes that meaning to be all measurements, as defined by policy,
> > with the exception of those in a white list.
> 
> The digest list is also measured, so the measurement list is complete.
> Verifiers have to check the digest of digest lists. Otherwise, they
> would get an unknown digest and conclude that the system being verified
> has been compromised.

Your proposal is basically a pre-approved "batched" measurement, of a
set of known good measurements, without the corresponding list of
measurements that this "batched" measurement represents.  Right?

This pre-approved "batched" measurement represents not what has been
accessed/executed on the system, but what potentially could be
accessed/executed.  That's a major difference.

> If you prefer, I could add a new policy rule option to avoid file
> measurements if the digest is in the digest list.

Huh?  Patch "ima: don't report measurements if digests are included in
the loaded lists" is already doing this.

> 
> > Changing the fundamental meaning of the measurement list is not
> > acceptable.  You could define a new securityfs file to differentiate
> > between the full measurement list and this abbreviated one.  But
> 
> There cannot be two measurement lists at the same time. Providing the
> full measurement list (containing the digest of files being accessed)
> implies that its integrity must be protected with PCR extends, making
> the optimization done by this patch set useless.

True, so you would be able to configure the system with one or the
other type of list, not both.  At least there would be a clear
understanding of what that list represents.

> 
> > before making this sort of change, I would prefer to address the
> > underlying problem - TPM peformance.
> 
> Even if the TPM driver performance improves significantly (17 seconds
> for 1000 extends), the boot time delay would be still noticeable
> (8.5 seconds for normal boot + 24 seconds for 1400 PCR extends).

Agreed, there is still room for more TPM improvements.  Just Nayna's
one patch, without any other changes, brought the timing down from 53s
for a 1000 extends to just 11s.  (The initial patch was Nack'ed, but
we're working with the tpmdd and the TCG's device driver work group
(DDWG).)

> In my opinion, this patch set is useful without considering the
> performance improvement: reduced size of measurement lists and
> verification of digest list signatures, instead of file signatures,
> where signatures are already provided by Linux distributions.

Right, there's always a trade off.  My suggestion, assuming we go with
this approach, would be to make that trade off clear by using
different lists.

> 
> > There are a couple of things that could be done to improve the TPM
> > driver performance, itself.  Once all of these options have been
> > pursued, we could then consider batching the measurements to the TPM,
> > meaning that the measurement list would still contain all the file
> > measurements, but instead of extending the TPM for each measurement, a
> > batched hash - a hash of a group of file measurements - would be
> > extended into the TPM.
> 
> Probably, I didn't explain clearly that this patch set does not decrease
> the security of IMA.
> 
> Extending the PCR for a group of file measurements means that the system
> can be compromised between two PCR extends without detection because
> a malicious binary could alter IMA before the next extend.

Currently, a measurement is added to the measurement list and then is
used to extend the TPM, before returning to the caller.

A performance improvement would still first add the measurement to the
measurement list, but would then queue and wait for the measurement to
extend the TPM, before returning to the caller.  In a multi threaded
environment, the queued measurements could be "batched" - a hash of a
set of hashes - to extend the TPM.

The delay would be at most two times it takes to extend the TPM - one
to complete an existing current "batched" extend and another new
"batched" extend.

The difficulty with this approach is identifying which measurements
are included in which "batched" measurement.  This approach provides
the same guarantees as previously.

Before making the TPM performance problem an IMA issue and "fixing" it
in IMA, I would prefer that the TPM performance be addressed directly.

Mimi

> 
> This patch set extends the PCR with the digest of digest lists, before
> files are accessed. No actions happen before either the digest lists
> have been measured or the file measurement is added to the measurement
> list, if the file digest is not included in the digest list.

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

* Re: [Linux-ima-devel] [PATCH 11/12] ima: don't report measurements if digests are included in the loaded lists
  2017-08-09 20:36   ` [Linux-ima-devel] " Ken Goldman
@ 2017-08-17  8:32     ` Roberto Sassu
  0 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-08-17  8:32 UTC (permalink / raw)
  To: Ken Goldman, linux-ima-devel
  Cc: linux-fsdevel, linux-security-module, linux-kernel, linux-doc

On 8/9/2017 10:36 PM, Ken Goldman wrote:
> On 7/25/2017 11:44 AM, Roberto Sassu wrote:
>> Don't report measurements if the file digest has been included in
>> an uploaded digest list.
>>
>> The advantage of this solution is that the boot time overhead, when
>> a TPM is available, is very small because a PCR is extended only
>> for unknown files. The disadvantage is that verifiers do not know
>> anymore which and when files are accessed (they must assume that
>> the worst case happened, i.e. all files have been accessed).
>
> Am I reading this correctly that you want to measure certain files, but
> not ones that have been included in a "digest list", which sounds like a
> white list of sorts.
>
> If so, I have two concerns:
>
> 1 - How would the client get this digest list?  Shouldn't it be up to
> the relying party to decide what is trusted and not trusted, not the
> client?

The client can get the digest list from the RPM database or the
measurement list of a previous boot. A verifier still decides if the
client is trusted or not, depending on what could be possibly accessed
rather than what has been accessed.


> What of the case with two different relying parties that have a
> different list of trusted applications?  E.g., one trusts any version of
> program X, while the other trusts only version 3.1 and up?

There are two ways to provide more accurate information (make the list
of possibly accessed files closer to the list of accessed files):

1) use the measurement list of a previous boot as a source for
    the digest list

2) use the RPM database as a source for the digest lists, and load the
    headers of the latest version of RPMs

    and:

    load only the headers of RPMs including files that appear in the
    measurement list of a previous boot (this solution should be
    preferred to solution 1, as signature-based attestation can be done)


> 2 - What about files on the digest list that were not run?  The relying
> party may want to know if a program wasn't run?  E.g., antivirus or a
> firewall.
>
> If the rule is "don't measure if it's on the digest list", how does the
> relying party know if it was run?

If a measurement list does not contain unknown digests, this means that
no malicious software was loaded. But, if the measurement list contains
the digest of an antivirus binary, this does not necessarily mean that
it was loaded.

Since PCR 10 can be extended from userspace, a malicious user can
extend the PCR with the digest of a fake measurement entry reporting
the loading of the antivirus. He can then add the fake entry to the
measurement list before it is sent to verifiers, so that they won't
notice the addition.

A possible countermeasure to this attack would be to modify the TPM
driver to refuse to extend the PCRs used by IMA.

Then, IMA could be further extended to accept a list of digests of files
that will be certainly used and to create a measurement entry only after
all files have been accessed.

Roberto


> --
> To unsubscribe from this list: send the line "unsubscribe
> linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Qiuen PENG, Shengli WANG

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

* Re: [Linux-ima-devel] [PATCH, RESEND 08/12] ima: added parser for RPM data type
  2017-08-10 13:12                 ` Mimi Zohar
@ 2017-08-17  9:15                   ` Roberto Sassu
  0 siblings, 0 replies; 30+ messages in thread
From: Roberto Sassu @ 2017-08-17  9:15 UTC (permalink / raw)
  To: Mimi Zohar, James Morris
  Cc: Christoph Hellwig, linux-doc, linux-kernel, linux-fsdevel,
	linux-security-module, keyrings, linux-ima-devel,
	Jarkko Sakkinen

On 8/10/2017 3:12 PM, Mimi Zohar wrote:
> On Wed, 2017-08-09 at 19:18 +0200, Roberto Sassu wrote:
>> On 8/9/2017 4:30 PM, Mimi Zohar wrote:
>>> On Wed, 2017-08-09 at 11:15 +0200, Roberto Sassu wrote:
>>>> On 8/2/2017 9:22 AM, James Morris wrote:
>>>>> On Tue, 1 Aug 2017, Roberto Sassu wrote:
>>>>>
>>>>>> On 8/1/2017 12:27 PM, Christoph Hellwig wrote:
>>>>>>> On Tue, Aug 01, 2017 at 12:20:36PM +0200, Roberto Sassu wrote:
>>>>>>>> This patch introduces a parser for RPM packages. It extracts the digests
>>>>>>>> from the RPMTAG_FILEDIGESTS header section and converts them to binary
>>>>>>>> data
>>>>>>>> before adding them to the hash table.
>>>>>>>>
>>>>>>>> The advantage of this data type is that verifiers can determine who
>>>>>>>> produced that data, as headers are signed by Linux distributions vendors.
>>>>>>>> RPM headers signatures can be provided as digest list metadata.
>>>>>>>
>>>>>>> Err, parsing arbitrary file formats has no business in the kernel.
>>>>>>
>>>>>> The benefit of this choice is that no actions are required for
>>>>>> Linux distribution vendors to support the solution I'm proposing,
>>>>>> because they already provide signed digest lists (RPM headers).
>>>>>>
>>>>>> Since the proof of loading a digest list is the digest of the
>>>>>> digest list (included in the list metadata), if RPM headers are
>>>>>> converted to a different format, remote attestation verifiers
>>>>>> cannot check the signature.
>>>>>>
>>>>>> If the concern is security, it would be possible to prevent unsigned
>>>>>> RPM headers from being parsed, if the PGP key type is upstreamed
>>>>>> (adding in CC keyrings@vger.kernel.org).
>>>>>
>>>>> It's a security concern and also a layering violation, there should be no
>>>>> need to parse package file formats in the kernel.
>>>>
>>>> Parsing RPMs is not strictly necessary. Digests from the headers
>>>> can be extracted and written to a new file using the compact data
>>>> format (introduced with patch 7/12).
>>>>
>>>> At boot time, IMA measures this file before digests are uploaded to the
>>>> kernel. At this point, only files with unknown digest will be added
>>>> to the measurement list. At verification time, verifiers recreate the
>>>> measurement list by merging together the digests uploaded to the
>>>> kernel with the unknown digests. Then, they verify the obtained list.
>>>>
>>>> There are two ways to verify the digests: searching them in a reference
>>>> database, or checking a signature. With the 'ima-sig' measurement list
>>>> template, it is possible to verify signatures for each accessed file.
>>>> With this patch set, it is possible to verify the signature of
>>>> the file containing the digests uploaded to the kernel. If the data
>>>> format changes, the signature cannot be verified.
>>>>
>>>> To avoid this limitation, the parsers could be moved to a userspace
>>>> tool which then uploads the parsed digests to the kernel. IMA would
>>>> measure the original files. But, if the tool is compromised, it could
>>>> load digests not included in the parsed files. With the current solution
>>>> this problem does not arise because no changes can be done by userspace
>>>> applications to the uploaded data while digests are parsed by IMA.
>>>>
>>>> I could remove the RPM parser from the patch set for now.
>>>>
>>>> Is the remaining part of the patch set ok, and is the explanation of
>>>> what it does clear?
>>>
>>> From a trusted boot perspective, file measurements are added to the
>>> measurement list, before access to the file is given.  The measurement
>>> list contains ALL measurements, as defined by policy.  This patch set
>>> changes that meaning to be all measurements, as defined by policy,
>>> with the exception of those in a white list.
>>
>> The digest list is also measured, so the measurement list is complete.
>> Verifiers have to check the digest of digest lists. Otherwise, they
>> would get an unknown digest and conclude that the system being verified
>> has been compromised.
>
> Your proposal is basically a pre-approved "batched" measurement, of a
> set of known good measurements, without the corresponding list of
> measurements that this "batched" measurement represents.  Right?

Yes, correct.


> This pre-approved "batched" measurement represents not what has been
> accessed/executed on the system, but what potentially could be
> accessed/executed.  That's a major difference.
>
>> If you prefer, I could add a new policy rule option to avoid file
>> measurements if the digest is in the digest list.
>
> Huh?  Patch "ima: don't report measurements if digests are included in
> the loaded lists" is already doing this.

Since the content of the measurement list depends on the policy,
adding a new option would give a better understanding of what the
measurement list represents. But, I agree that this is redundant.


>>> Changing the fundamental meaning of the measurement list is not
>>> acceptable.  You could define a new securityfs file to differentiate
>>> between the full measurement list and this abbreviated one.  But
>>
>> There cannot be two measurement lists at the same time. Providing the
>> full measurement list (containing the digest of files being accessed)
>> implies that its integrity must be protected with PCR extends, making
>> the optimization done by this patch set useless.
>
> True, so you would be able to configure the system with one or the
> other type of list, not both.  At least there would be a clear
> understanding of what that list represents.
>
>>
>>> before making this sort of change, I would prefer to address the
>>> underlying problem - TPM peformance.
>>
>> Even if the TPM driver performance improves significantly (17 seconds
>> for 1000 extends), the boot time delay would be still noticeable
>> (8.5 seconds for normal boot + 24 seconds for 1400 PCR extends).
>
> Agreed, there is still room for more TPM improvements.  Just Nayna's
> one patch, without any other changes, brought the timing down from 53s
> for a 1000 extends to just 11s.  (The initial patch was Nack'ed, but
> we're working with the tpmdd and the TCG's device driver work group
> (DDWG).)
>
>> In my opinion, this patch set is useful without considering the
>> performance improvement: reduced size of measurement lists and
>> verification of digest list signatures, instead of file signatures,
>> where signatures are already provided by Linux distributions.
>
> Right, there's always a trade off.  My suggestion, assuming we go with
> this approach, would be to make that trade off clear by using
> different lists.

You mean to add a new kernel command line option to create new
securityfs files instead of the existing ones
(ascii_runtime_measurements, binary_runtime_measurements)? I would
prefer a solution that does not change the interfaces, otherwise
remote attestation agents have to be modified. They can handle
the new list type, as the data format didn't change.

Thanks

Roberto


>>> There are a couple of things that could be done to improve the TPM
>>> driver performance, itself.  Once all of these options have been
>>> pursued, we could then consider batching the measurements to the TPM,
>>> meaning that the measurement list would still contain all the file
>>> measurements, but instead of extending the TPM for each measurement, a
>>> batched hash - a hash of a group of file measurements - would be
>>> extended into the TPM.
>>
>> Probably, I didn't explain clearly that this patch set does not decrease
>> the security of IMA.
>>
>> Extending the PCR for a group of file measurements means that the system
>> can be compromised between two PCR extends without detection because
>> a malicious binary could alter IMA before the next extend.
>
> Currently, a measurement is added to the measurement list and then is
> used to extend the TPM, before returning to the caller.
>
> A performance improvement would still first add the measurement to the
> measurement list, but would then queue and wait for the measurement to
> extend the TPM, before returning to the caller.  In a multi threaded
> environment, the queued measurements could be "batched" - a hash of a
> set of hashes - to extend the TPM.
>
> The delay would be at most two times it takes to extend the TPM - one
> to complete an existing current "batched" extend and another new
> "batched" extend.
>
> The difficulty with this approach is identifying which measurements
> are included in which "batched" measurement.  This approach provides
> the same guarantees as previously.
>
> Before making the TPM performance problem an IMA issue and "fixing" it
> in IMA, I would prefer that the TPM performance be addressed directly.
>
> Mimi
>
>>
>> This patch set extends the PCR with the digest of digest lists, before
>> files are accessed. No actions happen before either the digest lists
>> have been measured or the file measurement is added to the measurement
>> list, if the file digest is not included in the digest list.
>
>

-- 
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Qiuen PENG, Shengli WANG

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

end of thread, other threads:[~2017-08-17  9:17 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-25 15:44 [PATCH 00/12] ima: measure digest lists instead of individual files Roberto Sassu
2017-07-25 15:44 ` [PATCH 01/12] ima: generalize ima_read_policy() Roberto Sassu
2017-07-25 15:44 ` [PATCH 02/12] ima: generalize ima_write_policy() Roberto Sassu
2017-07-25 15:44 ` [PATCH 03/12] ima: generalize policy file operations Roberto Sassu
2017-07-25 15:44 ` [PATCH 04/12] ima: use ima_show_htable_value to show hash table data Roberto Sassu
2017-07-25 15:44 ` [PATCH 05/12] ima: add functions to manage digest lists Roberto Sassu
2017-07-25 15:44 ` [PATCH 06/12] ima: added parser of digest lists metadata Roberto Sassu
2017-07-27  5:15   ` kbuild test robot
2017-08-01 10:17   ` [PATCH, RESEND " Roberto Sassu
2017-07-25 15:44 ` [PATCH 07/12] ima: added parser for compact digest list Roberto Sassu
2017-07-25 15:44 ` [PATCH 08/12] ima: added parser for RPM data type Roberto Sassu
2017-07-27  5:03   ` kbuild test robot
2017-08-01 10:20   ` [PATCH, RESEND " Roberto Sassu
2017-08-01 10:27     ` Christoph Hellwig
2017-08-01 10:58       ` Roberto Sassu
2017-08-02  7:22         ` [Linux-ima-devel] " James Morris
2017-08-02 11:22           ` Roberto Sassu
2017-08-09  9:15           ` Roberto Sassu
2017-08-09 14:30             ` Mimi Zohar
2017-08-09 17:18               ` Roberto Sassu
2017-08-10 13:12                 ` Mimi Zohar
2017-08-17  9:15                   ` Roberto Sassu
2017-07-25 15:44 ` [PATCH 09/12] ima: introduce securityfs interfaces for digest lists Roberto Sassu
2017-07-27  5:38   ` kbuild test robot
2017-07-25 15:44 ` [PATCH 10/12] ima: disable digest lookup if digest lists are not measured Roberto Sassu
2017-07-25 15:44 ` [PATCH 11/12] ima: don't report measurements if digests are included in the loaded lists Roberto Sassu
2017-08-09 20:36   ` [Linux-ima-devel] " Ken Goldman
2017-08-17  8:32     ` Roberto Sassu
2017-07-25 15:44 ` [PATCH 12/12] ima: added Documentation/security/IMA-digest-lists.txt Roberto Sassu
2017-07-26 21:54 ` [PATCH 00/12] ima: measure digest lists instead of individual files Mimi Zohar

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).