Linux-Modules Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v3 00/22] vfs: support for a common kernel file loader
@ 2016-02-03 19:06 Mimi Zohar
  2016-02-03 19:06 ` [PATCH v3 01/22] ima: separate 'security.ima' reading functionality from collect Mimi Zohar
                   ` (22 more replies)
  0 siblings, 23 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

For a while it was looked down upon to directly read files from Linux.
These days there exists a few mechanisms in the kernel that do just this
though to load a file into a local buffer. There are minor but important
checks differences on each, we should take all the best practices from
each of them, generalize them and make all places in the kernel that
read a file use it.[1]

One difference is the method for opening the file.  In some cases we
have a file, while in other cases we have a pathname or a file descriptor.

Another difference is the security hook calls, or lack of them.  In
some versions there is a post file read hook, while in others there
is a pre file read hook. 

This patch set attempts to resolve these differences.  It does not attempt
to merge the different methods of opening a file, but defines a single
common kernel file read function with two wrappers. In addition, as none
of the upstreamed LSMs define either a kernel_module_from_file or a
kernel_fw_from_file hook, this patch set removes these hooks and the
associated functions.  The ima_module_check() and ima_fw_from_file()
functions are renamed and called from the pre and post kernel_read_file
security functions respectively.

Changelog:
- Rebased on top of some of the "firmware_class: extensible firmware API"
patches posted by Luis.
- Removed the kernel_module_from_file and kernel_fw_from_file security
hooks and functions.
- Defined "kernel_read_file_id" enumeration, independently of "ima_hooks".
- Split patches for ease of review.

The latest version of these patches can be found in the next-kernel-read-v3
branch of:
git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git

[1] Taken from Luis Rodriguez's wiki -
http://kernelnewbies.org/KernelProjects/common-kernel-loader

Mimi

David Howells (1):
  firmware: fold successful fw read early

Dmitry Kasatkin (3):
  ima: separate 'security.ima' reading functionality from collect
  ima: provide buffer hash calculation function
  ima: load policy using path

Luis R. Rodriguez (2):
  firmware: simplify dev_*() print messages for generic helpers
  firmware: move completing fw into a helper

Mimi Zohar (16):
  ima: refactor ima_policy_show() to display "ima_hooks" rules
  ima: use "ima_hooks" enum as function argument
  vfs: define a generic function to read a file from the kernel
  vfs: define kernel_read_file_id enumeration
  ima: calculate the hash of a buffer using aynchronous hash(ahash)
  ima: define a new hook to measure and appraise a file already in
    memory
  vfs: define kernel_read_file_from_path
  firmware: replace call to fw_read_file_contents() with kernel version
  security: define kernel_read_file hook
  vfs: define kernel_copy_file_from_fd()
  module: replace copy_module_from_fd with kernel version
  ima: remove firmware and module specific cached status info
  kexec: replace call to copy_file_from_fd() with kernel version
  ima: support for kexec image and initramfs
  ima: measure and appraise the IMA policy itself
  ima: require signed IMA policy

 Documentation/ABI/testing/ima_policy      |   2 +-
 drivers/base/firmware_class.c             |  76 ++++++-------------
 fs/exec.c                                 |  95 +++++++++++++++++++++++
 include/linux/fs.h                        |  15 ++++
 include/linux/ima.h                       |  10 ++-
 include/linux/lsm_hooks.h                 |  35 ++++-----
 include/linux/security.h                  |  16 ++--
 kernel/kexec_file.c                       |  73 +++---------------
 kernel/module.c                           |  68 ++---------------
 security/integrity/iint.c                 |   4 +-
 security/integrity/ima/ima.h              |  49 ++++++++----
 security/integrity/ima/ima_api.c          |  25 +++----
 security/integrity/ima/ima_appraise.c     |  69 ++++++++---------
 security/integrity/ima/ima_crypto.c       | 120 +++++++++++++++++++++++++++++-
 security/integrity/ima/ima_fs.c           |  50 ++++++++++++-
 security/integrity/ima/ima_init.c         |   2 +-
 security/integrity/ima/ima_main.c         | 104 +++++++++++++++++++-------
 security/integrity/ima/ima_policy.c       | 107 +++++++++++++++++---------
 security/integrity/ima/ima_template.c     |   2 -
 security/integrity/ima/ima_template_lib.c |   1 -
 security/integrity/integrity.h            |  15 ++--
 security/security.c                       |  32 ++++----
 22 files changed, 605 insertions(+), 365 deletions(-)

-- 
2.1.0


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

* [PATCH v3 01/22] ima: separate 'security.ima' reading functionality from collect
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-03 19:06 ` [PATCH v3 02/22] ima: refactor ima_policy_show() to display "ima_hooks" rules Mimi Zohar
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Dmitry Kasatkin, Dmitry Kasatkin, Mimi Zohar

From: Dmitry Kasatkin <d.kasatkin@samsung.com>

Instead of passing pointers to pointers to ima_collect_measurent() to
read and return the 'security.ima' xattr value, this patch moves the
functionality to the calling process_measurement() to directly read
the xattr and pass only the hash algo to the ima_collect_measurement().

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/ima/ima.h              | 15 +++++++--------
 security/integrity/ima/ima_api.c          | 15 +++------------
 security/integrity/ima/ima_appraise.c     | 25 ++++++++++++++-----------
 security/integrity/ima/ima_crypto.c       |  2 +-
 security/integrity/ima/ima_init.c         |  2 +-
 security/integrity/ima/ima_main.c         | 11 +++++++----
 security/integrity/ima/ima_template.c     |  2 --
 security/integrity/ima/ima_template_lib.c |  1 -
 8 files changed, 33 insertions(+), 40 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 585af61..fb8da36 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -23,6 +23,7 @@
 #include <linux/hash.h>
 #include <linux/tpm.h>
 #include <linux/audit.h>
+#include <crypto/hash_info.h>
 
 #include "../integrity.h"
 
@@ -140,9 +141,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
 int ima_get_action(struct inode *inode, int mask, int function);
 int ima_must_measure(struct inode *inode, int mask, int function);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
-			    struct file *file,
-			    struct evm_ima_xattr_data **xattr_value,
-			    int *xattr_len);
+			    struct file *file, enum hash_algo algo);
 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
 			   const unsigned char *filename,
 			   struct evm_ima_xattr_data *xattr_value,
@@ -188,8 +187,8 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
 					   int func);
-void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len,
-		       struct ima_digest_data *hash);
+enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
+				 int xattr_len);
 int ima_read_xattr(struct dentry *dentry,
 		   struct evm_ima_xattr_data **xattr_value);
 
@@ -221,10 +220,10 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c
 	return INTEGRITY_UNKNOWN;
 }
 
-static inline void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
-				     int xattr_len,
-				     struct ima_digest_data *hash)
+static inline enum hash_algo
+ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len)
 {
+	return ima_hash_algo;
 }
 
 static inline int ima_read_xattr(struct dentry *dentry,
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 1d950fb..e7c7a5d 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -18,7 +18,7 @@
 #include <linux/fs.h>
 #include <linux/xattr.h>
 #include <linux/evm.h>
-#include <crypto/hash_info.h>
+
 #include "ima.h"
 
 /*
@@ -188,9 +188,7 @@ int ima_get_action(struct inode *inode, int mask, int function)
  * Return 0 on success, error code otherwise
  */
 int ima_collect_measurement(struct integrity_iint_cache *iint,
-			    struct file *file,
-			    struct evm_ima_xattr_data **xattr_value,
-			    int *xattr_len)
+			    struct file *file, enum hash_algo algo)
 {
 	const char *audit_cause = "failed";
 	struct inode *inode = file_inode(file);
@@ -201,9 +199,6 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 		char digest[IMA_MAX_DIGEST_SIZE];
 	} hash;
 
-	if (xattr_value)
-		*xattr_len = ima_read_xattr(file->f_path.dentry, xattr_value);
-
 	if (!(iint->flags & IMA_COLLECTED)) {
 		u64 i_version = file_inode(file)->i_version;
 
@@ -213,11 +208,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 			goto out;
 		}
 
-		/* use default hash algorithm */
-		hash.hdr.algo = ima_hash_algo;
-
-		if (xattr_value)
-			ima_get_hash_algo(*xattr_value, *xattr_len, &hash.hdr);
+		hash.hdr.algo = algo;
 
 		result = ima_calc_file_hash(file, &hash.hdr);
 		if (!result) {
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 1873b55..9c2b46b 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -15,7 +15,6 @@
 #include <linux/magic.h>
 #include <linux/ima.h>
 #include <linux/evm.h>
-#include <crypto/hash_info.h>
 
 #include "ima.h"
 
@@ -130,36 +129,40 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
 	}
 }
 
-void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len,
-		       struct ima_digest_data *hash)
+enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
+				 int xattr_len)
 {
 	struct signature_v2_hdr *sig;
 
 	if (!xattr_value || xattr_len < 2)
-		return;
+		/* return default hash algo */
+		return ima_hash_algo;
 
 	switch (xattr_value->type) {
 	case EVM_IMA_XATTR_DIGSIG:
 		sig = (typeof(sig))xattr_value;
 		if (sig->version != 2 || xattr_len <= sizeof(*sig))
-			return;
-		hash->algo = sig->hash_algo;
+			return ima_hash_algo;
+		return sig->hash_algo;
 		break;
 	case IMA_XATTR_DIGEST_NG:
-		hash->algo = xattr_value->digest[0];
+		return xattr_value->digest[0];
 		break;
 	case IMA_XATTR_DIGEST:
 		/* this is for backward compatibility */
 		if (xattr_len == 21) {
 			unsigned int zero = 0;
 			if (!memcmp(&xattr_value->digest[16], &zero, 4))
-				hash->algo = HASH_ALGO_MD5;
+				return HASH_ALGO_MD5;
 			else
-				hash->algo = HASH_ALGO_SHA1;
+				return HASH_ALGO_SHA1;
 		} else if (xattr_len == 17)
-			hash->algo = HASH_ALGO_MD5;
+			return HASH_ALGO_MD5;
 		break;
 	}
+
+	/* return default hash algo */
+	return ima_hash_algo;
 }
 
 int ima_read_xattr(struct dentry *dentry,
@@ -296,7 +299,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
 	if (iint->flags & IMA_DIGSIG)
 		return;
 
-	rc = ima_collect_measurement(iint, file, NULL, NULL);
+	rc = ima_collect_measurement(iint, file, ima_hash_algo);
 	if (rc < 0)
 		return;
 
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 6eb6293..fb30ce4 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -24,7 +24,7 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <crypto/hash.h>
-#include <crypto/hash_info.h>
+
 #include "ima.h"
 
 struct ahash_completion {
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index bd79f25..5d679a6 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -21,7 +21,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/err.h>
-#include <crypto/hash_info.h>
+
 #include "ima.h"
 
 /* name for boot aggregate entry */
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index c21f09b..d9fc463 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -24,7 +24,6 @@
 #include <linux/slab.h>
 #include <linux/xattr.h>
 #include <linux/ima.h>
-#include <crypto/hash_info.h>
 
 #include "ima.h"
 
@@ -163,9 +162,10 @@ static int process_measurement(struct file *file, int mask, int function,
 	char *pathbuf = NULL;
 	const char *pathname = NULL;
 	int rc = -ENOMEM, action, must_appraise;
-	struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
+	struct evm_ima_xattr_data *xattr_value = NULL;
 	int xattr_len = 0;
 	bool violation_check;
+	enum hash_algo hash_algo;
 
 	if (!ima_policy_flag || !S_ISREG(inode->i_mode))
 		return 0;
@@ -221,9 +221,12 @@ static int process_measurement(struct file *file, int mask, int function,
 	template_desc = ima_template_desc_current();
 	if ((action & IMA_APPRAISE_SUBMASK) ||
 		    strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
-		xattr_ptr = &xattr_value;
+		/* read 'security.ima' */
+		xattr_len = ima_read_xattr(file->f_path.dentry, &xattr_value);
 
-	rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
+	hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
+
+	rc = ima_collect_measurement(iint, file, hash_algo);
 	if (rc != 0) {
 		if (file->f_flags & O_DIRECT)
 			rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 0b7404e..febd12e 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -15,8 +15,6 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <crypto/hash_info.h>
-
 #include "ima.h"
 #include "ima_template_lib.h"
 
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 2934e3d..f9bae04 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -12,7 +12,6 @@
  * File: ima_template_lib.c
  *      Library of supported template fields.
  */
-#include <crypto/hash_info.h>
 
 #include "ima_template_lib.h"
 
-- 
2.1.0


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

* [PATCH v3 02/22] ima: refactor ima_policy_show() to display "ima_hooks" rules
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
  2016-02-03 19:06 ` [PATCH v3 01/22] ima: separate 'security.ima' reading functionality from collect Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-07 19:45   ` Petko Manolov
  2016-02-10 19:33   ` Dmitry Kasatkin
  2016-02-03 19:06 ` [PATCH v3 03/22] ima: use "ima_hooks" enum as function argument Mimi Zohar
                   ` (20 subsequent siblings)
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Define and call a function to display the "ima_hooks" rules.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/ima/ima_policy.c | 63 +++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 27 deletions(-)

diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index e0e18cc..43b6425 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -903,6 +903,40 @@ void ima_policy_stop(struct seq_file *m, void *v)
 #define mt(token)	mask_tokens[token]
 #define ft(token)	func_tokens[token]
 
+/*
+ * policy_func_show - display the ima_hooks policy rule
+ */
+static void policy_func_show(struct seq_file *m, enum ima_hooks func)
+{
+	char tbuf[64] = {0,};
+
+	switch (func) {
+	case FILE_CHECK:
+		seq_printf(m, pt(Opt_func), ft(func_file));
+		break;
+	case MMAP_CHECK:
+		seq_printf(m, pt(Opt_func), ft(func_mmap));
+		break;
+	case BPRM_CHECK:
+		seq_printf(m, pt(Opt_func), ft(func_bprm));
+		break;
+	case MODULE_CHECK:
+		seq_printf(m, pt(Opt_func), ft(func_module));
+		break;
+	case FIRMWARE_CHECK:
+		seq_printf(m, pt(Opt_func), ft(func_firmware));
+		break;
+	case POST_SETATTR:
+		seq_printf(m, pt(Opt_func), ft(func_post));
+		break;
+	default:
+		snprintf(tbuf, sizeof(tbuf), "%d", func);
+		seq_printf(m, pt(Opt_func), tbuf);
+		break;
+	}
+	seq_puts(m, " ");
+}
+
 int ima_policy_show(struct seq_file *m, void *v)
 {
 	struct ima_rule_entry *entry = v;
@@ -924,33 +958,8 @@ int ima_policy_show(struct seq_file *m, void *v)
 
 	seq_puts(m, " ");
 
-	if (entry->flags & IMA_FUNC) {
-		switch (entry->func) {
-		case FILE_CHECK:
-			seq_printf(m, pt(Opt_func), ft(func_file));
-			break;
-		case MMAP_CHECK:
-			seq_printf(m, pt(Opt_func), ft(func_mmap));
-			break;
-		case BPRM_CHECK:
-			seq_printf(m, pt(Opt_func), ft(func_bprm));
-			break;
-		case MODULE_CHECK:
-			seq_printf(m, pt(Opt_func), ft(func_module));
-			break;
-		case FIRMWARE_CHECK:
-			seq_printf(m, pt(Opt_func), ft(func_firmware));
-			break;
-		case POST_SETATTR:
-			seq_printf(m, pt(Opt_func), ft(func_post));
-			break;
-		default:
-			snprintf(tbuf, sizeof(tbuf), "%d", entry->func);
-			seq_printf(m, pt(Opt_func), tbuf);
-			break;
-		}
-		seq_puts(m, " ");
-	}
+	if (entry->flags & IMA_FUNC)
+		policy_func_show(m, entry->func);
 
 	if (entry->flags & IMA_MASK) {
 		if (entry->mask & MAY_EXEC)
-- 
2.1.0


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

* [PATCH v3 03/22] ima: use "ima_hooks" enum as function argument
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
  2016-02-03 19:06 ` [PATCH v3 01/22] ima: separate 'security.ima' reading functionality from collect Mimi Zohar
  2016-02-03 19:06 ` [PATCH v3 02/22] ima: refactor ima_policy_show() to display "ima_hooks" rules Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-07 19:46   ` Petko Manolov
  2016-02-10 19:35   ` Dmitry Kasatkin
  2016-02-03 19:06 ` [PATCH v3 04/22] firmware: simplify dev_*() print messages for generic helpers Mimi Zohar
                   ` (19 subsequent siblings)
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Cleanup the function arguments by using "ima_hooks" enumerator as needed.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/ima/ima.h          | 25 +++++++++++++++++--------
 security/integrity/ima/ima_api.c      |  6 +++---
 security/integrity/ima/ima_appraise.c | 13 +++++++------
 security/integrity/ima/ima_main.c     | 14 +++++++-------
 security/integrity/ima/ima_policy.c   |  6 +++---
 5 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index fb8da36..b7e7935 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -137,9 +137,18 @@ static inline unsigned long ima_hash_key(u8 *digest)
 	return hash_long(*digest, IMA_HASH_BITS);
 }
 
+enum ima_hooks {
+	FILE_CHECK = 1,
+	MMAP_CHECK,
+	BPRM_CHECK,
+	MODULE_CHECK,
+	FIRMWARE_CHECK,
+	POST_SETATTR
+};
+
 /* LIM API function definitions */
-int ima_get_action(struct inode *inode, int mask, int function);
-int ima_must_measure(struct inode *inode, int mask, int function);
+int ima_get_action(struct inode *inode, int mask, enum ima_hooks func);
+int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
 			    struct file *file, enum hash_algo algo);
 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
@@ -156,8 +165,6 @@ void ima_free_template_entry(struct ima_template_entry *entry);
 const char *ima_d_path(struct path *path, char **pathbuf);
 
 /* IMA policy related functions */
-enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR };
-
 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
 		     int flags);
 void ima_init_policy(void);
@@ -179,21 +186,22 @@ int ima_policy_show(struct seq_file *m, void *v);
 #define IMA_APPRAISE_FIRMWARE	0x10
 
 #ifdef CONFIG_IMA_APPRAISE
-int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
+int ima_appraise_measurement(enum ima_hooks func,
+			     struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
 			     int xattr_len, int opened);
 int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
-					   int func);
+					   enum ima_hooks func);
 enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
 				 int xattr_len);
 int ima_read_xattr(struct dentry *dentry,
 		   struct evm_ima_xattr_data **xattr_value);
 
 #else
-static inline int ima_appraise_measurement(int func,
+static inline int ima_appraise_measurement(enum ima_hooks func,
 					   struct integrity_iint_cache *iint,
 					   struct file *file,
 					   const unsigned char *filename,
@@ -215,7 +223,8 @@ static inline void ima_update_xattr(struct integrity_iint_cache *iint,
 }
 
 static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache
-							 *iint, int func)
+							 *iint,
+							 enum ima_hooks func)
 {
 	return INTEGRITY_UNKNOWN;
 }
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index e7c7a5d..8750254 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -156,7 +156,7 @@ err_out:
  * ima_get_action - appraise & measure decision based on policy.
  * @inode: pointer to inode to measure
  * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
- * @function: calling function (FILE_CHECK, BPRM_CHECK, MMAP_CHECK, MODULE_CHECK)
+ * @func: caller identifier
  *
  * The policy is defined in terms of keypairs:
  *		subj=, obj=, type=, func=, mask=, fsmagic=
@@ -168,13 +168,13 @@ err_out:
  * Returns IMA_MEASURE, IMA_APPRAISE mask.
  *
  */
-int ima_get_action(struct inode *inode, int mask, int function)
+int ima_get_action(struct inode *inode, int mask, enum ima_hooks func)
 {
 	int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;
 
 	flags &= ima_policy_flag;
 
-	return ima_match_policy(inode, function, mask, flags);
+	return ima_match_policy(inode, func, mask, flags);
 }
 
 /*
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 9c2b46b..2888449 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -67,7 +67,7 @@ static int ima_fix_xattr(struct dentry *dentry,
 
 /* Return specific func appraised cached result */
 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
-					   int func)
+					   enum ima_hooks func)
 {
 	switch (func) {
 	case MMAP_CHECK:
@@ -85,7 +85,8 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
 }
 
 static void ima_set_cache_status(struct integrity_iint_cache *iint,
-				 int func, enum integrity_status status)
+				 enum ima_hooks func,
+				 enum integrity_status status)
 {
 	switch (func) {
 	case MMAP_CHECK:
@@ -103,11 +104,11 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
 	case FILE_CHECK:
 	default:
 		iint->ima_file_status = status;
-		break;
 	}
 }
 
-static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
+static void ima_cache_flags(struct integrity_iint_cache *iint,
+			     enum ima_hooks func)
 {
 	switch (func) {
 	case MMAP_CHECK:
@@ -125,7 +126,6 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
 	case FILE_CHECK:
 	default:
 		iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
-		break;
 	}
 }
 
@@ -185,7 +185,8 @@ int ima_read_xattr(struct dentry *dentry,
  *
  * Return 0 on success, error code otherwise
  */
-int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
+int ima_appraise_measurement(enum ima_hooks func,
+			     struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
 			     int xattr_len, int opened)
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index d9fc463..78a80c8 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -153,8 +153,8 @@ void ima_file_free(struct file *file)
 	ima_check_last_writer(iint, inode, file);
 }
 
-static int process_measurement(struct file *file, int mask, int function,
-			       int opened)
+static int process_measurement(struct file *file, int mask,
+			       enum ima_hooks func, int opened)
 {
 	struct inode *inode = file_inode(file);
 	struct integrity_iint_cache *iint = NULL;
@@ -174,8 +174,8 @@ static int process_measurement(struct file *file, int mask, int function,
 	 * bitmask based on the appraise/audit/measurement policy.
 	 * Included is the appraise submask.
 	 */
-	action = ima_get_action(inode, mask, function);
-	violation_check = ((function == FILE_CHECK || function == MMAP_CHECK) &&
+	action = ima_get_action(inode, mask, func);
+	violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
 			   (ima_policy_flag & IMA_MEASURE));
 	if (!action && !violation_check)
 		return 0;
@@ -184,7 +184,7 @@ static int process_measurement(struct file *file, int mask, int function,
 
 	/*  Is the appraise rule hook specific?  */
 	if (action & IMA_FILE_APPRAISE)
-		function = FILE_CHECK;
+		func = FILE_CHECK;
 
 	mutex_lock(&inode->i_mutex);
 
@@ -214,7 +214,7 @@ static int process_measurement(struct file *file, int mask, int function,
 	/* Nothing to do, just return existing appraised status */
 	if (!action) {
 		if (must_appraise)
-			rc = ima_get_cache_status(iint, function);
+			rc = ima_get_cache_status(iint, func);
 		goto out_digsig;
 	}
 
@@ -240,7 +240,7 @@ static int process_measurement(struct file *file, int mask, int function,
 		ima_store_measurement(iint, file, pathname,
 				      xattr_value, xattr_len);
 	if (action & IMA_APPRAISE_SUBMASK)
-		rc = ima_appraise_measurement(function, iint, file, pathname,
+		rc = ima_appraise_measurement(func, iint, file, pathname,
 					      xattr_value, xattr_len, opened);
 	if (action & IMA_AUDIT)
 		ima_audit_measurement(iint, pathname);
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 43b6425..b089ebe 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -207,8 +207,8 @@ static void ima_lsm_update_rules(void)
  *
  * Returns true on rule match, false on failure.
  */
-static bool ima_match_rules(struct ima_rule_entry *rule,
-			    struct inode *inode, enum ima_hooks func, int mask)
+static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
+			    enum ima_hooks func, int mask)
 {
 	struct task_struct *tsk = current;
 	const struct cred *cred = current_cred();
@@ -289,7 +289,7 @@ retry:
  * In addition to knowing that we need to appraise the file in general,
  * we need to differentiate between calling hooks, for hook specific rules.
  */
-static int get_subaction(struct ima_rule_entry *rule, int func)
+static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
 {
 	if (!(rule->flags & IMA_FUNC))
 		return IMA_FILE_APPRAISE;
-- 
2.1.0


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

* [PATCH v3 04/22] firmware: simplify dev_*() print messages for generic helpers
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (2 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 03/22] ima: use "ima_hooks" enum as function argument Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:26   ` Kees Cook
  2016-02-03 19:06 ` [PATCH v3 05/22] firmware: move completing fw into a helper Mimi Zohar
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Luis R. Rodriguez, Andrew Morton, Greg Kroah-Hartman,
	Casey Schaufler, Ming Lei, Takashi Iwai,
	Vojtěch Pavlík, Kyle McMartin, Matthew Garrett,
	linux-kernel, Mimi Zohar

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

Simplify a few of the *generic* shared dev_warn() and dev_dbg()
print messages for three reasons:

0) Historically firmware_class code was added to help
   get device driver firmware binaries but these days
   request_firmware*() helpers are being repurposed for
   general *system data* needed by the kernel.

1) This will also help generalize shared code as much as possible
   later in the future in consideration for a new extensible firmware
   API which will enable to separate usermode helper code out as much
   as possible.

2) Kees Cook pointed out the the prints already have the device
   associated as dev_*() helpers are used, that should help identify
   the user and case in which the helpers are used. That should provide
   enough context and simplifies the messages further.

v4: generalize debug/warn messages even further as suggested by
    Kees Cook.

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Cc: Ming Lei <ming.lei@canonical.com>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Vojtěch Pavlík <vojtech@suse.cz>
Cc: Kyle McMartin <kyle@kernel.org>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 drivers/base/firmware_class.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 8524450..3358f5d 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -353,15 +353,15 @@ static int fw_get_filesystem_firmware(struct device *device,
 		rc = fw_read_file_contents(file, buf);
 		fput(file);
 		if (rc)
-			dev_warn(device, "firmware, attempted to load %s, but failed with error %d\n",
-				path, rc);
+			dev_warn(device, "loading %s failed with error %d\n",
+				 path, rc);
 		else
 			break;
 	}
 	__putname(path);
 
 	if (!rc) {
-		dev_dbg(device, "firmware: direct-loading firmware %s\n",
+		dev_dbg(device, "direct-loading %s\n",
 			buf->fw_id);
 		mutex_lock(&fw_lock);
 		set_bit(FW_STATUS_DONE, &buf->status);
@@ -1051,7 +1051,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
 	}
 
 	if (fw_get_builtin_firmware(firmware, name)) {
-		dev_dbg(device, "firmware: using built-in firmware %s\n", name);
+		dev_dbg(device, "using built-in %s\n", name);
 		return 0; /* assigned */
 	}
 
-- 
2.1.0


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

* [PATCH v3 05/22] firmware: move completing fw into a helper
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (3 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 04/22] firmware: simplify dev_*() print messages for generic helpers Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:27   ` Kees Cook
  2016-02-03 19:06 ` [PATCH v3 06/22] firmware: fold successful fw read early Mimi Zohar
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Luis R. Rodriguez, Mimi Zohar

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

This will be re-used later through a new extensible interface.

Reviewed-by: Josh Boyer <jwboyer@fedoraproject.org>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 drivers/base/firmware_class.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 3358f5d..fb64814 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -322,6 +322,15 @@ fail:
 	return rc;
 }
 
+static void fw_finish_direct_load(struct device *device,
+				  struct firmware_buf *buf)
+{
+	mutex_lock(&fw_lock);
+	set_bit(FW_STATUS_DONE, &buf->status);
+	complete_all(&buf->completion);
+	mutex_unlock(&fw_lock);
+}
+
 static int fw_get_filesystem_firmware(struct device *device,
 				       struct firmware_buf *buf)
 {
@@ -363,10 +372,7 @@ static int fw_get_filesystem_firmware(struct device *device,
 	if (!rc) {
 		dev_dbg(device, "direct-loading %s\n",
 			buf->fw_id);
-		mutex_lock(&fw_lock);
-		set_bit(FW_STATUS_DONE, &buf->status);
-		complete_all(&buf->completion);
-		mutex_unlock(&fw_lock);
+		fw_finish_direct_load(device, buf);
 	}
 
 	return rc;
-- 
2.1.0


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

* [PATCH v3 06/22] firmware: fold successful fw read early
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (4 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 05/22] firmware: move completing fw into a helper Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:36   ` Kees Cook
  2016-02-03 19:06 ` [PATCH v3 07/22] vfs: define a generic function to read a file from the kernel Mimi Zohar
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Luis R. Rodriguez, Mimi Zohar

From: David Howells <dhowells@redhat.com>

We'll be folding in some more checks on fw_read_file_contents(),
this will make the success case easier to follow.

Reviewed-by: Josh Boyer <jwboyer@fedoraproject.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 drivers/base/firmware_class.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index fb64814..c658cec 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -361,20 +361,18 @@ static int fw_get_filesystem_firmware(struct device *device,
 			continue;
 		rc = fw_read_file_contents(file, buf);
 		fput(file);
-		if (rc)
+		if (rc == 0) {
+			dev_dbg(device, "direct-loading %s\n",
+				buf->fw_id);
+			fw_finish_direct_load(device, buf);
+			goto out;
+		} else
 			dev_warn(device, "loading %s failed with error %d\n",
 				 path, rc);
-		else
-			break;
 	}
+out:
 	__putname(path);
 
-	if (!rc) {
-		dev_dbg(device, "direct-loading %s\n",
-			buf->fw_id);
-		fw_finish_direct_load(device, buf);
-	}
-
 	return rc;
 }
 
-- 
2.1.0


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

* [PATCH v3 07/22] vfs: define a generic function to read a file from the kernel
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (5 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 06/22] firmware: fold successful fw read early Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:41   ` Kees Cook
  2016-02-03 19:06 ` [PATCH v3 08/22] vfs: define kernel_read_file_id enumeration Mimi Zohar
                   ` (15 subsequent siblings)
  22 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

For a while it was looked down upon to directly read files from Linux.
These days there exists a few mechanisms in the kernel that do just
this though to load a file into a local buffer.  There are minor but
important checks differences on each.  This patch set is the first
attempt at resolving some of these differences.

This patch introduces a common function for reading files from the kernel
with the corresponding security post-read hook and function.

Changelog v3:
- additional bounds checking - Luis
v2:
- To simplify patch review, re-ordered patches

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Reviewed-by: Luis R. Rodriguez <mcgrof@suse.com>
---
 fs/exec.c                 | 53 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs.h        |  1 +
 include/linux/lsm_hooks.h |  9 ++++++++
 include/linux/security.h  |  7 +++++++
 security/security.c       |  7 +++++++
 5 files changed, 77 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index b06623a..742de7a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -56,6 +56,7 @@
 #include <linux/pipe_fs_i.h>
 #include <linux/oom.h>
 #include <linux/compat.h>
+#include <linux/vmalloc.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -831,6 +832,58 @@ int kernel_read(struct file *file, loff_t offset,
 
 EXPORT_SYMBOL(kernel_read);
 
+int kernel_read_file(struct file *file, void **buf, loff_t *size,
+		     loff_t max_size)
+{
+	loff_t i_size, pos;
+	ssize_t bytes = 0;
+	int ret;
+
+	if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
+		return -EINVAL;
+
+	i_size = i_size_read(file_inode(file));
+	if (max_size > 0 && i_size > max_size)
+		return -EFBIG;
+	if (i_size <= 0)
+		return -EINVAL;
+
+	*buf = vmalloc(i_size);
+	if (!*buf)
+		return -ENOMEM;
+
+	pos = 0;
+	while (pos < i_size) {
+		bytes = kernel_read(file, pos, (char *)(*buf) + pos,
+				    i_size - pos);
+		if (bytes < 0) {
+			ret = bytes;
+			goto out;
+		}
+
+		if (bytes == 0)
+			break;
+		pos += bytes;
+	}
+
+	if (pos != i_size) {
+		ret = -EIO;
+		goto out;
+	}
+
+	ret = security_kernel_post_read_file(file, *buf, i_size);
+	if (!ret)
+		*size = pos;
+
+out:
+	if (ret < 0) {
+		vfree(*buf);
+		*buf = NULL;
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kernel_read_file);
+
 ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
 {
 	ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3aa5142..93ca379 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2527,6 +2527,7 @@ static inline void i_readcount_inc(struct inode *inode)
 extern int do_pipe_flags(int *, int);
 
 extern int kernel_read(struct file *, loff_t, char *, unsigned long);
+extern int kernel_read_file(struct file *, void **, loff_t *, loff_t);
 extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
 extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
 extern struct file * open_exec(const char *);
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 71969de..f82631c 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -561,6 +561,13 @@
  *	the kernel module to load. If the module is being loaded from a blob,
  *	this argument will be NULL.
  *	Return 0 if permission is granted.
+ * @kernel_post_read_file:
+ *	Read a file specified by userspace.
+ *	@file contains the file structure pointing to the file being read
+ *	by the kernel.
+ *	@buf pointer to buffer containing the file contents.
+ *	@size length of the file contents.
+ *	Return 0 if permission is granted.
  * @task_fix_setuid:
  *	Update the module's state after setting one or more of the user
  *	identity attributes of the current process.  The @flags parameter
@@ -1457,6 +1464,7 @@ union security_list_options {
 	int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size);
 	int (*kernel_module_request)(char *kmod_name);
 	int (*kernel_module_from_file)(struct file *file);
+	int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size);
 	int (*task_fix_setuid)(struct cred *new, const struct cred *old,
 				int flags);
 	int (*task_setpgid)(struct task_struct *p, pid_t pgid);
@@ -1716,6 +1724,7 @@ struct security_hook_heads {
 	struct list_head kernel_act_as;
 	struct list_head kernel_create_files_as;
 	struct list_head kernel_fw_from_file;
+	struct list_head kernel_post_read_file;
 	struct list_head kernel_module_request;
 	struct list_head kernel_module_from_file;
 	struct list_head task_fix_setuid;
diff --git a/include/linux/security.h b/include/linux/security.h
index 4824a4c..f30f564 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -301,6 +301,7 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode);
 int security_kernel_fw_from_file(struct file *file, char *buf, size_t size);
 int security_kernel_module_request(char *kmod_name);
 int security_kernel_module_from_file(struct file *file);
+int security_kernel_post_read_file(struct file *file, char *buf, loff_t size);
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
 			     int flags);
 int security_task_setpgid(struct task_struct *p, pid_t pgid);
@@ -866,6 +867,12 @@ static inline int security_kernel_module_from_file(struct file *file)
 	return 0;
 }
 
+static inline int security_kernel_post_read_file(struct file *file,
+						 char *buf, loff_t size)
+{
+	return 0;
+}
+
 static inline int security_task_fix_setuid(struct cred *new,
 					   const struct cred *old,
 					   int flags)
diff --git a/security/security.c b/security/security.c
index e8ffd92..ae50730 100644
--- a/security/security.c
+++ b/security/security.c
@@ -910,6 +910,11 @@ int security_kernel_module_from_file(struct file *file)
 	return ima_module_check(file);
 }
 
+int security_kernel_post_read_file(struct file *file, char *buf, loff_t size)
+{
+	return call_int_hook(kernel_post_read_file, 0, file, buf, size);
+}
+
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
 			     int flags)
 {
@@ -1697,6 +1702,8 @@ struct security_hook_heads security_hook_heads = {
 		LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
 	.kernel_module_from_file =
 		LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file),
+	.kernel_post_read_file =
+		LIST_HEAD_INIT(security_hook_heads.kernel_post_read_file),
 	.task_fix_setuid =
 		LIST_HEAD_INIT(security_hook_heads.task_fix_setuid),
 	.task_setpgid =	LIST_HEAD_INIT(security_hook_heads.task_setpgid),
-- 
2.1.0


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

* [PATCH v3 08/22] vfs: define kernel_read_file_id enumeration
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (6 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 07/22] vfs: define a generic function to read a file from the kernel Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:41   ` Kees Cook
  2016-02-04 19:45   ` Luis R. Rodriguez
  2016-02-03 19:06 ` [PATCH v3 09/22] ima: provide buffer hash calculation function Mimi Zohar
                   ` (14 subsequent siblings)
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

To differentiate between the kernel_read_file() callers, this patch
defines a new enumeration named kernel_read_file_id and includes the
caller identifier as an argument.

Subsequent patches define READING_KEXEC_IMAGE, READING_KEXEC_INITRAMFS,
READING_FIRMWARE, READING_MODULE, and READING_POLICY.

Changelog v3:
- Replace the IMA specific enumeration with a generic one.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 fs/exec.c                 | 4 ++--
 include/linux/fs.h        | 7 ++++++-
 include/linux/lsm_hooks.h | 4 +++-
 include/linux/security.h  | 7 +++++--
 security/security.c       | 5 +++--
 5 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 742de7a..cd2b5b2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -833,7 +833,7 @@ int kernel_read(struct file *file, loff_t offset,
 EXPORT_SYMBOL(kernel_read);
 
 int kernel_read_file(struct file *file, void **buf, loff_t *size,
-		     loff_t max_size)
+		     loff_t max_size, enum kernel_read_file_id id)
 {
 	loff_t i_size, pos;
 	ssize_t bytes = 0;
@@ -871,7 +871,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 		goto out;
 	}
 
-	ret = security_kernel_post_read_file(file, *buf, i_size);
+	ret = security_kernel_post_read_file(file, *buf, i_size, id);
 	if (!ret)
 		*size = pos;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 93ca379..1458ca5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2526,8 +2526,13 @@ static inline void i_readcount_inc(struct inode *inode)
 #endif
 extern int do_pipe_flags(int *, int);
 
+enum kernel_read_file_id {
+	READING_MAX_ID
+};
+
 extern int kernel_read(struct file *, loff_t, char *, unsigned long);
-extern int kernel_read_file(struct file *, void **, loff_t *, loff_t);
+extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
+			    enum kernel_read_file_id);
 extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
 extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
 extern struct file * open_exec(const char *);
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index f82631c..2337f33 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -567,6 +567,7 @@
  *	by the kernel.
  *	@buf pointer to buffer containing the file contents.
  *	@size length of the file contents.
+ *	@id kernel read file identifier
  *	Return 0 if permission is granted.
  * @task_fix_setuid:
  *	Update the module's state after setting one or more of the user
@@ -1464,7 +1465,8 @@ union security_list_options {
 	int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size);
 	int (*kernel_module_request)(char *kmod_name);
 	int (*kernel_module_from_file)(struct file *file);
-	int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size);
+	int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size,
+				     enum kernel_read_file_id id);
 	int (*task_fix_setuid)(struct cred *new, const struct cred *old,
 				int flags);
 	int (*task_setpgid)(struct task_struct *p, pid_t pgid);
diff --git a/include/linux/security.h b/include/linux/security.h
index f30f564..b68ce94 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -28,6 +28,7 @@
 #include <linux/err.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/fs.h>
 
 struct linux_binprm;
 struct cred;
@@ -301,7 +302,8 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode);
 int security_kernel_fw_from_file(struct file *file, char *buf, size_t size);
 int security_kernel_module_request(char *kmod_name);
 int security_kernel_module_from_file(struct file *file);
-int security_kernel_post_read_file(struct file *file, char *buf, loff_t size);
+int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
+				   enum kernel_read_file_id id);
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
 			     int flags);
 int security_task_setpgid(struct task_struct *p, pid_t pgid);
@@ -868,7 +870,8 @@ static inline int security_kernel_module_from_file(struct file *file)
 }
 
 static inline int security_kernel_post_read_file(struct file *file,
-						 char *buf, loff_t size)
+						 char *buf, loff_t size,
+						 enum kernel_read_file_id id)
 {
 	return 0;
 }
diff --git a/security/security.c b/security/security.c
index ae50730..796a261 100644
--- a/security/security.c
+++ b/security/security.c
@@ -910,9 +910,10 @@ int security_kernel_module_from_file(struct file *file)
 	return ima_module_check(file);
 }
 
-int security_kernel_post_read_file(struct file *file, char *buf, loff_t size)
+int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
+				   enum kernel_read_file_id id)
 {
-	return call_int_hook(kernel_post_read_file, 0, file, buf, size);
+	return call_int_hook(kernel_post_read_file, 0, file, buf, size, id);
 }
 
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
-- 
2.1.0


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

* [PATCH v3 09/22] ima: provide buffer hash calculation function
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (7 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 08/22] vfs: define kernel_read_file_id enumeration Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-03 19:06 ` [PATCH v3 10/22] ima: calculate the hash of a buffer using aynchronous hash(ahash) Mimi Zohar
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Dmitry Kasatkin, Dmitry Kasatkin, Mimi Zohar

From: Dmitry Kasatkin <d.kasatkin@samsung.com>

This patch provides convenient buffer hash calculation function.

Changelog v3:
- fix while hash calculation - Dmitry
v1:
- rewrite to support loff_t sized buffers - Mimi
  (based on Fenguang Wu's testing)

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/ima/ima.h        |  2 ++
 security/integrity/ima/ima_crypto.c | 47 +++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index b7e7935..2c5262f 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -107,6 +107,8 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
 			   const char *op, struct inode *inode,
 			   const unsigned char *filename);
 int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
+int ima_calc_buffer_hash(const void *buf, loff_t len,
+			 struct ima_digest_data *hash);
 int ima_calc_field_array_hash(struct ima_field_data *field_data,
 			      struct ima_template_desc *desc, int num_fields,
 			      struct ima_digest_data *hash);
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index fb30ce4..fccb6ce 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -519,6 +519,53 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data,
 	return rc;
 }
 
+static int calc_buffer_shash_tfm(const void *buf, loff_t size,
+				struct ima_digest_data *hash,
+				struct crypto_shash *tfm)
+{
+	SHASH_DESC_ON_STACK(shash, tfm);
+	unsigned int len;
+	int rc;
+
+	shash->tfm = tfm;
+	shash->flags = 0;
+
+	hash->length = crypto_shash_digestsize(tfm);
+
+	rc = crypto_shash_init(shash);
+	if (rc != 0)
+		return rc;
+
+	while (size) {
+		len = size < PAGE_SIZE ? size : PAGE_SIZE;
+		rc = crypto_shash_update(shash, buf, len);
+		if (rc)
+			break;
+		buf += len;
+		size -= len;
+	}
+
+	if (!rc)
+		rc = crypto_shash_final(shash, hash->digest);
+	return rc;
+}
+
+int ima_calc_buffer_hash(const void *buf, loff_t len,
+			 struct ima_digest_data *hash)
+{
+	struct crypto_shash *tfm;
+	int rc;
+
+	tfm = ima_alloc_tfm(hash->algo);
+	if (IS_ERR(tfm))
+		return PTR_ERR(tfm);
+
+	rc = calc_buffer_shash_tfm(buf, len, hash, tfm);
+
+	ima_free_tfm(tfm);
+	return rc;
+}
+
 static void __init ima_pcrread(int idx, u8 *pcr)
 {
 	if (!ima_used_chip)
-- 
2.1.0


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

* [PATCH v3 10/22] ima: calculate the hash of a buffer using aynchronous hash(ahash)
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (8 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 09/22] ima: provide buffer hash calculation function Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-10 19:58   ` Dmitry Kasatkin
  2016-02-03 19:06 ` [PATCH v3 11/22] ima: define a new hook to measure and appraise a file already in memory Mimi Zohar
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Setting up ahash has some overhead.  Only use ahash to calculate the
hash of a buffer, if the buffer is larger than ima_ahash_minsize.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/ima/ima_crypto.c | 75 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index fccb6ce..38f2ed8 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -519,6 +519,63 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data,
 	return rc;
 }
 
+static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
+				  struct ima_digest_data *hash,
+				  struct crypto_ahash *tfm)
+{
+	struct ahash_request *req;
+	struct scatterlist sg;
+	struct ahash_completion res;
+	int rc, ahash_rc = 0;
+
+	hash->length = crypto_ahash_digestsize(tfm);
+
+	req = ahash_request_alloc(tfm, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	init_completion(&res.completion);
+	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+				   CRYPTO_TFM_REQ_MAY_SLEEP,
+				   ahash_complete, &res);
+
+	rc = ahash_wait(crypto_ahash_init(req), &res);
+	if (rc)
+		goto out;
+
+	sg_init_one(&sg, buf, len);
+	ahash_request_set_crypt(req, &sg, NULL, len);
+
+	ahash_rc = crypto_ahash_update(req);
+
+	/* wait for the update request to complete */
+	rc = ahash_wait(ahash_rc, &res);
+	if (!rc) {
+		ahash_request_set_crypt(req, NULL, hash->digest, 0);
+		rc = ahash_wait(crypto_ahash_final(req), &res);
+	}
+out:
+	ahash_request_free(req);
+	return rc;
+}
+
+static int calc_buffer_ahash(const void *buf, loff_t len,
+			     struct ima_digest_data *hash)
+{
+	struct crypto_ahash *tfm;
+	int rc;
+
+	tfm = ima_alloc_atfm(hash->algo);
+	if (IS_ERR(tfm))
+		return PTR_ERR(tfm);
+
+	rc = calc_buffer_ahash_atfm(buf, len, hash, tfm);
+
+	ima_free_atfm(tfm);
+
+	return rc;
+}
+
 static int calc_buffer_shash_tfm(const void *buf, loff_t size,
 				struct ima_digest_data *hash,
 				struct crypto_shash *tfm)
@@ -550,8 +607,8 @@ static int calc_buffer_shash_tfm(const void *buf, loff_t size,
 	return rc;
 }
 
-int ima_calc_buffer_hash(const void *buf, loff_t len,
-			 struct ima_digest_data *hash)
+static int calc_buffer_shash(const void *buf, loff_t len,
+			     struct ima_digest_data *hash)
 {
 	struct crypto_shash *tfm;
 	int rc;
@@ -566,6 +623,20 @@ int ima_calc_buffer_hash(const void *buf, loff_t len,
 	return rc;
 }
 
+int ima_calc_buffer_hash(const void *buf, loff_t len,
+			 struct ima_digest_data *hash)
+{
+	int rc;
+
+	if (ima_ahash_minsize && len >= ima_ahash_minsize) {
+		rc = calc_buffer_ahash(buf, len, hash);
+		if (!rc)
+			return 0;
+	}
+
+	return calc_buffer_shash(buf, len, hash);
+}
+
 static void __init ima_pcrread(int idx, u8 *pcr)
 {
 	if (!ima_used_chip)
-- 
2.1.0


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

* [PATCH v3 11/22] ima: define a new hook to measure and appraise a file already in memory
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (9 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 10/22] ima: calculate the hash of a buffer using aynchronous hash(ahash) Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-10 20:27   ` Dmitry Kasatkin
  2016-02-03 19:06 ` [PATCH v3 12/22] vfs: define kernel_read_file_from_path Mimi Zohar
                   ` (11 subsequent siblings)
  22 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

This patch defines a new IMA hook ima_post_read_file() for measuring
and appraising files read by the kernel. The caller loads the file into
memory before calling this function, which calculates the hash followed by
the normal IMA policy based processing.

Changelog v3:
- rename ima_hash_and_process_file() to ima_post_read_file()

v1:
- To simplify patch review, separate the IMA changes from the kexec
and initramfs changes in "ima: measure and appraise kexec image and
initramfs" patch.  This patch contains just the IMA changes.  The
kexec and initramfs changes are with the rest of the kexec changes
in "kexec: replace call to copy_file_from_fd() with kernel version".

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 include/linux/ima.h                   |  8 +++++++
 include/linux/security.h              |  1 +
 security/integrity/ima/ima.h          |  4 +++-
 security/integrity/ima/ima_api.c      |  6 +++--
 security/integrity/ima/ima_appraise.c |  2 +-
 security/integrity/ima/ima_main.c     | 45 ++++++++++++++++++++++++++++-------
 security/integrity/ima/ima_policy.c   |  1 +
 security/integrity/integrity.h        |  7 ++++--
 security/security.c                   |  7 +++++-
 9 files changed, 66 insertions(+), 15 deletions(-)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index 120ccc5..d29a6a2 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -20,6 +20,8 @@ extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
 extern int ima_module_check(struct file *file);
 extern int ima_fw_from_file(struct file *file, char *buf, size_t size);
+extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
+			      enum kernel_read_file_id id);
 
 #else
 static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -52,6 +54,12 @@ static inline int ima_fw_from_file(struct file *file, char *buf, size_t size)
 	return 0;
 }
 
+static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
+				     enum kernel_read_file_id id)
+{
+	return 0;
+}
+
 #endif /* CONFIG_IMA */
 
 #ifdef CONFIG_IMA_APPRAISE
diff --git a/include/linux/security.h b/include/linux/security.h
index b68ce94..d920718 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -24,6 +24,7 @@
 
 #include <linux/key.h>
 #include <linux/capability.h>
+#include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/string.h>
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 2c5262f..0b7134c 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -19,6 +19,7 @@
 
 #include <linux/types.h>
 #include <linux/crypto.h>
+#include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/hash.h>
 #include <linux/tpm.h>
@@ -152,7 +153,8 @@ enum ima_hooks {
 int ima_get_action(struct inode *inode, int mask, enum ima_hooks func);
 int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
-			    struct file *file, enum hash_algo algo);
+			    struct file *file, void *buf, loff_t size,
+			    enum hash_algo algo);
 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
 			   const unsigned char *filename,
 			   struct evm_ima_xattr_data *xattr_value,
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 8750254..370e42d 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -188,7 +188,8 @@ int ima_get_action(struct inode *inode, int mask, enum ima_hooks func)
  * Return 0 on success, error code otherwise
  */
 int ima_collect_measurement(struct integrity_iint_cache *iint,
-			    struct file *file, enum hash_algo algo)
+			    struct file *file, void *buf, loff_t size,
+			    enum hash_algo algo)
 {
 	const char *audit_cause = "failed";
 	struct inode *inode = file_inode(file);
@@ -210,7 +211,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 
 		hash.hdr.algo = algo;
 
-		result = ima_calc_file_hash(file, &hash.hdr);
+		result = (!buf) ?  ima_calc_file_hash(file, &hash.hdr) :
+			ima_calc_buffer_hash(buf, size, &hash.hdr);
 		if (!result) {
 			int length = sizeof(hash.hdr) + hash.hdr.length;
 			void *tmpbuf = krealloc(iint->ima_hash, length,
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 2888449..cb0d0ff 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -300,7 +300,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
 	if (iint->flags & IMA_DIGSIG)
 		return;
 
-	rc = ima_collect_measurement(iint, file, ima_hash_algo);
+	rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo);
 	if (rc < 0)
 		return;
 
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 78a80c8..bead94b 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -153,8 +153,8 @@ void ima_file_free(struct file *file)
 	ima_check_last_writer(iint, inode, file);
 }
 
-static int process_measurement(struct file *file, int mask,
-			       enum ima_hooks func, int opened)
+static int process_measurement(struct file *file, char *buf, loff_t size,
+			       int mask, enum ima_hooks func, int opened)
 {
 	struct inode *inode = file_inode(file);
 	struct integrity_iint_cache *iint = NULL;
@@ -226,7 +226,7 @@ static int process_measurement(struct file *file, int mask,
 
 	hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
 
-	rc = ima_collect_measurement(iint, file, hash_algo);
+	rc = ima_collect_measurement(iint, file, buf, size, hash_algo);
 	if (rc != 0) {
 		if (file->f_flags & O_DIRECT)
 			rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
@@ -273,7 +273,8 @@ out:
 int ima_file_mmap(struct file *file, unsigned long prot)
 {
 	if (file && (prot & PROT_EXEC))
-		return process_measurement(file, MAY_EXEC, MMAP_CHECK, 0);
+		return process_measurement(file, NULL, 0, MAY_EXEC,
+					   MMAP_CHECK, 0);
 	return 0;
 }
 
@@ -292,7 +293,8 @@ int ima_file_mmap(struct file *file, unsigned long prot)
  */
 int ima_bprm_check(struct linux_binprm *bprm)
 {
-	return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, 0);
+	return process_measurement(bprm->file, NULL, 0, MAY_EXEC,
+				   BPRM_CHECK, 0);
 }
 
 /**
@@ -307,7 +309,7 @@ int ima_bprm_check(struct linux_binprm *bprm)
  */
 int ima_file_check(struct file *file, int mask, int opened)
 {
-	return process_measurement(file,
+	return process_measurement(file, NULL, 0,
 				   mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
 				   FILE_CHECK, opened);
 }
@@ -332,7 +334,7 @@ int ima_module_check(struct file *file)
 #endif
 		return 0;	/* We rely on module signature checking */
 	}
-	return process_measurement(file, MAY_EXEC, MODULE_CHECK, 0);
+	return process_measurement(file, NULL, 0, MAY_EXEC, MODULE_CHECK, 0);
 }
 
 int ima_fw_from_file(struct file *file, char *buf, size_t size)
@@ -343,7 +345,34 @@ int ima_fw_from_file(struct file *file, char *buf, size_t size)
 			return -EACCES;	/* INTEGRITY_UNKNOWN */
 		return 0;
 	}
-	return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, 0);
+	return process_measurement(file, NULL, 0, MAY_EXEC, FIRMWARE_CHECK, 0);
+}
+
+/**
+ * ima_post_read_file - in memory collect/appraise/audit measurement
+ * @file: pointer to the file to be measured/appraised/audit
+ * @buf: pointer to in memory file contents
+ * @size: size of in memory file contents
+ * @read_id: caller identifier
+ *
+ * Measure/appraise/audit in memory file based on policy.  Policy rules
+ * are written in terms of a policy identifier.
+ *
+ * On success return 0.  On integrity appraisal error, assuming the file
+ * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
+ */
+int ima_post_read_file(struct file *file, void *buf, loff_t size,
+		       enum kernel_read_file_id read_id)
+{
+	enum ima_hooks func = FILE_CHECK;
+
+	if (!file && (!buf || size == 0)) { /* should never happen */
+		if (ima_appraise & IMA_APPRAISE_ENFORCE)
+			return -EACCES;
+		return 0;
+	}
+
+	return process_measurement(file, buf, size, MAY_READ, func, 0);
 }
 
 static int __init init_ima(void)
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index b089ebe..cfbe86f 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -12,6 +12,7 @@
  */
 #include <linux/module.h>
 #include <linux/list.h>
+#include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/magic.h>
 #include <linux/parser.h>
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 5efe2ec..9a0ea4c 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -49,12 +49,14 @@
 #define IMA_MODULE_APPRAISED	0x00008000
 #define IMA_FIRMWARE_APPRAISE	0x00010000
 #define IMA_FIRMWARE_APPRAISED	0x00020000
+#define IMA_READ_APPRAISE	0x00040000
+#define IMA_READ_APPRAISED	0x00080000
 #define IMA_APPRAISE_SUBMASK	(IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
 				 IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \
-				 IMA_FIRMWARE_APPRAISE)
+				 IMA_FIRMWARE_APPRAISE | IMA_READ_APPRAISE)
 #define IMA_APPRAISED_SUBMASK	(IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
 				 IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \
-				 IMA_FIRMWARE_APPRAISED)
+				 IMA_FIRMWARE_APPRAISED | IMA_READ_APPRAISED)
 
 enum evm_ima_xattr_type {
 	IMA_XATTR_DIGEST = 0x01,
@@ -111,6 +113,7 @@ struct integrity_iint_cache {
 	enum integrity_status ima_bprm_status:4;
 	enum integrity_status ima_module_status:4;
 	enum integrity_status ima_firmware_status:4;
+	enum integrity_status ima_read_status:4;
 	enum integrity_status evm_status:4;
 	struct ima_digest_data *ima_hash;
 };
diff --git a/security/security.c b/security/security.c
index 796a261..ad87e8d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -913,7 +913,12 @@ int security_kernel_module_from_file(struct file *file)
 int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
 				   enum kernel_read_file_id id)
 {
-	return call_int_hook(kernel_post_read_file, 0, file, buf, size, id);
+	int ret;
+
+	ret = call_int_hook(kernel_post_read_file, 0, file, buf, size, id);
+	if (ret)
+		return ret;
+	return ima_post_read_file(file, buf, size, id);
 }
 
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
-- 
2.1.0


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

* [PATCH v3 12/22] vfs: define kernel_read_file_from_path
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (10 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 11/22] ima: define a new hook to measure and appraise a file already in memory Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:46   ` Kees Cook
  2016-02-04 19:47   ` Luis R. Rodriguez
  2016-02-03 19:06 ` [PATCH v3 13/22] firmware: replace call to fw_read_file_contents() with kernel version Mimi Zohar
                   ` (10 subsequent siblings)
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

This patch defines kernel_read_file_from_path(), a wrapper for the VFS
common kernel_read_file().

Changelog:
- Separated from the IMA patch

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 fs/exec.c          | 22 ++++++++++++++++++++++
 include/linux/fs.h |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index cd2b5b2..5629958 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -884,6 +884,28 @@ out:
 }
 EXPORT_SYMBOL_GPL(kernel_read_file);
 
+int kernel_read_file_from_path(char *path, void **buf, loff_t *size,
+			       loff_t max_size, enum kernel_read_file_id id)
+{
+	struct file *file;
+	int ret;
+
+	if (!path || !*path)
+		return -EINVAL;
+
+	file = filp_open(path, O_RDONLY, 0);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+		pr_err("Unable to open file: %s (%d)", path, ret);
+		return ret;
+	}
+
+	ret = kernel_read_file(file, buf, size, max_size, id);
+	fput(file);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
+
 ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
 {
 	ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1458ca5..962c491 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2533,6 +2533,8 @@ enum kernel_read_file_id {
 extern int kernel_read(struct file *, loff_t, char *, unsigned long);
 extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
 			    enum kernel_read_file_id);
+extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t,
+				      enum kernel_read_file_id);
 extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
 extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
 extern struct file * open_exec(const char *);
-- 
2.1.0


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

* [PATCH v3 13/22] firmware: replace call to fw_read_file_contents() with kernel version
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (11 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 12/22] vfs: define kernel_read_file_from_path Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:56   ` Kees Cook
  2016-02-04 19:51   ` Luis R. Rodriguez
  2016-02-03 19:06 ` [PATCH v3 14/22] security: define kernel_read_file hook Mimi Zohar
                   ` (9 subsequent siblings)
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Replace the fw_read_file_contents with kernel_file_read_from_path().

Although none of the upstreamed LSMs define a kernel_fw_from_file hook,
IMA is called by the security function to prevent unsigned firmware from
being loaded and to measure/appraise signed firmware, based on policy.

Instead of reading the firmware twice, once for measuring/appraising the
firmware and again for reading the firmware contents into memory, the
kernel_post_read_file() security hook calculates the file hash based on
the in memory file buffer.  The firmware is read once.

This patch removes the LSM kernel_fw_from_file() hook and security call.

Changelog v3:
- remove kernel_fw_from_file hook
- use kernel_file_read_from_path() - requested by Luis
v2:
- reordered and squashed firmware patches
- fix MAX firmware size (Kees Cook)

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 drivers/base/firmware_class.c     | 48 +++++++--------------------------------
 include/linux/fs.h                |  1 +
 include/linux/ima.h               |  6 -----
 include/linux/lsm_hooks.h         | 11 ---------
 include/linux/security.h          |  7 ------
 security/integrity/ima/ima_main.c | 21 ++++++++---------
 security/security.c               | 13 -----------
 7 files changed, 19 insertions(+), 88 deletions(-)

diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index c658cec..e06a3d8 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -291,37 +291,6 @@ static const char * const fw_path[] = {
 module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
 MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
 
-static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
-{
-	int size;
-	char *buf;
-	int rc;
-
-	if (!S_ISREG(file_inode(file)->i_mode))
-		return -EINVAL;
-	size = i_size_read(file_inode(file));
-	if (size <= 0)
-		return -EINVAL;
-	buf = vmalloc(size);
-	if (!buf)
-		return -ENOMEM;
-	rc = kernel_read(file, 0, buf, size);
-	if (rc != size) {
-		if (rc > 0)
-			rc = -EIO;
-		goto fail;
-	}
-	rc = security_kernel_fw_from_file(file, buf, size);
-	if (rc)
-		goto fail;
-	fw_buf->data = buf;
-	fw_buf->size = size;
-	return 0;
-fail:
-	vfree(buf);
-	return rc;
-}
-
 static void fw_finish_direct_load(struct device *device,
 				  struct firmware_buf *buf)
 {
@@ -334,6 +303,7 @@ static void fw_finish_direct_load(struct device *device,
 static int fw_get_filesystem_firmware(struct device *device,
 				       struct firmware_buf *buf)
 {
+	loff_t size;
 	int i, len;
 	int rc = -ENOENT;
 	char *path;
@@ -343,8 +313,6 @@ static int fw_get_filesystem_firmware(struct device *device,
 		return -ENOMEM;
 
 	for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
-		struct file *file;
-
 		/* skip the unset customized path */
 		if (!fw_path[i][0])
 			continue;
@@ -356,12 +324,11 @@ static int fw_get_filesystem_firmware(struct device *device,
 			break;
 		}
 
-		file = filp_open(path, O_RDONLY, 0);
-		if (IS_ERR(file))
-			continue;
-		rc = fw_read_file_contents(file, buf);
-		fput(file);
+		buf->size = 0;
+		rc = kernel_read_file_from_path(path, &buf->data, &size,
+						INT_MAX, READING_FIRMWARE);
 		if (rc == 0) {
+			buf->size = (size_t) size;
 			dev_dbg(device, "direct-loading %s\n",
 				buf->fw_id);
 			fw_finish_direct_load(device, buf);
@@ -689,8 +656,9 @@ static ssize_t firmware_loading_store(struct device *dev,
 				dev_err(dev, "%s: map pages failed\n",
 					__func__);
 			else
-				rc = security_kernel_fw_from_file(NULL,
-						fw_buf->data, fw_buf->size);
+				rc = security_kernel_post_read_file(NULL,
+						fw_buf->data, fw_buf->size,
+						READING_FIRMWARE);
 
 			/*
 			 * Same logic as fw_load_abort, only the DONE bit
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 962c491..2a9670a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2527,6 +2527,7 @@ static inline void i_readcount_inc(struct inode *inode)
 extern int do_pipe_flags(int *, int);
 
 enum kernel_read_file_id {
+	READING_FIRMWARE = 1,
 	READING_MAX_ID
 };
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index d29a6a2..7aea486 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -19,7 +19,6 @@ extern int ima_file_check(struct file *file, int mask, int opened);
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
 extern int ima_module_check(struct file *file);
-extern int ima_fw_from_file(struct file *file, char *buf, size_t size);
 extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
 			      enum kernel_read_file_id id);
 
@@ -49,11 +48,6 @@ static inline int ima_module_check(struct file *file)
 	return 0;
 }
 
-static inline int ima_fw_from_file(struct file *file, char *buf, size_t size)
-{
-	return 0;
-}
-
 static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
 				     enum kernel_read_file_id id)
 {
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 2337f33..7d04a12 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -541,15 +541,6 @@
  *	@inode points to the inode to use as a reference.
  *	The current task must be the one that nominated @inode.
  *	Return 0 if successful.
- * @kernel_fw_from_file:
- *	Load firmware from userspace (not called for built-in firmware).
- *	@file contains the file structure pointing to the file containing
- *	the firmware to load. This argument will be NULL if the firmware
- *	was loaded via the uevent-triggered blob-based interface exposed
- *	by CONFIG_FW_LOADER_USER_HELPER.
- *	@buf pointer to buffer containing firmware contents.
- *	@size length of the firmware contents.
- *	Return 0 if permission is granted.
  * @kernel_module_request:
  *	Ability to trigger the kernel to automatically upcall to userspace for
  *	userspace to load a kernel module with the given name.
@@ -1462,7 +1453,6 @@ union security_list_options {
 	void (*cred_transfer)(struct cred *new, const struct cred *old);
 	int (*kernel_act_as)(struct cred *new, u32 secid);
 	int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
-	int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size);
 	int (*kernel_module_request)(char *kmod_name);
 	int (*kernel_module_from_file)(struct file *file);
 	int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size,
@@ -1725,7 +1715,6 @@ struct security_hook_heads {
 	struct list_head cred_transfer;
 	struct list_head kernel_act_as;
 	struct list_head kernel_create_files_as;
-	struct list_head kernel_fw_from_file;
 	struct list_head kernel_post_read_file;
 	struct list_head kernel_module_request;
 	struct list_head kernel_module_from_file;
diff --git a/include/linux/security.h b/include/linux/security.h
index d920718..cee1349 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -300,7 +300,6 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
 void security_transfer_creds(struct cred *new, const struct cred *old);
 int security_kernel_act_as(struct cred *new, u32 secid);
 int security_kernel_create_files_as(struct cred *new, struct inode *inode);
-int security_kernel_fw_from_file(struct file *file, char *buf, size_t size);
 int security_kernel_module_request(char *kmod_name);
 int security_kernel_module_from_file(struct file *file);
 int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
@@ -854,12 +853,6 @@ static inline int security_kernel_create_files_as(struct cred *cred,
 	return 0;
 }
 
-static inline int security_kernel_fw_from_file(struct file *file,
-					       char *buf, size_t size)
-{
-	return 0;
-}
-
 static inline int security_kernel_module_request(char *kmod_name)
 {
 	return 0;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index bead94b..4a5db31 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -337,17 +337,6 @@ int ima_module_check(struct file *file)
 	return process_measurement(file, NULL, 0, MAY_EXEC, MODULE_CHECK, 0);
 }
 
-int ima_fw_from_file(struct file *file, char *buf, size_t size)
-{
-	if (!file) {
-		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
-		    (ima_appraise & IMA_APPRAISE_ENFORCE))
-			return -EACCES;	/* INTEGRITY_UNKNOWN */
-		return 0;
-	}
-	return process_measurement(file, NULL, 0, MAY_EXEC, FIRMWARE_CHECK, 0);
-}
-
 /**
  * ima_post_read_file - in memory collect/appraise/audit measurement
  * @file: pointer to the file to be measured/appraised/audit
@@ -366,12 +355,22 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
 {
 	enum ima_hooks func = FILE_CHECK;
 
+	if (!file && read_id == READING_FIRMWARE) {
+		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
+		    (ima_appraise & IMA_APPRAISE_ENFORCE))
+			return -EACCES;	/* INTEGRITY_UNKNOWN */
+		return 0;
+	}
+
 	if (!file && (!buf || size == 0)) { /* should never happen */
 		if (ima_appraise & IMA_APPRAISE_ENFORCE)
 			return -EACCES;
 		return 0;
 	}
 
+	if (read_id == READING_FIRMWARE)
+		func = FIRMWARE_CHECK;
+
 	return process_measurement(file, buf, size, MAY_READ, func, 0);
 }
 
diff --git a/security/security.c b/security/security.c
index ad87e8d..81a4c3a 100644
--- a/security/security.c
+++ b/security/security.c
@@ -884,17 +884,6 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
 	return call_int_hook(kernel_create_files_as, 0, new, inode);
 }
 
-int security_kernel_fw_from_file(struct file *file, char *buf, size_t size)
-{
-	int ret;
-
-	ret = call_int_hook(kernel_fw_from_file, 0, file, buf, size);
-	if (ret)
-		return ret;
-	return ima_fw_from_file(file, buf, size);
-}
-EXPORT_SYMBOL_GPL(security_kernel_fw_from_file);
-
 int security_kernel_module_request(char *kmod_name)
 {
 	return call_int_hook(kernel_module_request, 0, kmod_name);
@@ -1702,8 +1691,6 @@ struct security_hook_heads security_hook_heads = {
 		LIST_HEAD_INIT(security_hook_heads.kernel_act_as),
 	.kernel_create_files_as =
 		LIST_HEAD_INIT(security_hook_heads.kernel_create_files_as),
-	.kernel_fw_from_file =
-		LIST_HEAD_INIT(security_hook_heads.kernel_fw_from_file),
 	.kernel_module_request =
 		LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
 	.kernel_module_from_file =
-- 
2.1.0


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

* [PATCH v3 14/22] security: define kernel_read_file hook
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (12 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 13/22] firmware: replace call to fw_read_file_contents() with kernel version Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:57   ` Kees Cook
                     ` (2 more replies)
  2016-02-03 19:06 ` [PATCH v3 15/22] vfs: define kernel_copy_file_from_fd() Mimi Zohar
                   ` (8 subsequent siblings)
  22 siblings, 3 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

The kernel_read_file security hook is called prior to reading the file
into memory.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 fs/exec.c                         |  4 ++++
 include/linux/ima.h               |  6 ++++++
 include/linux/lsm_hooks.h         |  8 ++++++++
 include/linux/security.h          |  7 +++++++
 security/integrity/ima/ima_main.c | 16 ++++++++++++++++
 security/security.c               | 12 ++++++++++++
 6 files changed, 53 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index 5629958..1d39c4e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -842,6 +842,10 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 	if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
 		return -EINVAL;
 
+	ret = security_kernel_read_file(file, id);
+	if (ret)
+		return ret;
+
 	i_size = i_size_read(file_inode(file));
 	if (max_size > 0 && i_size > max_size)
 		return -EFBIG;
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 7aea486..6adcaea 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -19,6 +19,7 @@ extern int ima_file_check(struct file *file, int mask, int opened);
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
 extern int ima_module_check(struct file *file);
+extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
 extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
 			      enum kernel_read_file_id id);
 
@@ -48,6 +49,11 @@ static inline int ima_module_check(struct file *file)
 	return 0;
 }
 
+static inline int ima_read_file(struct file *file, enum kernel_read_file_id id)
+{
+	return 0;
+}
+
 static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
 				     enum kernel_read_file_id id)
 {
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7d04a12..d32b7bd 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -552,6 +552,12 @@
  *	the kernel module to load. If the module is being loaded from a blob,
  *	this argument will be NULL.
  *	Return 0 if permission is granted.
+ * @kernel_read_file:
+ *	Read a file specified by userspace.
+ *	@file contains the file structure pointing to the file being read
+ *	by the kernel.
+ *	@id kernel read file identifier
+ *	Return 0 if permission is granted.
  * @kernel_post_read_file:
  *	Read a file specified by userspace.
  *	@file contains the file structure pointing to the file being read
@@ -1455,6 +1461,7 @@ union security_list_options {
 	int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
 	int (*kernel_module_request)(char *kmod_name);
 	int (*kernel_module_from_file)(struct file *file);
+	int (*kernel_read_file)(struct file *file, enum kernel_read_file_id id);
 	int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size,
 				     enum kernel_read_file_id id);
 	int (*task_fix_setuid)(struct cred *new, const struct cred *old,
@@ -1715,6 +1722,7 @@ struct security_hook_heads {
 	struct list_head cred_transfer;
 	struct list_head kernel_act_as;
 	struct list_head kernel_create_files_as;
+	struct list_head kernel_read_file;
 	struct list_head kernel_post_read_file;
 	struct list_head kernel_module_request;
 	struct list_head kernel_module_from_file;
diff --git a/include/linux/security.h b/include/linux/security.h
index cee1349..071fb74 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -302,6 +302,7 @@ int security_kernel_act_as(struct cred *new, u32 secid);
 int security_kernel_create_files_as(struct cred *new, struct inode *inode);
 int security_kernel_module_request(char *kmod_name);
 int security_kernel_module_from_file(struct file *file);
+int security_kernel_read_file(struct file *file, enum kernel_read_file_id id);
 int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
 				   enum kernel_read_file_id id);
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
@@ -863,6 +864,12 @@ static inline int security_kernel_module_from_file(struct file *file)
 	return 0;
 }
 
+static inline int security_kernel_read_file(struct file *file,
+					    enum kernel_read_file_id id)
+{
+	return 0;
+}
+
 static inline int security_kernel_post_read_file(struct file *file,
 						 char *buf, loff_t size,
 						 enum kernel_read_file_id id)
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 4a5db31..6f79bdf 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -338,6 +338,22 @@ int ima_module_check(struct file *file)
 }
 
 /**
+ * ima_read_file - pre-measure/appraise hook decision based on policy
+ * @file: pointer to the file to be measured/appraised/audit
+ * @read_id: caller identifier
+ *
+ * Permit reading a file based on policy. The policy rules are written
+ * in terms of the policy identifier.  Appraising the integrity of
+ * a file requires a file descriptor.
+ *
+ * For permission return 0, otherwise return -EACCES.
+ */
+int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
+{
+	return 0;
+}
+
+/**
  * ima_post_read_file - in memory collect/appraise/audit measurement
  * @file: pointer to the file to be measured/appraised/audit
  * @buf: pointer to in memory file contents
diff --git a/security/security.c b/security/security.c
index 81a4c3a..1728fe2 100644
--- a/security/security.c
+++ b/security/security.c
@@ -899,6 +899,16 @@ int security_kernel_module_from_file(struct file *file)
 	return ima_module_check(file);
 }
 
+int security_kernel_read_file(struct file *file, enum kernel_read_file_id id)
+{
+	int ret;
+
+	ret = call_int_hook(kernel_read_file, 0, file, id);
+	if (ret)
+		return ret;
+	return ima_read_file(file, id);
+}
+
 int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
 				   enum kernel_read_file_id id)
 {
@@ -1695,6 +1705,8 @@ struct security_hook_heads security_hook_heads = {
 		LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
 	.kernel_module_from_file =
 		LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file),
+	.kernel_read_file =
+		LIST_HEAD_INIT(security_hook_heads.kernel_read_file),
 	.kernel_post_read_file =
 		LIST_HEAD_INIT(security_hook_heads.kernel_post_read_file),
 	.task_fix_setuid =
-- 
2.1.0


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

* [PATCH v3 15/22] vfs: define kernel_copy_file_from_fd()
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (13 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 14/22] security: define kernel_read_file hook Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 17:58   ` Kees Cook
  2016-02-04 19:55   ` Luis R. Rodriguez
  2016-02-03 19:06 ` [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version Mimi Zohar
                   ` (7 subsequent siblings)
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

This patch defines kernel_read_file_from_fd(), a wrapper for the VFS
common kernel_read_file().

Changelog:
- Separated from the kernel modules patch

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 fs/exec.c          | 16 ++++++++++++++++
 include/linux/fs.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index 1d39c4e..f3a0ce2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -910,6 +910,22 @@ int kernel_read_file_from_path(char *path, void **buf, loff_t *size,
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
 
+int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
+			     enum kernel_read_file_id id)
+{
+	struct fd f = fdget(fd);
+	int ret = -EBADF;
+
+	if (!f.file)
+		goto out;
+
+	ret = kernel_read_file(f.file, buf, size, max_size, id);
+out:
+	fdput(f);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);
+
 ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
 {
 	ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2a9670a..5ba806b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2536,6 +2536,8 @@ extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
 			    enum kernel_read_file_id);
 extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t,
 				      enum kernel_read_file_id);
+extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t,
+				    enum kernel_read_file_id);
 extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
 extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
 extern struct file * open_exec(const char *);
-- 
2.1.0


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

* [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (14 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 15/22] vfs: define kernel_copy_file_from_fd() Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 18:04   ` Kees Cook
  2016-02-04 19:56   ` Luis R. Rodriguez
  2016-02-03 19:06 ` [PATCH v3 17/22] ima: remove firmware and module specific cached status info Mimi Zohar
                   ` (6 subsequent siblings)
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Replace copy_module_from_fd() with kernel_read_file_from_fd().

Although none of the upstreamed LSMs define a kernel_module_from_file
hook, IMA is called, based on policy, to prevent unsigned kernel modules
from being loaded by the original kernel module syscall and to
measure/appraise signed kernel modules.

The security function security_kernel_module_from_file() was called prior
to reading a kernel module.  Preventing unsigned kernel modules from being
loaded by the original kernel module syscall remains on the pre-read
kernel_read_file() security hook.  Instead of reading the kernel module
twice, once for measuring/appraising and again for loading the kernel
module, the signature validation is moved to the kernel_post_read_file()
security hook.

This patch removes the security_kernel_module_from_file() hook and security
call.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 include/linux/fs.h                |  1 +
 include/linux/ima.h               |  6 ----
 include/linux/lsm_hooks.h         |  7 ----
 include/linux/security.h          |  5 ---
 kernel/module.c                   | 68 +++++----------------------------------
 security/integrity/ima/ima_main.c | 35 ++++++++------------
 security/security.c               | 12 -------
 7 files changed, 22 insertions(+), 112 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 5ba806b..9e1f1e3 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2528,6 +2528,7 @@ extern int do_pipe_flags(int *, int);
 
 enum kernel_read_file_id {
 	READING_FIRMWARE = 1,
+	READING_MODULE,
 	READING_MAX_ID
 };
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 6adcaea..e6516cb 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -18,7 +18,6 @@ extern int ima_bprm_check(struct linux_binprm *bprm);
 extern int ima_file_check(struct file *file, int mask, int opened);
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
-extern int ima_module_check(struct file *file);
 extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
 extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
 			      enum kernel_read_file_id id);
@@ -44,11 +43,6 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
 	return 0;
 }
 
-static inline int ima_module_check(struct file *file)
-{
-	return 0;
-}
-
 static inline int ima_read_file(struct file *file, enum kernel_read_file_id id)
 {
 	return 0;
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d32b7bd..cdee11c 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -546,12 +546,6 @@
  *	userspace to load a kernel module with the given name.
  *	@kmod_name name of the module requested by the kernel
  *	Return 0 if successful.
- * @kernel_module_from_file:
- *	Load a kernel module from userspace.
- *	@file contains the file structure pointing to the file containing
- *	the kernel module to load. If the module is being loaded from a blob,
- *	this argument will be NULL.
- *	Return 0 if permission is granted.
  * @kernel_read_file:
  *	Read a file specified by userspace.
  *	@file contains the file structure pointing to the file being read
@@ -1725,7 +1719,6 @@ struct security_hook_heads {
 	struct list_head kernel_read_file;
 	struct list_head kernel_post_read_file;
 	struct list_head kernel_module_request;
-	struct list_head kernel_module_from_file;
 	struct list_head task_fix_setuid;
 	struct list_head task_setpgid;
 	struct list_head task_getpgid;
diff --git a/include/linux/security.h b/include/linux/security.h
index 071fb74..157f0cb 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -859,11 +859,6 @@ static inline int security_kernel_module_request(char *kmod_name)
 	return 0;
 }
 
-static inline int security_kernel_module_from_file(struct file *file)
-{
-	return 0;
-}
-
 static inline int security_kernel_read_file(struct file *file,
 					    enum kernel_read_file_id id)
 {
diff --git a/kernel/module.c b/kernel/module.c
index 8f051a1..d77c4f1 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2665,7 +2665,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
 	if (info->len < sizeof(*(info->hdr)))
 		return -ENOEXEC;
 
-	err = security_kernel_module_from_file(NULL);
+	err = security_kernel_read_file(NULL, READING_MODULE);
 	if (err)
 		return err;
 
@@ -2683,63 +2683,6 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
 	return 0;
 }
 
-/* Sets info->hdr and info->len. */
-static int copy_module_from_fd(int fd, struct load_info *info)
-{
-	struct fd f = fdget(fd);
-	int err;
-	struct kstat stat;
-	loff_t pos;
-	ssize_t bytes = 0;
-
-	if (!f.file)
-		return -ENOEXEC;
-
-	err = security_kernel_module_from_file(f.file);
-	if (err)
-		goto out;
-
-	err = vfs_getattr(&f.file->f_path, &stat);
-	if (err)
-		goto out;
-
-	if (stat.size > INT_MAX) {
-		err = -EFBIG;
-		goto out;
-	}
-
-	/* Don't hand 0 to vmalloc, it whines. */
-	if (stat.size == 0) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	info->hdr = vmalloc(stat.size);
-	if (!info->hdr) {
-		err = -ENOMEM;
-		goto out;
-	}
-
-	pos = 0;
-	while (pos < stat.size) {
-		bytes = kernel_read(f.file, pos, (char *)(info->hdr) + pos,
-				    stat.size - pos);
-		if (bytes < 0) {
-			vfree(info->hdr);
-			err = bytes;
-			goto out;
-		}
-		if (bytes == 0)
-			break;
-		pos += bytes;
-	}
-	info->len = pos;
-
-out:
-	fdput(f);
-	return err;
-}
-
 static void free_copy(struct load_info *info)
 {
 	vfree(info->hdr);
@@ -3602,8 +3545,10 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
 
 SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
 {
-	int err;
 	struct load_info info = { };
+	loff_t size;
+	void *hdr;
+	int err;
 
 	err = may_init_module();
 	if (err)
@@ -3615,9 +3560,12 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
 		      |MODULE_INIT_IGNORE_VERMAGIC))
 		return -EINVAL;
 
-	err = copy_module_from_fd(fd, &info);
+	err = kernel_read_file_from_fd(fd, &hdr, &size, INT_MAX,
+				       READING_MODULE);
 	if (err)
 		return err;
+	info.hdr = hdr;
+	info.len = size;
 
 	return load_module(&info, uargs, flags);
 }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 6f79bdf..1e91d94 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -316,28 +316,6 @@ int ima_file_check(struct file *file, int mask, int opened)
 EXPORT_SYMBOL_GPL(ima_file_check);
 
 /**
- * ima_module_check - based on policy, collect/store/appraise measurement.
- * @file: pointer to the file to be measured/appraised
- *
- * Measure/appraise kernel modules based on policy.
- *
- * On success return 0.  On integrity appraisal error, assuming the file
- * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
- */
-int ima_module_check(struct file *file)
-{
-	if (!file) {
-#ifndef CONFIG_MODULE_SIG_FORCE
-		if ((ima_appraise & IMA_APPRAISE_MODULES) &&
-		    (ima_appraise & IMA_APPRAISE_ENFORCE))
-			return -EACCES;	/* INTEGRITY_UNKNOWN */
-#endif
-		return 0;	/* We rely on module signature checking */
-	}
-	return process_measurement(file, NULL, 0, MAY_EXEC, MODULE_CHECK, 0);
-}
-
-/**
  * ima_read_file - pre-measure/appraise hook decision based on policy
  * @file: pointer to the file to be measured/appraised/audit
  * @read_id: caller identifier
@@ -350,6 +328,14 @@ int ima_module_check(struct file *file)
  */
 int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
 {
+	if (!file && read_id == READING_MODULE) {
+#ifndef CONFIG_MODULE_SIG_FORCE
+		if ((ima_appraise & IMA_APPRAISE_MODULES) &&
+		    (ima_appraise & IMA_APPRAISE_ENFORCE))
+			return -EACCES;	/* INTEGRITY_UNKNOWN */
+#endif
+		return 0;	/* We rely on module signature checking */
+	}
 	return 0;
 }
 
@@ -378,6 +364,9 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
 		return 0;
 	}
 
+	if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */
+		return 0;
+
 	if (!file && (!buf || size == 0)) { /* should never happen */
 		if (ima_appraise & IMA_APPRAISE_ENFORCE)
 			return -EACCES;
@@ -386,6 +375,8 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
 
 	if (read_id == READING_FIRMWARE)
 		func = FIRMWARE_CHECK;
+	else if (read_id == READING_MODULE)
+		func = MODULE_CHECK;
 
 	return process_measurement(file, buf, size, MAY_READ, func, 0);
 }
diff --git a/security/security.c b/security/security.c
index 1728fe2..3573c82 100644
--- a/security/security.c
+++ b/security/security.c
@@ -889,16 +889,6 @@ int security_kernel_module_request(char *kmod_name)
 	return call_int_hook(kernel_module_request, 0, kmod_name);
 }
 
-int security_kernel_module_from_file(struct file *file)
-{
-	int ret;
-
-	ret = call_int_hook(kernel_module_from_file, 0, file);
-	if (ret)
-		return ret;
-	return ima_module_check(file);
-}
-
 int security_kernel_read_file(struct file *file, enum kernel_read_file_id id)
 {
 	int ret;
@@ -1703,8 +1693,6 @@ struct security_hook_heads security_hook_heads = {
 		LIST_HEAD_INIT(security_hook_heads.kernel_create_files_as),
 	.kernel_module_request =
 		LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
-	.kernel_module_from_file =
-		LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file),
 	.kernel_read_file =
 		LIST_HEAD_INIT(security_hook_heads.kernel_read_file),
 	.kernel_post_read_file =
-- 
2.1.0


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

* [PATCH v3 17/22] ima: remove firmware and module specific cached status info
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (15 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-07 19:56   ` Petko Manolov
  2016-02-10 20:18   ` Dmitry Kasatkin
  2016-02-03 19:06 ` [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version Mimi Zohar
                   ` (5 subsequent siblings)
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Each time a file is read by the kernel, the file should be re-measured and
the file signature re-appraised, based on policy.  As there is no need to
preserve the status information, this patch replaces the firmware and
module specific cache status with a generic one named read_file.

This change simplifies adding support for other files read by the kernel.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/iint.c             |  4 ++--
 security/integrity/ima/ima.h          |  3 ++-
 security/integrity/ima/ima_appraise.c | 35 ++++++++++++++++-------------------
 security/integrity/ima/ima_policy.c   |  9 ++++-----
 security/integrity/integrity.h        | 16 ++++------------
 5 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 8f1ab37..345b759 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -77,7 +77,7 @@ static void iint_free(struct integrity_iint_cache *iint)
 	iint->ima_file_status = INTEGRITY_UNKNOWN;
 	iint->ima_mmap_status = INTEGRITY_UNKNOWN;
 	iint->ima_bprm_status = INTEGRITY_UNKNOWN;
-	iint->ima_module_status = INTEGRITY_UNKNOWN;
+	iint->ima_read_status = INTEGRITY_UNKNOWN;
 	iint->evm_status = INTEGRITY_UNKNOWN;
 	kmem_cache_free(iint_cache, iint);
 }
@@ -157,7 +157,7 @@ static void init_once(void *foo)
 	iint->ima_file_status = INTEGRITY_UNKNOWN;
 	iint->ima_mmap_status = INTEGRITY_UNKNOWN;
 	iint->ima_bprm_status = INTEGRITY_UNKNOWN;
-	iint->ima_module_status = INTEGRITY_UNKNOWN;
+	iint->ima_read_status = INTEGRITY_UNKNOWN;
 	iint->evm_status = INTEGRITY_UNKNOWN;
 }
 
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 0b7134c..a5d2592 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -144,9 +144,10 @@ enum ima_hooks {
 	FILE_CHECK = 1,
 	MMAP_CHECK,
 	BPRM_CHECK,
+	POST_SETATTR,
 	MODULE_CHECK,
 	FIRMWARE_CHECK,
-	POST_SETATTR
+	MAX_CHECK
 };
 
 /* LIM API function definitions */
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index cb0d0ff..6b4694a 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -74,13 +74,12 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
 		return iint->ima_mmap_status;
 	case BPRM_CHECK:
 		return iint->ima_bprm_status;
-	case MODULE_CHECK:
-		return iint->ima_module_status;
-	case FIRMWARE_CHECK:
-		return iint->ima_firmware_status;
 	case FILE_CHECK:
-	default:
+	case POST_SETATTR:
 		return iint->ima_file_status;
+	case MODULE_CHECK ... MAX_CHECK - 1:
+	default:
+		return iint->ima_read_status;
 	}
 }
 
@@ -95,15 +94,14 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
 	case BPRM_CHECK:
 		iint->ima_bprm_status = status;
 		break;
-	case MODULE_CHECK:
-		iint->ima_module_status = status;
-		break;
-	case FIRMWARE_CHECK:
-		iint->ima_firmware_status = status;
-		break;
 	case FILE_CHECK:
-	default:
+	case POST_SETATTR:
 		iint->ima_file_status = status;
+		break;
+	case MODULE_CHECK ... MAX_CHECK - 1:
+	default:
+		iint->ima_read_status = status;
+		break;
 	}
 }
 
@@ -117,15 +115,14 @@ static void ima_cache_flags(struct integrity_iint_cache *iint,
 	case BPRM_CHECK:
 		iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
 		break;
-	case MODULE_CHECK:
-		iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED);
-		break;
-	case FIRMWARE_CHECK:
-		iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED);
-		break;
 	case FILE_CHECK:
-	default:
+	case POST_SETATTR:
 		iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
+		break;
+	case MODULE_CHECK ... MAX_CHECK - 1:
+	default:
+		iint->flags |= (IMA_READ_APPRAISED | IMA_APPRAISED);
+		break;
 	}
 }
 
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index cfbe86f..7571ce8 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -300,13 +300,12 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
 		return IMA_MMAP_APPRAISE;
 	case BPRM_CHECK:
 		return IMA_BPRM_APPRAISE;
-	case MODULE_CHECK:
-		return IMA_MODULE_APPRAISE;
-	case FIRMWARE_CHECK:
-		return IMA_FIRMWARE_APPRAISE;
 	case FILE_CHECK:
-	default:
+	case POST_SETATTR:
 		return IMA_FILE_APPRAISE;
+	case MODULE_CHECK ... MAX_CHECK - 1:
+	default:
+		return IMA_READ_APPRAISE;
 	}
 }
 
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 9a0ea4c..c7a111c 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -45,18 +45,12 @@
 #define IMA_MMAP_APPRAISED	0x00000800
 #define IMA_BPRM_APPRAISE	0x00001000
 #define IMA_BPRM_APPRAISED	0x00002000
-#define IMA_MODULE_APPRAISE	0x00004000
-#define IMA_MODULE_APPRAISED	0x00008000
-#define IMA_FIRMWARE_APPRAISE	0x00010000
-#define IMA_FIRMWARE_APPRAISED	0x00020000
-#define IMA_READ_APPRAISE	0x00040000
-#define IMA_READ_APPRAISED	0x00080000
+#define IMA_READ_APPRAISE	0x00004000
+#define IMA_READ_APPRAISED	0x00008000
 #define IMA_APPRAISE_SUBMASK	(IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
-				 IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \
-				 IMA_FIRMWARE_APPRAISE | IMA_READ_APPRAISE)
+				 IMA_BPRM_APPRAISE | IMA_READ_APPRAISE)
 #define IMA_APPRAISED_SUBMASK	(IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
-				 IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \
-				 IMA_FIRMWARE_APPRAISED | IMA_READ_APPRAISED)
+				 IMA_BPRM_APPRAISED | IMA_READ_APPRAISED)
 
 enum evm_ima_xattr_type {
 	IMA_XATTR_DIGEST = 0x01,
@@ -111,8 +105,6 @@ struct integrity_iint_cache {
 	enum integrity_status ima_file_status:4;
 	enum integrity_status ima_mmap_status:4;
 	enum integrity_status ima_bprm_status:4;
-	enum integrity_status ima_module_status:4;
-	enum integrity_status ima_firmware_status:4;
 	enum integrity_status ima_read_status:4;
 	enum integrity_status evm_status:4;
 	struct ima_digest_data *ima_hash;
-- 
2.1.0


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

* [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (16 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 17/22] ima: remove firmware and module specific cached status info Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-04 18:05   ` Kees Cook
                     ` (2 more replies)
  2016-02-03 19:06 ` [PATCH v3 19/22] ima: support for kexec image and initramfs Mimi Zohar
                   ` (4 subsequent siblings)
  22 siblings, 3 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Replace copy_file_from_fd() with kernel_read_file_from_fd().

Two new identifiers named READING_KEXEC_IMAGE and READING_KEXEC_INITRAMFS
are defined for measuring, appraising or auditing the kexec image and
initramfs.

Changelog v3:
- return -EBADF, not -ENOEXEC
- identifier change
- moved copy_file_from_fd() to a separate patch
- defer support for IMA
v1:
- re-order and squash the kexec patches
v0: ima: measure and appraise kexec image and initramfs (squashed)
- rename ima_read_hooks enumeration to ima_policy_id
- use kstat file size type loff_t, not size_t
- add union name "hooks" to fix sparse warning
- Calculate the file hash from the in memory buffer
(suggested by Dave Young)
- Rename ima_read_and_process_file() to ima_hash_and_process_file()
- replace individual case statements with range:
        KEXEC_CHECK ... IMA_MAX_READ_CHECK - 1
- Instead of ima_read_and_process_file() allocating memory, the caller
allocates and frees the memory.
- Moved the kexec measurement/appraisal call to copy_file_from_fd(). The
same call now measures and appraises both the kexec image and initramfs.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 include/linux/fs.h  |  2 ++
 kernel/kexec_file.c | 73 +++++++----------------------------------------------
 2 files changed, 11 insertions(+), 64 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9e1f1e3..d4d556e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2529,6 +2529,8 @@ extern int do_pipe_flags(int *, int);
 enum kernel_read_file_id {
 	READING_FIRMWARE = 1,
 	READING_MODULE,
+	READING_KEXEC_IMAGE,
+	READING_KEXEC_INITRAMFS,
 	READING_MAX_ID
 };
 
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index b70ada0..1443f93 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -18,6 +18,7 @@
 #include <linux/kexec.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
+#include <linux/fs.h>
 #include <crypto/hash.h>
 #include <crypto/sha.h>
 #include <linux/syscalls.h>
@@ -33,65 +34,6 @@ size_t __weak kexec_purgatory_size = 0;
 
 static int kexec_calculate_store_digests(struct kimage *image);
 
-static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len)
-{
-	struct fd f = fdget(fd);
-	int ret;
-	struct kstat stat;
-	loff_t pos;
-	ssize_t bytes = 0;
-
-	if (!f.file)
-		return -EBADF;
-
-	ret = vfs_getattr(&f.file->f_path, &stat);
-	if (ret)
-		goto out;
-
-	if (stat.size > INT_MAX) {
-		ret = -EFBIG;
-		goto out;
-	}
-
-	/* Don't hand 0 to vmalloc, it whines. */
-	if (stat.size == 0) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	*buf = vmalloc(stat.size);
-	if (!*buf) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	pos = 0;
-	while (pos < stat.size) {
-		bytes = kernel_read(f.file, pos, (char *)(*buf) + pos,
-				    stat.size - pos);
-		if (bytes < 0) {
-			vfree(*buf);
-			ret = bytes;
-			goto out;
-		}
-
-		if (bytes == 0)
-			break;
-		pos += bytes;
-	}
-
-	if (pos != stat.size) {
-		ret = -EBADF;
-		vfree(*buf);
-		goto out;
-	}
-
-	*buf_len = pos;
-out:
-	fdput(f);
-	return ret;
-}
-
 /* Architectures can provide this probe function */
 int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
 					 unsigned long buf_len)
@@ -180,16 +122,17 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 {
 	int ret = 0;
 	void *ldata;
+	loff_t size;
 
-	ret = copy_file_from_fd(kernel_fd, &image->kernel_buf,
-				&image->kernel_buf_len);
+	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
+				       &size, INT_MAX, READING_KEXEC_IMAGE);
 	if (ret)
 		return ret;
+	image->kernel_buf_len = size;
 
 	/* Call arch image probe handlers */
 	ret = arch_kexec_kernel_image_probe(image, image->kernel_buf,
 					    image->kernel_buf_len);
-
 	if (ret)
 		goto out;
 
@@ -204,10 +147,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 #endif
 	/* It is possible that there no initramfs is being loaded */
 	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
-		ret = copy_file_from_fd(initrd_fd, &image->initrd_buf,
-					&image->initrd_buf_len);
+		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
+					       &size, INT_MAX,
+					       READING_KEXEC_INITRAMFS);
 		if (ret)
 			goto out;
+		image->initrd_buf_len = size;
 	}
 
 	if (cmdline_len) {
-- 
2.1.0


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

* [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (17 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-07 20:10   ` Petko Manolov
                     ` (2 more replies)
  2016-02-03 19:06 ` [PATCH v3 20/22] ima: load policy using path Mimi Zohar
                   ` (3 subsequent siblings)
  22 siblings, 3 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Add IMA policy support for measuring/appraising the kexec image and
initramfs.

Moving the enumeration to the vfs layer simplified the patches, allowing
the IMA changes, for the most part, to be separated from the other
changes.  Unfortunately, passing either a kernel_read_file_id or a
ima_hooks enumeration within IMA is messy.

Option 1: duplicate kernel_read_file enumeration in ima_hooks

enum kernel_read_file_id {
	...
        READING_KEXEC_IMAGE,
        READING_KEXEC_INITRAMFS,
        READING_MAX_ID

enum ima_hooks {
	...
	KEXEC_CHECK
	INITRAMFS_CHECK

Option 2: define ima_hooks as extension of kernel_read_file
eg: enum ima_hooks {
        FILE_CHECK = READING_MAX_ID,
        MMAP_CHECK,

In order to pass both kernel_read_file_id and ima_hooks values, we
would need to specify a struct containing a union.

struct caller_id {
        union {
                enum ima_hooks func_id;
                enum kernel_read_file_id read_id;
        };
};

Option 3: incorportate the ima_hooks enumeration into kernel_read_file_id,
perhaps changing the enumeration name.

For now, duplicate the new READING_KEXEC_IMAGE/INITRAMFS in ima_hooks.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 Documentation/ABI/testing/ima_policy |  2 +-
 security/integrity/ima/ima.h         |  2 ++
 security/integrity/ima/ima_main.c    | 19 ++++++++++++++++---
 security/integrity/ima/ima_policy.c  | 13 ++++++++++++-
 4 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 0a378a8..e80f767 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -26,7 +26,7 @@ Description:
 			option:	[[appraise_type=]] [permit_directio]
 
 		base: 	func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
-				[FIRMWARE_CHECK]
+				[FIRMWARE_CHECK] [KEXEC_CHECK] [INITRAMFS_CHECK]
 			mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
 			       [[^]MAY_EXEC]
 			fsmagic:= hex value
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index a5d2592..832e62a 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -147,6 +147,8 @@ enum ima_hooks {
 	POST_SETATTR,
 	MODULE_CHECK,
 	FIRMWARE_CHECK,
+	KEXEC_CHECK,
+	INITRAMFS_CHECK,
 	MAX_CHECK
 };
 
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 1e91d94..ccf9526 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -355,7 +355,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
 int ima_post_read_file(struct file *file, void *buf, loff_t size,
 		       enum kernel_read_file_id read_id)
 {
-	enum ima_hooks func = FILE_CHECK;
+	enum ima_hooks func;
 
 	if (!file && read_id == READING_FIRMWARE) {
 		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
@@ -373,10 +373,23 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
 		return 0;
 	}
 
-	if (read_id == READING_FIRMWARE)
+	switch (read_id) {
+	case READING_FIRMWARE:
 		func = FIRMWARE_CHECK;
-	else if (read_id == READING_MODULE)
+		break;
+	case READING_MODULE:
 		func = MODULE_CHECK;
+		break;
+	case READING_KEXEC_IMAGE:
+		func = KEXEC_CHECK;
+		break;
+	case READING_KEXEC_INITRAMFS:
+		func = INITRAMFS_CHECK;
+		break;
+	default:
+		func = FILE_CHECK;
+		break;
+	}
 
 	return process_measurement(file, buf, size, MAY_READ, func, 0);
 }
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 7571ce8..d02560e 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -612,6 +612,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 				entry->func = MMAP_CHECK;
 			else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
 				entry->func = BPRM_CHECK;
+			else if (strcmp(args[0].from, "KEXEC_CHECK") == 0)
+				entry->func = KEXEC_CHECK;
+			else if (strcmp(args[0].from, "INITRAMFS_CHECK") == 0)
+				entry->func = INITRAMFS_CHECK;
 			else
 				result = -EINVAL;
 			if (!result)
@@ -855,7 +859,8 @@ static char *mask_tokens[] = {
 
 enum {
 	func_file = 0, func_mmap, func_bprm,
-	func_module, func_firmware, func_post
+	func_module, func_firmware, func_post,
+	func_kexec, func_initramfs
 };
 
 static char *func_tokens[] = {
@@ -929,6 +934,12 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
 	case POST_SETATTR:
 		seq_printf(m, pt(Opt_func), ft(func_post));
 		break;
+	case KEXEC_CHECK:
+		seq_printf(m, pt(Opt_func), ft(func_kexec));
+		break;
+	case INITRAMFS_CHECK:
+		seq_printf(m, pt(Opt_func), ft(func_initramfs));
+		break;
 	default:
 		snprintf(tbuf, sizeof(tbuf), "%d", func);
 		seq_printf(m, pt(Opt_func), tbuf);
-- 
2.1.0


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

* [PATCH v3 20/22] ima: load policy using path
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (18 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 19/22] ima: support for kexec image and initramfs Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-07 19:59   ` Petko Manolov
  2016-02-03 19:06 ` [PATCH v3 21/22] ima: measure and appraise the IMA policy itself Mimi Zohar
                   ` (2 subsequent siblings)
  22 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Dmitry Kasatkin, Dmitry Kasatkin, Mimi Zohar

From: Dmitry Kasatkin <d.kasatkin@samsung.com>

We currently cannot do appraisal or signature vetting of IMA policies
since we currently can only load IMA policies by writing the contents
of the policy directly in, as follows:

cat policy-file > <securityfs>/ima/policy

If we provide the kernel the path to the IMA policy so it can load
the policy itself it'd be able to later appraise or vet the file
signature if it has one.  This patch adds support to load the IMA
policy with a given path as follows:

echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy

Changelog v3:
- moved kernel_read_file_from_path() to a separate patch
v2:
- after re-ordering the patches, replace calling integrity_kernel_read()
  to read the file with kernel_read_file_from_path() (Mimi)
- Patch description re-written by Luis R. Rodriguez

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 include/linux/fs.h              |  1 +
 security/integrity/ima/ima_fs.c | 43 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index d4d556e..b648e6d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2531,6 +2531,7 @@ enum kernel_read_file_id {
 	READING_MODULE,
 	READING_KEXEC_IMAGE,
 	READING_KEXEC_INITRAMFS,
+	READING_POLICY,
 	READING_MAX_ID
 };
 
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index f355231..00ccd67 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -22,6 +22,7 @@
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
 #include <linux/parser.h>
+#include <linux/vmalloc.h>
 
 #include "ima.h"
 
@@ -258,6 +259,41 @@ static const struct file_operations ima_ascii_measurements_ops = {
 	.release = seq_release,
 };
 
+static ssize_t ima_read_policy(char *path)
+{
+	void *data;
+	char *datap;
+	loff_t size;
+	int rc, pathlen = strlen(path);
+
+	char *p;
+
+	/* remove \n */
+	datap = path;
+	strsep(&datap, "\n");
+
+	rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
+	if (rc < 0)
+		return rc;
+
+	datap = data;
+	while (size > 0 && (p = strsep(&datap, "\n"))) {
+		pr_debug("rule: %s\n", p);
+		rc = ima_parse_add_rule(p);
+		if (rc < 0)
+			break;
+		size -= rc;
+	}
+
+	vfree(data);
+	if (rc < 0)
+		return rc;
+	else if (size)
+		return -EINVAL;
+	else
+		return pathlen;
+}
+
 static ssize_t ima_write_policy(struct file *file, const char __user *buf,
 				size_t datalen, loff_t *ppos)
 {
@@ -286,9 +322,12 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
 	result = mutex_lock_interruptible(&ima_write_mutex);
 	if (result < 0)
 		goto out_free;
-	result = ima_parse_add_rule(data);
-	mutex_unlock(&ima_write_mutex);
 
+	if (data[0] == '/')
+		result = ima_read_policy(data);
+	else
+		result = ima_parse_add_rule(data);
+	mutex_unlock(&ima_write_mutex);
 out_free:
 	kfree(data);
 out:
-- 
2.1.0


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

* [PATCH v3 21/22] ima: measure and appraise the IMA policy itself
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (19 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 20/22] ima: load policy using path Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-07 20:01   ` Petko Manolov
  2016-02-10 20:22   ` Dmitry Kasatkin
  2016-02-03 19:06 ` [PATCH v3 22/22] ima: require signed IMA policy Mimi Zohar
  2016-02-04 18:15 ` [PATCH v3 00/22] vfs: support for a common kernel file loader Kees Cook
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Add support for measuring and appraising the IMA policy itself.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/ima/ima.h        |  2 ++
 security/integrity/ima/ima_fs.c     |  9 ++++++++-
 security/integrity/ima/ima_main.c   |  3 +++
 security/integrity/ima/ima_policy.c | 10 +++++++++-
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 832e62a..6685968 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -149,6 +149,7 @@ enum ima_hooks {
 	FIRMWARE_CHECK,
 	KEXEC_CHECK,
 	INITRAMFS_CHECK,
+	POLICY_CHECK,
 	MAX_CHECK
 };
 
@@ -191,6 +192,7 @@ int ima_policy_show(struct seq_file *m, void *v);
 #define IMA_APPRAISE_LOG	0x04
 #define IMA_APPRAISE_MODULES	0x08
 #define IMA_APPRAISE_FIRMWARE	0x10
+#define IMA_APPRAISE_POLICY	0x20
 
 #ifdef CONFIG_IMA_APPRAISE
 int ima_appraise_measurement(enum ima_hooks func,
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 00ccd67..7b15e80 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -325,7 +325,14 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
 
 	if (data[0] == '/')
 		result = ima_read_policy(data);
-	else
+	else if (ima_appraise & IMA_APPRAISE_POLICY) {
+		pr_err("IMA: signed policy 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);
 	mutex_unlock(&ima_write_mutex);
 out_free:
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index ccf9526..497a6f2 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -386,6 +386,9 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
 	case READING_KEXEC_INITRAMFS:
 		func = INITRAMFS_CHECK;
 		break;
+	case READING_POLICY:
+		func = POLICY_CHECK;
+		break;
 	default:
 		func = FILE_CHECK;
 		break;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index d02560e..39a811a 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -114,6 +114,7 @@ static struct ima_rule_entry default_measurement_rules[] = {
 	 .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID},
 	{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
+	{.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC},
 };
 
 static struct ima_rule_entry default_appraise_rules[] = {
@@ -616,6 +617,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 				entry->func = KEXEC_CHECK;
 			else if (strcmp(args[0].from, "INITRAMFS_CHECK") == 0)
 				entry->func = INITRAMFS_CHECK;
+			else if (strcmp(args[0].from, "POLICY_CHECK") == 0)
+				entry->func = POLICY_CHECK;
 			else
 				result = -EINVAL;
 			if (!result)
@@ -774,6 +777,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 		temp_ima_appraise |= IMA_APPRAISE_MODULES;
 	else if (entry->func == FIRMWARE_CHECK)
 		temp_ima_appraise |= IMA_APPRAISE_FIRMWARE;
+	else if (entry->func == POLICY_CHECK)
+		temp_ima_appraise |= IMA_APPRAISE_POLICY;
 	audit_log_format(ab, "res=%d", !result);
 	audit_log_end(ab);
 	return result;
@@ -860,7 +865,7 @@ static char *mask_tokens[] = {
 enum {
 	func_file = 0, func_mmap, func_bprm,
 	func_module, func_firmware, func_post,
-	func_kexec, func_initramfs
+	func_kexec, func_initramfs, func_policy
 };
 
 static char *func_tokens[] = {
@@ -940,6 +945,9 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
 	case INITRAMFS_CHECK:
 		seq_printf(m, pt(Opt_func), ft(func_initramfs));
 		break;
+	case POLICY_CHECK:
+		seq_printf(m, pt(Opt_func), ft(func_policy));
+		break;
 	default:
 		snprintf(tbuf, sizeof(tbuf), "%d", func);
 		seq_printf(m, pt(Opt_func), tbuf);
-- 
2.1.0


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

* [PATCH v3 22/22] ima: require signed IMA policy
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (20 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 21/22] ima: measure and appraise the IMA policy itself Mimi Zohar
@ 2016-02-03 19:06 ` Mimi Zohar
  2016-02-07 20:02   ` Petko Manolov
  2016-02-10 20:24   ` Dmitry Kasatkin
  2016-02-04 18:15 ` [PATCH v3 00/22] vfs: support for a common kernel file loader Kees Cook
  22 siblings, 2 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-03 19:06 UTC (permalink / raw)
  To: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell
  Cc: Mimi Zohar

Require the IMA policy to be signed when additional rules can be added.

v1:
- initialize the policy flag
- include IMA_APPRAISE_POLICY in the policy flag

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/ima/ima_policy.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 39a811a..ba0f6dc 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -129,6 +129,10 @@ static struct ima_rule_entry default_appraise_rules[] = {
 	{.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
+#ifdef CONFIG_IMA_WRITE_POLICY
+	{.action = APPRAISE, .func = POLICY_CHECK,
+	.flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
+#endif
 #ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT
 	{.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER},
 #else
@@ -412,9 +416,12 @@ void __init ima_init_policy(void)
 	for (i = 0; i < appraise_entries; i++) {
 		list_add_tail(&default_appraise_rules[i].list,
 			      &ima_default_rules);
+		if (default_appraise_rules[i].func == POLICY_CHECK)
+			temp_ima_appraise |= IMA_APPRAISE_POLICY;
 	}
 
 	ima_rules = &ima_default_rules;
+	ima_update_policy_flag();
 }
 
 /* Make sure we have a valid policy, at least containing some rules. */
-- 
2.1.0


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

* Re: [PATCH v3 04/22] firmware: simplify dev_*() print messages for generic helpers
  2016-02-03 19:06 ` [PATCH v3 04/22] firmware: simplify dev_*() print messages for generic helpers Mimi Zohar
@ 2016-02-04 17:26   ` Kees Cook
  0 siblings, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:26 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, linux-fsdevel, David Howells, David Woodhouse,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell,
	Luis R. Rodriguez, Andrew Morton, Greg Kroah-Hartman,
	Casey Schaufler, Ming Lei, Takashi Iwai,
	Vojtěch Pavlík, Kyle McMartin, Matthew Garrett, LKML

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> From: "Luis R. Rodriguez" <mcgrof@kernel.org>
>
> Simplify a few of the *generic* shared dev_warn() and dev_dbg()
> print messages for three reasons:
>
> 0) Historically firmware_class code was added to help
>    get device driver firmware binaries but these days
>    request_firmware*() helpers are being repurposed for
>    general *system data* needed by the kernel.
>
> 1) This will also help generalize shared code as much as possible
>    later in the future in consideration for a new extensible firmware
>    API which will enable to separate usermode helper code out as much
>    as possible.
>
> 2) Kees Cook pointed out the the prints already have the device
>    associated as dev_*() helpers are used, that should help identify
>    the user and case in which the helpers are used. That should provide
>    enough context and simplifies the messages further.
>
> v4: generalize debug/warn messages even further as suggested by
>     Kees Cook.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: David Howells <dhowells@redhat.com>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Casey Schaufler <casey@schaufler-ca.com>
> Cc: Ming Lei <ming.lei@canonical.com>
> Cc: Takashi Iwai <tiwai@suse.de>
> Cc: Vojtěch Pavlík <vojtech@suse.cz>
> Cc: Kyle McMartin <kyle@kernel.org>
> Cc: Matthew Garrett <mjg59@srcf.ucam.org>
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  drivers/base/firmware_class.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> index 8524450..3358f5d 100644
> --- a/drivers/base/firmware_class.c
> +++ b/drivers/base/firmware_class.c
> @@ -353,15 +353,15 @@ static int fw_get_filesystem_firmware(struct device *device,
>                 rc = fw_read_file_contents(file, buf);
>                 fput(file);
>                 if (rc)
> -                       dev_warn(device, "firmware, attempted to load %s, but failed with error %d\n",
> -                               path, rc);
> +                       dev_warn(device, "loading %s failed with error %d\n",
> +                                path, rc);
>                 else
>                         break;
>         }
>         __putname(path);
>
>         if (!rc) {
> -               dev_dbg(device, "firmware: direct-loading firmware %s\n",
> +               dev_dbg(device, "direct-loading %s\n",
>                         buf->fw_id);
>                 mutex_lock(&fw_lock);
>                 set_bit(FW_STATUS_DONE, &buf->status);
> @@ -1051,7 +1051,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
>         }
>
>         if (fw_get_builtin_firmware(firmware, name)) {
> -               dev_dbg(device, "firmware: using built-in firmware %s\n", name);
> +               dev_dbg(device, "using built-in %s\n", name);
>                 return 0; /* assigned */
>         }
>
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 05/22] firmware: move completing fw into a helper
  2016-02-03 19:06 ` [PATCH v3 05/22] firmware: move completing fw into a helper Mimi Zohar
@ 2016-02-04 17:27   ` Kees Cook
  0 siblings, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:27 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell,
	Luis R. Rodriguez

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> From: "Luis R. Rodriguez" <mcgrof@kernel.org>
>
> This will be re-used later through a new extensible interface.
>
> Reviewed-by: Josh Boyer <jwboyer@fedoraproject.org>
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  drivers/base/firmware_class.c | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> index 3358f5d..fb64814 100644
> --- a/drivers/base/firmware_class.c
> +++ b/drivers/base/firmware_class.c
> @@ -322,6 +322,15 @@ fail:
>         return rc;
>  }
>
> +static void fw_finish_direct_load(struct device *device,
> +                                 struct firmware_buf *buf)
> +{
> +       mutex_lock(&fw_lock);
> +       set_bit(FW_STATUS_DONE, &buf->status);
> +       complete_all(&buf->completion);
> +       mutex_unlock(&fw_lock);
> +}
> +
>  static int fw_get_filesystem_firmware(struct device *device,
>                                        struct firmware_buf *buf)
>  {
> @@ -363,10 +372,7 @@ static int fw_get_filesystem_firmware(struct device *device,
>         if (!rc) {
>                 dev_dbg(device, "direct-loading %s\n",
>                         buf->fw_id);
> -               mutex_lock(&fw_lock);
> -               set_bit(FW_STATUS_DONE, &buf->status);
> -               complete_all(&buf->completion);
> -               mutex_unlock(&fw_lock);
> +               fw_finish_direct_load(device, buf);
>         }
>
>         return rc;
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 06/22] firmware: fold successful fw read early
  2016-02-03 19:06 ` [PATCH v3 06/22] firmware: fold successful fw read early Mimi Zohar
@ 2016-02-04 17:36   ` Kees Cook
  2016-02-04 20:26     ` Luis R. Rodriguez
  0 siblings, 1 reply; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:36 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, linux-fsdevel, David Howells, David Woodhouse,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell,
	Luis R. Rodriguez

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> From: David Howells <dhowells@redhat.com>
>
> We'll be folding in some more checks on fw_read_file_contents(),
> this will make the success case easier to follow.
>
> Reviewed-by: Josh Boyer <jwboyer@fedoraproject.org>
> Signed-off-by: David Howells <dhowells@redhat.com>
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> ---
>  drivers/base/firmware_class.c | 16 +++++++---------
>  1 file changed, 7 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> index fb64814..c658cec 100644
> --- a/drivers/base/firmware_class.c
> +++ b/drivers/base/firmware_class.c
> @@ -361,20 +361,18 @@ static int fw_get_filesystem_firmware(struct device *device,
>                         continue;
>                 rc = fw_read_file_contents(file, buf);
>                 fput(file);
> -               if (rc)
> +               if (rc == 0) {
> +                       dev_dbg(device, "direct-loading %s\n",
> +                               buf->fw_id);
> +                       fw_finish_direct_load(device, buf);
> +                       goto out;
> +               } else
>                         dev_warn(device, "loading %s failed with error %d\n",
>                                  path, rc);
> -               else
> -                       break;
>         }
> +out:
>         __putname(path);
>
> -       if (!rc) {
> -               dev_dbg(device, "direct-loading %s\n",
> -                       buf->fw_id);
> -               fw_finish_direct_load(device, buf);
> -       }
> -
>         return rc;
>  }

Looking at this code, why does this use "break":

                len = snprintf(path, PATH_MAX, "%s/%s",
                               fw_path[i], buf->fw_id);
                if (len >= PATH_MAX) {
                        rc = -ENAMETOOLONG;
                        break;
                }

Shouldn't that emit a warning, set rc, and continue?


Regardless, I think this is more readable. Adding an "out" target at
the end of a for loop seems weird, given "break" existing. :)

                rc = fw_read_file_contents(file, buf);
                fput(file);
-               if (rc)
+               if (rc) {
                        dev_warn(device, "loading %s failed with error %d\n",
                                 path, rc);
+                       continue;
+               }
+               dev_dbg(device, "direct-loading %s\n", buf->fw_id);
+               fw_finish_direct_load(device, buf);
-               else
-                       break;
+               break;
        }
        __putname(path);
-
-       if (!rc) {
-               dev_dbg(device, "direct-loading %s\n",
-                       buf->fw_id);
-               fw_finish_direct_load(device, buf);
-       }
-
        return rc;
 }



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 07/22] vfs: define a generic function to read a file from the kernel
  2016-02-03 19:06 ` [PATCH v3 07/22] vfs: define a generic function to read a file from the kernel Mimi Zohar
@ 2016-02-04 17:41   ` Kees Cook
  0 siblings, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:41 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> For a while it was looked down upon to directly read files from Linux.
> These days there exists a few mechanisms in the kernel that do just
> this though to load a file into a local buffer.  There are minor but
> important checks differences on each.  This patch set is the first
> attempt at resolving some of these differences.
>
> This patch introduces a common function for reading files from the kernel
> with the corresponding security post-read hook and function.
>
> Changelog v3:
> - additional bounds checking - Luis
> v2:
> - To simplify patch review, re-ordered patches
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> Reviewed-by: Luis R. Rodriguez <mcgrof@suse.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  fs/exec.c                 | 53 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/fs.h        |  1 +
>  include/linux/lsm_hooks.h |  9 ++++++++
>  include/linux/security.h  |  7 +++++++
>  security/security.c       |  7 +++++++
>  5 files changed, 77 insertions(+)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index b06623a..742de7a 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -56,6 +56,7 @@
>  #include <linux/pipe_fs_i.h>
>  #include <linux/oom.h>
>  #include <linux/compat.h>
> +#include <linux/vmalloc.h>
>
>  #include <asm/uaccess.h>
>  #include <asm/mmu_context.h>
> @@ -831,6 +832,58 @@ int kernel_read(struct file *file, loff_t offset,
>
>  EXPORT_SYMBOL(kernel_read);
>
> +int kernel_read_file(struct file *file, void **buf, loff_t *size,
> +                    loff_t max_size)
> +{
> +       loff_t i_size, pos;
> +       ssize_t bytes = 0;
> +       int ret;
> +
> +       if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
> +               return -EINVAL;
> +
> +       i_size = i_size_read(file_inode(file));
> +       if (max_size > 0 && i_size > max_size)
> +               return -EFBIG;
> +       if (i_size <= 0)
> +               return -EINVAL;
> +
> +       *buf = vmalloc(i_size);
> +       if (!*buf)
> +               return -ENOMEM;
> +
> +       pos = 0;
> +       while (pos < i_size) {
> +               bytes = kernel_read(file, pos, (char *)(*buf) + pos,
> +                                   i_size - pos);
> +               if (bytes < 0) {
> +                       ret = bytes;
> +                       goto out;
> +               }
> +
> +               if (bytes == 0)
> +                       break;
> +               pos += bytes;
> +       }
> +
> +       if (pos != i_size) {
> +               ret = -EIO;
> +               goto out;
> +       }
> +
> +       ret = security_kernel_post_read_file(file, *buf, i_size);
> +       if (!ret)
> +               *size = pos;
> +
> +out:
> +       if (ret < 0) {
> +               vfree(*buf);
> +               *buf = NULL;
> +       }
> +       return ret;
> +}
> +EXPORT_SYMBOL_GPL(kernel_read_file);
> +
>  ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
>  {
>         ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 3aa5142..93ca379 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2527,6 +2527,7 @@ static inline void i_readcount_inc(struct inode *inode)
>  extern int do_pipe_flags(int *, int);
>
>  extern int kernel_read(struct file *, loff_t, char *, unsigned long);
> +extern int kernel_read_file(struct file *, void **, loff_t *, loff_t);
>  extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
>  extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
>  extern struct file * open_exec(const char *);
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 71969de..f82631c 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -561,6 +561,13 @@
>   *     the kernel module to load. If the module is being loaded from a blob,
>   *     this argument will be NULL.
>   *     Return 0 if permission is granted.
> + * @kernel_post_read_file:
> + *     Read a file specified by userspace.
> + *     @file contains the file structure pointing to the file being read
> + *     by the kernel.
> + *     @buf pointer to buffer containing the file contents.
> + *     @size length of the file contents.
> + *     Return 0 if permission is granted.
>   * @task_fix_setuid:
>   *     Update the module's state after setting one or more of the user
>   *     identity attributes of the current process.  The @flags parameter
> @@ -1457,6 +1464,7 @@ union security_list_options {
>         int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size);
>         int (*kernel_module_request)(char *kmod_name);
>         int (*kernel_module_from_file)(struct file *file);
> +       int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size);
>         int (*task_fix_setuid)(struct cred *new, const struct cred *old,
>                                 int flags);
>         int (*task_setpgid)(struct task_struct *p, pid_t pgid);
> @@ -1716,6 +1724,7 @@ struct security_hook_heads {
>         struct list_head kernel_act_as;
>         struct list_head kernel_create_files_as;
>         struct list_head kernel_fw_from_file;
> +       struct list_head kernel_post_read_file;
>         struct list_head kernel_module_request;
>         struct list_head kernel_module_from_file;
>         struct list_head task_fix_setuid;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 4824a4c..f30f564 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -301,6 +301,7 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode);
>  int security_kernel_fw_from_file(struct file *file, char *buf, size_t size);
>  int security_kernel_module_request(char *kmod_name);
>  int security_kernel_module_from_file(struct file *file);
> +int security_kernel_post_read_file(struct file *file, char *buf, loff_t size);
>  int security_task_fix_setuid(struct cred *new, const struct cred *old,
>                              int flags);
>  int security_task_setpgid(struct task_struct *p, pid_t pgid);
> @@ -866,6 +867,12 @@ static inline int security_kernel_module_from_file(struct file *file)
>         return 0;
>  }
>
> +static inline int security_kernel_post_read_file(struct file *file,
> +                                                char *buf, loff_t size)
> +{
> +       return 0;
> +}
> +
>  static inline int security_task_fix_setuid(struct cred *new,
>                                            const struct cred *old,
>                                            int flags)
> diff --git a/security/security.c b/security/security.c
> index e8ffd92..ae50730 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -910,6 +910,11 @@ int security_kernel_module_from_file(struct file *file)
>         return ima_module_check(file);
>  }
>
> +int security_kernel_post_read_file(struct file *file, char *buf, loff_t size)
> +{
> +       return call_int_hook(kernel_post_read_file, 0, file, buf, size);
> +}
> +
>  int security_task_fix_setuid(struct cred *new, const struct cred *old,
>                              int flags)
>  {
> @@ -1697,6 +1702,8 @@ struct security_hook_heads security_hook_heads = {
>                 LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
>         .kernel_module_from_file =
>                 LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file),
> +       .kernel_post_read_file =
> +               LIST_HEAD_INIT(security_hook_heads.kernel_post_read_file),
>         .task_fix_setuid =
>                 LIST_HEAD_INIT(security_hook_heads.task_fix_setuid),
>         .task_setpgid = LIST_HEAD_INIT(security_hook_heads.task_setpgid),
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 08/22] vfs: define kernel_read_file_id enumeration
  2016-02-03 19:06 ` [PATCH v3 08/22] vfs: define kernel_read_file_id enumeration Mimi Zohar
@ 2016-02-04 17:41   ` Kees Cook
  2016-02-04 19:45   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:41 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, linux-fsdevel, David Howells, David Woodhouse,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> To differentiate between the kernel_read_file() callers, this patch
> defines a new enumeration named kernel_read_file_id and includes the
> caller identifier as an argument.
>
> Subsequent patches define READING_KEXEC_IMAGE, READING_KEXEC_INITRAMFS,
> READING_FIRMWARE, READING_MODULE, and READING_POLICY.
>
> Changelog v3:
> - Replace the IMA specific enumeration with a generic one.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  fs/exec.c                 | 4 ++--
>  include/linux/fs.h        | 7 ++++++-
>  include/linux/lsm_hooks.h | 4 +++-
>  include/linux/security.h  | 7 +++++--
>  security/security.c       | 5 +++--
>  5 files changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index 742de7a..cd2b5b2 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -833,7 +833,7 @@ int kernel_read(struct file *file, loff_t offset,
>  EXPORT_SYMBOL(kernel_read);
>
>  int kernel_read_file(struct file *file, void **buf, loff_t *size,
> -                    loff_t max_size)
> +                    loff_t max_size, enum kernel_read_file_id id)
>  {
>         loff_t i_size, pos;
>         ssize_t bytes = 0;
> @@ -871,7 +871,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
>                 goto out;
>         }
>
> -       ret = security_kernel_post_read_file(file, *buf, i_size);
> +       ret = security_kernel_post_read_file(file, *buf, i_size, id);
>         if (!ret)
>                 *size = pos;
>
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 93ca379..1458ca5 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2526,8 +2526,13 @@ static inline void i_readcount_inc(struct inode *inode)
>  #endif
>  extern int do_pipe_flags(int *, int);
>
> +enum kernel_read_file_id {
> +       READING_MAX_ID
> +};
> +
>  extern int kernel_read(struct file *, loff_t, char *, unsigned long);
> -extern int kernel_read_file(struct file *, void **, loff_t *, loff_t);
> +extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
> +                           enum kernel_read_file_id);
>  extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
>  extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
>  extern struct file * open_exec(const char *);
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index f82631c..2337f33 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -567,6 +567,7 @@
>   *     by the kernel.
>   *     @buf pointer to buffer containing the file contents.
>   *     @size length of the file contents.
> + *     @id kernel read file identifier
>   *     Return 0 if permission is granted.
>   * @task_fix_setuid:
>   *     Update the module's state after setting one or more of the user
> @@ -1464,7 +1465,8 @@ union security_list_options {
>         int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size);
>         int (*kernel_module_request)(char *kmod_name);
>         int (*kernel_module_from_file)(struct file *file);
> -       int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size);
> +       int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size,
> +                                    enum kernel_read_file_id id);
>         int (*task_fix_setuid)(struct cred *new, const struct cred *old,
>                                 int flags);
>         int (*task_setpgid)(struct task_struct *p, pid_t pgid);
> diff --git a/include/linux/security.h b/include/linux/security.h
> index f30f564..b68ce94 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -28,6 +28,7 @@
>  #include <linux/err.h>
>  #include <linux/string.h>
>  #include <linux/mm.h>
> +#include <linux/fs.h>
>
>  struct linux_binprm;
>  struct cred;
> @@ -301,7 +302,8 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode);
>  int security_kernel_fw_from_file(struct file *file, char *buf, size_t size);
>  int security_kernel_module_request(char *kmod_name);
>  int security_kernel_module_from_file(struct file *file);
> -int security_kernel_post_read_file(struct file *file, char *buf, loff_t size);
> +int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
> +                                  enum kernel_read_file_id id);
>  int security_task_fix_setuid(struct cred *new, const struct cred *old,
>                              int flags);
>  int security_task_setpgid(struct task_struct *p, pid_t pgid);
> @@ -868,7 +870,8 @@ static inline int security_kernel_module_from_file(struct file *file)
>  }
>
>  static inline int security_kernel_post_read_file(struct file *file,
> -                                                char *buf, loff_t size)
> +                                                char *buf, loff_t size,
> +                                                enum kernel_read_file_id id)
>  {
>         return 0;
>  }
> diff --git a/security/security.c b/security/security.c
> index ae50730..796a261 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -910,9 +910,10 @@ int security_kernel_module_from_file(struct file *file)
>         return ima_module_check(file);
>  }
>
> -int security_kernel_post_read_file(struct file *file, char *buf, loff_t size)
> +int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
> +                                  enum kernel_read_file_id id)
>  {
> -       return call_int_hook(kernel_post_read_file, 0, file, buf, size);
> +       return call_int_hook(kernel_post_read_file, 0, file, buf, size, id);
>  }
>
>  int security_task_fix_setuid(struct cred *new, const struct cred *old,
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 12/22] vfs: define kernel_read_file_from_path
  2016-02-03 19:06 ` [PATCH v3 12/22] vfs: define kernel_read_file_from_path Mimi Zohar
@ 2016-02-04 17:46   ` Kees Cook
  2016-02-04 19:47   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:46 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> This patch defines kernel_read_file_from_path(), a wrapper for the VFS
> common kernel_read_file().
>
> Changelog:
> - Separated from the IMA patch
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  fs/exec.c          | 22 ++++++++++++++++++++++
>  include/linux/fs.h |  2 ++
>  2 files changed, 24 insertions(+)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index cd2b5b2..5629958 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -884,6 +884,28 @@ out:
>  }
>  EXPORT_SYMBOL_GPL(kernel_read_file);
>
> +int kernel_read_file_from_path(char *path, void **buf, loff_t *size,
> +                              loff_t max_size, enum kernel_read_file_id id)
> +{
> +       struct file *file;
> +       int ret;
> +
> +       if (!path || !*path)
> +               return -EINVAL;
> +
> +       file = filp_open(path, O_RDONLY, 0);
> +       if (IS_ERR(file)) {
> +               ret = PTR_ERR(file);
> +               pr_err("Unable to open file: %s (%d)", path, ret);
> +               return ret;
> +       }
> +
> +       ret = kernel_read_file(file, buf, size, max_size, id);
> +       fput(file);
> +       return ret;
> +}
> +EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
> +
>  ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
>  {
>         ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 1458ca5..962c491 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2533,6 +2533,8 @@ enum kernel_read_file_id {
>  extern int kernel_read(struct file *, loff_t, char *, unsigned long);
>  extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
>                             enum kernel_read_file_id);
> +extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t,
> +                                     enum kernel_read_file_id);
>  extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
>  extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
>  extern struct file * open_exec(const char *);
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 13/22] firmware: replace call to fw_read_file_contents() with kernel version
  2016-02-03 19:06 ` [PATCH v3 13/22] firmware: replace call to fw_read_file_contents() with kernel version Mimi Zohar
@ 2016-02-04 17:56   ` Kees Cook
  2016-02-04 19:51   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:56 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Replace the fw_read_file_contents with kernel_file_read_from_path().
>
> Although none of the upstreamed LSMs define a kernel_fw_from_file hook,
> IMA is called by the security function to prevent unsigned firmware from
> being loaded and to measure/appraise signed firmware, based on policy.
>
> Instead of reading the firmware twice, once for measuring/appraising the
> firmware and again for reading the firmware contents into memory, the
> kernel_post_read_file() security hook calculates the file hash based on
> the in memory file buffer.  The firmware is read once.
>
> This patch removes the LSM kernel_fw_from_file() hook and security call.
>
> Changelog v3:
> - remove kernel_fw_from_file hook
> - use kernel_file_read_from_path() - requested by Luis
> v2:
> - reordered and squashed firmware patches
> - fix MAX firmware size (Kees Cook)
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  drivers/base/firmware_class.c     | 48 +++++++--------------------------------
>  include/linux/fs.h                |  1 +
>  include/linux/ima.h               |  6 -----
>  include/linux/lsm_hooks.h         | 11 ---------
>  include/linux/security.h          |  7 ------
>  security/integrity/ima/ima_main.c | 21 ++++++++---------
>  security/security.c               | 13 -----------
>  7 files changed, 19 insertions(+), 88 deletions(-)
>
> diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> index c658cec..e06a3d8 100644
> --- a/drivers/base/firmware_class.c
> +++ b/drivers/base/firmware_class.c
> @@ -291,37 +291,6 @@ static const char * const fw_path[] = {
>  module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
>  MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
>
> -static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
> -{
> -       int size;
> -       char *buf;
> -       int rc;
> -
> -       if (!S_ISREG(file_inode(file)->i_mode))
> -               return -EINVAL;
> -       size = i_size_read(file_inode(file));
> -       if (size <= 0)
> -               return -EINVAL;
> -       buf = vmalloc(size);
> -       if (!buf)
> -               return -ENOMEM;
> -       rc = kernel_read(file, 0, buf, size);
> -       if (rc != size) {
> -               if (rc > 0)
> -                       rc = -EIO;
> -               goto fail;
> -       }
> -       rc = security_kernel_fw_from_file(file, buf, size);
> -       if (rc)
> -               goto fail;
> -       fw_buf->data = buf;
> -       fw_buf->size = size;
> -       return 0;
> -fail:
> -       vfree(buf);
> -       return rc;
> -}
> -
>  static void fw_finish_direct_load(struct device *device,
>                                   struct firmware_buf *buf)
>  {
> @@ -334,6 +303,7 @@ static void fw_finish_direct_load(struct device *device,
>  static int fw_get_filesystem_firmware(struct device *device,
>                                        struct firmware_buf *buf)
>  {
> +       loff_t size;
>         int i, len;
>         int rc = -ENOENT;
>         char *path;
> @@ -343,8 +313,6 @@ static int fw_get_filesystem_firmware(struct device *device,
>                 return -ENOMEM;
>
>         for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
> -               struct file *file;
> -
>                 /* skip the unset customized path */
>                 if (!fw_path[i][0])
>                         continue;
> @@ -356,12 +324,11 @@ static int fw_get_filesystem_firmware(struct device *device,
>                         break;
>                 }
>
> -               file = filp_open(path, O_RDONLY, 0);
> -               if (IS_ERR(file))
> -                       continue;
> -               rc = fw_read_file_contents(file, buf);
> -               fput(file);
> +               buf->size = 0;
> +               rc = kernel_read_file_from_path(path, &buf->data, &size,
> +                                               INT_MAX, READING_FIRMWARE);
>                 if (rc == 0) {
> +                       buf->size = (size_t) size;
>                         dev_dbg(device, "direct-loading %s\n",
>                                 buf->fw_id);
>                         fw_finish_direct_load(device, buf);
> @@ -689,8 +656,9 @@ static ssize_t firmware_loading_store(struct device *dev,
>                                 dev_err(dev, "%s: map pages failed\n",
>                                         __func__);
>                         else
> -                               rc = security_kernel_fw_from_file(NULL,
> -                                               fw_buf->data, fw_buf->size);
> +                               rc = security_kernel_post_read_file(NULL,
> +                                               fw_buf->data, fw_buf->size,
> +                                               READING_FIRMWARE);
>
>                         /*
>                          * Same logic as fw_load_abort, only the DONE bit
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 962c491..2a9670a 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2527,6 +2527,7 @@ static inline void i_readcount_inc(struct inode *inode)
>  extern int do_pipe_flags(int *, int);
>
>  enum kernel_read_file_id {
> +       READING_FIRMWARE = 1,
>         READING_MAX_ID
>  };
>
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index d29a6a2..7aea486 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -19,7 +19,6 @@ extern int ima_file_check(struct file *file, int mask, int opened);
>  extern void ima_file_free(struct file *file);
>  extern int ima_file_mmap(struct file *file, unsigned long prot);
>  extern int ima_module_check(struct file *file);
> -extern int ima_fw_from_file(struct file *file, char *buf, size_t size);
>  extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
>                               enum kernel_read_file_id id);
>
> @@ -49,11 +48,6 @@ static inline int ima_module_check(struct file *file)
>         return 0;
>  }
>
> -static inline int ima_fw_from_file(struct file *file, char *buf, size_t size)
> -{
> -       return 0;
> -}
> -
>  static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
>                                      enum kernel_read_file_id id)
>  {
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 2337f33..7d04a12 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -541,15 +541,6 @@
>   *     @inode points to the inode to use as a reference.
>   *     The current task must be the one that nominated @inode.
>   *     Return 0 if successful.
> - * @kernel_fw_from_file:
> - *     Load firmware from userspace (not called for built-in firmware).
> - *     @file contains the file structure pointing to the file containing
> - *     the firmware to load. This argument will be NULL if the firmware
> - *     was loaded via the uevent-triggered blob-based interface exposed
> - *     by CONFIG_FW_LOADER_USER_HELPER.
> - *     @buf pointer to buffer containing firmware contents.
> - *     @size length of the firmware contents.
> - *     Return 0 if permission is granted.
>   * @kernel_module_request:
>   *     Ability to trigger the kernel to automatically upcall to userspace for
>   *     userspace to load a kernel module with the given name.
> @@ -1462,7 +1453,6 @@ union security_list_options {
>         void (*cred_transfer)(struct cred *new, const struct cred *old);
>         int (*kernel_act_as)(struct cred *new, u32 secid);
>         int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
> -       int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size);
>         int (*kernel_module_request)(char *kmod_name);
>         int (*kernel_module_from_file)(struct file *file);
>         int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size,
> @@ -1725,7 +1715,6 @@ struct security_hook_heads {
>         struct list_head cred_transfer;
>         struct list_head kernel_act_as;
>         struct list_head kernel_create_files_as;
> -       struct list_head kernel_fw_from_file;
>         struct list_head kernel_post_read_file;
>         struct list_head kernel_module_request;
>         struct list_head kernel_module_from_file;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index d920718..cee1349 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -300,7 +300,6 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
>  void security_transfer_creds(struct cred *new, const struct cred *old);
>  int security_kernel_act_as(struct cred *new, u32 secid);
>  int security_kernel_create_files_as(struct cred *new, struct inode *inode);
> -int security_kernel_fw_from_file(struct file *file, char *buf, size_t size);
>  int security_kernel_module_request(char *kmod_name);
>  int security_kernel_module_from_file(struct file *file);
>  int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
> @@ -854,12 +853,6 @@ static inline int security_kernel_create_files_as(struct cred *cred,
>         return 0;
>  }
>
> -static inline int security_kernel_fw_from_file(struct file *file,
> -                                              char *buf, size_t size)
> -{
> -       return 0;
> -}
> -
>  static inline int security_kernel_module_request(char *kmod_name)
>  {
>         return 0;
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index bead94b..4a5db31 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -337,17 +337,6 @@ int ima_module_check(struct file *file)
>         return process_measurement(file, NULL, 0, MAY_EXEC, MODULE_CHECK, 0);
>  }
>
> -int ima_fw_from_file(struct file *file, char *buf, size_t size)
> -{
> -       if (!file) {
> -               if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
> -                   (ima_appraise & IMA_APPRAISE_ENFORCE))
> -                       return -EACCES; /* INTEGRITY_UNKNOWN */
> -               return 0;
> -       }
> -       return process_measurement(file, NULL, 0, MAY_EXEC, FIRMWARE_CHECK, 0);
> -}
> -
>  /**
>   * ima_post_read_file - in memory collect/appraise/audit measurement
>   * @file: pointer to the file to be measured/appraised/audit
> @@ -366,12 +355,22 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>  {
>         enum ima_hooks func = FILE_CHECK;
>
> +       if (!file && read_id == READING_FIRMWARE) {
> +               if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
> +                   (ima_appraise & IMA_APPRAISE_ENFORCE))
> +                       return -EACCES; /* INTEGRITY_UNKNOWN */
> +               return 0;
> +       }
> +
>         if (!file && (!buf || size == 0)) { /* should never happen */
>                 if (ima_appraise & IMA_APPRAISE_ENFORCE)
>                         return -EACCES;
>                 return 0;
>         }
>
> +       if (read_id == READING_FIRMWARE)
> +               func = FIRMWARE_CHECK;
> +
>         return process_measurement(file, buf, size, MAY_READ, func, 0);
>  }
>
> diff --git a/security/security.c b/security/security.c
> index ad87e8d..81a4c3a 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -884,17 +884,6 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
>         return call_int_hook(kernel_create_files_as, 0, new, inode);
>  }
>
> -int security_kernel_fw_from_file(struct file *file, char *buf, size_t size)
> -{
> -       int ret;
> -
> -       ret = call_int_hook(kernel_fw_from_file, 0, file, buf, size);
> -       if (ret)
> -               return ret;
> -       return ima_fw_from_file(file, buf, size);
> -}
> -EXPORT_SYMBOL_GPL(security_kernel_fw_from_file);
> -
>  int security_kernel_module_request(char *kmod_name)
>  {
>         return call_int_hook(kernel_module_request, 0, kmod_name);
> @@ -1702,8 +1691,6 @@ struct security_hook_heads security_hook_heads = {
>                 LIST_HEAD_INIT(security_hook_heads.kernel_act_as),
>         .kernel_create_files_as =
>                 LIST_HEAD_INIT(security_hook_heads.kernel_create_files_as),
> -       .kernel_fw_from_file =
> -               LIST_HEAD_INIT(security_hook_heads.kernel_fw_from_file),
>         .kernel_module_request =
>                 LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
>         .kernel_module_from_file =
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 14/22] security: define kernel_read_file hook
  2016-02-03 19:06 ` [PATCH v3 14/22] security: define kernel_read_file hook Mimi Zohar
@ 2016-02-04 17:57   ` Kees Cook
  2016-02-04 19:54   ` Luis R. Rodriguez
  2016-02-11 16:54   ` Casey Schaufler
  2 siblings, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:57 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> The kernel_read_file security hook is called prior to reading the file
> into memory.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  fs/exec.c                         |  4 ++++
>  include/linux/ima.h               |  6 ++++++
>  include/linux/lsm_hooks.h         |  8 ++++++++
>  include/linux/security.h          |  7 +++++++
>  security/integrity/ima/ima_main.c | 16 ++++++++++++++++
>  security/security.c               | 12 ++++++++++++
>  6 files changed, 53 insertions(+)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index 5629958..1d39c4e 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -842,6 +842,10 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
>         if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
>                 return -EINVAL;
>
> +       ret = security_kernel_read_file(file, id);
> +       if (ret)
> +               return ret;
> +
>         i_size = i_size_read(file_inode(file));
>         if (max_size > 0 && i_size > max_size)
>                 return -EFBIG;
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 7aea486..6adcaea 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -19,6 +19,7 @@ extern int ima_file_check(struct file *file, int mask, int opened);
>  extern void ima_file_free(struct file *file);
>  extern int ima_file_mmap(struct file *file, unsigned long prot);
>  extern int ima_module_check(struct file *file);
> +extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
>  extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
>                               enum kernel_read_file_id id);
>
> @@ -48,6 +49,11 @@ static inline int ima_module_check(struct file *file)
>         return 0;
>  }
>
> +static inline int ima_read_file(struct file *file, enum kernel_read_file_id id)
> +{
> +       return 0;
> +}
> +
>  static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
>                                      enum kernel_read_file_id id)
>  {
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7d04a12..d32b7bd 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -552,6 +552,12 @@
>   *     the kernel module to load. If the module is being loaded from a blob,
>   *     this argument will be NULL.
>   *     Return 0 if permission is granted.
> + * @kernel_read_file:
> + *     Read a file specified by userspace.
> + *     @file contains the file structure pointing to the file being read
> + *     by the kernel.
> + *     @id kernel read file identifier
> + *     Return 0 if permission is granted.
>   * @kernel_post_read_file:
>   *     Read a file specified by userspace.
>   *     @file contains the file structure pointing to the file being read
> @@ -1455,6 +1461,7 @@ union security_list_options {
>         int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
>         int (*kernel_module_request)(char *kmod_name);
>         int (*kernel_module_from_file)(struct file *file);
> +       int (*kernel_read_file)(struct file *file, enum kernel_read_file_id id);
>         int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size,
>                                      enum kernel_read_file_id id);
>         int (*task_fix_setuid)(struct cred *new, const struct cred *old,
> @@ -1715,6 +1722,7 @@ struct security_hook_heads {
>         struct list_head cred_transfer;
>         struct list_head kernel_act_as;
>         struct list_head kernel_create_files_as;
> +       struct list_head kernel_read_file;
>         struct list_head kernel_post_read_file;
>         struct list_head kernel_module_request;
>         struct list_head kernel_module_from_file;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index cee1349..071fb74 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -302,6 +302,7 @@ int security_kernel_act_as(struct cred *new, u32 secid);
>  int security_kernel_create_files_as(struct cred *new, struct inode *inode);
>  int security_kernel_module_request(char *kmod_name);
>  int security_kernel_module_from_file(struct file *file);
> +int security_kernel_read_file(struct file *file, enum kernel_read_file_id id);
>  int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
>                                    enum kernel_read_file_id id);
>  int security_task_fix_setuid(struct cred *new, const struct cred *old,
> @@ -863,6 +864,12 @@ static inline int security_kernel_module_from_file(struct file *file)
>         return 0;
>  }
>
> +static inline int security_kernel_read_file(struct file *file,
> +                                           enum kernel_read_file_id id)
> +{
> +       return 0;
> +}
> +
>  static inline int security_kernel_post_read_file(struct file *file,
>                                                  char *buf, loff_t size,
>                                                  enum kernel_read_file_id id)
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 4a5db31..6f79bdf 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -338,6 +338,22 @@ int ima_module_check(struct file *file)
>  }
>
>  /**
> + * ima_read_file - pre-measure/appraise hook decision based on policy
> + * @file: pointer to the file to be measured/appraised/audit
> + * @read_id: caller identifier
> + *
> + * Permit reading a file based on policy. The policy rules are written
> + * in terms of the policy identifier.  Appraising the integrity of
> + * a file requires a file descriptor.
> + *
> + * For permission return 0, otherwise return -EACCES.
> + */
> +int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
> +{
> +       return 0;
> +}
> +
> +/**
>   * ima_post_read_file - in memory collect/appraise/audit measurement
>   * @file: pointer to the file to be measured/appraised/audit
>   * @buf: pointer to in memory file contents
> diff --git a/security/security.c b/security/security.c
> index 81a4c3a..1728fe2 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -899,6 +899,16 @@ int security_kernel_module_from_file(struct file *file)
>         return ima_module_check(file);
>  }
>
> +int security_kernel_read_file(struct file *file, enum kernel_read_file_id id)
> +{
> +       int ret;
> +
> +       ret = call_int_hook(kernel_read_file, 0, file, id);
> +       if (ret)
> +               return ret;
> +       return ima_read_file(file, id);
> +}
> +
>  int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
>                                    enum kernel_read_file_id id)
>  {
> @@ -1695,6 +1705,8 @@ struct security_hook_heads security_hook_heads = {
>                 LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
>         .kernel_module_from_file =
>                 LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file),
> +       .kernel_read_file =
> +               LIST_HEAD_INIT(security_hook_heads.kernel_read_file),
>         .kernel_post_read_file =
>                 LIST_HEAD_INIT(security_hook_heads.kernel_post_read_file),
>         .task_fix_setuid =
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 15/22] vfs: define kernel_copy_file_from_fd()
  2016-02-03 19:06 ` [PATCH v3 15/22] vfs: define kernel_copy_file_from_fd() Mimi Zohar
@ 2016-02-04 17:58   ` Kees Cook
  2016-02-04 19:55   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 17:58 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> This patch defines kernel_read_file_from_fd(), a wrapper for the VFS
> common kernel_read_file().
>
> Changelog:
> - Separated from the kernel modules patch
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  fs/exec.c          | 16 ++++++++++++++++
>  include/linux/fs.h |  2 ++
>  2 files changed, 18 insertions(+)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index 1d39c4e..f3a0ce2 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -910,6 +910,22 @@ int kernel_read_file_from_path(char *path, void **buf, loff_t *size,
>  }
>  EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
>
> +int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
> +                            enum kernel_read_file_id id)
> +{
> +       struct fd f = fdget(fd);
> +       int ret = -EBADF;
> +
> +       if (!f.file)
> +               goto out;
> +
> +       ret = kernel_read_file(f.file, buf, size, max_size, id);
> +out:
> +       fdput(f);
> +       return ret;
> +}
> +EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);
> +
>  ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
>  {
>         ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 2a9670a..5ba806b 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2536,6 +2536,8 @@ extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
>                             enum kernel_read_file_id);
>  extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t,
>                                       enum kernel_read_file_id);
> +extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t,
> +                                   enum kernel_read_file_id);
>  extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
>  extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
>  extern struct file * open_exec(const char *);
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version
  2016-02-03 19:06 ` [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version Mimi Zohar
@ 2016-02-04 18:04   ` Kees Cook
  2016-02-04 19:56   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 18:04 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Replace copy_module_from_fd() with kernel_read_file_from_fd().
>
> Although none of the upstreamed LSMs define a kernel_module_from_file
> hook, IMA is called, based on policy, to prevent unsigned kernel modules
> from being loaded by the original kernel module syscall and to
> measure/appraise signed kernel modules.
>
> The security function security_kernel_module_from_file() was called prior
> to reading a kernel module.  Preventing unsigned kernel modules from being
> loaded by the original kernel module syscall remains on the pre-read
> kernel_read_file() security hook.  Instead of reading the kernel module
> twice, once for measuring/appraising and again for loading the kernel
> module, the signature validation is moved to the kernel_post_read_file()
> security hook.
>
> This patch removes the security_kernel_module_from_file() hook and security
> call.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

I'm really liking this consolidation. :)

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  include/linux/fs.h                |  1 +
>  include/linux/ima.h               |  6 ----
>  include/linux/lsm_hooks.h         |  7 ----
>  include/linux/security.h          |  5 ---
>  kernel/module.c                   | 68 +++++----------------------------------
>  security/integrity/ima/ima_main.c | 35 ++++++++------------
>  security/security.c               | 12 -------
>  7 files changed, 22 insertions(+), 112 deletions(-)
>
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 5ba806b..9e1f1e3 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2528,6 +2528,7 @@ extern int do_pipe_flags(int *, int);
>
>  enum kernel_read_file_id {
>         READING_FIRMWARE = 1,
> +       READING_MODULE,
>         READING_MAX_ID
>  };
>
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 6adcaea..e6516cb 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -18,7 +18,6 @@ extern int ima_bprm_check(struct linux_binprm *bprm);
>  extern int ima_file_check(struct file *file, int mask, int opened);
>  extern void ima_file_free(struct file *file);
>  extern int ima_file_mmap(struct file *file, unsigned long prot);
> -extern int ima_module_check(struct file *file);
>  extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
>  extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
>                               enum kernel_read_file_id id);
> @@ -44,11 +43,6 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
>         return 0;
>  }
>
> -static inline int ima_module_check(struct file *file)
> -{
> -       return 0;
> -}
> -
>  static inline int ima_read_file(struct file *file, enum kernel_read_file_id id)
>  {
>         return 0;
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index d32b7bd..cdee11c 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -546,12 +546,6 @@
>   *     userspace to load a kernel module with the given name.
>   *     @kmod_name name of the module requested by the kernel
>   *     Return 0 if successful.
> - * @kernel_module_from_file:
> - *     Load a kernel module from userspace.
> - *     @file contains the file structure pointing to the file containing
> - *     the kernel module to load. If the module is being loaded from a blob,
> - *     this argument will be NULL.
> - *     Return 0 if permission is granted.
>   * @kernel_read_file:
>   *     Read a file specified by userspace.
>   *     @file contains the file structure pointing to the file being read
> @@ -1725,7 +1719,6 @@ struct security_hook_heads {
>         struct list_head kernel_read_file;
>         struct list_head kernel_post_read_file;
>         struct list_head kernel_module_request;
> -       struct list_head kernel_module_from_file;
>         struct list_head task_fix_setuid;
>         struct list_head task_setpgid;
>         struct list_head task_getpgid;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 071fb74..157f0cb 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -859,11 +859,6 @@ static inline int security_kernel_module_request(char *kmod_name)
>         return 0;
>  }
>
> -static inline int security_kernel_module_from_file(struct file *file)
> -{
> -       return 0;
> -}
> -
>  static inline int security_kernel_read_file(struct file *file,
>                                             enum kernel_read_file_id id)
>  {
> diff --git a/kernel/module.c b/kernel/module.c
> index 8f051a1..d77c4f1 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2665,7 +2665,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
>         if (info->len < sizeof(*(info->hdr)))
>                 return -ENOEXEC;
>
> -       err = security_kernel_module_from_file(NULL);
> +       err = security_kernel_read_file(NULL, READING_MODULE);
>         if (err)
>                 return err;
>
> @@ -2683,63 +2683,6 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
>         return 0;
>  }
>
> -/* Sets info->hdr and info->len. */
> -static int copy_module_from_fd(int fd, struct load_info *info)
> -{
> -       struct fd f = fdget(fd);
> -       int err;
> -       struct kstat stat;
> -       loff_t pos;
> -       ssize_t bytes = 0;
> -
> -       if (!f.file)
> -               return -ENOEXEC;
> -
> -       err = security_kernel_module_from_file(f.file);
> -       if (err)
> -               goto out;
> -
> -       err = vfs_getattr(&f.file->f_path, &stat);
> -       if (err)
> -               goto out;
> -
> -       if (stat.size > INT_MAX) {
> -               err = -EFBIG;
> -               goto out;
> -       }
> -
> -       /* Don't hand 0 to vmalloc, it whines. */
> -       if (stat.size == 0) {
> -               err = -EINVAL;
> -               goto out;
> -       }
> -
> -       info->hdr = vmalloc(stat.size);
> -       if (!info->hdr) {
> -               err = -ENOMEM;
> -               goto out;
> -       }
> -
> -       pos = 0;
> -       while (pos < stat.size) {
> -               bytes = kernel_read(f.file, pos, (char *)(info->hdr) + pos,
> -                                   stat.size - pos);
> -               if (bytes < 0) {
> -                       vfree(info->hdr);
> -                       err = bytes;
> -                       goto out;
> -               }
> -               if (bytes == 0)
> -                       break;
> -               pos += bytes;
> -       }
> -       info->len = pos;
> -
> -out:
> -       fdput(f);
> -       return err;
> -}
> -
>  static void free_copy(struct load_info *info)
>  {
>         vfree(info->hdr);
> @@ -3602,8 +3545,10 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
>
>  SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
>  {
> -       int err;
>         struct load_info info = { };
> +       loff_t size;
> +       void *hdr;
> +       int err;
>
>         err = may_init_module();
>         if (err)
> @@ -3615,9 +3560,12 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
>                       |MODULE_INIT_IGNORE_VERMAGIC))
>                 return -EINVAL;
>
> -       err = copy_module_from_fd(fd, &info);
> +       err = kernel_read_file_from_fd(fd, &hdr, &size, INT_MAX,
> +                                      READING_MODULE);
>         if (err)
>                 return err;
> +       info.hdr = hdr;
> +       info.len = size;
>
>         return load_module(&info, uargs, flags);
>  }
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 6f79bdf..1e91d94 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -316,28 +316,6 @@ int ima_file_check(struct file *file, int mask, int opened)
>  EXPORT_SYMBOL_GPL(ima_file_check);
>
>  /**
> - * ima_module_check - based on policy, collect/store/appraise measurement.
> - * @file: pointer to the file to be measured/appraised
> - *
> - * Measure/appraise kernel modules based on policy.
> - *
> - * On success return 0.  On integrity appraisal error, assuming the file
> - * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
> - */
> -int ima_module_check(struct file *file)
> -{
> -       if (!file) {
> -#ifndef CONFIG_MODULE_SIG_FORCE
> -               if ((ima_appraise & IMA_APPRAISE_MODULES) &&
> -                   (ima_appraise & IMA_APPRAISE_ENFORCE))
> -                       return -EACCES; /* INTEGRITY_UNKNOWN */
> -#endif
> -               return 0;       /* We rely on module signature checking */
> -       }
> -       return process_measurement(file, NULL, 0, MAY_EXEC, MODULE_CHECK, 0);
> -}
> -
> -/**
>   * ima_read_file - pre-measure/appraise hook decision based on policy
>   * @file: pointer to the file to be measured/appraised/audit
>   * @read_id: caller identifier
> @@ -350,6 +328,14 @@ int ima_module_check(struct file *file)
>   */
>  int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
>  {
> +       if (!file && read_id == READING_MODULE) {
> +#ifndef CONFIG_MODULE_SIG_FORCE
> +               if ((ima_appraise & IMA_APPRAISE_MODULES) &&
> +                   (ima_appraise & IMA_APPRAISE_ENFORCE))
> +                       return -EACCES; /* INTEGRITY_UNKNOWN */
> +#endif
> +               return 0;       /* We rely on module signature checking */
> +       }
>         return 0;
>  }
>
> @@ -378,6 +364,9 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>                 return 0;
>         }
>
> +       if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */
> +               return 0;
> +
>         if (!file && (!buf || size == 0)) { /* should never happen */
>                 if (ima_appraise & IMA_APPRAISE_ENFORCE)
>                         return -EACCES;
> @@ -386,6 +375,8 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>
>         if (read_id == READING_FIRMWARE)
>                 func = FIRMWARE_CHECK;
> +       else if (read_id == READING_MODULE)
> +               func = MODULE_CHECK;
>
>         return process_measurement(file, buf, size, MAY_READ, func, 0);
>  }
> diff --git a/security/security.c b/security/security.c
> index 1728fe2..3573c82 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -889,16 +889,6 @@ int security_kernel_module_request(char *kmod_name)
>         return call_int_hook(kernel_module_request, 0, kmod_name);
>  }
>
> -int security_kernel_module_from_file(struct file *file)
> -{
> -       int ret;
> -
> -       ret = call_int_hook(kernel_module_from_file, 0, file);
> -       if (ret)
> -               return ret;
> -       return ima_module_check(file);
> -}
> -
>  int security_kernel_read_file(struct file *file, enum kernel_read_file_id id)
>  {
>         int ret;
> @@ -1703,8 +1693,6 @@ struct security_hook_heads security_hook_heads = {
>                 LIST_HEAD_INIT(security_hook_heads.kernel_create_files_as),
>         .kernel_module_request =
>                 LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
> -       .kernel_module_from_file =
> -               LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file),
>         .kernel_read_file =
>                 LIST_HEAD_INIT(security_hook_heads.kernel_read_file),
>         .kernel_post_read_file =
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version
  2016-02-03 19:06 ` [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version Mimi Zohar
@ 2016-02-04 18:05   ` Kees Cook
  2016-02-04 19:57   ` Luis R. Rodriguez
  2016-02-12 12:50   ` Dave Young
  2 siblings, 0 replies; 77+ messages in thread
From: Kees Cook @ 2016-02-04 18:05 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Replace copy_file_from_fd() with kernel_read_file_from_fd().
>
> Two new identifiers named READING_KEXEC_IMAGE and READING_KEXEC_INITRAMFS
> are defined for measuring, appraising or auditing the kexec image and
> initramfs.
>
> Changelog v3:
> - return -EBADF, not -ENOEXEC
> - identifier change
> - moved copy_file_from_fd() to a separate patch
> - defer support for IMA
> v1:
> - re-order and squash the kexec patches
> v0: ima: measure and appraise kexec image and initramfs (squashed)
> - rename ima_read_hooks enumeration to ima_policy_id
> - use kstat file size type loff_t, not size_t
> - add union name "hooks" to fix sparse warning
> - Calculate the file hash from the in memory buffer
> (suggested by Dave Young)
> - Rename ima_read_and_process_file() to ima_hash_and_process_file()
> - replace individual case statements with range:
>         KEXEC_CHECK ... IMA_MAX_READ_CHECK - 1
> - Instead of ima_read_and_process_file() allocating memory, the caller
> allocates and frees the memory.
> - Moved the kexec measurement/appraisal call to copy_file_from_fd(). The
> same call now measures and appraises both the kexec image and initramfs.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
>  include/linux/fs.h  |  2 ++
>  kernel/kexec_file.c | 73 +++++++----------------------------------------------
>  2 files changed, 11 insertions(+), 64 deletions(-)
>
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 9e1f1e3..d4d556e 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2529,6 +2529,8 @@ extern int do_pipe_flags(int *, int);
>  enum kernel_read_file_id {
>         READING_FIRMWARE = 1,
>         READING_MODULE,
> +       READING_KEXEC_IMAGE,
> +       READING_KEXEC_INITRAMFS,
>         READING_MAX_ID
>  };
>
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index b70ada0..1443f93 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -18,6 +18,7 @@
>  #include <linux/kexec.h>
>  #include <linux/mutex.h>
>  #include <linux/list.h>
> +#include <linux/fs.h>
>  #include <crypto/hash.h>
>  #include <crypto/sha.h>
>  #include <linux/syscalls.h>
> @@ -33,65 +34,6 @@ size_t __weak kexec_purgatory_size = 0;
>
>  static int kexec_calculate_store_digests(struct kimage *image);
>
> -static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len)
> -{
> -       struct fd f = fdget(fd);
> -       int ret;
> -       struct kstat stat;
> -       loff_t pos;
> -       ssize_t bytes = 0;
> -
> -       if (!f.file)
> -               return -EBADF;
> -
> -       ret = vfs_getattr(&f.file->f_path, &stat);
> -       if (ret)
> -               goto out;
> -
> -       if (stat.size > INT_MAX) {
> -               ret = -EFBIG;
> -               goto out;
> -       }
> -
> -       /* Don't hand 0 to vmalloc, it whines. */
> -       if (stat.size == 0) {
> -               ret = -EINVAL;
> -               goto out;
> -       }
> -
> -       *buf = vmalloc(stat.size);
> -       if (!*buf) {
> -               ret = -ENOMEM;
> -               goto out;
> -       }
> -
> -       pos = 0;
> -       while (pos < stat.size) {
> -               bytes = kernel_read(f.file, pos, (char *)(*buf) + pos,
> -                                   stat.size - pos);
> -               if (bytes < 0) {
> -                       vfree(*buf);
> -                       ret = bytes;
> -                       goto out;
> -               }
> -
> -               if (bytes == 0)
> -                       break;
> -               pos += bytes;
> -       }
> -
> -       if (pos != stat.size) {
> -               ret = -EBADF;
> -               vfree(*buf);
> -               goto out;
> -       }
> -
> -       *buf_len = pos;
> -out:
> -       fdput(f);
> -       return ret;
> -}
> -
>  /* Architectures can provide this probe function */
>  int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
>                                          unsigned long buf_len)
> @@ -180,16 +122,17 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>  {
>         int ret = 0;
>         void *ldata;
> +       loff_t size;
>
> -       ret = copy_file_from_fd(kernel_fd, &image->kernel_buf,
> -                               &image->kernel_buf_len);
> +       ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
> +                                      &size, INT_MAX, READING_KEXEC_IMAGE);
>         if (ret)
>                 return ret;
> +       image->kernel_buf_len = size;
>
>         /* Call arch image probe handlers */
>         ret = arch_kexec_kernel_image_probe(image, image->kernel_buf,
>                                             image->kernel_buf_len);
> -
>         if (ret)
>                 goto out;
>
> @@ -204,10 +147,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>  #endif
>         /* It is possible that there no initramfs is being loaded */
>         if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
> -               ret = copy_file_from_fd(initrd_fd, &image->initrd_buf,
> -                                       &image->initrd_buf_len);
> +               ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
> +                                              &size, INT_MAX,
> +                                              READING_KEXEC_INITRAMFS);
>                 if (ret)
>                         goto out;
> +               image->initrd_buf_len = size;
>         }
>
>         if (cmdline_len) {
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 00/22] vfs: support for a common kernel file loader
  2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
                   ` (21 preceding siblings ...)
  2016-02-03 19:06 ` [PATCH v3 22/22] ima: require signed IMA policy Mimi Zohar
@ 2016-02-04 18:15 ` Kees Cook
  2016-02-04 23:54   ` Mimi Zohar
  22 siblings, 1 reply; 77+ messages in thread
From: Kees Cook @ 2016-02-04 18:15 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> For a while it was looked down upon to directly read files from Linux.
> These days there exists a few mechanisms in the kernel that do just this
> though to load a file into a local buffer. There are minor but important
> checks differences on each, we should take all the best practices from
> each of them, generalize them and make all places in the kernel that
> read a file use it.[1]
>
> One difference is the method for opening the file.  In some cases we
> have a file, while in other cases we have a pathname or a file descriptor.
>
> Another difference is the security hook calls, or lack of them.  In
> some versions there is a post file read hook, while in others there
> is a pre file read hook.
>
> This patch set attempts to resolve these differences.  It does not attempt
> to merge the different methods of opening a file, but defines a single
> common kernel file read function with two wrappers. In addition, as none
> of the upstreamed LSMs define either a kernel_module_from_file or a
> kernel_fw_from_file hook, this patch set removes these hooks and the
> associated functions.  The ima_module_check() and ima_fw_from_file()
> functions are renamed and called from the pre and post kernel_read_file
> security functions respectively.

I'm very happy about the pre and post hooks; this solves the primary
problem I'd had when comparing the firmware and module hooks. Thanks!

Once this series is in -next, I'll resend my rebased "loadpin" LSM.

-Kees

>
> Changelog:
> - Rebased on top of some of the "firmware_class: extensible firmware API"
> patches posted by Luis.
> - Removed the kernel_module_from_file and kernel_fw_from_file security
> hooks and functions.
> - Defined "kernel_read_file_id" enumeration, independently of "ima_hooks".
> - Split patches for ease of review.
>
> The latest version of these patches can be found in the next-kernel-read-v3
> branch of:
> git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
>
> [1] Taken from Luis Rodriguez's wiki -
> http://kernelnewbies.org/KernelProjects/common-kernel-loader
>
> Mimi
>
> David Howells (1):
>   firmware: fold successful fw read early
>
> Dmitry Kasatkin (3):
>   ima: separate 'security.ima' reading functionality from collect
>   ima: provide buffer hash calculation function
>   ima: load policy using path
>
> Luis R. Rodriguez (2):
>   firmware: simplify dev_*() print messages for generic helpers
>   firmware: move completing fw into a helper
>
> Mimi Zohar (16):
>   ima: refactor ima_policy_show() to display "ima_hooks" rules
>   ima: use "ima_hooks" enum as function argument
>   vfs: define a generic function to read a file from the kernel
>   vfs: define kernel_read_file_id enumeration
>   ima: calculate the hash of a buffer using aynchronous hash(ahash)
>   ima: define a new hook to measure and appraise a file already in
>     memory
>   vfs: define kernel_read_file_from_path
>   firmware: replace call to fw_read_file_contents() with kernel version
>   security: define kernel_read_file hook
>   vfs: define kernel_copy_file_from_fd()
>   module: replace copy_module_from_fd with kernel version
>   ima: remove firmware and module specific cached status info
>   kexec: replace call to copy_file_from_fd() with kernel version
>   ima: support for kexec image and initramfs
>   ima: measure and appraise the IMA policy itself
>   ima: require signed IMA policy
>
>  Documentation/ABI/testing/ima_policy      |   2 +-
>  drivers/base/firmware_class.c             |  76 ++++++-------------
>  fs/exec.c                                 |  95 +++++++++++++++++++++++
>  include/linux/fs.h                        |  15 ++++
>  include/linux/ima.h                       |  10 ++-
>  include/linux/lsm_hooks.h                 |  35 ++++-----
>  include/linux/security.h                  |  16 ++--
>  kernel/kexec_file.c                       |  73 +++---------------
>  kernel/module.c                           |  68 ++---------------
>  security/integrity/iint.c                 |   4 +-
>  security/integrity/ima/ima.h              |  49 ++++++++----
>  security/integrity/ima/ima_api.c          |  25 +++----
>  security/integrity/ima/ima_appraise.c     |  69 ++++++++---------
>  security/integrity/ima/ima_crypto.c       | 120 +++++++++++++++++++++++++++++-
>  security/integrity/ima/ima_fs.c           |  50 ++++++++++++-
>  security/integrity/ima/ima_init.c         |   2 +-
>  security/integrity/ima/ima_main.c         | 104 +++++++++++++++++++-------
>  security/integrity/ima/ima_policy.c       | 107 +++++++++++++++++---------
>  security/integrity/ima/ima_template.c     |   2 -
>  security/integrity/ima/ima_template_lib.c |   1 -
>  security/integrity/integrity.h            |  15 ++--
>  security/security.c                       |  32 ++++----
>  22 files changed, 605 insertions(+), 365 deletions(-)
>
> --
> 2.1.0
>



-- 
Kees Cook
Chrome OS & Brillo Security

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

* Re: [PATCH v3 08/22] vfs: define kernel_read_file_id enumeration
  2016-02-03 19:06 ` [PATCH v3 08/22] vfs: define kernel_read_file_id enumeration Mimi Zohar
  2016-02-04 17:41   ` Kees Cook
@ 2016-02-04 19:45   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Luis R. Rodriguez @ 2016-02-04 19:45 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, kexec, linux-modules, fsdevel,
	David Howells, David Woodhouse, Kees Cook, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 03, 2016 at 02:06:16PM -0500, Mimi Zohar wrote:
> To differentiate between the kernel_read_file() callers, this patch
> defines a new enumeration named kernel_read_file_id and includes the
> caller identifier as an argument.
> 
> Subsequent patches define READING_KEXEC_IMAGE, READING_KEXEC_INITRAMFS,
> READING_FIRMWARE, READING_MODULE, and READING_POLICY.
> 
> Changelog v3:
> - Replace the IMA specific enumeration with a generic one.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>

  Luis

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

* Re: [PATCH v3 12/22] vfs: define kernel_read_file_from_path
  2016-02-03 19:06 ` [PATCH v3 12/22] vfs: define kernel_read_file_from_path Mimi Zohar
  2016-02-04 17:46   ` Kees Cook
@ 2016-02-04 19:47   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Luis R. Rodriguez @ 2016-02-04 19:47 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, kexec, linux-modules, fsdevel,
	David Howells, David Woodhouse, Kees Cook, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 03, 2016 at 02:06:20PM -0500, Mimi Zohar wrote:
> This patch defines kernel_read_file_from_path(), a wrapper for the VFS
> common kernel_read_file().
> 
> Changelog:
> - Separated from the IMA patch
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>

  Luis

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

* Re: [PATCH v3 13/22] firmware: replace call to fw_read_file_contents() with kernel version
  2016-02-03 19:06 ` [PATCH v3 13/22] firmware: replace call to fw_read_file_contents() with kernel version Mimi Zohar
  2016-02-04 17:56   ` Kees Cook
@ 2016-02-04 19:51   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Luis R. Rodriguez @ 2016-02-04 19:51 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, kexec, linux-modules, fsdevel,
	David Howells, David Woodhouse, Kees Cook, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 03, 2016 at 02:06:21PM -0500, Mimi Zohar wrote:
> Replace the fw_read_file_contents with kernel_file_read_from_path().
> 
> Although none of the upstreamed LSMs define a kernel_fw_from_file hook,
> IMA is called by the security function to prevent unsigned firmware from
> being loaded and to measure/appraise signed firmware, based on policy.
> 
> Instead of reading the firmware twice, once for measuring/appraising the
> firmware and again for reading the firmware contents into memory, the
> kernel_post_read_file() security hook calculates the file hash based on
> the in memory file buffer.  The firmware is read once.
> 
> This patch removes the LSM kernel_fw_from_file() hook and security call.
> 
> Changelog v3:
> - remove kernel_fw_from_file hook
> - use kernel_file_read_from_path() - requested by Luis
> v2:
> - reordered and squashed firmware patches
> - fix MAX firmware size (Kees Cook)
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>

 Luis

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

* Re: [PATCH v3 14/22] security: define kernel_read_file hook
  2016-02-03 19:06 ` [PATCH v3 14/22] security: define kernel_read_file hook Mimi Zohar
  2016-02-04 17:57   ` Kees Cook
@ 2016-02-04 19:54   ` Luis R. Rodriguez
  2016-02-11 16:54   ` Casey Schaufler
  2 siblings, 0 replies; 77+ messages in thread
From: Luis R. Rodriguez @ 2016-02-04 19:54 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, kexec, linux-modules, fsdevel,
	David Howells, David Woodhouse, Kees Cook, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 03, 2016 at 02:06:22PM -0500, Mimi Zohar wrote:
> The kernel_read_file security hook is called prior to reading the file
> into memory.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>

  Luis

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

* Re: [PATCH v3 15/22] vfs: define kernel_copy_file_from_fd()
  2016-02-03 19:06 ` [PATCH v3 15/22] vfs: define kernel_copy_file_from_fd() Mimi Zohar
  2016-02-04 17:58   ` Kees Cook
@ 2016-02-04 19:55   ` Luis R. Rodriguez
  1 sibling, 0 replies; 77+ messages in thread
From: Luis R. Rodriguez @ 2016-02-04 19:55 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, kexec, linux-modules, fsdevel,
	David Howells, David Woodhouse, Kees Cook, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 03, 2016 at 02:06:23PM -0500, Mimi Zohar wrote:
> This patch defines kernel_read_file_from_fd(), a wrapper for the VFS
> common kernel_read_file().
> 
> Changelog:
> - Separated from the kernel modules patch
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>

  Luis

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

* Re: [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version
  2016-02-03 19:06 ` [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version Mimi Zohar
  2016-02-04 18:04   ` Kees Cook
@ 2016-02-04 19:56   ` Luis R. Rodriguez
  2016-02-05  0:19     ` Mimi Zohar
  1 sibling, 1 reply; 77+ messages in thread
From: Luis R. Rodriguez @ 2016-02-04 19:56 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, kexec, linux-modules, fsdevel,
	David Howells, David Woodhouse, Kees Cook, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 03, 2016 at 02:06:24PM -0500, Mimi Zohar wrote:
> Replace copy_module_from_fd() with kernel_read_file_from_fd().
> 
> Although none of the upstreamed LSMs define a kernel_module_from_file
> hook, IMA is called, based on policy, to prevent unsigned kernel modules
> from being loaded by the original kernel module syscall and to
> measure/appraise signed kernel modules.
> 
> The security function security_kernel_module_from_file() was called prior
> to reading a kernel module.  Preventing unsigned kernel modules from being
> loaded by the original kernel module syscall remains on the pre-read
> kernel_read_file() security hook.  Instead of reading the kernel module
> twice, once for measuring/appraising and again for loading the kernel
> module, the signature validation is moved to the kernel_post_read_file()
> security hook.
> 
> This patch removes the security_kernel_module_from_file() hook and security
> call.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>

  Luis

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

* Re: [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version
  2016-02-03 19:06 ` [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version Mimi Zohar
  2016-02-04 18:05   ` Kees Cook
@ 2016-02-04 19:57   ` Luis R. Rodriguez
  2016-02-12 12:50   ` Dave Young
  2 siblings, 0 replies; 77+ messages in thread
From: Luis R. Rodriguez @ 2016-02-04 19:57 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, kexec, linux-modules, fsdevel,
	David Howells, David Woodhouse, Kees Cook, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Wed, Feb 03, 2016 at 02:06:26PM -0500, Mimi Zohar wrote:
> Replace copy_file_from_fd() with kernel_read_file_from_fd().
> 
> Two new identifiers named READING_KEXEC_IMAGE and READING_KEXEC_INITRAMFS
> are defined for measuring, appraising or auditing the kexec image and
> initramfs.
> 
> Changelog v3:
> - return -EBADF, not -ENOEXEC
> - identifier change
> - moved copy_file_from_fd() to a separate patch
> - defer support for IMA
> v1:
> - re-order and squash the kexec patches
> v0: ima: measure and appraise kexec image and initramfs (squashed)
> - rename ima_read_hooks enumeration to ima_policy_id
> - use kstat file size type loff_t, not size_t
> - add union name "hooks" to fix sparse warning
> - Calculate the file hash from the in memory buffer
> (suggested by Dave Young)
> - Rename ima_read_and_process_file() to ima_hash_and_process_file()
> - replace individual case statements with range:
>         KEXEC_CHECK ... IMA_MAX_READ_CHECK - 1
> - Instead of ima_read_and_process_file() allocating memory, the caller
> allocates and frees the memory.
> - Moved the kexec measurement/appraisal call to copy_file_from_fd(). The
> same call now measures and appraises both the kexec image and initramfs.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>

  Luis

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

* Re: [PATCH v3 06/22] firmware: fold successful fw read early
  2016-02-04 17:36   ` Kees Cook
@ 2016-02-04 20:26     ` Luis R. Rodriguez
  0 siblings, 0 replies; 77+ messages in thread
From: Luis R. Rodriguez @ 2016-02-04 20:26 UTC (permalink / raw)
  To: Kees Cook
  Cc: Mimi Zohar, linux-security-module, Kexec Mailing List,
	linux-modules, linux-fsdevel, David Howells, David Woodhouse,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell,
	Luis R. Rodriguez

On Thu, Feb 04, 2016 at 09:36:50AM -0800, Kees Cook wrote:
> On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> > From: David Howells <dhowells@redhat.com>
> >
> > We'll be folding in some more checks on fw_read_file_contents(),
> > this will make the success case easier to follow.
> >
> > Reviewed-by: Josh Boyer <jwboyer@fedoraproject.org>
> > Signed-off-by: David Howells <dhowells@redhat.com>
> > Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> > Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> > ---
> >  drivers/base/firmware_class.c | 16 +++++++---------
> >  1 file changed, 7 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> > index fb64814..c658cec 100644
> > --- a/drivers/base/firmware_class.c
> > +++ b/drivers/base/firmware_class.c
> > @@ -361,20 +361,18 @@ static int fw_get_filesystem_firmware(struct device *device,
> >                         continue;
> >                 rc = fw_read_file_contents(file, buf);
> >                 fput(file);
> > -               if (rc)
> > +               if (rc == 0) {
> > +                       dev_dbg(device, "direct-loading %s\n",
> > +                               buf->fw_id);
> > +                       fw_finish_direct_load(device, buf);
> > +                       goto out;
> > +               } else
> >                         dev_warn(device, "loading %s failed with error %d\n",
> >                                  path, rc);
> > -               else
> > -                       break;
> >         }
> > +out:
> >         __putname(path);
> >
> > -       if (!rc) {
> > -               dev_dbg(device, "direct-loading %s\n",
> > -                       buf->fw_id);
> > -               fw_finish_direct_load(device, buf);
> > -       }
> > -
> >         return rc;
> >  }
> 
> Looking at this code, why does this use "break":
> 
>                 len = snprintf(path, PATH_MAX, "%s/%s",
>                                fw_path[i], buf->fw_id);
>                 if (len >= PATH_MAX) {
>                         rc = -ENAMETOOLONG;
>                         break;
>                 }
> 
> Shouldn't that emit a warning, set rc, and continue?

Yes but this is a separate piece of code, and that's a functional change but I
welcome the change for sure.  This could be done separately.

> Regardless, I think this is more readable. Adding an "out" target at
> the end of a for loop seems weird, given "break" existing. :)

Good call, goto mixed with while loops can be get iffy.  I'm fine with this
change as a replacement. To be fair we should also note both patches (the one
submitted and yours below) also make a small functional change so that the loop
continues over all other possible directories in the fw_path in case of failure
with the first directory used as a base. If we wanted to be pedantic and careful
we could split the functional change to not enable to continue in case of failure
onto the next directory, and instead require that as a separate patch. I'll leave
it to Mimi to decide.

> 
>                 rc = fw_read_file_contents(file, buf);
>                 fput(file);
> -               if (rc)
> +               if (rc) {
>                         dev_warn(device, "loading %s failed with error %d\n",
>                                  path, rc);
> +                       continue;
> +               }
> +               dev_dbg(device, "direct-loading %s\n", buf->fw_id);
> +               fw_finish_direct_load(device, buf);
> -               else
> -                       break;
> +               break;
>         }
>         __putname(path);
> -
> -       if (!rc) {
> -               dev_dbg(device, "direct-loading %s\n",
> -                       buf->fw_id);
> -               fw_finish_direct_load(device, buf);
> -       }
> -
>         return rc;
>  }

Can you provided a Signed-offy-by? If so consider my Acked-by.

  Luis

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

* Re: [PATCH v3 00/22] vfs: support for a common kernel file loader
  2016-02-04 18:15 ` [PATCH v3 00/22] vfs: support for a common kernel file loader Kees Cook
@ 2016-02-04 23:54   ` Mimi Zohar
  0 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-04 23:54 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-security-module, Luis R. Rodriguez, Kexec Mailing List,
	linux-modules, David Howells, David Woodhouse, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Thu, 2016-02-04 at 10:15 -0800, Kees Cook wrote:
> On Wed, Feb 3, 2016 at 11:06 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> > For a while it was looked down upon to directly read files from Linux.
> > These days there exists a few mechanisms in the kernel that do just this
> > though to load a file into a local buffer. There are minor but important
> > checks differences on each, we should take all the best practices from
> > each of them, generalize them and make all places in the kernel that
> > read a file use it.[1]
> >
> > One difference is the method for opening the file.  In some cases we
> > have a file, while in other cases we have a pathname or a file descriptor.
> >
> > Another difference is the security hook calls, or lack of them.  In
> > some versions there is a post file read hook, while in others there
> > is a pre file read hook.
> >
> > This patch set attempts to resolve these differences.  It does not attempt
> > to merge the different methods of opening a file, but defines a single
> > common kernel file read function with two wrappers. In addition, as none
> > of the upstreamed LSMs define either a kernel_module_from_file or a
> > kernel_fw_from_file hook, this patch set removes these hooks and the
> > associated functions.  The ima_module_check() and ima_fw_from_file()
> > functions are renamed and called from the pre and post kernel_read_file
> > security functions respectively.
> 
> I'm very happy about the pre and post hooks; this solves the primary
> problem I'd had when comparing the firmware and module hooks. Thanks!

Thank you for reviewing the patches!  

> Once this series is in -next, I'll resend my rebased "loadpin" LSM.

I was looking for this reference, when writing the patch description for
modules, but couldn't remember it.  Commit 2e72d51 "security: introduce
kernel_module_from_file hook" patch description references Chrome OS. 

Thanks!

Mimi


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

* Re: [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version
  2016-02-04 19:56   ` Luis R. Rodriguez
@ 2016-02-05  0:19     ` Mimi Zohar
  0 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-05  0:19 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: linux-security-module, kexec, linux-modules, fsdevel,
	David Howells, David Woodhouse, Kees Cook, Dmitry Torokhov,
	Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Thu, 2016-02-04 at 20:56 +0100, Luis R. Rodriguez wrote:
> On Wed, Feb 03, 2016 at 02:06:24PM -0500, Mimi Zohar wrote:
> > Replace copy_module_from_fd() with kernel_read_file_from_fd().
> > 
> > Although none of the upstreamed LSMs define a kernel_module_from_file
> > hook, IMA is called, based on policy, to prevent unsigned kernel modules
> > from being loaded by the original kernel module syscall and to
> > measure/appraise signed kernel modules.
> > 
> > The security function security_kernel_module_from_file() was called prior
> > to reading a kernel module.  Preventing unsigned kernel modules from being
> > loaded by the original kernel module syscall remains on the pre-read
> > kernel_read_file() security hook.  Instead of reading the kernel module
> > twice, once for measuring/appraising and again for loading the kernel
> > module, the signature validation is moved to the kernel_post_read_file()
> > security hook.
> > 
> > This patch removes the security_kernel_module_from_file() hook and security
> > call.
> > 
> > Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> 
> Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>

Thank you for reviewing the patches!

Mimi


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

* Re: [PATCH v3 02/22] ima: refactor ima_policy_show() to display "ima_hooks" rules
  2016-02-03 19:06 ` [PATCH v3 02/22] ima: refactor ima_policy_show() to display "ima_hooks" rules Mimi Zohar
@ 2016-02-07 19:45   ` Petko Manolov
  2016-02-10 19:33   ` Dmitry Kasatkin
  1 sibling, 0 replies; 77+ messages in thread
From: Petko Manolov @ 2016-02-07 19:45 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On 16-02-03 14:06:10, Mimi Zohar wrote:
> Define and call a function to display the "ima_hooks" rules.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Petko Manolov <petkan@mip-labs.com>

> ---
>  security/integrity/ima/ima_policy.c | 63 +++++++++++++++++++++----------------
>  1 file changed, 36 insertions(+), 27 deletions(-)
> 
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index e0e18cc..43b6425 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -903,6 +903,40 @@ void ima_policy_stop(struct seq_file *m, void *v)
>  #define mt(token)	mask_tokens[token]
>  #define ft(token)	func_tokens[token]
>  
> +/*
> + * policy_func_show - display the ima_hooks policy rule
> + */
> +static void policy_func_show(struct seq_file *m, enum ima_hooks func)
> +{
> +	char tbuf[64] = {0,};
> +
> +	switch (func) {
> +	case FILE_CHECK:
> +		seq_printf(m, pt(Opt_func), ft(func_file));
> +		break;
> +	case MMAP_CHECK:
> +		seq_printf(m, pt(Opt_func), ft(func_mmap));
> +		break;
> +	case BPRM_CHECK:
> +		seq_printf(m, pt(Opt_func), ft(func_bprm));
> +		break;
> +	case MODULE_CHECK:
> +		seq_printf(m, pt(Opt_func), ft(func_module));
> +		break;
> +	case FIRMWARE_CHECK:
> +		seq_printf(m, pt(Opt_func), ft(func_firmware));
> +		break;
> +	case POST_SETATTR:
> +		seq_printf(m, pt(Opt_func), ft(func_post));
> +		break;
> +	default:
> +		snprintf(tbuf, sizeof(tbuf), "%d", func);
> +		seq_printf(m, pt(Opt_func), tbuf);
> +		break;
> +	}
> +	seq_puts(m, " ");
> +}
> +
>  int ima_policy_show(struct seq_file *m, void *v)
>  {
>  	struct ima_rule_entry *entry = v;
> @@ -924,33 +958,8 @@ int ima_policy_show(struct seq_file *m, void *v)
>  
>  	seq_puts(m, " ");
>  
> -	if (entry->flags & IMA_FUNC) {
> -		switch (entry->func) {
> -		case FILE_CHECK:
> -			seq_printf(m, pt(Opt_func), ft(func_file));
> -			break;
> -		case MMAP_CHECK:
> -			seq_printf(m, pt(Opt_func), ft(func_mmap));
> -			break;
> -		case BPRM_CHECK:
> -			seq_printf(m, pt(Opt_func), ft(func_bprm));
> -			break;
> -		case MODULE_CHECK:
> -			seq_printf(m, pt(Opt_func), ft(func_module));
> -			break;
> -		case FIRMWARE_CHECK:
> -			seq_printf(m, pt(Opt_func), ft(func_firmware));
> -			break;
> -		case POST_SETATTR:
> -			seq_printf(m, pt(Opt_func), ft(func_post));
> -			break;
> -		default:
> -			snprintf(tbuf, sizeof(tbuf), "%d", entry->func);
> -			seq_printf(m, pt(Opt_func), tbuf);
> -			break;
> -		}
> -		seq_puts(m, " ");
> -	}
> +	if (entry->flags & IMA_FUNC)
> +		policy_func_show(m, entry->func);
>  
>  	if (entry->flags & IMA_MASK) {
>  		if (entry->mask & MAY_EXEC)
> -- 
> 2.1.0
> 
> --
> 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

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

* Re: [PATCH v3 03/22] ima: use "ima_hooks" enum as function argument
  2016-02-03 19:06 ` [PATCH v3 03/22] ima: use "ima_hooks" enum as function argument Mimi Zohar
@ 2016-02-07 19:46   ` Petko Manolov
  2016-02-10 19:35   ` Dmitry Kasatkin
  1 sibling, 0 replies; 77+ messages in thread
From: Petko Manolov @ 2016-02-07 19:46 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On 16-02-03 14:06:11, Mimi Zohar wrote:
> Cleanup the function arguments by using "ima_hooks" enumerator as needed.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Petko Manolov <petkan@mip-labs.com>

> ---
>  security/integrity/ima/ima.h          | 25 +++++++++++++++++--------
>  security/integrity/ima/ima_api.c      |  6 +++---
>  security/integrity/ima/ima_appraise.c | 13 +++++++------
>  security/integrity/ima/ima_main.c     | 14 +++++++-------
>  security/integrity/ima/ima_policy.c   |  6 +++---
>  5 files changed, 37 insertions(+), 27 deletions(-)
> 
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index fb8da36..b7e7935 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -137,9 +137,18 @@ static inline unsigned long ima_hash_key(u8 *digest)
>  	return hash_long(*digest, IMA_HASH_BITS);
>  }
>  
> +enum ima_hooks {
> +	FILE_CHECK = 1,
> +	MMAP_CHECK,
> +	BPRM_CHECK,
> +	MODULE_CHECK,
> +	FIRMWARE_CHECK,
> +	POST_SETATTR
> +};
> +
>  /* LIM API function definitions */
> -int ima_get_action(struct inode *inode, int mask, int function);
> -int ima_must_measure(struct inode *inode, int mask, int function);
> +int ima_get_action(struct inode *inode, int mask, enum ima_hooks func);
> +int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
>  int ima_collect_measurement(struct integrity_iint_cache *iint,
>  			    struct file *file, enum hash_algo algo);
>  void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
> @@ -156,8 +165,6 @@ void ima_free_template_entry(struct ima_template_entry *entry);
>  const char *ima_d_path(struct path *path, char **pathbuf);
>  
>  /* IMA policy related functions */
> -enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR };
> -
>  int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
>  		     int flags);
>  void ima_init_policy(void);
> @@ -179,21 +186,22 @@ int ima_policy_show(struct seq_file *m, void *v);
>  #define IMA_APPRAISE_FIRMWARE	0x10
>  
>  #ifdef CONFIG_IMA_APPRAISE
> -int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
> +int ima_appraise_measurement(enum ima_hooks func,
> +			     struct integrity_iint_cache *iint,
>  			     struct file *file, const unsigned char *filename,
>  			     struct evm_ima_xattr_data *xattr_value,
>  			     int xattr_len, int opened);
>  int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
>  void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
>  enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
> -					   int func);
> +					   enum ima_hooks func);
>  enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
>  				 int xattr_len);
>  int ima_read_xattr(struct dentry *dentry,
>  		   struct evm_ima_xattr_data **xattr_value);
>  
>  #else
> -static inline int ima_appraise_measurement(int func,
> +static inline int ima_appraise_measurement(enum ima_hooks func,
>  					   struct integrity_iint_cache *iint,
>  					   struct file *file,
>  					   const unsigned char *filename,
> @@ -215,7 +223,8 @@ static inline void ima_update_xattr(struct integrity_iint_cache *iint,
>  }
>  
>  static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache
> -							 *iint, int func)
> +							 *iint,
> +							 enum ima_hooks func)
>  {
>  	return INTEGRITY_UNKNOWN;
>  }
> diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
> index e7c7a5d..8750254 100644
> --- a/security/integrity/ima/ima_api.c
> +++ b/security/integrity/ima/ima_api.c
> @@ -156,7 +156,7 @@ err_out:
>   * ima_get_action - appraise & measure decision based on policy.
>   * @inode: pointer to inode to measure
>   * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
> - * @function: calling function (FILE_CHECK, BPRM_CHECK, MMAP_CHECK, MODULE_CHECK)
> + * @func: caller identifier
>   *
>   * The policy is defined in terms of keypairs:
>   *		subj=, obj=, type=, func=, mask=, fsmagic=
> @@ -168,13 +168,13 @@ err_out:
>   * Returns IMA_MEASURE, IMA_APPRAISE mask.
>   *
>   */
> -int ima_get_action(struct inode *inode, int mask, int function)
> +int ima_get_action(struct inode *inode, int mask, enum ima_hooks func)
>  {
>  	int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;
>  
>  	flags &= ima_policy_flag;
>  
> -	return ima_match_policy(inode, function, mask, flags);
> +	return ima_match_policy(inode, func, mask, flags);
>  }
>  
>  /*
> diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> index 9c2b46b..2888449 100644
> --- a/security/integrity/ima/ima_appraise.c
> +++ b/security/integrity/ima/ima_appraise.c
> @@ -67,7 +67,7 @@ static int ima_fix_xattr(struct dentry *dentry,
>  
>  /* Return specific func appraised cached result */
>  enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
> -					   int func)
> +					   enum ima_hooks func)
>  {
>  	switch (func) {
>  	case MMAP_CHECK:
> @@ -85,7 +85,8 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
>  }
>  
>  static void ima_set_cache_status(struct integrity_iint_cache *iint,
> -				 int func, enum integrity_status status)
> +				 enum ima_hooks func,
> +				 enum integrity_status status)
>  {
>  	switch (func) {
>  	case MMAP_CHECK:
> @@ -103,11 +104,11 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
>  	case FILE_CHECK:
>  	default:
>  		iint->ima_file_status = status;
> -		break;
>  	}
>  }
>  
> -static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
> +static void ima_cache_flags(struct integrity_iint_cache *iint,
> +			     enum ima_hooks func)
>  {
>  	switch (func) {
>  	case MMAP_CHECK:
> @@ -125,7 +126,6 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
>  	case FILE_CHECK:
>  	default:
>  		iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
> -		break;
>  	}
>  }
>  
> @@ -185,7 +185,8 @@ int ima_read_xattr(struct dentry *dentry,
>   *
>   * Return 0 on success, error code otherwise
>   */
> -int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
> +int ima_appraise_measurement(enum ima_hooks func,
> +			     struct integrity_iint_cache *iint,
>  			     struct file *file, const unsigned char *filename,
>  			     struct evm_ima_xattr_data *xattr_value,
>  			     int xattr_len, int opened)
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index d9fc463..78a80c8 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -153,8 +153,8 @@ void ima_file_free(struct file *file)
>  	ima_check_last_writer(iint, inode, file);
>  }
>  
> -static int process_measurement(struct file *file, int mask, int function,
> -			       int opened)
> +static int process_measurement(struct file *file, int mask,
> +			       enum ima_hooks func, int opened)
>  {
>  	struct inode *inode = file_inode(file);
>  	struct integrity_iint_cache *iint = NULL;
> @@ -174,8 +174,8 @@ static int process_measurement(struct file *file, int mask, int function,
>  	 * bitmask based on the appraise/audit/measurement policy.
>  	 * Included is the appraise submask.
>  	 */
> -	action = ima_get_action(inode, mask, function);
> -	violation_check = ((function == FILE_CHECK || function == MMAP_CHECK) &&
> +	action = ima_get_action(inode, mask, func);
> +	violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
>  			   (ima_policy_flag & IMA_MEASURE));
>  	if (!action && !violation_check)
>  		return 0;
> @@ -184,7 +184,7 @@ static int process_measurement(struct file *file, int mask, int function,
>  
>  	/*  Is the appraise rule hook specific?  */
>  	if (action & IMA_FILE_APPRAISE)
> -		function = FILE_CHECK;
> +		func = FILE_CHECK;
>  
>  	mutex_lock(&inode->i_mutex);
>  
> @@ -214,7 +214,7 @@ static int process_measurement(struct file *file, int mask, int function,
>  	/* Nothing to do, just return existing appraised status */
>  	if (!action) {
>  		if (must_appraise)
> -			rc = ima_get_cache_status(iint, function);
> +			rc = ima_get_cache_status(iint, func);
>  		goto out_digsig;
>  	}
>  
> @@ -240,7 +240,7 @@ static int process_measurement(struct file *file, int mask, int function,
>  		ima_store_measurement(iint, file, pathname,
>  				      xattr_value, xattr_len);
>  	if (action & IMA_APPRAISE_SUBMASK)
> -		rc = ima_appraise_measurement(function, iint, file, pathname,
> +		rc = ima_appraise_measurement(func, iint, file, pathname,
>  					      xattr_value, xattr_len, opened);
>  	if (action & IMA_AUDIT)
>  		ima_audit_measurement(iint, pathname);
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index 43b6425..b089ebe 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -207,8 +207,8 @@ static void ima_lsm_update_rules(void)
>   *
>   * Returns true on rule match, false on failure.
>   */
> -static bool ima_match_rules(struct ima_rule_entry *rule,
> -			    struct inode *inode, enum ima_hooks func, int mask)
> +static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
> +			    enum ima_hooks func, int mask)
>  {
>  	struct task_struct *tsk = current;
>  	const struct cred *cred = current_cred();
> @@ -289,7 +289,7 @@ retry:
>   * In addition to knowing that we need to appraise the file in general,
>   * we need to differentiate between calling hooks, for hook specific rules.
>   */
> -static int get_subaction(struct ima_rule_entry *rule, int func)
> +static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
>  {
>  	if (!(rule->flags & IMA_FUNC))
>  		return IMA_FILE_APPRAISE;
> -- 
> 2.1.0
> 
> --
> 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

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

* Re: [PATCH v3 17/22] ima: remove firmware and module specific cached status info
  2016-02-03 19:06 ` [PATCH v3 17/22] ima: remove firmware and module specific cached status info Mimi Zohar
@ 2016-02-07 19:56   ` Petko Manolov
  2016-02-10 20:18   ` Dmitry Kasatkin
  1 sibling, 0 replies; 77+ messages in thread
From: Petko Manolov @ 2016-02-07 19:56 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On 16-02-03 14:06:25, Mimi Zohar wrote:
> Each time a file is read by the kernel, the file should be re-measured and
> the file signature re-appraised, based on policy.  As there is no need to
> preserve the status information, this patch replaces the firmware and
> module specific cache status with a generic one named read_file.
> 
> This change simplifies adding support for other files read by the kernel.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Petko Manolov <petkan@mip-labs.com>

> ---
>  security/integrity/iint.c             |  4 ++--
>  security/integrity/ima/ima.h          |  3 ++-
>  security/integrity/ima/ima_appraise.c | 35 ++++++++++++++++-------------------
>  security/integrity/ima/ima_policy.c   |  9 ++++-----
>  security/integrity/integrity.h        | 16 ++++------------
>  5 files changed, 28 insertions(+), 39 deletions(-)
> 
> diff --git a/security/integrity/iint.c b/security/integrity/iint.c
> index 8f1ab37..345b759 100644
> --- a/security/integrity/iint.c
> +++ b/security/integrity/iint.c
> @@ -77,7 +77,7 @@ static void iint_free(struct integrity_iint_cache *iint)
>  	iint->ima_file_status = INTEGRITY_UNKNOWN;
>  	iint->ima_mmap_status = INTEGRITY_UNKNOWN;
>  	iint->ima_bprm_status = INTEGRITY_UNKNOWN;
> -	iint->ima_module_status = INTEGRITY_UNKNOWN;
> +	iint->ima_read_status = INTEGRITY_UNKNOWN;
>  	iint->evm_status = INTEGRITY_UNKNOWN;
>  	kmem_cache_free(iint_cache, iint);
>  }
> @@ -157,7 +157,7 @@ static void init_once(void *foo)
>  	iint->ima_file_status = INTEGRITY_UNKNOWN;
>  	iint->ima_mmap_status = INTEGRITY_UNKNOWN;
>  	iint->ima_bprm_status = INTEGRITY_UNKNOWN;
> -	iint->ima_module_status = INTEGRITY_UNKNOWN;
> +	iint->ima_read_status = INTEGRITY_UNKNOWN;
>  	iint->evm_status = INTEGRITY_UNKNOWN;
>  }
>  
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 0b7134c..a5d2592 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -144,9 +144,10 @@ enum ima_hooks {
>  	FILE_CHECK = 1,
>  	MMAP_CHECK,
>  	BPRM_CHECK,
> +	POST_SETATTR,
>  	MODULE_CHECK,
>  	FIRMWARE_CHECK,
> -	POST_SETATTR
> +	MAX_CHECK
>  };
>  
>  /* LIM API function definitions */
> diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> index cb0d0ff..6b4694a 100644
> --- a/security/integrity/ima/ima_appraise.c
> +++ b/security/integrity/ima/ima_appraise.c
> @@ -74,13 +74,12 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
>  		return iint->ima_mmap_status;
>  	case BPRM_CHECK:
>  		return iint->ima_bprm_status;
> -	case MODULE_CHECK:
> -		return iint->ima_module_status;
> -	case FIRMWARE_CHECK:
> -		return iint->ima_firmware_status;
>  	case FILE_CHECK:
> -	default:
> +	case POST_SETATTR:
>  		return iint->ima_file_status;
> +	case MODULE_CHECK ... MAX_CHECK - 1:
> +	default:
> +		return iint->ima_read_status;
>  	}
>  }

I assume you used "case MODULE_CHECK ... MAX_CHECK - 1:" for readability?


> @@ -95,15 +94,14 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
>  	case BPRM_CHECK:
>  		iint->ima_bprm_status = status;
>  		break;
> -	case MODULE_CHECK:
> -		iint->ima_module_status = status;
> -		break;
> -	case FIRMWARE_CHECK:
> -		iint->ima_firmware_status = status;
> -		break;
>  	case FILE_CHECK:
> -	default:
> +	case POST_SETATTR:
>  		iint->ima_file_status = status;
> +		break;
> +	case MODULE_CHECK ... MAX_CHECK - 1:
> +	default:
> +		iint->ima_read_status = status;
> +		break;
>  	}
>  }
>  
> @@ -117,15 +115,14 @@ static void ima_cache_flags(struct integrity_iint_cache *iint,
>  	case BPRM_CHECK:
>  		iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
>  		break;
> -	case MODULE_CHECK:
> -		iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED);
> -		break;
> -	case FIRMWARE_CHECK:
> -		iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED);
> -		break;
>  	case FILE_CHECK:
> -	default:
> +	case POST_SETATTR:
>  		iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
> +		break;
> +	case MODULE_CHECK ... MAX_CHECK - 1:
> +	default:
> +		iint->flags |= (IMA_READ_APPRAISED | IMA_APPRAISED);
> +		break;
>  	}
>  }
>  
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index cfbe86f..7571ce8 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -300,13 +300,12 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
>  		return IMA_MMAP_APPRAISE;
>  	case BPRM_CHECK:
>  		return IMA_BPRM_APPRAISE;
> -	case MODULE_CHECK:
> -		return IMA_MODULE_APPRAISE;
> -	case FIRMWARE_CHECK:
> -		return IMA_FIRMWARE_APPRAISE;
>  	case FILE_CHECK:
> -	default:
> +	case POST_SETATTR:
>  		return IMA_FILE_APPRAISE;
> +	case MODULE_CHECK ... MAX_CHECK - 1:
> +	default:
> +		return IMA_READ_APPRAISE;
>  	}
>  }
>  
> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> index 9a0ea4c..c7a111c 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -45,18 +45,12 @@
>  #define IMA_MMAP_APPRAISED	0x00000800
>  #define IMA_BPRM_APPRAISE	0x00001000
>  #define IMA_BPRM_APPRAISED	0x00002000
> -#define IMA_MODULE_APPRAISE	0x00004000
> -#define IMA_MODULE_APPRAISED	0x00008000
> -#define IMA_FIRMWARE_APPRAISE	0x00010000
> -#define IMA_FIRMWARE_APPRAISED	0x00020000
> -#define IMA_READ_APPRAISE	0x00040000
> -#define IMA_READ_APPRAISED	0x00080000
> +#define IMA_READ_APPRAISE	0x00004000
> +#define IMA_READ_APPRAISED	0x00008000
>  #define IMA_APPRAISE_SUBMASK	(IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
> -				 IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \
> -				 IMA_FIRMWARE_APPRAISE | IMA_READ_APPRAISE)
> +				 IMA_BPRM_APPRAISE | IMA_READ_APPRAISE)
>  #define IMA_APPRAISED_SUBMASK	(IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
> -				 IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \
> -				 IMA_FIRMWARE_APPRAISED | IMA_READ_APPRAISED)
> +				 IMA_BPRM_APPRAISED | IMA_READ_APPRAISED)
>  
>  enum evm_ima_xattr_type {
>  	IMA_XATTR_DIGEST = 0x01,
> @@ -111,8 +105,6 @@ struct integrity_iint_cache {
>  	enum integrity_status ima_file_status:4;
>  	enum integrity_status ima_mmap_status:4;
>  	enum integrity_status ima_bprm_status:4;
> -	enum integrity_status ima_module_status:4;
> -	enum integrity_status ima_firmware_status:4;
>  	enum integrity_status ima_read_status:4;
>  	enum integrity_status evm_status:4;
>  	struct ima_digest_data *ima_hash;
> -- 
> 2.1.0
> 
> --
> 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

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

* Re: [PATCH v3 20/22] ima: load policy using path
  2016-02-03 19:06 ` [PATCH v3 20/22] ima: load policy using path Mimi Zohar
@ 2016-02-07 19:59   ` Petko Manolov
  2016-02-08  9:58     ` Dmitry Kasatkin
  0 siblings, 1 reply; 77+ messages in thread
From: Petko Manolov @ 2016-02-07 19:59 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell,
	Dmitry Kasatkin, Dmitry Kasatkin

On 16-02-03 14:06:28, Mimi Zohar wrote:
> From: Dmitry Kasatkin <d.kasatkin@samsung.com>
> 
> We currently cannot do appraisal or signature vetting of IMA policies
> since we currently can only load IMA policies by writing the contents
> of the policy directly in, as follows:
> 
> cat policy-file > <securityfs>/ima/policy
> 
> If we provide the kernel the path to the IMA policy so it can load
> the policy itself it'd be able to later appraise or vet the file
> signature if it has one.  This patch adds support to load the IMA
> policy with a given path as follows:
> 
> echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy
> 
> Changelog v3:
> - moved kernel_read_file_from_path() to a separate patch
> v2:
> - after re-ordering the patches, replace calling integrity_kernel_read()
>   to read the file with kernel_read_file_from_path() (Mimi)
> - Patch description re-written by Luis R. Rodriguez
> 
> Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> ---
>  include/linux/fs.h              |  1 +
>  security/integrity/ima/ima_fs.c | 43 +++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index d4d556e..b648e6d 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2531,6 +2531,7 @@ enum kernel_read_file_id {
>  	READING_MODULE,
>  	READING_KEXEC_IMAGE,
>  	READING_KEXEC_INITRAMFS,
> +	READING_POLICY,
>  	READING_MAX_ID
>  };
>  
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index f355231..00ccd67 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -22,6 +22,7 @@
>  #include <linux/rculist.h>
>  #include <linux/rcupdate.h>
>  #include <linux/parser.h>
> +#include <linux/vmalloc.h>
>  
>  #include "ima.h"
>  
> @@ -258,6 +259,41 @@ static const struct file_operations ima_ascii_measurements_ops = {
>  	.release = seq_release,
>  };
>  
> +static ssize_t ima_read_policy(char *path)
> +{
> +	void *data;
> +	char *datap;
> +	loff_t size;
> +	int rc, pathlen = strlen(path);
> +
> +	char *p;
> +
> +	/* remove \n */
> +	datap = path;
> +	strsep(&datap, "\n");
> +
> +	rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
> +	if (rc < 0)
> +		return rc;
> +
> +	datap = data;
> +	while (size > 0 && (p = strsep(&datap, "\n"))) {
> +		pr_debug("rule: %s\n", p);
> +		rc = ima_parse_add_rule(p);
> +		if (rc < 0)
> +			break;
> +		size -= rc;
> +	}
> +
> +	vfree(data);
> +	if (rc < 0)
> +		return rc;
> +	else if (size)
> +		return -EINVAL;
> +	else
> +		return pathlen;
> +}
> +
>  static ssize_t ima_write_policy(struct file *file, const char __user *buf,
>  				size_t datalen, loff_t *ppos)
>  {
> @@ -286,9 +322,12 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
>  	result = mutex_lock_interruptible(&ima_write_mutex);
>  	if (result < 0)
>  		goto out_free;
> -	result = ima_parse_add_rule(data);
> -	mutex_unlock(&ima_write_mutex);
>  
> +	if (data[0] == '/')

It seems that if we feed relative path to ima_policy the update will fail...

> +		result = ima_read_policy(data);
> +	else
> +		result = ima_parse_add_rule(data);
> +	mutex_unlock(&ima_write_mutex);
>  out_free:
>  	kfree(data);
>  out:
> -- 
> 2.1.0
> 
> --
> 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

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

* Re: [PATCH v3 21/22] ima: measure and appraise the IMA policy itself
  2016-02-03 19:06 ` [PATCH v3 21/22] ima: measure and appraise the IMA policy itself Mimi Zohar
@ 2016-02-07 20:01   ` Petko Manolov
  2016-02-10 20:22   ` Dmitry Kasatkin
  1 sibling, 0 replies; 77+ messages in thread
From: Petko Manolov @ 2016-02-07 20:01 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On 16-02-03 14:06:29, Mimi Zohar wrote:
> Add support for measuring and appraising the IMA policy itself.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Petko Manolov <petkan@mip-labs.com>

> ---
>  security/integrity/ima/ima.h        |  2 ++
>  security/integrity/ima/ima_fs.c     |  9 ++++++++-
>  security/integrity/ima/ima_main.c   |  3 +++
>  security/integrity/ima/ima_policy.c | 10 +++++++++-
>  4 files changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 832e62a..6685968 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -149,6 +149,7 @@ enum ima_hooks {
>  	FIRMWARE_CHECK,
>  	KEXEC_CHECK,
>  	INITRAMFS_CHECK,
> +	POLICY_CHECK,
>  	MAX_CHECK
>  };
>  
> @@ -191,6 +192,7 @@ int ima_policy_show(struct seq_file *m, void *v);
>  #define IMA_APPRAISE_LOG	0x04
>  #define IMA_APPRAISE_MODULES	0x08
>  #define IMA_APPRAISE_FIRMWARE	0x10
> +#define IMA_APPRAISE_POLICY	0x20
>  
>  #ifdef CONFIG_IMA_APPRAISE
>  int ima_appraise_measurement(enum ima_hooks func,
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 00ccd67..7b15e80 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -325,7 +325,14 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
>  
>  	if (data[0] == '/')
>  		result = ima_read_policy(data);
> -	else
> +	else if (ima_appraise & IMA_APPRAISE_POLICY) {
> +		pr_err("IMA: signed policy 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);
>  	mutex_unlock(&ima_write_mutex);
>  out_free:
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index ccf9526..497a6f2 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -386,6 +386,9 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>  	case READING_KEXEC_INITRAMFS:
>  		func = INITRAMFS_CHECK;
>  		break;
> +	case READING_POLICY:
> +		func = POLICY_CHECK;
> +		break;
>  	default:
>  		func = FILE_CHECK;
>  		break;
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index d02560e..39a811a 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -114,6 +114,7 @@ static struct ima_rule_entry default_measurement_rules[] = {
>  	 .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID},
>  	{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
>  	{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
> +	{.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC},
>  };
>  
>  static struct ima_rule_entry default_appraise_rules[] = {
> @@ -616,6 +617,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>  				entry->func = KEXEC_CHECK;
>  			else if (strcmp(args[0].from, "INITRAMFS_CHECK") == 0)
>  				entry->func = INITRAMFS_CHECK;
> +			else if (strcmp(args[0].from, "POLICY_CHECK") == 0)
> +				entry->func = POLICY_CHECK;
>  			else
>  				result = -EINVAL;
>  			if (!result)
> @@ -774,6 +777,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>  		temp_ima_appraise |= IMA_APPRAISE_MODULES;
>  	else if (entry->func == FIRMWARE_CHECK)
>  		temp_ima_appraise |= IMA_APPRAISE_FIRMWARE;
> +	else if (entry->func == POLICY_CHECK)
> +		temp_ima_appraise |= IMA_APPRAISE_POLICY;
>  	audit_log_format(ab, "res=%d", !result);
>  	audit_log_end(ab);
>  	return result;
> @@ -860,7 +865,7 @@ static char *mask_tokens[] = {
>  enum {
>  	func_file = 0, func_mmap, func_bprm,
>  	func_module, func_firmware, func_post,
> -	func_kexec, func_initramfs
> +	func_kexec, func_initramfs, func_policy
>  };
>  
>  static char *func_tokens[] = {
> @@ -940,6 +945,9 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
>  	case INITRAMFS_CHECK:
>  		seq_printf(m, pt(Opt_func), ft(func_initramfs));
>  		break;
> +	case POLICY_CHECK:
> +		seq_printf(m, pt(Opt_func), ft(func_policy));
> +		break;
>  	default:
>  		snprintf(tbuf, sizeof(tbuf), "%d", func);
>  		seq_printf(m, pt(Opt_func), tbuf);
> -- 
> 2.1.0
> 
> --
> 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

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

* Re: [PATCH v3 22/22] ima: require signed IMA policy
  2016-02-03 19:06 ` [PATCH v3 22/22] ima: require signed IMA policy Mimi Zohar
@ 2016-02-07 20:02   ` Petko Manolov
  2016-02-10 20:24   ` Dmitry Kasatkin
  1 sibling, 0 replies; 77+ messages in thread
From: Petko Manolov @ 2016-02-07 20:02 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On 16-02-03 14:06:30, Mimi Zohar wrote:
> Require the IMA policy to be signed when additional rules can be added.
> 
> v1:
> - initialize the policy flag
> - include IMA_APPRAISE_POLICY in the policy flag
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Petko Manolov <petkan@mip-labs.com>

> ---
>  security/integrity/ima/ima_policy.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index 39a811a..ba0f6dc 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -129,6 +129,10 @@ static struct ima_rule_entry default_appraise_rules[] = {
>  	{.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
>  	{.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
>  	{.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
> +#ifdef CONFIG_IMA_WRITE_POLICY
> +	{.action = APPRAISE, .func = POLICY_CHECK,
> +	.flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
> +#endif
>  #ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT
>  	{.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER},
>  #else
> @@ -412,9 +416,12 @@ void __init ima_init_policy(void)
>  	for (i = 0; i < appraise_entries; i++) {
>  		list_add_tail(&default_appraise_rules[i].list,
>  			      &ima_default_rules);
> +		if (default_appraise_rules[i].func == POLICY_CHECK)
> +			temp_ima_appraise |= IMA_APPRAISE_POLICY;
>  	}
>  
>  	ima_rules = &ima_default_rules;
> +	ima_update_policy_flag();
>  }
>  
>  /* Make sure we have a valid policy, at least containing some rules. */
> -- 
> 2.1.0
> 
> --
> 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

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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-03 19:06 ` [PATCH v3 19/22] ima: support for kexec image and initramfs Mimi Zohar
@ 2016-02-07 20:10   ` Petko Manolov
  2016-02-08 23:34     ` Mimi Zohar
  2016-02-10 21:09   ` Dmitry Kasatkin
  2016-02-12 12:53   ` Dave Young
  2 siblings, 1 reply; 77+ messages in thread
From: Petko Manolov @ 2016-02-07 20:10 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On 16-02-03 14:06:27, Mimi Zohar wrote:
> Add IMA policy support for measuring/appraising the kexec image and
> initramfs.
> 
> Moving the enumeration to the vfs layer simplified the patches, allowing
> the IMA changes, for the most part, to be separated from the other
> changes.  Unfortunately, passing either a kernel_read_file_id or a
> ima_hooks enumeration within IMA is messy.
> 
> Option 1: duplicate kernel_read_file enumeration in ima_hooks
> 
> enum kernel_read_file_id {
> 	...
>         READING_KEXEC_IMAGE,
>         READING_KEXEC_INITRAMFS,
>         READING_MAX_ID
> 
> enum ima_hooks {
> 	...
> 	KEXEC_CHECK
> 	INITRAMFS_CHECK
> 
> Option 2: define ima_hooks as extension of kernel_read_file
> eg: enum ima_hooks {
>         FILE_CHECK = READING_MAX_ID,
>         MMAP_CHECK,
> 
> In order to pass both kernel_read_file_id and ima_hooks values, we
> would need to specify a struct containing a union.
> 
> struct caller_id {
>         union {
>                 enum ima_hooks func_id;
>                 enum kernel_read_file_id read_id;
>         };
> };
> 
> Option 3: incorportate the ima_hooks enumeration into kernel_read_file_id,
> perhaps changing the enumeration name.
> 
> For now, duplicate the new READING_KEXEC_IMAGE/INITRAMFS in ima_hooks.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Option 3 seems the right way to go, but for now:

Acked-by: Petko Manolov <petkan@mip-labs.com>

> ---
>  Documentation/ABI/testing/ima_policy |  2 +-
>  security/integrity/ima/ima.h         |  2 ++
>  security/integrity/ima/ima_main.c    | 19 ++++++++++++++++---
>  security/integrity/ima/ima_policy.c  | 13 ++++++++++++-
>  4 files changed, 31 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
> index 0a378a8..e80f767 100644
> --- a/Documentation/ABI/testing/ima_policy
> +++ b/Documentation/ABI/testing/ima_policy
> @@ -26,7 +26,7 @@ Description:
>  			option:	[[appraise_type=]] [permit_directio]
>  
>  		base: 	func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
> -				[FIRMWARE_CHECK]
> +				[FIRMWARE_CHECK] [KEXEC_CHECK] [INITRAMFS_CHECK]
>  			mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
>  			       [[^]MAY_EXEC]
>  			fsmagic:= hex value
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index a5d2592..832e62a 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -147,6 +147,8 @@ enum ima_hooks {
>  	POST_SETATTR,
>  	MODULE_CHECK,
>  	FIRMWARE_CHECK,
> +	KEXEC_CHECK,
> +	INITRAMFS_CHECK,
>  	MAX_CHECK
>  };
>  
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 1e91d94..ccf9526 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -355,7 +355,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
>  int ima_post_read_file(struct file *file, void *buf, loff_t size,
>  		       enum kernel_read_file_id read_id)
>  {
> -	enum ima_hooks func = FILE_CHECK;
> +	enum ima_hooks func;
>  
>  	if (!file && read_id == READING_FIRMWARE) {
>  		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
> @@ -373,10 +373,23 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>  		return 0;
>  	}
>  
> -	if (read_id == READING_FIRMWARE)
> +	switch (read_id) {
> +	case READING_FIRMWARE:
>  		func = FIRMWARE_CHECK;
> -	else if (read_id == READING_MODULE)
> +		break;
> +	case READING_MODULE:
>  		func = MODULE_CHECK;
> +		break;
> +	case READING_KEXEC_IMAGE:
> +		func = KEXEC_CHECK;
> +		break;
> +	case READING_KEXEC_INITRAMFS:
> +		func = INITRAMFS_CHECK;
> +		break;
> +	default:
> +		func = FILE_CHECK;
> +		break;
> +	}
>  
>  	return process_measurement(file, buf, size, MAY_READ, func, 0);
>  }
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index 7571ce8..d02560e 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -612,6 +612,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>  				entry->func = MMAP_CHECK;
>  			else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
>  				entry->func = BPRM_CHECK;
> +			else if (strcmp(args[0].from, "KEXEC_CHECK") == 0)
> +				entry->func = KEXEC_CHECK;
> +			else if (strcmp(args[0].from, "INITRAMFS_CHECK") == 0)
> +				entry->func = INITRAMFS_CHECK;
>  			else
>  				result = -EINVAL;
>  			if (!result)
> @@ -855,7 +859,8 @@ static char *mask_tokens[] = {
>  
>  enum {
>  	func_file = 0, func_mmap, func_bprm,
> -	func_module, func_firmware, func_post
> +	func_module, func_firmware, func_post,
> +	func_kexec, func_initramfs
>  };
>  
>  static char *func_tokens[] = {
> @@ -929,6 +934,12 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
>  	case POST_SETATTR:
>  		seq_printf(m, pt(Opt_func), ft(func_post));
>  		break;
> +	case KEXEC_CHECK:
> +		seq_printf(m, pt(Opt_func), ft(func_kexec));
> +		break;
> +	case INITRAMFS_CHECK:
> +		seq_printf(m, pt(Opt_func), ft(func_initramfs));
> +		break;
>  	default:
>  		snprintf(tbuf, sizeof(tbuf), "%d", func);
>  		seq_printf(m, pt(Opt_func), tbuf);
> -- 
> 2.1.0
> 
> --
> 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

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

* RE: [PATCH v3 20/22] ima: load policy using path
  2016-02-07 19:59   ` Petko Manolov
@ 2016-02-08  9:58     ` Dmitry Kasatkin
  2016-02-08 10:35       ` Petko Manolov
  0 siblings, 1 reply; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-08  9:58 UTC (permalink / raw)
  To: Petko Manolov, Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell,
	Dmitry Kasatkin


________________________________________
From: Petko Manolov [petkan@mip-labs.com]
Sent: Sunday, February 07, 2016 9:59 PM
To: Mimi Zohar
Cc: linux-security-module@vger.kernel.org; Luis R. Rodriguez; kexec@lists.infradead.org; linux-modules@vger.kernel.org; fsdevel@vger.kernel.org; David Howells; David Woodhouse; Kees Cook; Dmitry Torokhov; Dmitry Kasatkin; Eric Biederman; Rusty Russell; Dmitry Kasatkin; Dmitry Kasatkin
Subject: Re: [PATCH v3 20/22] ima: load policy using path

On 16-02-03 14:06:28, Mimi Zohar wrote:
> From: Dmitry Kasatkin <d.kasatkin@samsung.com>
>
> We currently cannot do appraisal or signature vetting of IMA policies
> since we currently can only load IMA policies by writing the contents
> of the policy directly in, as follows:
>
> cat policy-file > <securityfs>/ima/policy
>
> If we provide the kernel the path to the IMA policy so it can load
> the policy itself it'd be able to later appraise or vet the file
> signature if it has one.  This patch adds support to load the IMA
> policy with a given path as follows:
>
> echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy
>
> Changelog v3:
> - moved kernel_read_file_from_path() to a separate patch
> v2:
> - after re-ordering the patches, replace calling integrity_kernel_read()
>   to read the file with kernel_read_file_from_path() (Mimi)
> - Patch description re-written by Luis R. Rodriguez
>
> Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> ---
>  include/linux/fs.h              |  1 +
>  security/integrity/ima/ima_fs.c | 43 +++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 42 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index d4d556e..b648e6d 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2531,6 +2531,7 @@ enum kernel_read_file_id {
>       READING_MODULE,
>       READING_KEXEC_IMAGE,
>       READING_KEXEC_INITRAMFS,
> +     READING_POLICY,
>       READING_MAX_ID
>  };
>
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index f355231..00ccd67 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -22,6 +22,7 @@
>  #include <linux/rculist.h>
>  #include <linux/rcupdate.h>
>  #include <linux/parser.h>
> +#include <linux/vmalloc.h>
>
>  #include "ima.h"
>
> @@ -258,6 +259,41 @@ static const struct file_operations ima_ascii_measurements_ops = {
>       .release = seq_release,
>  };
>
> +static ssize_t ima_read_policy(char *path)
> +{
> +     void *data;
> +     char *datap;
> +     loff_t size;
> +     int rc, pathlen = strlen(path);
> +
> +     char *p;
> +
> +     /* remove \n */
> +     datap = path;
> +     strsep(&datap, "\n");
> +
> +     rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
> +     if (rc < 0)
> +             return rc;
> +
> +     datap = data;
> +     while (size > 0 && (p = strsep(&datap, "\n"))) {
> +             pr_debug("rule: %s\n", p);
> +             rc = ima_parse_add_rule(p);
> +             if (rc < 0)
> +                     break;
> +             size -= rc;
> +     }
> +
> +     vfree(data);
> +     if (rc < 0)
> +             return rc;
> +     else if (size)
> +             return -EINVAL;
> +     else
> +             return pathlen;
> +}
> +
>  static ssize_t ima_write_policy(struct file *file, const char __user *buf,
>                               size_t datalen, loff_t *ppos)
>  {
> @@ -286,9 +322,12 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
>       result = mutex_lock_interruptible(&ima_write_mutex);
>       if (result < 0)
>               goto out_free;
> -     result = ima_parse_add_rule(data);
> -     mutex_unlock(&ima_write_mutex);
>
> +     if (data[0] == '/')

>It seems that if we feed relative path to ima_policy the update will fail...

Yes, i think it is always a good idea to pass absolute path.

Dmitry

> +             result = ima_read_policy(data);
> +     else
> +             result = ima_parse_add_rule(data);
> +     mutex_unlock(&ima_write_mutex);
>  out_free:
>       kfree(data);
>  out:
> --
> 2.1.0
>
> --
> 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

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

* Re: [PATCH v3 20/22] ima: load policy using path
  2016-02-08  9:58     ` Dmitry Kasatkin
@ 2016-02-08 10:35       ` Petko Manolov
  2016-02-08 10:45         ` Dmitry Kasatkin
  0 siblings, 1 reply; 77+ messages in thread
From: Petko Manolov @ 2016-02-08 10:35 UTC (permalink / raw)
  To: Dmitry Kasatkin
  Cc: Mimi Zohar, linux-security-module, Luis R. Rodriguez, kexec,
	linux-modules, fsdevel, David Howells, David Woodhouse,
	Kees Cook, Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman,
	Rusty Russell, Dmitry Kasatkin

On 16-02-08 09:58:16, Dmitry Kasatkin wrote:
> 
> ________________________________________
> From: Petko Manolov [petkan@mip-labs.com]
> Sent: Sunday, February 07, 2016 9:59 PM
> To: Mimi Zohar
> Cc: linux-security-module@vger.kernel.org; Luis R. Rodriguez; kexec@lists.infradead.org; linux-modules@vger.kernel.org; fsdevel@vger.kernel.org; David Howells; David Woodhouse; Kees Cook; Dmitry Torokhov; Dmitry Kasatkin; Eric Biederman; Rusty Russell; Dmitry Kasatkin; Dmitry Kasatkin
> Subject: Re: [PATCH v3 20/22] ima: load policy using path
> 
> On 16-02-03 14:06:28, Mimi Zohar wrote:
> > From: Dmitry Kasatkin <d.kasatkin@samsung.com>
> >
> > We currently cannot do appraisal or signature vetting of IMA policies
> > since we currently can only load IMA policies by writing the contents
> > of the policy directly in, as follows:
> >
> > cat policy-file > <securityfs>/ima/policy
> >
> > If we provide the kernel the path to the IMA policy so it can load
> > the policy itself it'd be able to later appraise or vet the file
> > signature if it has one.  This patch adds support to load the IMA
> > policy with a given path as follows:
> >
> > echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy
> >
> > Changelog v3:
> > - moved kernel_read_file_from_path() to a separate patch
> > v2:
> > - after re-ordering the patches, replace calling integrity_kernel_read()
> >   to read the file with kernel_read_file_from_path() (Mimi)
> > - Patch description re-written by Luis R. Rodriguez
> >
> > Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
> > Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> > ---
> >  include/linux/fs.h              |  1 +
> >  security/integrity/ima/ima_fs.c | 43 +++++++++++++++++++++++++++++++++++++++--
> >  2 files changed, 42 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/linux/fs.h b/include/linux/fs.h
> > index d4d556e..b648e6d 100644
> > --- a/include/linux/fs.h
> > +++ b/include/linux/fs.h
> > @@ -2531,6 +2531,7 @@ enum kernel_read_file_id {
> >       READING_MODULE,
> >       READING_KEXEC_IMAGE,
> >       READING_KEXEC_INITRAMFS,
> > +     READING_POLICY,
> >       READING_MAX_ID
> >  };
> >
> > diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> > index f355231..00ccd67 100644
> > --- a/security/integrity/ima/ima_fs.c
> > +++ b/security/integrity/ima/ima_fs.c
> > @@ -22,6 +22,7 @@
> >  #include <linux/rculist.h>
> >  #include <linux/rcupdate.h>
> >  #include <linux/parser.h>
> > +#include <linux/vmalloc.h>
> >
> >  #include "ima.h"
> >
> > @@ -258,6 +259,41 @@ static const struct file_operations ima_ascii_measurements_ops = {
> >       .release = seq_release,
> >  };
> >
> > +static ssize_t ima_read_policy(char *path)
> > +{
> > +     void *data;
> > +     char *datap;
> > +     loff_t size;
> > +     int rc, pathlen = strlen(path);
> > +
> > +     char *p;
> > +
> > +     /* remove \n */
> > +     datap = path;
> > +     strsep(&datap, "\n");
> > +
> > +     rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
> > +     if (rc < 0)
> > +             return rc;
> > +
> > +     datap = data;
> > +     while (size > 0 && (p = strsep(&datap, "\n"))) {
> > +             pr_debug("rule: %s\n", p);
> > +             rc = ima_parse_add_rule(p);
> > +             if (rc < 0)
> > +                     break;
> > +             size -= rc;
> > +     }
> > +
> > +     vfree(data);
> > +     if (rc < 0)
> > +             return rc;
> > +     else if (size)
> > +             return -EINVAL;
> > +     else
> > +             return pathlen;
> > +}
> > +
> >  static ssize_t ima_write_policy(struct file *file, const char __user *buf,
> >                               size_t datalen, loff_t *ppos)
> >  {
> > @@ -286,9 +322,12 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
> >       result = mutex_lock_interruptible(&ima_write_mutex);
> >       if (result < 0)
> >               goto out_free;
> > -     result = ima_parse_add_rule(data);
> > -     mutex_unlock(&ima_write_mutex);
> >
> > +     if (data[0] == '/')
> 
> >It seems that if we feed relative path to ima_policy the update will fail...
> 
> Yes, i think it is always a good idea to pass absolute path.

What if we at least emit a warning so people know what's wrong?


		Petko

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

* RE: [PATCH v3 20/22] ima: load policy using path
  2016-02-08 10:35       ` Petko Manolov
@ 2016-02-08 10:45         ` Dmitry Kasatkin
  2016-02-08 21:12           ` Mimi Zohar
  0 siblings, 1 reply; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-08 10:45 UTC (permalink / raw)
  To: Petko Manolov
  Cc: Mimi Zohar, linux-security-module, Luis R. Rodriguez, kexec,
	linux-modules, fsdevel, David Howells, David Woodhouse,
	Kees Cook, Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman,
	Rusty Russell, Dmitry Kasatkin


________________________________________
From: Petko Manolov [petkan@mip-labs.com]
Sent: Monday, February 08, 2016 12:35 PM
To: Dmitry Kasatkin
Cc: Mimi Zohar; linux-security-module@vger.kernel.org; Luis R. Rodriguez; kexec@lists.infradead.org; linux-modules@vger.kernel.org; fsdevel@vger.kernel.org; David Howells; David Woodhouse; Kees Cook; Dmitry Torokhov; Dmitry Kasatkin; Eric Biederman; Rusty Russell; Dmitry Kasatkin
Subject: Re: [PATCH v3 20/22] ima: load policy using path

On 16-02-08 09:58:16, Dmitry Kasatkin wrote:
>
> ________________________________________
> From: Petko Manolov [petkan@mip-labs.com]
> Sent: Sunday, February 07, 2016 9:59 PM
> To: Mimi Zohar
> Cc: linux-security-module@vger.kernel.org; Luis R. Rodriguez; kexec@lists.infradead.org; linux-modules@vger.kernel.org; fsdevel@vger.kernel.org; David Howells; David Woodhouse; Kees Cook; Dmitry Torokhov; Dmitry Kasatkin; Eric Biederman; Rusty Russell; Dmitry Kasatkin; Dmitry Kasatkin
> Subject: Re: [PATCH v3 20/22] ima: load policy using path
>
> On 16-02-03 14:06:28, Mimi Zohar wrote:
> > From: Dmitry Kasatkin <d.kasatkin@samsung.com>
> >
> > We currently cannot do appraisal or signature vetting of IMA policies
> > since we currently can only load IMA policies by writing the contents
> > of the policy directly in, as follows:
> >
> > cat policy-file > <securityfs>/ima/policy
> >
> > If we provide the kernel the path to the IMA policy so it can load
> > the policy itself it'd be able to later appraise or vet the file
> > signature if it has one.  This patch adds support to load the IMA
> > policy with a given path as follows:
> >
> > echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy
> >
> > Changelog v3:
> > - moved kernel_read_file_from_path() to a separate patch
> > v2:
> > - after re-ordering the patches, replace calling integrity_kernel_read()
> >   to read the file with kernel_read_file_from_path() (Mimi)
> > - Patch description re-written by Luis R. Rodriguez
> >
> > Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
> > Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> > ---
> >  include/linux/fs.h              |  1 +
> >  security/integrity/ima/ima_fs.c | 43 +++++++++++++++++++++++++++++++++++++++--
> >  2 files changed, 42 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/linux/fs.h b/include/linux/fs.h
> > index d4d556e..b648e6d 100644
> > --- a/include/linux/fs.h
> > +++ b/include/linux/fs.h
> > @@ -2531,6 +2531,7 @@ enum kernel_read_file_id {
> >       READING_MODULE,
> >       READING_KEXEC_IMAGE,
> >       READING_KEXEC_INITRAMFS,
> > +     READING_POLICY,
> >       READING_MAX_ID
> >  };
> >
> > diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> > index f355231..00ccd67 100644
> > --- a/security/integrity/ima/ima_fs.c
> > +++ b/security/integrity/ima/ima_fs.c
> > @@ -22,6 +22,7 @@
> >  #include <linux/rculist.h>
> >  #include <linux/rcupdate.h>
> >  #include <linux/parser.h>
> > +#include <linux/vmalloc.h>
> >
> >  #include "ima.h"
> >
> > @@ -258,6 +259,41 @@ static const struct file_operations ima_ascii_measurements_ops = {
> >       .release = seq_release,
> >  };
> >
> > +static ssize_t ima_read_policy(char *path)
> > +{
> > +     void *data;
> > +     char *datap;
> > +     loff_t size;
> > +     int rc, pathlen = strlen(path);
> > +
> > +     char *p;
> > +
> > +     /* remove \n */
> > +     datap = path;
> > +     strsep(&datap, "\n");
> > +
> > +     rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
> > +     if (rc < 0)
> > +             return rc;
> > +
> > +     datap = data;
> > +     while (size > 0 && (p = strsep(&datap, "\n"))) {
> > +             pr_debug("rule: %s\n", p);
> > +             rc = ima_parse_add_rule(p);
> > +             if (rc < 0)
> > +                     break;
> > +             size -= rc;
> > +     }
> > +
> > +     vfree(data);
> > +     if (rc < 0)
> > +             return rc;
> > +     else if (size)
> > +             return -EINVAL;
> > +     else
> > +             return pathlen;
> > +}
> > +
> >  static ssize_t ima_write_policy(struct file *file, const char __user *buf,
> >                               size_t datalen, loff_t *ppos)
> >  {
> > @@ -286,9 +322,12 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
> >       result = mutex_lock_interruptible(&ima_write_mutex);
> >       if (result < 0)
> >               goto out_free;
> > -     result = ima_parse_add_rule(data);
> > -     mutex_unlock(&ima_write_mutex);
> >
> > +     if (data[0] == '/')
>
> >It seems that if we feed relative path to ima_policy the update will fail...
>
> Yes, i think it is always a good idea to pass absolute path.

What if we at least emit a warning so people know what's wrong?


                Petko

DK: May be a good idea to print that loading policy by path or not.

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

* Re: [PATCH v3 20/22] ima: load policy using path
  2016-02-08 10:45         ` Dmitry Kasatkin
@ 2016-02-08 21:12           ` Mimi Zohar
  2016-02-09  7:47             ` Petko Manolov
  0 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-08 21:12 UTC (permalink / raw)
  To: Dmitry Kasatkin
  Cc: Petko Manolov, linux-security-module, Luis R. Rodriguez, kexec,
	linux-modules, fsdevel, David Howells, David Woodhouse,
	Kees Cook, Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman,
	Rusty Russell, Dmitry Kasatkin

On Mon, 2016-02-08 at 10:45 +0000, Dmitry Kasatkin wrote:

> > > @@ -286,9 +322,12 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
> > >       result = mutex_lock_interruptible(&ima_write_mutex);
> > >       if (result < 0)
> > >               goto out_free;
> > > -     result = ima_parse_add_rule(data);
> > > -     mutex_unlock(&ima_write_mutex);
> > >
> > > +     if (data[0] == '/')
> >
> > >It seems that if we feed relative path to ima_policy the update will fail...
> >
> > Yes, i think it is always a good idea to pass absolute path.
> 
> What if we at least emit a warning so people know what's wrong?

The next patch "ima: measure and appraise the IMA policy itself" adds
the following.  Is a failure message enough?

+       else if (ima_appraise & IMA_APPRAISE_POLICY) {
+               pr_err("IMA: signed policy 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);

> 
>                 Petko
> 
> DK: May be a good idea to print that loading policy by path or not.

Are we including the pathname?  Are you suggesting a log or audit
message?

Mimi


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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-07 20:10   ` Petko Manolov
@ 2016-02-08 23:34     ` Mimi Zohar
  0 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-08 23:34 UTC (permalink / raw)
  To: Petko Manolov
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Sun, 2016-02-07 at 22:10 +0200, Petko Manolov wrote:
> On 16-02-03 14:06:27, Mimi Zohar wrote:
 
> > Option 3: incorportate the ima_hooks enumeration into kernel_read_file_id,
> > perhaps changing the enumeration name.
> > 
> > For now, duplicate the new READING_KEXEC_IMAGE/INITRAMFS in ima_hooks.
> > 
> > Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> 
> Option 3 seems the right way to go, but for now:

I'm just not sure.  The kernel_read_file_id enumeration is in
<linux/fs.h>.

> Acked-by: Petko Manolov <petkan@mip-labs.com>

Thank you.

Mimi


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

* Re: [PATCH v3 20/22] ima: load policy using path
  2016-02-08 21:12           ` Mimi Zohar
@ 2016-02-09  7:47             ` Petko Manolov
  0 siblings, 0 replies; 77+ messages in thread
From: Petko Manolov @ 2016-02-09  7:47 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: Dmitry Kasatkin, linux-security-module, Luis R. Rodriguez, kexec,
	linux-modules, fsdevel, David Howells, David Woodhouse,
	Kees Cook, Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman,
	Rusty Russell, Dmitry Kasatkin

On 16-02-08 16:12:16, Mimi Zohar wrote:
> On Mon, 2016-02-08 at 10:45 +0000, Dmitry Kasatkin wrote:
> 
> > > > @@ -286,9 +322,12 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
> > > >       result = mutex_lock_interruptible(&ima_write_mutex);
> > > >       if (result < 0)
> > > >               goto out_free;
> > > > -     result = ima_parse_add_rule(data);
> > > > -     mutex_unlock(&ima_write_mutex);
> > > >
> > > > +     if (data[0] == '/')
> > >
> > > >It seems that if we feed relative path to ima_policy the update will fail...
> > >
> > > Yes, i think it is always a good idea to pass absolute path.
> > 
> > What if we at least emit a warning so people know what's wrong?
> 
> The next patch "ima: measure and appraise the IMA policy itself" adds
> the following.  Is a failure message enough?

That would be the wrong message.  The above code does not handle relative paths 
so any attempt to load the policy by "./ima_policy_file" or 
"../../ima_policy_file" will fail.

Isn't there a kernel function that checks if given string is a path-name?

> +       else if (ima_appraise & IMA_APPRAISE_POLICY) {
> +               pr_err("IMA: signed policy 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);
> 
> > 
> >                 Petko
> > 
> > DK: May be a good idea to print that loading policy by path or not.
> 
> Are we including the pathname?  Are you suggesting a log or audit message?

I guess log is more appropriate.

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

* Re: [PATCH v3 02/22] ima: refactor ima_policy_show() to display "ima_hooks" rules
  2016-02-03 19:06 ` [PATCH v3 02/22] ima: refactor ima_policy_show() to display "ima_hooks" rules Mimi Zohar
  2016-02-07 19:45   ` Petko Manolov
@ 2016-02-10 19:33   ` Dmitry Kasatkin
  1 sibling, 0 replies; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-10 19:33 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Define and call a function to display the "ima_hooks" rules.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>

> ---
>  security/integrity/ima/ima_policy.c | 63 +++++++++++++++++++++----------------
>  1 file changed, 36 insertions(+), 27 deletions(-)
>
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index e0e18cc..43b6425 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -903,6 +903,40 @@ void ima_policy_stop(struct seq_file *m, void *v)
>  #define mt(token)      mask_tokens[token]
>  #define ft(token)      func_tokens[token]
>
> +/*
> + * policy_func_show - display the ima_hooks policy rule
> + */
> +static void policy_func_show(struct seq_file *m, enum ima_hooks func)
> +{
> +       char tbuf[64] = {0,};
> +
> +       switch (func) {
> +       case FILE_CHECK:
> +               seq_printf(m, pt(Opt_func), ft(func_file));
> +               break;
> +       case MMAP_CHECK:
> +               seq_printf(m, pt(Opt_func), ft(func_mmap));
> +               break;
> +       case BPRM_CHECK:
> +               seq_printf(m, pt(Opt_func), ft(func_bprm));
> +               break;
> +       case MODULE_CHECK:
> +               seq_printf(m, pt(Opt_func), ft(func_module));
> +               break;
> +       case FIRMWARE_CHECK:
> +               seq_printf(m, pt(Opt_func), ft(func_firmware));
> +               break;
> +       case POST_SETATTR:
> +               seq_printf(m, pt(Opt_func), ft(func_post));
> +               break;
> +       default:
> +               snprintf(tbuf, sizeof(tbuf), "%d", func);
> +               seq_printf(m, pt(Opt_func), tbuf);
> +               break;
> +       }
> +       seq_puts(m, " ");
> +}
> +
>  int ima_policy_show(struct seq_file *m, void *v)
>  {
>         struct ima_rule_entry *entry = v;
> @@ -924,33 +958,8 @@ int ima_policy_show(struct seq_file *m, void *v)
>
>         seq_puts(m, " ");
>
> -       if (entry->flags & IMA_FUNC) {
> -               switch (entry->func) {
> -               case FILE_CHECK:
> -                       seq_printf(m, pt(Opt_func), ft(func_file));
> -                       break;
> -               case MMAP_CHECK:
> -                       seq_printf(m, pt(Opt_func), ft(func_mmap));
> -                       break;
> -               case BPRM_CHECK:
> -                       seq_printf(m, pt(Opt_func), ft(func_bprm));
> -                       break;
> -               case MODULE_CHECK:
> -                       seq_printf(m, pt(Opt_func), ft(func_module));
> -                       break;
> -               case FIRMWARE_CHECK:
> -                       seq_printf(m, pt(Opt_func), ft(func_firmware));
> -                       break;
> -               case POST_SETATTR:
> -                       seq_printf(m, pt(Opt_func), ft(func_post));
> -                       break;
> -               default:
> -                       snprintf(tbuf, sizeof(tbuf), "%d", entry->func);
> -                       seq_printf(m, pt(Opt_func), tbuf);
> -                       break;
> -               }
> -               seq_puts(m, " ");
> -       }
> +       if (entry->flags & IMA_FUNC)
> +               policy_func_show(m, entry->func);
>
>         if (entry->flags & IMA_MASK) {
>                 if (entry->mask & MAY_EXEC)
> --
> 2.1.0
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 03/22] ima: use "ima_hooks" enum as function argument
  2016-02-03 19:06 ` [PATCH v3 03/22] ima: use "ima_hooks" enum as function argument Mimi Zohar
  2016-02-07 19:46   ` Petko Manolov
@ 2016-02-10 19:35   ` Dmitry Kasatkin
  1 sibling, 0 replies; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-10 19:35 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Cleanup the function arguments by using "ima_hooks" enumerator as needed.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>

> ---
>  security/integrity/ima/ima.h          | 25 +++++++++++++++++--------
>  security/integrity/ima/ima_api.c      |  6 +++---
>  security/integrity/ima/ima_appraise.c | 13 +++++++------
>  security/integrity/ima/ima_main.c     | 14 +++++++-------
>  security/integrity/ima/ima_policy.c   |  6 +++---
>  5 files changed, 37 insertions(+), 27 deletions(-)
>
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index fb8da36..b7e7935 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -137,9 +137,18 @@ static inline unsigned long ima_hash_key(u8 *digest)
>         return hash_long(*digest, IMA_HASH_BITS);
>  }
>
> +enum ima_hooks {
> +       FILE_CHECK = 1,
> +       MMAP_CHECK,
> +       BPRM_CHECK,
> +       MODULE_CHECK,
> +       FIRMWARE_CHECK,
> +       POST_SETATTR
> +};
> +
>  /* LIM API function definitions */
> -int ima_get_action(struct inode *inode, int mask, int function);
> -int ima_must_measure(struct inode *inode, int mask, int function);
> +int ima_get_action(struct inode *inode, int mask, enum ima_hooks func);
> +int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
>  int ima_collect_measurement(struct integrity_iint_cache *iint,
>                             struct file *file, enum hash_algo algo);
>  void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
> @@ -156,8 +165,6 @@ void ima_free_template_entry(struct ima_template_entry *entry);
>  const char *ima_d_path(struct path *path, char **pathbuf);
>
>  /* IMA policy related functions */
> -enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR };
> -
>  int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
>                      int flags);
>  void ima_init_policy(void);
> @@ -179,21 +186,22 @@ int ima_policy_show(struct seq_file *m, void *v);
>  #define IMA_APPRAISE_FIRMWARE  0x10
>
>  #ifdef CONFIG_IMA_APPRAISE
> -int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
> +int ima_appraise_measurement(enum ima_hooks func,
> +                            struct integrity_iint_cache *iint,
>                              struct file *file, const unsigned char *filename,
>                              struct evm_ima_xattr_data *xattr_value,
>                              int xattr_len, int opened);
>  int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
>  void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
>  enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
> -                                          int func);
> +                                          enum ima_hooks func);
>  enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
>                                  int xattr_len);
>  int ima_read_xattr(struct dentry *dentry,
>                    struct evm_ima_xattr_data **xattr_value);
>
>  #else
> -static inline int ima_appraise_measurement(int func,
> +static inline int ima_appraise_measurement(enum ima_hooks func,
>                                            struct integrity_iint_cache *iint,
>                                            struct file *file,
>                                            const unsigned char *filename,
> @@ -215,7 +223,8 @@ static inline void ima_update_xattr(struct integrity_iint_cache *iint,
>  }
>
>  static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache
> -                                                        *iint, int func)
> +                                                        *iint,
> +                                                        enum ima_hooks func)
>  {
>         return INTEGRITY_UNKNOWN;
>  }
> diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
> index e7c7a5d..8750254 100644
> --- a/security/integrity/ima/ima_api.c
> +++ b/security/integrity/ima/ima_api.c
> @@ -156,7 +156,7 @@ err_out:
>   * ima_get_action - appraise & measure decision based on policy.
>   * @inode: pointer to inode to measure
>   * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
> - * @function: calling function (FILE_CHECK, BPRM_CHECK, MMAP_CHECK, MODULE_CHECK)
> + * @func: caller identifier
>   *
>   * The policy is defined in terms of keypairs:
>   *             subj=, obj=, type=, func=, mask=, fsmagic=
> @@ -168,13 +168,13 @@ err_out:
>   * Returns IMA_MEASURE, IMA_APPRAISE mask.
>   *
>   */
> -int ima_get_action(struct inode *inode, int mask, int function)
> +int ima_get_action(struct inode *inode, int mask, enum ima_hooks func)
>  {
>         int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;
>
>         flags &= ima_policy_flag;
>
> -       return ima_match_policy(inode, function, mask, flags);
> +       return ima_match_policy(inode, func, mask, flags);
>  }
>
>  /*
> diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> index 9c2b46b..2888449 100644
> --- a/security/integrity/ima/ima_appraise.c
> +++ b/security/integrity/ima/ima_appraise.c
> @@ -67,7 +67,7 @@ static int ima_fix_xattr(struct dentry *dentry,
>
>  /* Return specific func appraised cached result */
>  enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
> -                                          int func)
> +                                          enum ima_hooks func)
>  {
>         switch (func) {
>         case MMAP_CHECK:
> @@ -85,7 +85,8 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
>  }
>
>  static void ima_set_cache_status(struct integrity_iint_cache *iint,
> -                                int func, enum integrity_status status)
> +                                enum ima_hooks func,
> +                                enum integrity_status status)
>  {
>         switch (func) {
>         case MMAP_CHECK:
> @@ -103,11 +104,11 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
>         case FILE_CHECK:
>         default:
>                 iint->ima_file_status = status;
> -               break;
>         }
>  }
>
> -static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
> +static void ima_cache_flags(struct integrity_iint_cache *iint,
> +                            enum ima_hooks func)
>  {
>         switch (func) {
>         case MMAP_CHECK:
> @@ -125,7 +126,6 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
>         case FILE_CHECK:
>         default:
>                 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
> -               break;
>         }
>  }
>
> @@ -185,7 +185,8 @@ int ima_read_xattr(struct dentry *dentry,
>   *
>   * Return 0 on success, error code otherwise
>   */
> -int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
> +int ima_appraise_measurement(enum ima_hooks func,
> +                            struct integrity_iint_cache *iint,
>                              struct file *file, const unsigned char *filename,
>                              struct evm_ima_xattr_data *xattr_value,
>                              int xattr_len, int opened)
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index d9fc463..78a80c8 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -153,8 +153,8 @@ void ima_file_free(struct file *file)
>         ima_check_last_writer(iint, inode, file);
>  }
>
> -static int process_measurement(struct file *file, int mask, int function,
> -                              int opened)
> +static int process_measurement(struct file *file, int mask,
> +                              enum ima_hooks func, int opened)
>  {
>         struct inode *inode = file_inode(file);
>         struct integrity_iint_cache *iint = NULL;
> @@ -174,8 +174,8 @@ static int process_measurement(struct file *file, int mask, int function,
>          * bitmask based on the appraise/audit/measurement policy.
>          * Included is the appraise submask.
>          */
> -       action = ima_get_action(inode, mask, function);
> -       violation_check = ((function == FILE_CHECK || function == MMAP_CHECK) &&
> +       action = ima_get_action(inode, mask, func);
> +       violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
>                            (ima_policy_flag & IMA_MEASURE));
>         if (!action && !violation_check)
>                 return 0;
> @@ -184,7 +184,7 @@ static int process_measurement(struct file *file, int mask, int function,
>
>         /*  Is the appraise rule hook specific?  */
>         if (action & IMA_FILE_APPRAISE)
> -               function = FILE_CHECK;
> +               func = FILE_CHECK;
>
>         mutex_lock(&inode->i_mutex);
>
> @@ -214,7 +214,7 @@ static int process_measurement(struct file *file, int mask, int function,
>         /* Nothing to do, just return existing appraised status */
>         if (!action) {
>                 if (must_appraise)
> -                       rc = ima_get_cache_status(iint, function);
> +                       rc = ima_get_cache_status(iint, func);
>                 goto out_digsig;
>         }
>
> @@ -240,7 +240,7 @@ static int process_measurement(struct file *file, int mask, int function,
>                 ima_store_measurement(iint, file, pathname,
>                                       xattr_value, xattr_len);
>         if (action & IMA_APPRAISE_SUBMASK)
> -               rc = ima_appraise_measurement(function, iint, file, pathname,
> +               rc = ima_appraise_measurement(func, iint, file, pathname,
>                                               xattr_value, xattr_len, opened);
>         if (action & IMA_AUDIT)
>                 ima_audit_measurement(iint, pathname);
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index 43b6425..b089ebe 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -207,8 +207,8 @@ static void ima_lsm_update_rules(void)
>   *
>   * Returns true on rule match, false on failure.
>   */
> -static bool ima_match_rules(struct ima_rule_entry *rule,
> -                           struct inode *inode, enum ima_hooks func, int mask)
> +static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
> +                           enum ima_hooks func, int mask)
>  {
>         struct task_struct *tsk = current;
>         const struct cred *cred = current_cred();
> @@ -289,7 +289,7 @@ retry:
>   * In addition to knowing that we need to appraise the file in general,
>   * we need to differentiate between calling hooks, for hook specific rules.
>   */
> -static int get_subaction(struct ima_rule_entry *rule, int func)
> +static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
>  {
>         if (!(rule->flags & IMA_FUNC))
>                 return IMA_FILE_APPRAISE;
> --
> 2.1.0
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 10/22] ima: calculate the hash of a buffer using aynchronous hash(ahash)
  2016-02-03 19:06 ` [PATCH v3 10/22] ima: calculate the hash of a buffer using aynchronous hash(ahash) Mimi Zohar
@ 2016-02-10 19:58   ` Dmitry Kasatkin
  0 siblings, 0 replies; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-10 19:58 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Setting up ahash has some overhead.  Only use ahash to calculate the
> hash of a buffer, if the buffer is larger than ima_ahash_minsize.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>

> ---
>  security/integrity/ima/ima_crypto.c | 75 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 73 insertions(+), 2 deletions(-)
>
> diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
> index fccb6ce..38f2ed8 100644
> --- a/security/integrity/ima/ima_crypto.c
> +++ b/security/integrity/ima/ima_crypto.c
> @@ -519,6 +519,63 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data,
>         return rc;
>  }
>
> +static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
> +                                 struct ima_digest_data *hash,
> +                                 struct crypto_ahash *tfm)
> +{
> +       struct ahash_request *req;
> +       struct scatterlist sg;
> +       struct ahash_completion res;
> +       int rc, ahash_rc = 0;
> +
> +       hash->length = crypto_ahash_digestsize(tfm);
> +
> +       req = ahash_request_alloc(tfm, GFP_KERNEL);
> +       if (!req)
> +               return -ENOMEM;
> +
> +       init_completion(&res.completion);
> +       ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
> +                                  CRYPTO_TFM_REQ_MAY_SLEEP,
> +                                  ahash_complete, &res);
> +
> +       rc = ahash_wait(crypto_ahash_init(req), &res);
> +       if (rc)
> +               goto out;
> +
> +       sg_init_one(&sg, buf, len);
> +       ahash_request_set_crypt(req, &sg, NULL, len);
> +
> +       ahash_rc = crypto_ahash_update(req);
> +
> +       /* wait for the update request to complete */
> +       rc = ahash_wait(ahash_rc, &res);
> +       if (!rc) {
> +               ahash_request_set_crypt(req, NULL, hash->digest, 0);
> +               rc = ahash_wait(crypto_ahash_final(req), &res);
> +       }
> +out:
> +       ahash_request_free(req);
> +       return rc;
> +}
> +
> +static int calc_buffer_ahash(const void *buf, loff_t len,
> +                            struct ima_digest_data *hash)
> +{
> +       struct crypto_ahash *tfm;
> +       int rc;
> +
> +       tfm = ima_alloc_atfm(hash->algo);
> +       if (IS_ERR(tfm))
> +               return PTR_ERR(tfm);
> +
> +       rc = calc_buffer_ahash_atfm(buf, len, hash, tfm);
> +
> +       ima_free_atfm(tfm);
> +
> +       return rc;
> +}
> +
>  static int calc_buffer_shash_tfm(const void *buf, loff_t size,
>                                 struct ima_digest_data *hash,
>                                 struct crypto_shash *tfm)
> @@ -550,8 +607,8 @@ static int calc_buffer_shash_tfm(const void *buf, loff_t size,
>         return rc;
>  }
>
> -int ima_calc_buffer_hash(const void *buf, loff_t len,
> -                        struct ima_digest_data *hash)
> +static int calc_buffer_shash(const void *buf, loff_t len,
> +                            struct ima_digest_data *hash)
>  {
>         struct crypto_shash *tfm;
>         int rc;
> @@ -566,6 +623,20 @@ int ima_calc_buffer_hash(const void *buf, loff_t len,
>         return rc;
>  }
>
> +int ima_calc_buffer_hash(const void *buf, loff_t len,
> +                        struct ima_digest_data *hash)
> +{
> +       int rc;
> +
> +       if (ima_ahash_minsize && len >= ima_ahash_minsize) {
> +               rc = calc_buffer_ahash(buf, len, hash);
> +               if (!rc)
> +                       return 0;
> +       }
> +
> +       return calc_buffer_shash(buf, len, hash);
> +}
> +
>  static void __init ima_pcrread(int idx, u8 *pcr)
>  {
>         if (!ima_used_chip)
> --
> 2.1.0
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 17/22] ima: remove firmware and module specific cached status info
  2016-02-03 19:06 ` [PATCH v3 17/22] ima: remove firmware and module specific cached status info Mimi Zohar
  2016-02-07 19:56   ` Petko Manolov
@ 2016-02-10 20:18   ` Dmitry Kasatkin
  2016-02-10 23:14     ` Mimi Zohar
  1 sibling, 1 reply; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-10 20:18 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Each time a file is read by the kernel, the file should be re-measured and
> the file signature re-appraised, based on policy.  As there is no need to
> preserve the status information, this patch replaces the firmware and
> module specific cache status with a generic one named read_file.
>
> This change simplifies adding support for other files read by the kernel.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> ---
>  security/integrity/iint.c             |  4 ++--
>  security/integrity/ima/ima.h          |  3 ++-
>  security/integrity/ima/ima_appraise.c | 35 ++++++++++++++++-------------------
>  security/integrity/ima/ima_policy.c   |  9 ++++-----
>  security/integrity/integrity.h        | 16 ++++------------
>  5 files changed, 28 insertions(+), 39 deletions(-)
>
> diff --git a/security/integrity/iint.c b/security/integrity/iint.c
> index 8f1ab37..345b759 100644
> --- a/security/integrity/iint.c
> +++ b/security/integrity/iint.c
> @@ -77,7 +77,7 @@ static void iint_free(struct integrity_iint_cache *iint)
>         iint->ima_file_status = INTEGRITY_UNKNOWN;
>         iint->ima_mmap_status = INTEGRITY_UNKNOWN;
>         iint->ima_bprm_status = INTEGRITY_UNKNOWN;
> -       iint->ima_module_status = INTEGRITY_UNKNOWN;
> +       iint->ima_read_status = INTEGRITY_UNKNOWN;
>         iint->evm_status = INTEGRITY_UNKNOWN;
>         kmem_cache_free(iint_cache, iint);
>  }
> @@ -157,7 +157,7 @@ static void init_once(void *foo)
>         iint->ima_file_status = INTEGRITY_UNKNOWN;
>         iint->ima_mmap_status = INTEGRITY_UNKNOWN;
>         iint->ima_bprm_status = INTEGRITY_UNKNOWN;
> -       iint->ima_module_status = INTEGRITY_UNKNOWN;
> +       iint->ima_read_status = INTEGRITY_UNKNOWN;
>         iint->evm_status = INTEGRITY_UNKNOWN;
>  }
>
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 0b7134c..a5d2592 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -144,9 +144,10 @@ enum ima_hooks {
>         FILE_CHECK = 1,
>         MMAP_CHECK,
>         BPRM_CHECK,
> +       POST_SETATTR,
>         MODULE_CHECK,
>         FIRMWARE_CHECK,
> -       POST_SETATTR
> +       MAX_CHECK
>  };
>
>  /* LIM API function definitions */
> diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> index cb0d0ff..6b4694a 100644
> --- a/security/integrity/ima/ima_appraise.c
> +++ b/security/integrity/ima/ima_appraise.c
> @@ -74,13 +74,12 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
>                 return iint->ima_mmap_status;
>         case BPRM_CHECK:
>                 return iint->ima_bprm_status;
> -       case MODULE_CHECK:
> -               return iint->ima_module_status;
> -       case FIRMWARE_CHECK:
> -               return iint->ima_firmware_status;
>         case FILE_CHECK:
> -       default:
> +       case POST_SETATTR:
>                 return iint->ima_file_status;
> +       case MODULE_CHECK ... MAX_CHECK - 1:

Will LLVM clang handles this range?

Otherwise it can be just like:

case MODULE_CHECK ... MAX_CHECK :


> +       default:
> +               return iint->ima_read_status;
>         }
>  }
>
> @@ -95,15 +94,14 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
>         case BPRM_CHECK:
>                 iint->ima_bprm_status = status;
>                 break;
> -       case MODULE_CHECK:
> -               iint->ima_module_status = status;
> -               break;
> -       case FIRMWARE_CHECK:
> -               iint->ima_firmware_status = status;
> -               break;
>         case FILE_CHECK:
> -       default:
> +       case POST_SETATTR:
>                 iint->ima_file_status = status;
> +               break;
> +       case MODULE_CHECK ... MAX_CHECK - 1:
> +       default:
> +               iint->ima_read_status = status;
> +               break;
>         }
>  }
>
> @@ -117,15 +115,14 @@ static void ima_cache_flags(struct integrity_iint_cache *iint,
>         case BPRM_CHECK:
>                 iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
>                 break;
> -       case MODULE_CHECK:
> -               iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED);
> -               break;
> -       case FIRMWARE_CHECK:
> -               iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED);
> -               break;
>         case FILE_CHECK:
> -       default:
> +       case POST_SETATTR:
>                 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
> +               break;
> +       case MODULE_CHECK ... MAX_CHECK - 1:
> +       default:
> +               iint->flags |= (IMA_READ_APPRAISED | IMA_APPRAISED);
> +               break;
>         }
>  }
>
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index cfbe86f..7571ce8 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -300,13 +300,12 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
>                 return IMA_MMAP_APPRAISE;
>         case BPRM_CHECK:
>                 return IMA_BPRM_APPRAISE;
> -       case MODULE_CHECK:
> -               return IMA_MODULE_APPRAISE;
> -       case FIRMWARE_CHECK:
> -               return IMA_FIRMWARE_APPRAISE;
>         case FILE_CHECK:
> -       default:
> +       case POST_SETATTR:
>                 return IMA_FILE_APPRAISE;
> +       case MODULE_CHECK ... MAX_CHECK - 1:
> +       default:
> +               return IMA_READ_APPRAISE;
>         }
>  }
>
> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> index 9a0ea4c..c7a111c 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -45,18 +45,12 @@
>  #define IMA_MMAP_APPRAISED     0x00000800
>  #define IMA_BPRM_APPRAISE      0x00001000
>  #define IMA_BPRM_APPRAISED     0x00002000
> -#define IMA_MODULE_APPRAISE    0x00004000
> -#define IMA_MODULE_APPRAISED   0x00008000
> -#define IMA_FIRMWARE_APPRAISE  0x00010000
> -#define IMA_FIRMWARE_APPRAISED 0x00020000
> -#define IMA_READ_APPRAISE      0x00040000
> -#define IMA_READ_APPRAISED     0x00080000
> +#define IMA_READ_APPRAISE      0x00004000
> +#define IMA_READ_APPRAISED     0x00008000
>  #define IMA_APPRAISE_SUBMASK   (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
> -                                IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \
> -                                IMA_FIRMWARE_APPRAISE | IMA_READ_APPRAISE)
> +                                IMA_BPRM_APPRAISE | IMA_READ_APPRAISE)
>  #define IMA_APPRAISED_SUBMASK  (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
> -                                IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \
> -                                IMA_FIRMWARE_APPRAISED | IMA_READ_APPRAISED)
> +                                IMA_BPRM_APPRAISED | IMA_READ_APPRAISED)
>
>  enum evm_ima_xattr_type {
>         IMA_XATTR_DIGEST = 0x01,
> @@ -111,8 +105,6 @@ struct integrity_iint_cache {
>         enum integrity_status ima_file_status:4;
>         enum integrity_status ima_mmap_status:4;
>         enum integrity_status ima_bprm_status:4;
> -       enum integrity_status ima_module_status:4;
> -       enum integrity_status ima_firmware_status:4;
>         enum integrity_status ima_read_status:4;
>         enum integrity_status evm_status:4;
>         struct ima_digest_data *ima_hash;
> --
> 2.1.0
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 21/22] ima: measure and appraise the IMA policy itself
  2016-02-03 19:06 ` [PATCH v3 21/22] ima: measure and appraise the IMA policy itself Mimi Zohar
  2016-02-07 20:01   ` Petko Manolov
@ 2016-02-10 20:22   ` Dmitry Kasatkin
  2016-02-10 23:15     ` Mimi Zohar
  1 sibling, 1 reply; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-10 20:22 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Add support for measuring and appraising the IMA policy itself.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>

But from Documentation/CodingStyle

if (condition)
    do_this();
else
    do_that();

This does not apply if only one branch of a conditional statement is a single
statement; in the latter case use braces in both branches:

if (condition) {
     do_this();
     do_that();
} else {
     otherwise();
}


You have similar issue in other patches as well...

Dmitry

> ---
>  security/integrity/ima/ima.h        |  2 ++
>  security/integrity/ima/ima_fs.c     |  9 ++++++++-
>  security/integrity/ima/ima_main.c   |  3 +++
>  security/integrity/ima/ima_policy.c | 10 +++++++++-
>  4 files changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 832e62a..6685968 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -149,6 +149,7 @@ enum ima_hooks {
>         FIRMWARE_CHECK,
>         KEXEC_CHECK,
>         INITRAMFS_CHECK,
> +       POLICY_CHECK,
>         MAX_CHECK
>  };
>
> @@ -191,6 +192,7 @@ int ima_policy_show(struct seq_file *m, void *v);
>  #define IMA_APPRAISE_LOG       0x04
>  #define IMA_APPRAISE_MODULES   0x08
>  #define IMA_APPRAISE_FIRMWARE  0x10
> +#define IMA_APPRAISE_POLICY    0x20
>
>  #ifdef CONFIG_IMA_APPRAISE
>  int ima_appraise_measurement(enum ima_hooks func,
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 00ccd67..7b15e80 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -325,7 +325,14 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
>
>         if (data[0] == '/')
>                 result = ima_read_policy(data);
> -       else
> +       else if (ima_appraise & IMA_APPRAISE_POLICY) {
> +               pr_err("IMA: signed policy 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);
>         mutex_unlock(&ima_write_mutex);
>  out_free:
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index ccf9526..497a6f2 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -386,6 +386,9 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>         case READING_KEXEC_INITRAMFS:
>                 func = INITRAMFS_CHECK;
>                 break;
> +       case READING_POLICY:
> +               func = POLICY_CHECK;
> +               break;
>         default:
>                 func = FILE_CHECK;
>                 break;
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index d02560e..39a811a 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -114,6 +114,7 @@ static struct ima_rule_entry default_measurement_rules[] = {
>          .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID},
>         {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
>         {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
> +       {.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC},
>  };
>
>  static struct ima_rule_entry default_appraise_rules[] = {
> @@ -616,6 +617,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>                                 entry->func = KEXEC_CHECK;
>                         else if (strcmp(args[0].from, "INITRAMFS_CHECK") == 0)
>                                 entry->func = INITRAMFS_CHECK;
> +                       else if (strcmp(args[0].from, "POLICY_CHECK") == 0)
> +                               entry->func = POLICY_CHECK;
>                         else
>                                 result = -EINVAL;
>                         if (!result)
> @@ -774,6 +777,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>                 temp_ima_appraise |= IMA_APPRAISE_MODULES;
>         else if (entry->func == FIRMWARE_CHECK)
>                 temp_ima_appraise |= IMA_APPRAISE_FIRMWARE;
> +       else if (entry->func == POLICY_CHECK)
> +               temp_ima_appraise |= IMA_APPRAISE_POLICY;
>         audit_log_format(ab, "res=%d", !result);
>         audit_log_end(ab);
>         return result;
> @@ -860,7 +865,7 @@ static char *mask_tokens[] = {
>  enum {
>         func_file = 0, func_mmap, func_bprm,
>         func_module, func_firmware, func_post,
> -       func_kexec, func_initramfs
> +       func_kexec, func_initramfs, func_policy
>  };
>
>  static char *func_tokens[] = {
> @@ -940,6 +945,9 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
>         case INITRAMFS_CHECK:
>                 seq_printf(m, pt(Opt_func), ft(func_initramfs));
>                 break;
> +       case POLICY_CHECK:
> +               seq_printf(m, pt(Opt_func), ft(func_policy));
> +               break;
>         default:
>                 snprintf(tbuf, sizeof(tbuf), "%d", func);
>                 seq_printf(m, pt(Opt_func), tbuf);
> --
> 2.1.0
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 22/22] ima: require signed IMA policy
  2016-02-03 19:06 ` [PATCH v3 22/22] ima: require signed IMA policy Mimi Zohar
  2016-02-07 20:02   ` Petko Manolov
@ 2016-02-10 20:24   ` Dmitry Kasatkin
  1 sibling, 0 replies; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-10 20:24 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Require the IMA policy to be signed when additional rules can be added.
>
> v1:
> - initialize the policy flag
> - include IMA_APPRAISE_POLICY in the policy flag
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>

> ---
>  security/integrity/ima/ima_policy.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index 39a811a..ba0f6dc 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -129,6 +129,10 @@ static struct ima_rule_entry default_appraise_rules[] = {
>         {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
>         {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
>         {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
> +#ifdef CONFIG_IMA_WRITE_POLICY
> +       {.action = APPRAISE, .func = POLICY_CHECK,
> +       .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
> +#endif
>  #ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT
>         {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER},
>  #else
> @@ -412,9 +416,12 @@ void __init ima_init_policy(void)
>         for (i = 0; i < appraise_entries; i++) {
>                 list_add_tail(&default_appraise_rules[i].list,
>                               &ima_default_rules);
> +               if (default_appraise_rules[i].func == POLICY_CHECK)
> +                       temp_ima_appraise |= IMA_APPRAISE_POLICY;
>         }
>
>         ima_rules = &ima_default_rules;
> +       ima_update_policy_flag();
>  }
>
>  /* Make sure we have a valid policy, at least containing some rules. */
> --
> 2.1.0
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 11/22] ima: define a new hook to measure and appraise a file already in memory
  2016-02-03 19:06 ` [PATCH v3 11/22] ima: define a new hook to measure and appraise a file already in memory Mimi Zohar
@ 2016-02-10 20:27   ` Dmitry Kasatkin
  0 siblings, 0 replies; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-10 20:27 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> This patch defines a new IMA hook ima_post_read_file() for measuring
> and appraising files read by the kernel. The caller loads the file into
> memory before calling this function, which calculates the hash followed by
> the normal IMA policy based processing.
>
> Changelog v3:
> - rename ima_hash_and_process_file() to ima_post_read_file()
>
> v1:
> - To simplify patch review, separate the IMA changes from the kexec
> and initramfs changes in "ima: measure and appraise kexec image and
> initramfs" patch.  This patch contains just the IMA changes.  The
> kexec and initramfs changes are with the rest of the kexec changes
> in "kexec: replace call to copy_file_from_fd() with kernel version".
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>

> ---
>  include/linux/ima.h                   |  8 +++++++
>  include/linux/security.h              |  1 +
>  security/integrity/ima/ima.h          |  4 +++-
>  security/integrity/ima/ima_api.c      |  6 +++--
>  security/integrity/ima/ima_appraise.c |  2 +-
>  security/integrity/ima/ima_main.c     | 45 ++++++++++++++++++++++++++++-------
>  security/integrity/ima/ima_policy.c   |  1 +
>  security/integrity/integrity.h        |  7 ++++--
>  security/security.c                   |  7 +++++-
>  9 files changed, 66 insertions(+), 15 deletions(-)
>
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 120ccc5..d29a6a2 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -20,6 +20,8 @@ extern void ima_file_free(struct file *file);
>  extern int ima_file_mmap(struct file *file, unsigned long prot);
>  extern int ima_module_check(struct file *file);
>  extern int ima_fw_from_file(struct file *file, char *buf, size_t size);
> +extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
> +                             enum kernel_read_file_id id);
>
>  #else
>  static inline int ima_bprm_check(struct linux_binprm *bprm)
> @@ -52,6 +54,12 @@ static inline int ima_fw_from_file(struct file *file, char *buf, size_t size)
>         return 0;
>  }
>
> +static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
> +                                    enum kernel_read_file_id id)
> +{
> +       return 0;
> +}
> +
>  #endif /* CONFIG_IMA */
>
>  #ifdef CONFIG_IMA_APPRAISE
> diff --git a/include/linux/security.h b/include/linux/security.h
> index b68ce94..d920718 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -24,6 +24,7 @@
>
>  #include <linux/key.h>
>  #include <linux/capability.h>
> +#include <linux/fs.h>
>  #include <linux/slab.h>
>  #include <linux/err.h>
>  #include <linux/string.h>
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 2c5262f..0b7134c 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -19,6 +19,7 @@
>
>  #include <linux/types.h>
>  #include <linux/crypto.h>
> +#include <linux/fs.h>
>  #include <linux/security.h>
>  #include <linux/hash.h>
>  #include <linux/tpm.h>
> @@ -152,7 +153,8 @@ enum ima_hooks {
>  int ima_get_action(struct inode *inode, int mask, enum ima_hooks func);
>  int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
>  int ima_collect_measurement(struct integrity_iint_cache *iint,
> -                           struct file *file, enum hash_algo algo);
> +                           struct file *file, void *buf, loff_t size,
> +                           enum hash_algo algo);
>  void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
>                            const unsigned char *filename,
>                            struct evm_ima_xattr_data *xattr_value,
> diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
> index 8750254..370e42d 100644
> --- a/security/integrity/ima/ima_api.c
> +++ b/security/integrity/ima/ima_api.c
> @@ -188,7 +188,8 @@ int ima_get_action(struct inode *inode, int mask, enum ima_hooks func)
>   * Return 0 on success, error code otherwise
>   */
>  int ima_collect_measurement(struct integrity_iint_cache *iint,
> -                           struct file *file, enum hash_algo algo)
> +                           struct file *file, void *buf, loff_t size,
> +                           enum hash_algo algo)
>  {
>         const char *audit_cause = "failed";
>         struct inode *inode = file_inode(file);
> @@ -210,7 +211,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
>
>                 hash.hdr.algo = algo;
>
> -               result = ima_calc_file_hash(file, &hash.hdr);
> +               result = (!buf) ?  ima_calc_file_hash(file, &hash.hdr) :
> +                       ima_calc_buffer_hash(buf, size, &hash.hdr);
>                 if (!result) {
>                         int length = sizeof(hash.hdr) + hash.hdr.length;
>                         void *tmpbuf = krealloc(iint->ima_hash, length,
> diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> index 2888449..cb0d0ff 100644
> --- a/security/integrity/ima/ima_appraise.c
> +++ b/security/integrity/ima/ima_appraise.c
> @@ -300,7 +300,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
>         if (iint->flags & IMA_DIGSIG)
>                 return;
>
> -       rc = ima_collect_measurement(iint, file, ima_hash_algo);
> +       rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo);
>         if (rc < 0)
>                 return;
>
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 78a80c8..bead94b 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -153,8 +153,8 @@ void ima_file_free(struct file *file)
>         ima_check_last_writer(iint, inode, file);
>  }
>
> -static int process_measurement(struct file *file, int mask,
> -                              enum ima_hooks func, int opened)
> +static int process_measurement(struct file *file, char *buf, loff_t size,
> +                              int mask, enum ima_hooks func, int opened)
>  {
>         struct inode *inode = file_inode(file);
>         struct integrity_iint_cache *iint = NULL;
> @@ -226,7 +226,7 @@ static int process_measurement(struct file *file, int mask,
>
>         hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
>
> -       rc = ima_collect_measurement(iint, file, hash_algo);
> +       rc = ima_collect_measurement(iint, file, buf, size, hash_algo);
>         if (rc != 0) {
>                 if (file->f_flags & O_DIRECT)
>                         rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
> @@ -273,7 +273,8 @@ out:
>  int ima_file_mmap(struct file *file, unsigned long prot)
>  {
>         if (file && (prot & PROT_EXEC))
> -               return process_measurement(file, MAY_EXEC, MMAP_CHECK, 0);
> +               return process_measurement(file, NULL, 0, MAY_EXEC,
> +                                          MMAP_CHECK, 0);
>         return 0;
>  }
>
> @@ -292,7 +293,8 @@ int ima_file_mmap(struct file *file, unsigned long prot)
>   */
>  int ima_bprm_check(struct linux_binprm *bprm)
>  {
> -       return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, 0);
> +       return process_measurement(bprm->file, NULL, 0, MAY_EXEC,
> +                                  BPRM_CHECK, 0);
>  }
>
>  /**
> @@ -307,7 +309,7 @@ int ima_bprm_check(struct linux_binprm *bprm)
>   */
>  int ima_file_check(struct file *file, int mask, int opened)
>  {
> -       return process_measurement(file,
> +       return process_measurement(file, NULL, 0,
>                                    mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
>                                    FILE_CHECK, opened);
>  }
> @@ -332,7 +334,7 @@ int ima_module_check(struct file *file)
>  #endif
>                 return 0;       /* We rely on module signature checking */
>         }
> -       return process_measurement(file, MAY_EXEC, MODULE_CHECK, 0);
> +       return process_measurement(file, NULL, 0, MAY_EXEC, MODULE_CHECK, 0);
>  }
>
>  int ima_fw_from_file(struct file *file, char *buf, size_t size)
> @@ -343,7 +345,34 @@ int ima_fw_from_file(struct file *file, char *buf, size_t size)
>                         return -EACCES; /* INTEGRITY_UNKNOWN */
>                 return 0;
>         }
> -       return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, 0);
> +       return process_measurement(file, NULL, 0, MAY_EXEC, FIRMWARE_CHECK, 0);
> +}
> +
> +/**
> + * ima_post_read_file - in memory collect/appraise/audit measurement
> + * @file: pointer to the file to be measured/appraised/audit
> + * @buf: pointer to in memory file contents
> + * @size: size of in memory file contents
> + * @read_id: caller identifier
> + *
> + * Measure/appraise/audit in memory file based on policy.  Policy rules
> + * are written in terms of a policy identifier.
> + *
> + * On success return 0.  On integrity appraisal error, assuming the file
> + * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
> + */
> +int ima_post_read_file(struct file *file, void *buf, loff_t size,
> +                      enum kernel_read_file_id read_id)
> +{
> +       enum ima_hooks func = FILE_CHECK;
> +
> +       if (!file && (!buf || size == 0)) { /* should never happen */
> +               if (ima_appraise & IMA_APPRAISE_ENFORCE)
> +                       return -EACCES;
> +               return 0;
> +       }
> +
> +       return process_measurement(file, buf, size, MAY_READ, func, 0);
>  }
>
>  static int __init init_ima(void)
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index b089ebe..cfbe86f 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -12,6 +12,7 @@
>   */
>  #include <linux/module.h>
>  #include <linux/list.h>
> +#include <linux/fs.h>
>  #include <linux/security.h>
>  #include <linux/magic.h>
>  #include <linux/parser.h>
> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> index 5efe2ec..9a0ea4c 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -49,12 +49,14 @@
>  #define IMA_MODULE_APPRAISED   0x00008000
>  #define IMA_FIRMWARE_APPRAISE  0x00010000
>  #define IMA_FIRMWARE_APPRAISED 0x00020000
> +#define IMA_READ_APPRAISE      0x00040000
> +#define IMA_READ_APPRAISED     0x00080000
>  #define IMA_APPRAISE_SUBMASK   (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
>                                  IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \
> -                                IMA_FIRMWARE_APPRAISE)
> +                                IMA_FIRMWARE_APPRAISE | IMA_READ_APPRAISE)
>  #define IMA_APPRAISED_SUBMASK  (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
>                                  IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \
> -                                IMA_FIRMWARE_APPRAISED)
> +                                IMA_FIRMWARE_APPRAISED | IMA_READ_APPRAISED)
>
>  enum evm_ima_xattr_type {
>         IMA_XATTR_DIGEST = 0x01,
> @@ -111,6 +113,7 @@ struct integrity_iint_cache {
>         enum integrity_status ima_bprm_status:4;
>         enum integrity_status ima_module_status:4;
>         enum integrity_status ima_firmware_status:4;
> +       enum integrity_status ima_read_status:4;
>         enum integrity_status evm_status:4;
>         struct ima_digest_data *ima_hash;
>  };
> diff --git a/security/security.c b/security/security.c
> index 796a261..ad87e8d 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -913,7 +913,12 @@ int security_kernel_module_from_file(struct file *file)
>  int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
>                                    enum kernel_read_file_id id)
>  {
> -       return call_int_hook(kernel_post_read_file, 0, file, buf, size, id);
> +       int ret;
> +
> +       ret = call_int_hook(kernel_post_read_file, 0, file, buf, size, id);
> +       if (ret)
> +               return ret;
> +       return ima_post_read_file(file, buf, size, id);
>  }
>
>  int security_task_fix_setuid(struct cred *new, const struct cred *old,
> --
> 2.1.0
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-03 19:06 ` [PATCH v3 19/22] ima: support for kexec image and initramfs Mimi Zohar
  2016-02-07 20:10   ` Petko Manolov
@ 2016-02-10 21:09   ` Dmitry Kasatkin
  2016-02-10 23:21     ` Mimi Zohar
  2016-02-12 12:53   ` Dave Young
  2 siblings, 1 reply; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-10 21:09 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> Add IMA policy support for measuring/appraising the kexec image and
> initramfs.
>
> Moving the enumeration to the vfs layer simplified the patches, allowing
> the IMA changes, for the most part, to be separated from the other
> changes.  Unfortunately, passing either a kernel_read_file_id or a
> ima_hooks enumeration within IMA is messy.
>
> Option 1: duplicate kernel_read_file enumeration in ima_hooks
>
> enum kernel_read_file_id {
>         ...
>         READING_KEXEC_IMAGE,
>         READING_KEXEC_INITRAMFS,
>         READING_MAX_ID
>
> enum ima_hooks {
>         ...
>         KEXEC_CHECK
>         INITRAMFS_CHECK
>
> Option 2: define ima_hooks as extension of kernel_read_file
> eg: enum ima_hooks {
>         FILE_CHECK = READING_MAX_ID,
>         MMAP_CHECK,
>
> In order to pass both kernel_read_file_id and ima_hooks values, we
> would need to specify a struct containing a union.
>
> struct caller_id {
>         union {
>                 enum ima_hooks func_id;
>                 enum kernel_read_file_id read_id;
>         };
> };
>
> Option 3: incorportate the ima_hooks enumeration into kernel_read_file_id,
> perhaps changing the enumeration name.
>
> For now, duplicate the new READING_KEXEC_IMAGE/INITRAMFS in ima_hooks.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> ---
>  Documentation/ABI/testing/ima_policy |  2 +-
>  security/integrity/ima/ima.h         |  2 ++
>  security/integrity/ima/ima_main.c    | 19 ++++++++++++++++---
>  security/integrity/ima/ima_policy.c  | 13 ++++++++++++-
>  4 files changed, 31 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
> index 0a378a8..e80f767 100644
> --- a/Documentation/ABI/testing/ima_policy
> +++ b/Documentation/ABI/testing/ima_policy
> @@ -26,7 +26,7 @@ Description:
>                         option: [[appraise_type=]] [permit_directio]
>
>                 base:   func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
> -                               [FIRMWARE_CHECK]
> +                               [FIRMWARE_CHECK] [KEXEC_CHECK] [INITRAMFS_CHECK]
>                         mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
>                                [[^]MAY_EXEC]
>                         fsmagic:= hex value
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index a5d2592..832e62a 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -147,6 +147,8 @@ enum ima_hooks {
>         POST_SETATTR,
>         MODULE_CHECK,
>         FIRMWARE_CHECK,
> +       KEXEC_CHECK,
> +       INITRAMFS_CHECK,
>         MAX_CHECK
>  };
>
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 1e91d94..ccf9526 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -355,7 +355,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
>  int ima_post_read_file(struct file *file, void *buf, loff_t size,
>                        enum kernel_read_file_id read_id)
>  {
> -       enum ima_hooks func = FILE_CHECK;
> +       enum ima_hooks func;
>
>         if (!file && read_id == READING_FIRMWARE) {
>                 if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
> @@ -373,10 +373,23 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>                 return 0;
>         }
>
> -       if (read_id == READING_FIRMWARE)
> +       switch (read_id) {
> +       case READING_FIRMWARE:
>                 func = FIRMWARE_CHECK;
> -       else if (read_id == READING_MODULE)
> +               break;
> +       case READING_MODULE:
>                 func = MODULE_CHECK;
> +               break;
> +       case READING_KEXEC_IMAGE:
> +               func = KEXEC_CHECK;
> +               break;
> +       case READING_KEXEC_INITRAMFS:
> +               func = INITRAMFS_CHECK;
> +               break;
> +       default:
> +               func = FILE_CHECK;
> +               break;
> +       }
>

I would define a separate function like "int ima_read_id_to_func(id)"
which search over the map

Something like...

struct
{
     int id;
     int func;
}  map[] = {
  { .id = READING_FIRMWARE, .fun = FIRMWARE_CHECK },
   ...
  { -1, 0 }
};

Dmitry


>         return process_measurement(file, buf, size, MAY_READ, func, 0);
>  }
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index 7571ce8..d02560e 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -612,6 +612,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>                                 entry->func = MMAP_CHECK;
>                         else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
>                                 entry->func = BPRM_CHECK;
> +                       else if (strcmp(args[0].from, "KEXEC_CHECK") == 0)
> +                               entry->func = KEXEC_CHECK;
> +                       else if (strcmp(args[0].from, "INITRAMFS_CHECK") == 0)
> +                               entry->func = INITRAMFS_CHECK;
>                         else
>                                 result = -EINVAL;
>                         if (!result)
> @@ -855,7 +859,8 @@ static char *mask_tokens[] = {
>
>  enum {
>         func_file = 0, func_mmap, func_bprm,
> -       func_module, func_firmware, func_post
> +       func_module, func_firmware, func_post,
> +       func_kexec, func_initramfs
>  };
>
>  static char *func_tokens[] = {
> @@ -929,6 +934,12 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
>         case POST_SETATTR:
>                 seq_printf(m, pt(Opt_func), ft(func_post));
>                 break;
> +       case KEXEC_CHECK:
> +               seq_printf(m, pt(Opt_func), ft(func_kexec));
> +               break;
> +       case INITRAMFS_CHECK:
> +               seq_printf(m, pt(Opt_func), ft(func_initramfs));
> +               break;
>         default:
>                 snprintf(tbuf, sizeof(tbuf), "%d", func);
>                 seq_printf(m, pt(Opt_func), tbuf);
> --
> 2.1.0
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 17/22] ima: remove firmware and module specific cached status info
  2016-02-10 20:18   ` Dmitry Kasatkin
@ 2016-02-10 23:14     ` Mimi Zohar
  0 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-10 23:14 UTC (permalink / raw)
  To: Dmitry Kasatkin
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, 2016-02-10 at 22:18 +0200, Dmitry Kasatkin wrote:

> > diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> > index cb0d0ff..6b4694a 100644
> > --- a/security/integrity/ima/ima_appraise.c
> > +++ b/security/integrity/ima/ima_appraise.c
> > @@ -74,13 +74,12 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
> >                 return iint->ima_mmap_status;
> >         case BPRM_CHECK:
> >                 return iint->ima_bprm_status;
> > -       case MODULE_CHECK:
> > -               return iint->ima_module_status;
> > -       case FIRMWARE_CHECK:
> > -               return iint->ima_firmware_status;
> >         case FILE_CHECK:
> > -       default:
> > +       case POST_SETATTR:
> >                 return iint->ima_file_status;
> > +       case MODULE_CHECK ... MAX_CHECK - 1:
> 
> Will LLVM clang handles this range?
> 
> Otherwise it can be just like:
> 
> case MODULE_CHECK ... MAX_CHECK :

Yes, my test program compiled fine with clang.  Similar usage exists in
the kernel (eg. fs/afs/callback.c).

Mimi


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

* Re: [PATCH v3 21/22] ima: measure and appraise the IMA policy itself
  2016-02-10 20:22   ` Dmitry Kasatkin
@ 2016-02-10 23:15     ` Mimi Zohar
  0 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-10 23:15 UTC (permalink / raw)
  To: Dmitry Kasatkin
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, 2016-02-10 at 22:22 +0200, Dmitry Kasatkin wrote:
> On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> > Add support for measuring and appraising the IMA policy itself.
> >
> > Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> 
> Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
> 
> But from Documentation/CodingStyle
> 
> if (condition)
>     do_this();
> else
>     do_that();
> 
> This does not apply if only one branch of a conditional statement is a single
> statement; in the latter case use braces in both branches:
> 
> if (condition) {
>      do_this();
>      do_that();
> } else {
>      otherwise();
> }
> 
> 
> You have similar issue in other patches as well...
> 
> Dmitry

Ok, I'll find and fix them.  Thank you for the review!

Mimi


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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-10 21:09   ` Dmitry Kasatkin
@ 2016-02-10 23:21     ` Mimi Zohar
       [not found]       ` <CACE9dm8OJ1cgbKszUG-pCiEMVarUFLLWi_jewVV-JEMGAJsA-g@mail.gmail.com>
  0 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-10 23:21 UTC (permalink / raw)
  To: Dmitry Kasatkin
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Eric Biederman, Rusty Russell

On Wed, 2016-02-10 at 23:09 +0200, Dmitry Kasatkin wrote:
> On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> > Add IMA policy support for measuring/appraising the kexec image and
> > initramfs.
> >
> > Moving the enumeration to the vfs layer simplified the patches, allowing
> > the IMA changes, for the most part, to be separated from the other
> > changes.  Unfortunately, passing either a kernel_read_file_id or a
> > ima_hooks enumeration within IMA is messy.
> >
> > Option 1: duplicate kernel_read_file enumeration in ima_hooks
> >
> > enum kernel_read_file_id {
> >         ...
> >         READING_KEXEC_IMAGE,
> >         READING_KEXEC_INITRAMFS,
> >         READING_MAX_ID
> >
> > enum ima_hooks {
> >         ...
> >         KEXEC_CHECK
> >         INITRAMFS_CHECK
> >
> > Option 2: define ima_hooks as extension of kernel_read_file
> > eg: enum ima_hooks {
> >         FILE_CHECK = READING_MAX_ID,
> >         MMAP_CHECK,
> >
> > In order to pass both kernel_read_file_id and ima_hooks values, we
> > would need to specify a struct containing a union.
> >
> > struct caller_id {
> >         union {
> >                 enum ima_hooks func_id;
> >                 enum kernel_read_file_id read_id;
> >         };
> > };
> >
> > Option 3: incorportate the ima_hooks enumeration into kernel_read_file_id,
> > perhaps changing the enumeration name.
> >
> > For now, duplicate the new READING_KEXEC_IMAGE/INITRAMFS in ima_hooks.
> >
> > Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> > ---
> >  Documentation/ABI/testing/ima_policy |  2 +-
> >  security/integrity/ima/ima.h         |  2 ++
> >  security/integrity/ima/ima_main.c    | 19 ++++++++++++++++---
> >  security/integrity/ima/ima_policy.c  | 13 ++++++++++++-
> >  4 files changed, 31 insertions(+), 5 deletions(-)
> >
> > diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
> > index 0a378a8..e80f767 100644
> > --- a/Documentation/ABI/testing/ima_policy
> > +++ b/Documentation/ABI/testing/ima_policy
> > @@ -26,7 +26,7 @@ Description:
> >                         option: [[appraise_type=]] [permit_directio]
> >
> >                 base:   func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
> > -                               [FIRMWARE_CHECK]
> > +                               [FIRMWARE_CHECK] [KEXEC_CHECK] [INITRAMFS_CHECK]
> >                         mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
> >                                [[^]MAY_EXEC]
> >                         fsmagic:= hex value
> > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> > index a5d2592..832e62a 100644
> > --- a/security/integrity/ima/ima.h
> > +++ b/security/integrity/ima/ima.h
> > @@ -147,6 +147,8 @@ enum ima_hooks {
> >         POST_SETATTR,
> >         MODULE_CHECK,
> >         FIRMWARE_CHECK,
> > +       KEXEC_CHECK,
> > +       INITRAMFS_CHECK,
> >         MAX_CHECK
> >  };
> >
> > diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> > index 1e91d94..ccf9526 100644
> > --- a/security/integrity/ima/ima_main.c
> > +++ b/security/integrity/ima/ima_main.c
> > @@ -355,7 +355,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
> >  int ima_post_read_file(struct file *file, void *buf, loff_t size,
> >                        enum kernel_read_file_id read_id)
> >  {
> > -       enum ima_hooks func = FILE_CHECK;
> > +       enum ima_hooks func;
> >
> >         if (!file && read_id == READING_FIRMWARE) {
> >                 if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
> > @@ -373,10 +373,23 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
> >                 return 0;
> >         }
> >
> > -       if (read_id == READING_FIRMWARE)
> > +       switch (read_id) {
> > +       case READING_FIRMWARE:
> >                 func = FIRMWARE_CHECK;
> > -       else if (read_id == READING_MODULE)
> > +               break;
> > +       case READING_MODULE:
> >                 func = MODULE_CHECK;
> > +               break;
> > +       case READING_KEXEC_IMAGE:
> > +               func = KEXEC_CHECK;
> > +               break;
> > +       case READING_KEXEC_INITRAMFS:
> > +               func = INITRAMFS_CHECK;
> > +               break;
> > +       default:
> > +               func = FILE_CHECK;
> > +               break;
> > +       }
> >
> 
> I would define a separate function like "int ima_read_id_to_func(id)"
> which search over the map
> 
> Something like...
> 
> struct
> {
>      int id;
>      int func;
> }  map[] = {
>   { .id = READING_FIRMWARE, .fun = FIRMWARE_CHECK },
>    ...
>   { -1, 0 }
> };
> 

So we stay with the duplication (option 1), but clean it up.  That works
for me.

Mimi


> >         return process_measurement(file, buf, size, MAY_READ, func, 0);
> >  }
> > diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> > index 7571ce8..d02560e 100644
> > --- a/security/integrity/ima/ima_policy.c
> > +++ b/security/integrity/ima/ima_policy.c
> > @@ -612,6 +612,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
> >                                 entry->func = MMAP_CHECK;
> >                         else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
> >                                 entry->func = BPRM_CHECK;
> > +                       else if (strcmp(args[0].from, "KEXEC_CHECK") == 0)
> > +                               entry->func = KEXEC_CHECK;
> > +                       else if (strcmp(args[0].from, "INITRAMFS_CHECK") == 0)
> > +                               entry->func = INITRAMFS_CHECK;
> >                         else
> >                                 result = -EINVAL;
> >                         if (!result)
> > @@ -855,7 +859,8 @@ static char *mask_tokens[] = {
> >
> >  enum {
> >         func_file = 0, func_mmap, func_bprm,
> > -       func_module, func_firmware, func_post
> > +       func_module, func_firmware, func_post,
> > +       func_kexec, func_initramfs
> >  };
> >
> >  static char *func_tokens[] = {
> > @@ -929,6 +934,12 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
> >         case POST_SETATTR:
> >                 seq_printf(m, pt(Opt_func), ft(func_post));
> >                 break;
> > +       case KEXEC_CHECK:
> > +               seq_printf(m, pt(Opt_func), ft(func_kexec));
> > +               break;
> > +       case INITRAMFS_CHECK:
> > +               seq_printf(m, pt(Opt_func), ft(func_initramfs));
> > +               break;
> >         default:
> >                 snprintf(tbuf, sizeof(tbuf), "%d", func);
> >                 seq_printf(m, pt(Opt_func), tbuf);
> > --
> > 2.1.0
> >
> 
> 
> 



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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
       [not found]       ` <CACE9dm8OJ1cgbKszUG-pCiEMVarUFLLWi_jewVV-JEMGAJsA-g@mail.gmail.com>
@ 2016-02-11  2:08         ` Mimi Zohar
  2016-02-11  8:47           ` Dmitry Kasatkin
  0 siblings, 1 reply; 77+ messages in thread
From: Mimi Zohar @ 2016-02-11  2:08 UTC (permalink / raw)
  To: Dmitry Kasatkin
  Cc: linux-security-module, Eric W. Biederman, David Woodhouse,
	Kees Cook, kexec, linux-modules, Rusty Russell, David Howells,
	fsdevel, Dmitry Torokhov, Luis R. Rodriguez

On Thu, 2016-02-11 at 01:55 +0200, Dmitry Kasatkin wrote:
> On Feb 11, 2016 1:22 AM, "Mimi Zohar" <zohar@linux.vnet.ibm.com> wrote:
> >
> > On Wed, 2016-02-10 at 23:09 +0200, Dmitry Kasatkin wrote:
> > > On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com>
> wrote:

> > > >
> > > > -       if (read_id == READING_FIRMWARE)
> > > > +       switch (read_id) {
> > > > +       case READING_FIRMWARE:
> > > >                 func = FIRMWARE_CHECK;
> > > > -       else if (read_id == READING_MODULE)
> > > > +               break;
> > > > +       case READING_MODULE:
> > > >                 func = MODULE_CHECK;
> > > > +               break;
> > > > +       case READING_KEXEC_IMAGE:
> > > > +               func = KEXEC_CHECK;
> > > > +               break;
> > > > +       case READING_KEXEC_INITRAMFS:
> > > > +               func = INITRAMFS_CHECK;
> > > > +               break;
> > > > +       default:
> > > > +               func = FILE_CHECK;
> > > > +               break;
> > > > +       }
> > > >
> > >
> > > I would define a separate function like "int ima_read_id_to_func(id)"
> > > which search over the map
> > >
> > > Something like...
> > >
> > > struct
> > > {
> > >      int id;
> > >      int func;
> > > }  map[] = {
> > >   { .id = READING_FIRMWARE, .fun = FIRMWARE_CHECK },
> > >    ...
> > >   { -1, 0 }
> > > };
> > >
> >
> > So we stay with the duplication (option 1), but clean it up.  That works
> > for me.
> >
> 
> Actually it may be simpler.
> Just define int idmap[MAX_ID] and assign to every id corresponding func.
> It will be quick and simple.

Unlike the ima_read_id_to_func() above or the original switch/case
statement, this method assumes the kernel_read_file_id enumeration stays
in sync with ima_hooks.  In terms of the  ima_read_id_to_func()
function, it would iterate over the map[] to find the corresponding .id,
whereas the current switch/case is a direct lookup.

Perhaps we should defer making a change for now.
  
Mimi


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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-11  2:08         ` Mimi Zohar
@ 2016-02-11  8:47           ` Dmitry Kasatkin
  2016-02-11 12:16             ` Mimi Zohar
  0 siblings, 1 reply; 77+ messages in thread
From: Dmitry Kasatkin @ 2016-02-11  8:47 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Eric W. Biederman, David Woodhouse,
	Kees Cook, kexec, linux-modules, Rusty Russell, David Howells,
	fsdevel, Dmitry Torokhov, Luis R. Rodriguez

On Thu, Feb 11, 2016 at 4:08 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
> On Thu, 2016-02-11 at 01:55 +0200, Dmitry Kasatkin wrote:
>> On Feb 11, 2016 1:22 AM, "Mimi Zohar" <zohar@linux.vnet.ibm.com> wrote:
>> >
>> > On Wed, 2016-02-10 at 23:09 +0200, Dmitry Kasatkin wrote:
>> > > On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar@linux.vnet.ibm.com>
>> wrote:
>
>> > > >
>> > > > -       if (read_id == READING_FIRMWARE)
>> > > > +       switch (read_id) {
>> > > > +       case READING_FIRMWARE:
>> > > >                 func = FIRMWARE_CHECK;
>> > > > -       else if (read_id == READING_MODULE)
>> > > > +               break;
>> > > > +       case READING_MODULE:
>> > > >                 func = MODULE_CHECK;
>> > > > +               break;
>> > > > +       case READING_KEXEC_IMAGE:
>> > > > +               func = KEXEC_CHECK;
>> > > > +               break;
>> > > > +       case READING_KEXEC_INITRAMFS:
>> > > > +               func = INITRAMFS_CHECK;
>> > > > +               break;
>> > > > +       default:
>> > > > +               func = FILE_CHECK;
>> > > > +               break;
>> > > > +       }
>> > > >
>> > >
>> > > I would define a separate function like "int ima_read_id_to_func(id)"
>> > > which search over the map
>> > >
>> > > Something like...
>> > >
>> > > struct
>> > > {
>> > >      int id;
>> > >      int func;
>> > > }  map[] = {
>> > >   { .id = READING_FIRMWARE, .fun = FIRMWARE_CHECK },
>> > >    ...
>> > >   { -1, 0 }
>> > > };
>> > >
>> >
>> > So we stay with the duplication (option 1), but clean it up.  That works
>> > for me.
>> >
>>
>> Actually it may be simpler.
>> Just define int idmap[MAX_ID] and assign to every id corresponding func.
>> It will be quick and simple.
>
> Unlike the ima_read_id_to_func() above or the original switch/case
> statement, this method assumes the kernel_read_file_id enumeration stays
> in sync with ima_hooks.

Actually not necessary. You can use array initialization by index,
then you do not need to worry about sync...

static int idmap[] = {
         [READING_FIRMWARE] = FIRMWARE_CHECK,
         [READING_MODULE] = MODULE_CHECK,
         ...
};

> In terms of the  ima_read_id_to_func()
> function, it would iterate over the map[] to find the corresponding .id,
> whereas the current switch/case is a direct lookup.
>

switch is also iteration.

Dmitry
Actually

> Perhaps we should defer making a change for now.
>
> Mimi
>



-- 
Thanks,
Dmitry

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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-11  8:47           ` Dmitry Kasatkin
@ 2016-02-11 12:16             ` Mimi Zohar
  0 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-11 12:16 UTC (permalink / raw)
  To: Dmitry Kasatkin
  Cc: linux-security-module, Eric W. Biederman, David Woodhouse,
	Kees Cook, kexec, linux-modules, Rusty Russell, David Howells,
	fsdevel, Dmitry Torokhov, Luis R. Rodriguez

On Thu, 2016-02-11 at 10:47 +0200, Dmitry Kasatkin wrote:
> On Thu, Feb 11, 2016 at 4:08 AM, Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:

> static int idmap[] = {
>          [READING_FIRMWARE] = FIRMWARE_CHECK,
>          [READING_MODULE] = MODULE_CHECK,
>          ...
> };

That works nicely, even with non-sequential ordering or missing entries.
The switch case be replaced with a single line:

func = read_idmap[read_id] == 0 ? FILE_CHECK : read_idmap[read_id]; 

Thank you!

Mimi


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

* Re: [PATCH v3 14/22] security: define kernel_read_file hook
  2016-02-03 19:06 ` [PATCH v3 14/22] security: define kernel_read_file hook Mimi Zohar
  2016-02-04 17:57   ` Kees Cook
  2016-02-04 19:54   ` Luis R. Rodriguez
@ 2016-02-11 16:54   ` Casey Schaufler
  2016-02-11 19:35     ` Mimi Zohar
  2 siblings, 1 reply; 77+ messages in thread
From: Casey Schaufler @ 2016-02-11 16:54 UTC (permalink / raw)
  To: Mimi Zohar, linux-security-module, Luis R. Rodriguez, kexec,
	linux-modules, fsdevel, David Howells, David Woodhouse,
	Kees Cook, Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman,
	Rusty Russell

On 2/3/2016 11:06 AM, Mimi Zohar wrote:
> The kernel_read_file security hook is called prior to reading the file
> into memory.
>
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Acked-by: Casey Schaufler <casey@schaufler-ca.com>

Being able to deny the read prior to performing any
real work makes a lot of sense.

> ---
>  fs/exec.c                         |  4 ++++
>  include/linux/ima.h               |  6 ++++++
>  include/linux/lsm_hooks.h         |  8 ++++++++
>  include/linux/security.h          |  7 +++++++
>  security/integrity/ima/ima_main.c | 16 ++++++++++++++++
>  security/security.c               | 12 ++++++++++++
>  6 files changed, 53 insertions(+)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index 5629958..1d39c4e 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -842,6 +842,10 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
>  	if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
>  		return -EINVAL;
>  
> +	ret = security_kernel_read_file(file, id);
> +	if (ret)
> +		return ret;
> +
>  	i_size = i_size_read(file_inode(file));
>  	if (max_size > 0 && i_size > max_size)
>  		return -EFBIG;
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 7aea486..6adcaea 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -19,6 +19,7 @@ extern int ima_file_check(struct file *file, int mask, int opened);
>  extern void ima_file_free(struct file *file);
>  extern int ima_file_mmap(struct file *file, unsigned long prot);
>  extern int ima_module_check(struct file *file);
> +extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
>  extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
>  			      enum kernel_read_file_id id);
>  
> @@ -48,6 +49,11 @@ static inline int ima_module_check(struct file *file)
>  	return 0;
>  }
>  
> +static inline int ima_read_file(struct file *file, enum kernel_read_file_id id)
> +{
> +	return 0;
> +}
> +
>  static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
>  				     enum kernel_read_file_id id)
>  {
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7d04a12..d32b7bd 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -552,6 +552,12 @@
>   *	the kernel module to load. If the module is being loaded from a blob,
>   *	this argument will be NULL.
>   *	Return 0 if permission is granted.
> + * @kernel_read_file:
> + *	Read a file specified by userspace.
> + *	@file contains the file structure pointing to the file being read
> + *	by the kernel.
> + *	@id kernel read file identifier
> + *	Return 0 if permission is granted.
>   * @kernel_post_read_file:
>   *	Read a file specified by userspace.
>   *	@file contains the file structure pointing to the file being read
> @@ -1455,6 +1461,7 @@ union security_list_options {
>  	int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
>  	int (*kernel_module_request)(char *kmod_name);
>  	int (*kernel_module_from_file)(struct file *file);
> +	int (*kernel_read_file)(struct file *file, enum kernel_read_file_id id);
>  	int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size,
>  				     enum kernel_read_file_id id);
>  	int (*task_fix_setuid)(struct cred *new, const struct cred *old,
> @@ -1715,6 +1722,7 @@ struct security_hook_heads {
>  	struct list_head cred_transfer;
>  	struct list_head kernel_act_as;
>  	struct list_head kernel_create_files_as;
> +	struct list_head kernel_read_file;
>  	struct list_head kernel_post_read_file;
>  	struct list_head kernel_module_request;
>  	struct list_head kernel_module_from_file;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index cee1349..071fb74 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -302,6 +302,7 @@ int security_kernel_act_as(struct cred *new, u32 secid);
>  int security_kernel_create_files_as(struct cred *new, struct inode *inode);
>  int security_kernel_module_request(char *kmod_name);
>  int security_kernel_module_from_file(struct file *file);
> +int security_kernel_read_file(struct file *file, enum kernel_read_file_id id);
>  int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
>  				   enum kernel_read_file_id id);
>  int security_task_fix_setuid(struct cred *new, const struct cred *old,
> @@ -863,6 +864,12 @@ static inline int security_kernel_module_from_file(struct file *file)
>  	return 0;
>  }
>  
> +static inline int security_kernel_read_file(struct file *file,
> +					    enum kernel_read_file_id id)
> +{
> +	return 0;
> +}
> +
>  static inline int security_kernel_post_read_file(struct file *file,
>  						 char *buf, loff_t size,
>  						 enum kernel_read_file_id id)
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 4a5db31..6f79bdf 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -338,6 +338,22 @@ int ima_module_check(struct file *file)
>  }
>  
>  /**
> + * ima_read_file - pre-measure/appraise hook decision based on policy
> + * @file: pointer to the file to be measured/appraised/audit
> + * @read_id: caller identifier
> + *
> + * Permit reading a file based on policy. The policy rules are written
> + * in terms of the policy identifier.  Appraising the integrity of
> + * a file requires a file descriptor.
> + *
> + * For permission return 0, otherwise return -EACCES.
> + */
> +int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
> +{
> +	return 0;
> +}
> +
> +/**
>   * ima_post_read_file - in memory collect/appraise/audit measurement
>   * @file: pointer to the file to be measured/appraised/audit
>   * @buf: pointer to in memory file contents
> diff --git a/security/security.c b/security/security.c
> index 81a4c3a..1728fe2 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -899,6 +899,16 @@ int security_kernel_module_from_file(struct file *file)
>  	return ima_module_check(file);
>  }
>  
> +int security_kernel_read_file(struct file *file, enum kernel_read_file_id id)
> +{
> +	int ret;
> +
> +	ret = call_int_hook(kernel_read_file, 0, file, id);
> +	if (ret)
> +		return ret;
> +	return ima_read_file(file, id);
> +}
> +
>  int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
>  				   enum kernel_read_file_id id)
>  {
> @@ -1695,6 +1705,8 @@ struct security_hook_heads security_hook_heads = {
>  		LIST_HEAD_INIT(security_hook_heads.kernel_module_request),
>  	.kernel_module_from_file =
>  		LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file),
> +	.kernel_read_file =
> +		LIST_HEAD_INIT(security_hook_heads.kernel_read_file),
>  	.kernel_post_read_file =
>  		LIST_HEAD_INIT(security_hook_heads.kernel_post_read_file),
>  	.task_fix_setuid =


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

* Re: [PATCH v3 14/22] security: define kernel_read_file hook
  2016-02-11 16:54   ` Casey Schaufler
@ 2016-02-11 19:35     ` Mimi Zohar
  0 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-11 19:35 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Thu, 2016-02-11 at 08:54 -0800, Casey Schaufler wrote:
> On 2/3/2016 11:06 AM, Mimi Zohar wrote:
> > The kernel_read_file security hook is called prior to reading the file
> > into memory.
> >
> > Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> 
> Acked-by: Casey Schaufler <casey@schaufler-ca.com>
> 
> Being able to deny the read prior to performing any
> real work makes a lot of sense.

Thanks, Casey!

Mimi


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

* Re: [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version
  2016-02-03 19:06 ` [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version Mimi Zohar
  2016-02-04 18:05   ` Kees Cook
  2016-02-04 19:57   ` Luis R. Rodriguez
@ 2016-02-12 12:50   ` Dave Young
  2 siblings, 0 replies; 77+ messages in thread
From: Dave Young @ 2016-02-12 12:50 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On 02/03/16 at 02:06pm, Mimi Zohar wrote:
> Replace copy_file_from_fd() with kernel_read_file_from_fd().
> 
> Two new identifiers named READING_KEXEC_IMAGE and READING_KEXEC_INITRAMFS
> are defined for measuring, appraising or auditing the kexec image and
> initramfs.
> 
> Changelog v3:
> - return -EBADF, not -ENOEXEC
> - identifier change
> - moved copy_file_from_fd() to a separate patch
> - defer support for IMA
> v1:
> - re-order and squash the kexec patches
> v0: ima: measure and appraise kexec image and initramfs (squashed)
> - rename ima_read_hooks enumeration to ima_policy_id
> - use kstat file size type loff_t, not size_t
> - add union name "hooks" to fix sparse warning
> - Calculate the file hash from the in memory buffer
> (suggested by Dave Young)
> - Rename ima_read_and_process_file() to ima_hash_and_process_file()
> - replace individual case statements with range:
>         KEXEC_CHECK ... IMA_MAX_READ_CHECK - 1
> - Instead of ima_read_and_process_file() allocating memory, the caller
> allocates and frees the memory.
> - Moved the kexec measurement/appraisal call to copy_file_from_fd(). The
> same call now measures and appraises both the kexec image and initramfs.
> 
> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> ---
>  include/linux/fs.h  |  2 ++
>  kernel/kexec_file.c | 73 +++++++----------------------------------------------
>  2 files changed, 11 insertions(+), 64 deletions(-)
> 
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 9e1f1e3..d4d556e 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2529,6 +2529,8 @@ extern int do_pipe_flags(int *, int);
>  enum kernel_read_file_id {
>  	READING_FIRMWARE = 1,
>  	READING_MODULE,
> +	READING_KEXEC_IMAGE,
> +	READING_KEXEC_INITRAMFS,
>  	READING_MAX_ID
>  };
>  
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index b70ada0..1443f93 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -18,6 +18,7 @@
>  #include <linux/kexec.h>
>  #include <linux/mutex.h>
>  #include <linux/list.h>
> +#include <linux/fs.h>
>  #include <crypto/hash.h>
>  #include <crypto/sha.h>
>  #include <linux/syscalls.h>
> @@ -33,65 +34,6 @@ size_t __weak kexec_purgatory_size = 0;
>  
>  static int kexec_calculate_store_digests(struct kimage *image);
>  
> -static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len)
> -{
> -	struct fd f = fdget(fd);
> -	int ret;
> -	struct kstat stat;
> -	loff_t pos;
> -	ssize_t bytes = 0;
> -
> -	if (!f.file)
> -		return -EBADF;
> -
> -	ret = vfs_getattr(&f.file->f_path, &stat);
> -	if (ret)
> -		goto out;
> -
> -	if (stat.size > INT_MAX) {
> -		ret = -EFBIG;
> -		goto out;
> -	}
> -
> -	/* Don't hand 0 to vmalloc, it whines. */
> -	if (stat.size == 0) {
> -		ret = -EINVAL;
> -		goto out;
> -	}
> -
> -	*buf = vmalloc(stat.size);
> -	if (!*buf) {
> -		ret = -ENOMEM;
> -		goto out;
> -	}
> -
> -	pos = 0;
> -	while (pos < stat.size) {
> -		bytes = kernel_read(f.file, pos, (char *)(*buf) + pos,
> -				    stat.size - pos);
> -		if (bytes < 0) {
> -			vfree(*buf);
> -			ret = bytes;
> -			goto out;
> -		}
> -
> -		if (bytes == 0)
> -			break;
> -		pos += bytes;
> -	}
> -
> -	if (pos != stat.size) {
> -		ret = -EBADF;
> -		vfree(*buf);
> -		goto out;
> -	}
> -
> -	*buf_len = pos;
> -out:
> -	fdput(f);
> -	return ret;
> -}
> -
>  /* Architectures can provide this probe function */
>  int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
>  					 unsigned long buf_len)
> @@ -180,16 +122,17 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>  {
>  	int ret = 0;
>  	void *ldata;
> +	loff_t size;
>  
> -	ret = copy_file_from_fd(kernel_fd, &image->kernel_buf,
> -				&image->kernel_buf_len);
> +	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
> +				       &size, INT_MAX, READING_KEXEC_IMAGE);
>  	if (ret)
>  		return ret;
> +	image->kernel_buf_len = size;
>  
>  	/* Call arch image probe handlers */
>  	ret = arch_kexec_kernel_image_probe(image, image->kernel_buf,
>  					    image->kernel_buf_len);
> -
>  	if (ret)
>  		goto out;
>  
> @@ -204,10 +147,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>  #endif
>  	/* It is possible that there no initramfs is being loaded */
>  	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
> -		ret = copy_file_from_fd(initrd_fd, &image->initrd_buf,
> -					&image->initrd_buf_len);
> +		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
> +					       &size, INT_MAX,
> +					       READING_KEXEC_INITRAMFS);
>  		if (ret)
>  			goto out;
> +		image->initrd_buf_len = size;
>  	}
>  
>  	if (cmdline_len) {

Acked-by: Dave Young <dyoung@redhat.com>

Thanks
Dave

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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-03 19:06 ` [PATCH v3 19/22] ima: support for kexec image and initramfs Mimi Zohar
  2016-02-07 20:10   ` Petko Manolov
  2016-02-10 21:09   ` Dmitry Kasatkin
@ 2016-02-12 12:53   ` Dave Young
  2016-02-12 13:09     ` Mimi Zohar
  2 siblings, 1 reply; 77+ messages in thread
From: Dave Young @ 2016-02-12 12:53 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

Hi, Mimi

> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index a5d2592..832e62a 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -147,6 +147,8 @@ enum ima_hooks {
>  	POST_SETATTR,
>  	MODULE_CHECK,
>  	FIRMWARE_CHECK,
> +	KEXEC_CHECK,
> +	INITRAMFS_CHECK,

KEXEC_CHECK is actually kexec kernel image check, INITRAMFS_CHECK is for
kexec initramfs check, they are both for checking kexec loaded files.

Do you mind a longer id like KEXEC_KERNEL_CHECK and KEXEC_INITRAMFS_CHECK?

>  	MAX_CHECK
>  };
>  

Thanks
Dave

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

* Re: [PATCH v3 19/22] ima: support for kexec image and initramfs
  2016-02-12 12:53   ` Dave Young
@ 2016-02-12 13:09     ` Mimi Zohar
  0 siblings, 0 replies; 77+ messages in thread
From: Mimi Zohar @ 2016-02-12 13:09 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-security-module, Luis R. Rodriguez, kexec, linux-modules,
	fsdevel, David Howells, David Woodhouse, Kees Cook,
	Dmitry Torokhov, Dmitry Kasatkin, Eric Biederman, Rusty Russell

On Fri, 2016-02-12 at 20:53 +0800, Dave Young wrote:
> Hi, Mimi
> 
> > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> > index a5d2592..832e62a 100644
> > --- a/security/integrity/ima/ima.h
> > +++ b/security/integrity/ima/ima.h
> > @@ -147,6 +147,8 @@ enum ima_hooks {
> >  	POST_SETATTR,
> >  	MODULE_CHECK,
> >  	FIRMWARE_CHECK,
> > +	KEXEC_CHECK,
> > +	INITRAMFS_CHECK,
> 
> KEXEC_CHECK is actually kexec kernel image check, INITRAMFS_CHECK is for
> kexec initramfs check, they are both for checking kexec loaded files.
> 
> Do you mind a longer id like KEXEC_KERNEL_CHECK and KEXEC_INITRAMFS_CHECK?

These are the IMA policy tokens.  Currently the IMA policy would include
these KEXEC rules, where "appraise_type=imasig" indicates requiring a
signature as opposed to a hash.

measure func=KEXEC_CHECK
appraise func=KEXEC_CHECK appraise_type=imasig
#
measure func=INITRAMFS_CHECK
appraise func=INITRAMFS_CHECK appraise_type=imasig

I'll change these IMA policy identifiers to the longer names you
suggested.

thanks,

Mimi

> >  	MAX_CHECK
> >  };
> >  
> 
> Thanks
> Dave



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

end of thread, back to index

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-03 19:06 [PATCH v3 00/22] vfs: support for a common kernel file loader Mimi Zohar
2016-02-03 19:06 ` [PATCH v3 01/22] ima: separate 'security.ima' reading functionality from collect Mimi Zohar
2016-02-03 19:06 ` [PATCH v3 02/22] ima: refactor ima_policy_show() to display "ima_hooks" rules Mimi Zohar
2016-02-07 19:45   ` Petko Manolov
2016-02-10 19:33   ` Dmitry Kasatkin
2016-02-03 19:06 ` [PATCH v3 03/22] ima: use "ima_hooks" enum as function argument Mimi Zohar
2016-02-07 19:46   ` Petko Manolov
2016-02-10 19:35   ` Dmitry Kasatkin
2016-02-03 19:06 ` [PATCH v3 04/22] firmware: simplify dev_*() print messages for generic helpers Mimi Zohar
2016-02-04 17:26   ` Kees Cook
2016-02-03 19:06 ` [PATCH v3 05/22] firmware: move completing fw into a helper Mimi Zohar
2016-02-04 17:27   ` Kees Cook
2016-02-03 19:06 ` [PATCH v3 06/22] firmware: fold successful fw read early Mimi Zohar
2016-02-04 17:36   ` Kees Cook
2016-02-04 20:26     ` Luis R. Rodriguez
2016-02-03 19:06 ` [PATCH v3 07/22] vfs: define a generic function to read a file from the kernel Mimi Zohar
2016-02-04 17:41   ` Kees Cook
2016-02-03 19:06 ` [PATCH v3 08/22] vfs: define kernel_read_file_id enumeration Mimi Zohar
2016-02-04 17:41   ` Kees Cook
2016-02-04 19:45   ` Luis R. Rodriguez
2016-02-03 19:06 ` [PATCH v3 09/22] ima: provide buffer hash calculation function Mimi Zohar
2016-02-03 19:06 ` [PATCH v3 10/22] ima: calculate the hash of a buffer using aynchronous hash(ahash) Mimi Zohar
2016-02-10 19:58   ` Dmitry Kasatkin
2016-02-03 19:06 ` [PATCH v3 11/22] ima: define a new hook to measure and appraise a file already in memory Mimi Zohar
2016-02-10 20:27   ` Dmitry Kasatkin
2016-02-03 19:06 ` [PATCH v3 12/22] vfs: define kernel_read_file_from_path Mimi Zohar
2016-02-04 17:46   ` Kees Cook
2016-02-04 19:47   ` Luis R. Rodriguez
2016-02-03 19:06 ` [PATCH v3 13/22] firmware: replace call to fw_read_file_contents() with kernel version Mimi Zohar
2016-02-04 17:56   ` Kees Cook
2016-02-04 19:51   ` Luis R. Rodriguez
2016-02-03 19:06 ` [PATCH v3 14/22] security: define kernel_read_file hook Mimi Zohar
2016-02-04 17:57   ` Kees Cook
2016-02-04 19:54   ` Luis R. Rodriguez
2016-02-11 16:54   ` Casey Schaufler
2016-02-11 19:35     ` Mimi Zohar
2016-02-03 19:06 ` [PATCH v3 15/22] vfs: define kernel_copy_file_from_fd() Mimi Zohar
2016-02-04 17:58   ` Kees Cook
2016-02-04 19:55   ` Luis R. Rodriguez
2016-02-03 19:06 ` [PATCH v3 16/22] module: replace copy_module_from_fd with kernel version Mimi Zohar
2016-02-04 18:04   ` Kees Cook
2016-02-04 19:56   ` Luis R. Rodriguez
2016-02-05  0:19     ` Mimi Zohar
2016-02-03 19:06 ` [PATCH v3 17/22] ima: remove firmware and module specific cached status info Mimi Zohar
2016-02-07 19:56   ` Petko Manolov
2016-02-10 20:18   ` Dmitry Kasatkin
2016-02-10 23:14     ` Mimi Zohar
2016-02-03 19:06 ` [PATCH v3 18/22] kexec: replace call to copy_file_from_fd() with kernel version Mimi Zohar
2016-02-04 18:05   ` Kees Cook
2016-02-04 19:57   ` Luis R. Rodriguez
2016-02-12 12:50   ` Dave Young
2016-02-03 19:06 ` [PATCH v3 19/22] ima: support for kexec image and initramfs Mimi Zohar
2016-02-07 20:10   ` Petko Manolov
2016-02-08 23:34     ` Mimi Zohar
2016-02-10 21:09   ` Dmitry Kasatkin
2016-02-10 23:21     ` Mimi Zohar
     [not found]       ` <CACE9dm8OJ1cgbKszUG-pCiEMVarUFLLWi_jewVV-JEMGAJsA-g@mail.gmail.com>
2016-02-11  2:08         ` Mimi Zohar
2016-02-11  8:47           ` Dmitry Kasatkin
2016-02-11 12:16             ` Mimi Zohar
2016-02-12 12:53   ` Dave Young
2016-02-12 13:09     ` Mimi Zohar
2016-02-03 19:06 ` [PATCH v3 20/22] ima: load policy using path Mimi Zohar
2016-02-07 19:59   ` Petko Manolov
2016-02-08  9:58     ` Dmitry Kasatkin
2016-02-08 10:35       ` Petko Manolov
2016-02-08 10:45         ` Dmitry Kasatkin
2016-02-08 21:12           ` Mimi Zohar
2016-02-09  7:47             ` Petko Manolov
2016-02-03 19:06 ` [PATCH v3 21/22] ima: measure and appraise the IMA policy itself Mimi Zohar
2016-02-07 20:01   ` Petko Manolov
2016-02-10 20:22   ` Dmitry Kasatkin
2016-02-10 23:15     ` Mimi Zohar
2016-02-03 19:06 ` [PATCH v3 22/22] ima: require signed IMA policy Mimi Zohar
2016-02-07 20:02   ` Petko Manolov
2016-02-10 20:24   ` Dmitry Kasatkin
2016-02-04 18:15 ` [PATCH v3 00/22] vfs: support for a common kernel file loader Kees Cook
2016-02-04 23:54   ` Mimi Zohar

Linux-Modules Archive on lore.kernel.org

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

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

Example config snippet for mirrors

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


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