linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V3 0/6] IMA: Support asking the VFS for a file hash
@ 2019-05-17 21:24 Matthew Garrett
  2019-05-17 21:24 ` [PATCH V3 1/6] VFS: Add a call to obtain a file's hash Matthew Garrett
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Matthew Garrett @ 2019-05-17 21:24 UTC (permalink / raw)
  To: linux-integrity; +Cc: zohar, dmitry.kasatkin, miklos, linux-fsdevel, viro

Updated to add a new template type and to allow templates to be
configured per-rule. This allows additional information about the source
of the hash to be provided without breaking any existing deployments.



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

* [PATCH V3 1/6] VFS: Add a call to obtain a file's hash
  2019-05-17 21:24 [PATCH V3 0/6] IMA: Support asking the VFS for a file hash Matthew Garrett
@ 2019-05-17 21:24 ` Matthew Garrett
  2019-05-18 11:25   ` kbuild test robot
  2019-05-20  7:10   ` Johannes Thumshirn
  2019-05-17 21:24 ` [PATCH V3 2/6] FUSE: Allow filesystems to provide gethash methods Matthew Garrett
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 14+ messages in thread
From: Matthew Garrett @ 2019-05-17 21:24 UTC (permalink / raw)
  To: linux-integrity
  Cc: zohar, dmitry.kasatkin, miklos, linux-fsdevel, viro, Matthew Garrett

From: Matthew Garrett <mjg59@google.com>

IMA wants to know what the hash of a file is, and currently does so by
reading the entire file and generating the hash. Some filesystems may
have the ability to store the hash in a secure manner resistant to
offline attacks (eg, filesystem-level file signing), and in that case
it's a performance win for IMA to be able to use that rather than having
to re-hash everything. This patch simply adds VFS-level support for
calling down to filesystems.

Signed-off-by: Matthew Garrett <mjg59@google.com>
---
 fs/read_write.c    | 24 ++++++++++++++++++++++++
 include/linux/fs.h |  6 +++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/fs/read_write.c b/fs/read_write.c
index 61b43ad7608e..3ba7038ba9a9 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -2157,3 +2157,27 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
 	return ret;
 }
 EXPORT_SYMBOL(vfs_dedupe_file_range);
+
+/**
+ * vfs_gethash - obtain a file's hash
+ * @file:	file structure in question
+ * @hash_algo:	the hash algorithm requested
+ * @buf:	buffer to return the hash in
+ * @size:	size allocated for the buffer by the caller
+ *
+ * This function allows filesystems that support securely storing the hash
+ * of a file to return it rather than forcing the kernel to recalculate it.
+ * Filesystems that cannot provide guarantees about the hash being resistant
+ * to offline attack should not implement this functionality.
+ *
+ * Returns 0 on success, -EOPNOTSUPP if the filesystem doesn't support it.
+ */
+int vfs_get_hash(struct file *file, enum hash_algo hash, uint8_t *buf,
+		 size_t size)
+{
+	if (!file->f_op->get_hash)
+		return -EOPNOTSUPP;
+
+	return file->f_op->get_hash(file, hash, buf, size);
+}
+EXPORT_SYMBOL(vfs_get_hash);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dd28e7679089..211f0e214953 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -43,6 +43,7 @@
 
 #include <asm/byteorder.h>
 #include <uapi/linux/fs.h>
+#include <uapi/linux/hash_info.h>
 
 struct backing_dev_info;
 struct bdi_writeback;
@@ -1822,6 +1823,8 @@ struct file_operations {
 				   struct file *file_out, loff_t pos_out,
 				   loff_t len, unsigned int remap_flags);
 	int (*fadvise)(struct file *, loff_t, loff_t, int);
+	int (*get_hash)(struct file *, enum hash_algo hash, uint8_t *buf,
+			size_t size);
 } __randomize_layout;
 
 struct inode_operations {
@@ -1898,7 +1901,8 @@ extern int vfs_dedupe_file_range(struct file *file,
 extern loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
 					struct file *dst_file, loff_t dst_pos,
 					loff_t len, unsigned int remap_flags);
-
+extern int vfs_get_hash(struct file *file, enum hash_algo hash, uint8_t *buf,
+			size_t size);
 
 struct super_operations {
    	struct inode *(*alloc_inode)(struct super_block *sb);
-- 
2.21.0.1020.gf2820cf01a-goog


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

* [PATCH V3 2/6] FUSE: Allow filesystems to provide gethash methods
  2019-05-17 21:24 [PATCH V3 0/6] IMA: Support asking the VFS for a file hash Matthew Garrett
  2019-05-17 21:24 ` [PATCH V3 1/6] VFS: Add a call to obtain a file's hash Matthew Garrett
@ 2019-05-17 21:24 ` Matthew Garrett
  2019-05-17 21:24 ` [PATCH V3 3/6] IMA: Allow rule matching on filesystem subtype Matthew Garrett
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Matthew Garrett @ 2019-05-17 21:24 UTC (permalink / raw)
  To: linux-integrity
  Cc: zohar, dmitry.kasatkin, miklos, linux-fsdevel, viro, Matthew Garrett

From: Matthew Garrett <mjg59@google.com>

FUSE implementations may have a secure way to provide file hashes (eg,
they're a front-end to a remote store that ties files to their hashes).
Allow filesystems to expose this information, but require an option to
be provided before it can be used. This is to avoid malicious users
being able to mount an unprivileged FUSE filesystem that provides
incorrect hashes.

A sufficiently malicious FUSE filesystem may still simply swap out its
contents after the hash has been obtained - this patchset does nothing
to change that, and sysadmins should have appropriate policy in place to
protect against that.

Signed-off-by: Matthew Garrett <mjg59@google.com>
---
 fs/fuse/file.c            | 33 +++++++++++++++++++++++++++++++++
 fs/fuse/fuse_i.h          |  7 +++++++
 fs/fuse/inode.c           | 15 +++++++++++++++
 include/uapi/linux/fuse.h |  6 ++++++
 4 files changed, 61 insertions(+)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 06096b60f1df..cf73c1712333 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -3156,6 +3156,38 @@ static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in,
 
 	inode_unlock(inode_out);
 
+	return err;
+};
+
+static int fuse_file_get_hash(struct file *file, enum hash_algo hash,
+			      uint8_t *buf, size_t size)
+{
+	struct fuse_file *ff = file->private_data;
+	struct fuse_conn *fc = ff->fc;
+	FUSE_ARGS(args);
+	struct fuse_gethash_in inarg;
+	int err = 0;
+
+	if (!fc->allow_gethash)
+		return -EOPNOTSUPP;
+
+	memset(&inarg, 0, sizeof(inarg));
+	inarg.size = size;
+	inarg.hash = hash;
+	args.in.h.opcode = FUSE_GETHASH;
+	args.in.h.nodeid = ff->nodeid;
+	args.in.numargs = 1;
+	args.in.args[0].size = sizeof(inarg);
+	args.in.args[0].value = &inarg;
+	args.out.numargs = 1;
+	args.out.args[0].size = size;
+	args.out.args[0].value = buf;
+
+	err = fuse_simple_request(fc, &args);
+
+	if (err == -ENOSYS)
+		err = -EOPNOTSUPP;
+
 	return err;
 }
 
@@ -3177,6 +3209,7 @@ static const struct file_operations fuse_file_operations = {
 	.poll		= fuse_file_poll,
 	.fallocate	= fuse_file_fallocate,
 	.copy_file_range = fuse_copy_file_range,
+	.get_hash	= fuse_file_get_hash,
 };
 
 static const struct address_space_operations fuse_file_aops  = {
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 0920c0c032a0..7e796eaebe38 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -714,6 +714,13 @@ struct fuse_conn {
 	/** Does the filesystem support copy_file_range? */
 	unsigned no_copy_file_range:1;
 
+	/*
+	 * Allow the underlying filesystem to the hash of a file. This is
+	 * used by IMA to avoid needing to calculate the hash on every
+	 * measurement
+	 */
+	unsigned allow_gethash:1;
+
 	/** The number of requests waiting for completion */
 	atomic_t num_waiting;
 
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index ec5d9953dfb6..845e6c48a6f4 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -70,6 +70,7 @@ struct fuse_mount_data {
 	unsigned group_id_present:1;
 	unsigned default_permissions:1;
 	unsigned allow_other:1;
+	unsigned allow_gethash:1;
 	unsigned max_read;
 	unsigned blksize;
 };
@@ -456,6 +457,7 @@ enum {
 	OPT_ALLOW_OTHER,
 	OPT_MAX_READ,
 	OPT_BLKSIZE,
+	OPT_ALLOW_GETHASH,
 	OPT_ERR
 };
 
@@ -468,6 +470,7 @@ static const match_table_t tokens = {
 	{OPT_ALLOW_OTHER,		"allow_other"},
 	{OPT_MAX_READ,			"max_read=%u"},
 	{OPT_BLKSIZE,			"blksize=%u"},
+	{OPT_ALLOW_GETHASH,		"allow_gethash"},
 	{OPT_ERR,			NULL}
 };
 
@@ -554,6 +557,15 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev,
 			d->blksize = value;
 			break;
 
+		case OPT_ALLOW_GETHASH:
+			/*
+			 * This is relevant to security decisions made in
+			 * the root namespace, so restrict it more strongly
+			 */
+			if (capable(CAP_SYS_ADMIN))
+				d->allow_gethash = 1;
+			break;
+
 		default:
 			return 0;
 		}
@@ -577,6 +589,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
 		seq_puts(m, ",default_permissions");
 	if (fc->allow_other)
 		seq_puts(m, ",allow_other");
+	if (fc->allow_gethash)
+		seq_puts(m, ",allow_gethash");
 	if (fc->max_read != ~0)
 		seq_printf(m, ",max_read=%u", fc->max_read);
 	if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE)
@@ -1167,6 +1181,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 	fc->user_id = d.user_id;
 	fc->group_id = d.group_id;
 	fc->max_read = max_t(unsigned, 4096, d.max_read);
+	fc->allow_gethash = d.allow_gethash;
 
 	/* Used by get_root_inode() */
 	sb->s_fs_info = fc;
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index 2ac598614a8f..31a2dc016a8b 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -399,6 +399,7 @@ enum fuse_opcode {
 	FUSE_RENAME2		= 45,
 	FUSE_LSEEK		= 46,
 	FUSE_COPY_FILE_RANGE	= 47,
+	FUSE_GETHASH		= 48,
 
 	/* CUSE specific operations */
 	CUSE_INIT		= 4096,
@@ -822,4 +823,9 @@ struct fuse_copy_file_range_in {
 	uint64_t	flags;
 };
 
+struct fuse_gethash_in {
+	uint32_t	size;
+	uint32_t	hash;
+};
+
 #endif /* _LINUX_FUSE_H */
-- 
2.21.0.1020.gf2820cf01a-goog


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

* [PATCH V3 3/6] IMA: Allow rule matching on filesystem subtype
  2019-05-17 21:24 [PATCH V3 0/6] IMA: Support asking the VFS for a file hash Matthew Garrett
  2019-05-17 21:24 ` [PATCH V3 1/6] VFS: Add a call to obtain a file's hash Matthew Garrett
  2019-05-17 21:24 ` [PATCH V3 2/6] FUSE: Allow filesystems to provide gethash methods Matthew Garrett
@ 2019-05-17 21:24 ` Matthew Garrett
  2019-05-17 21:24 ` [PATCH V3 4/6] IMA: Optionally make use of filesystem-provided hashes Matthew Garrett
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Matthew Garrett @ 2019-05-17 21:24 UTC (permalink / raw)
  To: linux-integrity
  Cc: zohar, dmitry.kasatkin, miklos, linux-fsdevel, viro,
	Matthew Garrett, Matthew Garrett

IMA currently allows rules to match on the filesystem type. Certain
filesystem types permit subtypes (eg, fuse). Add support to IMA to allow
rules to match on subtypes as well as types.

Signed-off-by: Matthew Garrett <mjg59@google.com>
---
 Documentation/ABI/testing/ima_policy |  4 +++-
 security/integrity/ima/ima_policy.c  | 26 +++++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 74c6702de74e..09a5def7e28a 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -21,7 +21,7 @@ Description:
 			audit | hash | dont_hash
 		condition:= base | lsm  [option]
 			base:	[[func=] [mask=] [fsmagic=] [fsuuid=] [uid=]
-				[euid=] [fowner=] [fsname=]]
+				[euid=] [fowner=] [fsname=] [subtype=]]
 			lsm:	[[subj_user=] [subj_role=] [subj_type=]
 				 [obj_user=] [obj_role=] [obj_type=]]
 			option:	[[appraise_type=]] [permit_directio]
@@ -33,6 +33,8 @@ Description:
 			       [[^]MAY_EXEC]
 			fsmagic:= hex value
 			fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
+			fsname:= file system type (e.g fuse)
+			subtype:= file system subtype (e.g ntfs3g)
 			uid:= decimal value
 			euid:= decimal value
 			fowner:= decimal value
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index e0cc323f948f..bb4e265823a7 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -35,6 +35,7 @@
 #define IMA_EUID	0x0080
 #define IMA_PCR		0x0100
 #define IMA_FSNAME	0x0200
+#define IMA_SUBTYPE	0x0400
 
 #define UNKNOWN		0
 #define MEASURE		0x0001	/* same as IMA_MEASURE */
@@ -80,6 +81,7 @@ struct ima_rule_entry {
 		int type;	/* audit type */
 	} lsm[MAX_LSM_RULES];
 	char *fsname;
+	char *subtype;
 };
 
 /*
@@ -306,6 +308,10 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
 	if ((rule->flags & IMA_FSNAME)
 	    && strcmp(rule->fsname, inode->i_sb->s_type->name))
 		return false;
+	if ((rule->flags & IMA_SUBTYPE)
+	    && (inode->i_sb->s_subtype == NULL ||
+		strcmp(rule->subtype, inode->i_sb->s_subtype)))
+		return false;
 	if ((rule->flags & IMA_FSUUID) &&
 	    !uuid_equal(&rule->fsuuid, &inode->i_sb->s_uuid))
 		return false;
@@ -670,7 +676,7 @@ enum {
 	Opt_audit, Opt_hash, Opt_dont_hash,
 	Opt_obj_user, Opt_obj_role, Opt_obj_type,
 	Opt_subj_user, Opt_subj_role, Opt_subj_type,
-	Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname,
+	Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_subtype,
 	Opt_fsuuid, Opt_uid_eq, Opt_euid_eq, Opt_fowner_eq,
 	Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
 	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
@@ -696,6 +702,7 @@ static const match_table_t policy_tokens = {
 	{Opt_mask, "mask=%s"},
 	{Opt_fsmagic, "fsmagic=%s"},
 	{Opt_fsname, "fsname=%s"},
+	{Opt_subtype, "subtype=%s"},
 	{Opt_fsuuid, "fsuuid=%s"},
 	{Opt_uid_eq, "uid=%s"},
 	{Opt_euid_eq, "euid=%s"},
@@ -921,6 +928,17 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			result = 0;
 			entry->flags |= IMA_FSNAME;
 			break;
+		case Opt_subtype:
+			ima_log_string(ab, "subtype", args[0].from);
+
+			entry->subtype = kstrdup(args[0].from, GFP_KERNEL);
+			if (!entry->subtype) {
+				result = -ENOMEM;
+				break;
+			}
+			result = 0;
+			entry->flags |= IMA_SUBTYPE;
+			break;
 		case Opt_fsuuid:
 			ima_log_string(ab, "fsuuid", args[0].from);
 
@@ -1256,6 +1274,12 @@ int ima_policy_show(struct seq_file *m, void *v)
 		seq_puts(m, " ");
 	}
 
+	if (entry->flags & IMA_SUBTYPE) {
+		snprintf(tbuf, sizeof(tbuf), "%s", entry->subtype);
+		seq_printf(m, pt(Opt_subtype), tbuf);
+		seq_puts(m, " ");
+	}
+
 	if (entry->flags & IMA_PCR) {
 		snprintf(tbuf, sizeof(tbuf), "%d", entry->pcr);
 		seq_printf(m, pt(Opt_pcr), tbuf);
-- 
2.21.0.1020.gf2820cf01a-goog


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

* [PATCH V3 4/6] IMA: Optionally make use of filesystem-provided hashes
  2019-05-17 21:24 [PATCH V3 0/6] IMA: Support asking the VFS for a file hash Matthew Garrett
                   ` (2 preceding siblings ...)
  2019-05-17 21:24 ` [PATCH V3 3/6] IMA: Allow rule matching on filesystem subtype Matthew Garrett
@ 2019-05-17 21:24 ` Matthew Garrett
  2019-05-17 21:24 ` [PATCH V3 5/6] IMA: Add a ima-vfs-sig measurement template Matthew Garrett
  2019-05-17 21:24 ` [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template Matthew Garrett
  5 siblings, 0 replies; 14+ messages in thread
From: Matthew Garrett @ 2019-05-17 21:24 UTC (permalink / raw)
  To: linux-integrity
  Cc: zohar, dmitry.kasatkin, miklos, linux-fsdevel, viro, Matthew Garrett

From: Matthew Garrett <mjg59@google.com>

Some filesystems may be able to provide hashes in an out of band manner,
and allowing them to do so is a performance win. This is especially true
of FUSE-based filesystems where otherwise we recalculate the hash on
every measurement. Make use of this if policy says we should, but provide
a parameter to force recalculation rather than trusting the filesystem.

Signed-off-by: Matthew Garrett <mjg59@google.com>
---
 Documentation/ABI/testing/ima_policy          |  5 +++-
 .../admin-guide/kernel-parameters.txt         |  5 ++++
 security/integrity/ima/ima.h                  |  3 ++-
 security/integrity/ima/ima_api.c              |  5 +++-
 security/integrity/ima/ima_crypto.c           | 23 ++++++++++++++++++-
 security/integrity/ima/ima_policy.c           |  8 ++++++-
 security/integrity/ima/ima_template_lib.c     |  2 +-
 security/integrity/integrity.h                |  1 +
 8 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 09a5def7e28a..6a517282068d 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -24,7 +24,8 @@ Description:
 				[euid=] [fowner=] [fsname=] [subtype=]]
 			lsm:	[[subj_user=] [subj_role=] [subj_type=]
 				 [obj_user=] [obj_role=] [obj_type=]]
-			option:	[[appraise_type=]] [permit_directio]
+			option:	[[appraise_type=] [permit_directio]
+			         [trust_vfs]]
 
 		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
 				[FIRMWARE_CHECK]
@@ -41,6 +42,8 @@ Description:
 		lsm:  	are LSM specific
 		option:	appraise_type:= [imasig]
 			pcr:= decimal value
+			permit_directio:= allow directio accesses
+			trust_vfs:= trust VFS-provided hash values
 
 		default policy:
 			# PROC_SUPER_MAGIC
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 2b8ee90bb644..573cef13d268 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1656,6 +1656,11 @@
 			different crypto accelerators. This option can be used
 			to achieve best performance for particular HW.
 
+	ima.force_hash= [IMA] Force hash calculation in IMA
+			Format: <bool>
+			Always calculate hashes rather than trusting the
+			filesystem to provide them to us.
+
 	init=		[KNL]
 			Format: <full_path>
 			Run specified binary instead of /sbin/init as init
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index d213e835c498..cdaffe6c8a8d 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -133,7 +133,8 @@ int ima_fs_init(void);
 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_file_hash(struct file *file, struct ima_digest_data *hash,
+		       bool trust_vfs);
 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,
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index c7505fb122d4..0def9cf43549 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -206,6 +206,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 	int length;
 	void *tmpbuf;
 	u64 i_version;
+	bool trust_vfs;
 	struct {
 		struct ima_digest_data hdr;
 		char digest[IMA_MAX_DIGEST_SIZE];
@@ -225,10 +226,12 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 	/* Initialize hash digest to 0's in case of failure */
 	memset(&hash.digest, 0, sizeof(hash.digest));
 
+	trust_vfs = iint->flags & IMA_TRUST_VFS;
+
 	if (buf)
 		result = ima_calc_buffer_hash(buf, size, &hash.hdr);
 	else
-		result = ima_calc_file_hash(file, &hash.hdr);
+		result = ima_calc_file_hash(file, &hash.hdr, trust_vfs);
 
 	if (result && result != -EBADF && result != -EINVAL)
 		goto out;
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 16a4f45863b1..cceedce750d3 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -32,6 +32,10 @@ static unsigned long ima_ahash_minsize;
 module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644);
 MODULE_PARM_DESC(ahash_minsize, "Minimum file size for ahash use");
 
+static bool ima_force_hash;
+module_param_named(force_hash, ima_force_hash, bool_enable_only, 0644);
+MODULE_PARM_DESC(force_hash, "Always calculate hashes");
+
 /* default is 0 - 1 page. */
 static int ima_maxorder;
 static unsigned int ima_bufsize = PAGE_SIZE;
@@ -402,11 +406,14 @@ static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash)
  * shash for the hash calculation.  If ahash fails, it falls back to using
  * shash.
  */
-int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
+int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash,
+		       bool trust_vfs)
 {
 	loff_t i_size;
 	int rc;
 	struct file *f = file;
+	struct dentry *dentry = file_dentry(file);
+	struct inode *inode = d_backing_inode(dentry);
 	bool new_file_instance = false, modified_flags = false;
 
 	/*
@@ -419,6 +426,20 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
 		return -EINVAL;
 	}
 
+	/*
+	 * If policy says we should trust VFS-provided hashes, and
+	 * we're not configured to force hashing, and if the
+	 * filesystem is trusted, ask the VFS if it can obtain the
+	 * hash without us having to calculate it ourself.
+	 */
+	if (trust_vfs && !ima_force_hash &&
+	    !(inode->i_sb->s_iflags & SB_I_UNTRUSTED_MOUNTER)) {
+		hash->length = hash_digest_size[hash->algo];
+		rc = vfs_get_hash(file, hash->algo, hash->digest, hash->length);
+		if (!rc)
+			return 0;
+	}
+
 	/* Open a new file instance in O_RDONLY if we cannot read */
 	if (!(file->f_mode & FMODE_READ)) {
 		int flags = file->f_flags & ~(O_WRONLY | O_APPEND |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index bb4e265823a7..c293cbc6c578 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -681,7 +681,7 @@ enum {
 	Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
 	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
 	Opt_appraise_type, Opt_permit_directio,
-	Opt_pcr, Opt_err
+	Opt_pcr, Opt_trust_vfs, Opt_err
 };
 
 static const match_table_t policy_tokens = {
@@ -716,6 +716,7 @@ static const match_table_t policy_tokens = {
 	{Opt_appraise_type, "appraise_type=%s"},
 	{Opt_permit_directio, "permit_directio"},
 	{Opt_pcr, "pcr=%s"},
+	{Opt_trust_vfs, "trust_vfs"},
 	{Opt_err, NULL}
 };
 
@@ -1062,6 +1063,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 		case Opt_permit_directio:
 			entry->flags |= IMA_PERMIT_DIRECTIO;
 			break;
+		case Opt_trust_vfs:
+			entry->flags |= IMA_TRUST_VFS;
+			break;
 		case Opt_pcr:
 			if (entry->action != MEASURE) {
 				result = -EINVAL;
@@ -1358,6 +1362,8 @@ int ima_policy_show(struct seq_file *m, void *v)
 		seq_puts(m, "appraise_type=imasig ");
 	if (entry->flags & IMA_PERMIT_DIRECTIO)
 		seq_puts(m, "permit_directio ");
+	if (entry->flags & IMA_TRUST_VFS)
+		seq_puts(m, "trust_vfs ");
 	rcu_read_unlock();
 	seq_puts(m, "\n");
 	return 0;
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 513b457ae900..26f71c5805f0 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -291,7 +291,7 @@ int ima_eventdigest_init(struct ima_event_data *event_data,
 	inode = file_inode(event_data->file);
 	hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
 	    ima_hash_algo : HASH_ALGO_SHA1;
-	result = ima_calc_file_hash(event_data->file, &hash.hdr);
+	result = ima_calc_file_hash(event_data->file, &hash.hdr, false);
 	if (result) {
 		integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
 				    event_data->filename, "collect_data",
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7de59f44cba3..a03f859c1602 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -36,6 +36,7 @@
 #define IMA_NEW_FILE		0x04000000
 #define EVM_IMMUTABLE_DIGSIG	0x08000000
 #define IMA_FAIL_UNVERIFIABLE_SIGS	0x10000000
+#define IMA_TRUST_VFS		0x20000000
 
 #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
 				 IMA_HASH | IMA_APPRAISE_SUBMASK)
-- 
2.21.0.1020.gf2820cf01a-goog


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

* [PATCH V3 5/6] IMA: Add a ima-vfs-sig measurement template
  2019-05-17 21:24 [PATCH V3 0/6] IMA: Support asking the VFS for a file hash Matthew Garrett
                   ` (3 preceding siblings ...)
  2019-05-17 21:24 ` [PATCH V3 4/6] IMA: Optionally make use of filesystem-provided hashes Matthew Garrett
@ 2019-05-17 21:24 ` Matthew Garrett
  2019-05-18 10:04   ` kbuild test robot
  2019-05-17 21:24 ` [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template Matthew Garrett
  5 siblings, 1 reply; 14+ messages in thread
From: Matthew Garrett @ 2019-05-17 21:24 UTC (permalink / raw)
  To: linux-integrity
  Cc: zohar, dmitry.kasatkin, miklos, linux-fsdevel, viro,
	Matthew Garrett, Matthew Garrett

Admins may wish to know whether measurements were sourced from the VFS
or calculated by IMA, so we should provide an additional tag to indicate
that. However, doing this by default would potentially break existing
log parsing pipelines, so add a new template type rather than changing
the default behaviour.

Signed-off-by: Matthew Garrett <mjg59@google.com>
---
 security/integrity/ima/Kconfig            |  7 +++-
 security/integrity/ima/ima.h              |  2 +-
 security/integrity/ima/ima_api.c          |  6 +++-
 security/integrity/ima/ima_crypto.c       |  7 ++--
 security/integrity/ima/ima_template.c     |  3 ++
 security/integrity/ima/ima_template_lib.c | 41 ++++++++++++++++++++---
 security/integrity/ima/ima_template_lib.h |  2 ++
 security/integrity/integrity.h            |  1 +
 8 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index a18f8c6d13b5..d2c7623d1dde 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -69,12 +69,16 @@ choice
 	  hash, defined as 20 bytes, and a null terminated pathname,
 	  limited to 255 characters.  The 'ima-ng' measurement list
 	  template permits both larger hash digests and longer
-	  pathnames.
+	  pathnames. The 'ima-vfs-ng' measurement list template includes
+	  an additional vfs: tag if the measurement was sourced directly
+	  from the filesystem.
 
 	config IMA_TEMPLATE
 		bool "ima"
 	config IMA_NG_TEMPLATE
 		bool "ima-ng (default)"
+	config IMA_VFS_NG_TEMPLATE
+	        bool "ima-vfs-ng"
 	config IMA_SIG_TEMPLATE
 		bool "ima-sig"
 endchoice
@@ -85,6 +89,7 @@ config IMA_DEFAULT_TEMPLATE
 	default "ima" if IMA_TEMPLATE
 	default "ima-ng" if IMA_NG_TEMPLATE
 	default "ima-sig" if IMA_SIG_TEMPLATE
+	default "ima-vfs-ng" if IMA_VFS_NG_TEMPLATE
 
 choice
 	prompt "Default integrity hash algorithm"
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index cdaffe6c8a8d..d99b867bdc53 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -134,7 +134,7 @@ 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,
-		       bool trust_vfs);
+		       bool *trust_vfs);
 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,
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 0def9cf43549..55bafce3d9c0 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -231,7 +231,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 	if (buf)
 		result = ima_calc_buffer_hash(buf, size, &hash.hdr);
 	else
-		result = ima_calc_file_hash(file, &hash.hdr, trust_vfs);
+		result = ima_calc_file_hash(file, &hash.hdr, &trust_vfs);
 
 	if (result && result != -EBADF && result != -EINVAL)
 		goto out;
@@ -247,6 +247,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 	memcpy(iint->ima_hash, &hash, length);
 	iint->version = i_version;
 
+	/* Record whether we got this measurement from the VFS or not */
+	if (trust_vfs)
+		set_bit(IMA_TRUSTED_VFS, &iint->atomic_flags);
+
 	/* Possibly temporary failure due to type of read (eg. O_DIRECT) */
 	if (!result)
 		iint->flags |= IMA_COLLECTED;
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index cceedce750d3..721893073607 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -407,7 +407,7 @@ static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash)
  * shash.
  */
 int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash,
-		       bool trust_vfs)
+		       bool *trust_vfs)
 {
 	loff_t i_size;
 	int rc;
@@ -432,7 +432,7 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash,
 	 * filesystem is trusted, ask the VFS if it can obtain the
 	 * hash without us having to calculate it ourself.
 	 */
-	if (trust_vfs && !ima_force_hash &&
+	if (*trust_vfs == true && !ima_force_hash &&
 	    !(inode->i_sb->s_iflags & SB_I_UNTRUSTED_MOUNTER)) {
 		hash->length = hash_digest_size[hash->algo];
 		rc = vfs_get_hash(file, hash->algo, hash->digest, hash->length);
@@ -440,6 +440,9 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash,
 			return 0;
 	}
 
+	/* If we're here then we're not using the VFS to obtain the hash */
+	*trust_vfs = false;
+
 	/* Open a new file instance in O_RDONLY if we cannot read */
 	if (!(file->f_mode & FMODE_READ)) {
 		int flags = file->f_flags & ~(O_WRONLY | O_APPEND |
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index b631b8bc7624..78bd8fea8b35 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -25,6 +25,7 @@ enum header_fields { HDR_PCR, HDR_DIGEST, HDR_TEMPLATE_NAME,
 static struct ima_template_desc builtin_templates[] = {
 	{.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
 	{.name = "ima-ng", .fmt = "d-ng|n-ng"},
+	{.name = "ima-vfs-ng", .fmt = "d-vng|n-ng"},
 	{.name = "ima-sig", .fmt = "d-ng|n-ng|sig"},
 	{.name = "", .fmt = ""},	/* placeholder for a custom format */
 };
@@ -41,6 +42,8 @@ static const struct ima_template_field supported_fields[] = {
 	 .field_show = ima_show_template_digest_ng},
 	{.field_id = "n-ng", .field_init = ima_eventname_ng_init,
 	 .field_show = ima_show_template_string},
+	{.field_id = "d-vng", .field_init = ima_eventdigest_vfs_ng_init,
+	 .field_show = ima_show_template_digest_ng},
 	{.field_id = "sig", .field_init = ima_eventsig_init,
 	 .field_show = ima_show_template_sig},
 };
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 26f71c5805f0..863e95281c4b 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -224,7 +224,9 @@ int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp,
 }
 
 static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
-				       struct ima_field_data *field_data)
+				       struct ima_event_data *event_data,
+				       struct ima_field_data *field_data,
+				       bool from_vfs)
 {
 	/*
 	 * digest formats:
@@ -237,10 +239,13 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
 	enum data_formats fmt = DATA_FMT_DIGEST;
 	u32 offset = 0;
 
+	if (from_vfs)
+		offset += snprintf(buffer, 5, "vfs:");
+
 	if (hash_algo < HASH_ALGO__LAST) {
 		fmt = DATA_FMT_DIGEST_WITH_ALGO;
-		offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, "%s",
-				   hash_algo_name[hash_algo]);
+		offset += snprintf(buffer + offset, CRYPTO_MAX_ALG_NAME + 1,
+				   "%s", hash_algo_name[hash_algo]);
 		buffer[offset] = ':';
 		offset += 2;
 	}
@@ -302,7 +307,7 @@ int ima_eventdigest_init(struct ima_event_data *event_data,
 	cur_digestsize = hash.hdr.length;
 out:
 	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
-					   HASH_ALGO__LAST, field_data);
+			       HASH_ALGO__LAST, event_data, field_data, false);
 }
 
 /*
@@ -323,7 +328,33 @@ int ima_eventdigest_ng_init(struct ima_event_data *event_data,
 	hash_algo = event_data->iint->ima_hash->algo;
 out:
 	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
-					   hash_algo, field_data);
+				     hash_algo, event_data, field_data, false);
+}
+
+/*
+ * This function is identical to ima_eventdigest_ng_init but tags events whose
+ * digest came from the VFS
+ */
+int ima_eventdigest_vfs_ng_init(struct ima_event_data *event_data,
+				struct ima_field_data *field_data)
+{
+	u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1;
+	u32 cur_digestsize = 0;
+	bool vfs = false;
+
+	if (test_bit(IMA_TRUSTED_VFS, &event_data->iint->atomic_flags))
+		vfs = true;
+
+	if (event_data->violation)	/* recording a violation. */
+		goto out;
+
+	cur_digest = event_data->iint->ima_hash->digest;
+	cur_digestsize = event_data->iint->ima_hash->length;
+
+	hash_algo = event_data->iint->ima_hash->algo;
+out:
+	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
+				       hash_algo, event_data, field_data, vfs);
 }
 
 static int ima_eventname_init_common(struct ima_event_data *event_data,
diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h
index 6a3d8b831deb..3f320299e0a0 100644
--- a/security/integrity/ima/ima_template_lib.h
+++ b/security/integrity/ima/ima_template_lib.h
@@ -38,6 +38,8 @@ int ima_eventname_init(struct ima_event_data *event_data,
 		       struct ima_field_data *field_data);
 int ima_eventdigest_ng_init(struct ima_event_data *event_data,
 			    struct ima_field_data *field_data);
+int ima_eventdigest_vfs_ng_init(struct ima_event_data *event_data,
+				struct ima_field_data *field_data);
 int ima_eventname_ng_init(struct ima_event_data *event_data,
 			  struct ima_field_data *field_data);
 int ima_eventsig_init(struct ima_event_data *event_data,
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index a03f859c1602..9d74119bcdfd 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -68,6 +68,7 @@
 #define IMA_CHANGE_ATTR		2
 #define IMA_DIGSIG		3
 #define IMA_MUST_MEASURE	4
+#define IMA_TRUSTED_VFS		5
 
 enum evm_ima_xattr_type {
 	IMA_XATTR_DIGEST = 0x01,
-- 
2.21.0.1020.gf2820cf01a-goog


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

* [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template
  2019-05-17 21:24 [PATCH V3 0/6] IMA: Support asking the VFS for a file hash Matthew Garrett
                   ` (4 preceding siblings ...)
  2019-05-17 21:24 ` [PATCH V3 5/6] IMA: Add a ima-vfs-sig measurement template Matthew Garrett
@ 2019-05-17 21:24 ` Matthew Garrett
  2019-05-17 23:47   ` Mimi Zohar
  5 siblings, 1 reply; 14+ messages in thread
From: Matthew Garrett @ 2019-05-17 21:24 UTC (permalink / raw)
  To: linux-integrity
  Cc: zohar, dmitry.kasatkin, miklos, linux-fsdevel, viro,
	Matthew Garrett, Matthew Garrett

Admins may wish to log different measurements using different IMA
templates. Add support for overriding the default template on a per-rule
basis.

Signed-off-by: Matthew Garrett <mjg59@google.com>
---
 Documentation/ABI/testing/ima_policy  |  3 ++-
 security/integrity/ima/ima.h          |  7 +++++--
 security/integrity/ima/ima_api.c      |  7 +++++--
 security/integrity/ima/ima_appraise.c |  2 +-
 security/integrity/ima/ima_main.c     |  9 ++++++---
 security/integrity/ima/ima_policy.c   | 24 ++++++++++++++++++++++--
 security/integrity/ima/ima_template.c | 10 ++++++++--
 security/integrity/integrity.h        |  1 +
 8 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 6a517282068d..f707ef7eda88 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -24,7 +24,7 @@ Description:
 				[euid=] [fowner=] [fsname=] [subtype=]]
 			lsm:	[[subj_user=] [subj_role=] [subj_type=]
 				 [obj_user=] [obj_role=] [obj_type=]]
-			option:	[[appraise_type=] [permit_directio]
+			option:	[[appraise_type=] [template=] [permit_directio]
 			         [trust_vfs]]
 
 		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
@@ -41,6 +41,7 @@ Description:
 			fowner:= decimal value
 		lsm:  	are LSM specific
 		option:	appraise_type:= [imasig]
+			template:= name of an IMA template type (eg, d-ng)
 			pcr:= decimal value
 			permit_directio:= allow directio accesses
 			trust_vfs:= trust VFS-provided hash values
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index d99b867bdc53..29a71c2e6cfa 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -148,6 +148,7 @@ int ima_init_crypto(void);
 void ima_putc(struct seq_file *m, void *data, int datalen);
 void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
 struct ima_template_desc *ima_template_desc_current(void);
+struct ima_template_desc *lookup_template_desc(const char *name);
 int ima_restore_measurement_entry(struct ima_template_entry *entry);
 int ima_restore_measurement_list(loff_t bufsize, void *buf);
 int ima_measurements_show(struct seq_file *m, void *v);
@@ -194,7 +195,8 @@ enum ima_hooks {
 
 /* LIM API function definitions */
 int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
-		   int mask, enum ima_hooks func, int *pcr);
+		   int mask, enum ima_hooks func, int *pcr,
+		   struct ima_template_desc **template_desc);
 int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
 			    struct file *file, void *buf, loff_t size,
@@ -215,7 +217,8 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
 
 /* IMA policy related functions */
 int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
-		     enum ima_hooks func, int mask, int flags, int *pcr);
+		     enum ima_hooks func, int mask, int flags, int *pcr,
+		     struct ima_template_desc **template_desc);
 void ima_init_policy(void);
 void ima_update_policy(void);
 void ima_update_policy_flag(void);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 55bafce3d9c0..457b071669ff 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -164,6 +164,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
  *        MAY_APPEND)
  * @func: caller identifier
  * @pcr: pointer filled in if matched measure policy sets pcr=
+ * @template_desc: pointer filled in if matched measure policy sets template=
  *
  * The policy is defined in terms of keypairs:
  *		subj=, obj=, type=, func=, mask=, fsmagic=
@@ -176,13 +177,15 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
  *
  */
 int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
-		   int mask, enum ima_hooks func, int *pcr)
+		   int mask, enum ima_hooks func, int *pcr,
+		   struct ima_template_desc **template_desc)
 {
 	int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH;
 
 	flags &= ima_policy_flag;
 
-	return ima_match_policy(inode, cred, secid, func, mask, flags, pcr);
+	return ima_match_policy(inode, cred, secid, func, mask, flags, pcr,
+				template_desc);
 }
 
 /*
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 5fb7127bbe68..2f6536ab69e8 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -57,7 +57,7 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
 
 	security_task_getsecid(current, &secid);
 	return ima_match_policy(inode, current_cred(), secid, func, mask,
-				IMA_APPRAISE | IMA_HASH, NULL);
+				IMA_APPRAISE | IMA_HASH, NULL, NULL);
 }
 
 static int ima_fix_xattr(struct dentry *dentry,
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 357edd140c09..f23069d9e43d 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -174,7 +174,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
 {
 	struct inode *inode = file_inode(file);
 	struct integrity_iint_cache *iint = NULL;
-	struct ima_template_desc *template_desc;
+	struct ima_template_desc *template_desc = NULL;
 	char *pathbuf = NULL;
 	char filename[NAME_MAX];
 	const char *pathname = NULL;
@@ -192,7 +192,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
 	 * bitmask based on the appraise/audit/measurement policy.
 	 * Included is the appraise submask.
 	 */
-	action = ima_get_action(inode, cred, secid, mask, func, &pcr);
+	action = ima_get_action(inode, cred, secid, mask, func, &pcr,
+				&template_desc);
 	violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
 			   (ima_policy_flag & IMA_MEASURE));
 	if (!action && !violation_check)
@@ -275,7 +276,9 @@ static int process_measurement(struct file *file, const struct cred *cred,
 		goto out_locked;
 	}
 
-	template_desc = ima_template_desc_current();
+	if (!template_desc)
+		template_desc = ima_template_desc_current();
+
 	if ((action & IMA_APPRAISE_SUBMASK) ||
 		    strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
 		/* read 'security.ima' */
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index c293cbc6c578..33c52466bc8a 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -82,6 +82,7 @@ struct ima_rule_entry {
 	} lsm[MAX_LSM_RULES];
 	char *fsname;
 	char *subtype;
+	struct ima_template_desc *template;
 };
 
 /*
@@ -403,6 +404,7 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
  * @func: IMA hook identifier
  * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
  * @pcr: set the pcr to extend
+ * @template_desc: the template that should be used for this rule
  *
  * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type)
  * conditions.
@@ -412,7 +414,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
  * than writes so ima_match_policy() is classical RCU candidate.
  */
 int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
-		     enum ima_hooks func, int mask, int flags, int *pcr)
+		     enum ima_hooks func, int mask, int flags, int *pcr,
+		     struct ima_template_desc **template_desc)
 {
 	struct ima_rule_entry *entry;
 	int action = 0, actmask = flags | (flags << 1);
@@ -444,6 +447,9 @@ int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
 		if ((pcr) && (entry->flags & IMA_PCR))
 			*pcr = entry->pcr;
 
+		if (template_desc && entry->flags & IMA_TEMPLATE)
+			*template_desc = entry->template;
+
 		if (!actmask)
 			break;
 	}
@@ -681,7 +687,7 @@ enum {
 	Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
 	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
 	Opt_appraise_type, Opt_permit_directio,
-	Opt_pcr, Opt_trust_vfs, Opt_err
+	Opt_pcr, Opt_trust_vfs, Opt_template, Opt_err
 };
 
 static const match_table_t policy_tokens = {
@@ -717,6 +723,7 @@ static const match_table_t policy_tokens = {
 	{Opt_permit_directio, "permit_directio"},
 	{Opt_pcr, "pcr=%s"},
 	{Opt_trust_vfs, "trust_vfs"},
+	{Opt_template, "template=%s"},
 	{Opt_err, NULL}
 };
 
@@ -770,6 +777,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 	char *from;
 	char *p;
 	bool uid_token;
+	struct ima_template_desc *template_desc;
 	int result = 0;
 
 	ab = integrity_audit_log_start(audit_context(), GFP_KERNEL,
@@ -1079,6 +1087,16 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			else
 				entry->flags |= IMA_PCR;
 
+			break;
+		case Opt_template:
+			ima_log_string(ab, "template", args[0].from);
+			template_desc = lookup_template_desc(args[0].from);
+			if (!template_desc) {
+				result = -EINVAL;
+			} else {
+				entry->template = template_desc;
+				entry->flags |= IMA_TEMPLATE;
+			}
 			break;
 		case Opt_err:
 			ima_log_string(ab, "UNKNOWN", p);
@@ -1358,6 +1376,8 @@ int ima_policy_show(struct seq_file *m, void *v)
 			}
 		}
 	}
+	if (entry->flags & IMA_TEMPLATE)
+		seq_printf(m, "template=%s ", entry->template->name);
 	if (entry->flags & IMA_DIGSIG_REQUIRED)
 		seq_puts(m, "appraise_type=imasig ");
 	if (entry->flags & IMA_PERMIT_DIRECTIO)
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 78bd8fea8b35..aea95754d523 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -50,7 +50,6 @@ static const struct ima_template_field supported_fields[] = {
 #define MAX_TEMPLATE_NAME_LEN 15
 
 static struct ima_template_desc *ima_template;
-static struct ima_template_desc *lookup_template_desc(const char *name);
 static int template_desc_init_fields(const char *template_fmt,
 				     const struct ima_template_field ***fields,
 				     int *num_fields);
@@ -111,7 +110,7 @@ static int __init ima_template_fmt_setup(char *str)
 }
 __setup("ima_template_fmt=", ima_template_fmt_setup);
 
-static struct ima_template_desc *lookup_template_desc(const char *name)
+struct ima_template_desc *lookup_template_desc(const char *name)
 {
 	struct ima_template_desc *template_desc;
 	int found = 0;
@@ -120,6 +119,13 @@ static struct ima_template_desc *lookup_template_desc(const char *name)
 	list_for_each_entry_rcu(template_desc, &defined_templates, list) {
 		if ((strcmp(template_desc->name, name) == 0) ||
 		    (strcmp(template_desc->fmt, name) == 0)) {
+			/*
+			 * template_desc_init_fields() will return immediately
+			 * if the template is already initialised
+			 */
+			template_desc_init_fields(template_desc->fmt,
+						  &(template_desc->fields),
+						  &(template_desc->num_fields));
 			found = 1;
 			break;
 		}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 9d74119bcdfd..9f647b04fc23 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -37,6 +37,7 @@
 #define EVM_IMMUTABLE_DIGSIG	0x08000000
 #define IMA_FAIL_UNVERIFIABLE_SIGS	0x10000000
 #define IMA_TRUST_VFS		0x20000000
+#define IMA_TEMPLATE		0x40000000
 
 #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
 				 IMA_HASH | IMA_APPRAISE_SUBMASK)
-- 
2.21.0.1020.gf2820cf01a-goog


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

* Re: [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template
  2019-05-17 21:24 ` [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template Matthew Garrett
@ 2019-05-17 23:47   ` Mimi Zohar
  2019-05-20 20:59     ` Matthew Garrett
  0 siblings, 1 reply; 14+ messages in thread
From: Mimi Zohar @ 2019-05-17 23:47 UTC (permalink / raw)
  To: Matthew Garrett, linux-integrity, prakhar srivastava,
	Thiago Jung Bauermann, Roberto Sassu
  Cc: zohar, dmitry.kasatkin, miklos, linux-fsdevel, viro, Matthew Garrett

[Cc'ing Prakhar, Thiago, Roberto]

Hi Matthew,

On Fri, 2019-05-17 at 14:24 -0700, Matthew Garrett wrote:
> Admins may wish to log different measurements using different IMA
> templates. Add support for overriding the default template on a per-rule
> basis.
> 
> Signed-off-by: Matthew Garrett <mjg59@google.com>

All of sudden there are three different patch sets needing to include
different types of measurements in the measurement list.  Matthew's
VFS sourced file hashes, Thiago's kexec kernel image appended
signature, and Prakhar's kexec boot command line.  I'd like you to
work together to get this upstreamed.

Matthew, I'm going to ask you to separate out this patch from this
patch set.  Roberto, Thiago, Prakhar, I'm going to ask you to review
Matthew's patch.  I'm expecting all of the patchsets will be re-posted 
based on it.

thanks!

Mimi


> ---
>  Documentation/ABI/testing/ima_policy  |  3 ++-
>  security/integrity/ima/ima.h          |  7 +++++--
>  security/integrity/ima/ima_api.c      |  7 +++++--
>  security/integrity/ima/ima_appraise.c |  2 +-
>  security/integrity/ima/ima_main.c     |  9 ++++++---
>  security/integrity/ima/ima_policy.c   | 24 ++++++++++++++++++++++--
>  security/integrity/ima/ima_template.c | 10 ++++++++--
>  security/integrity/integrity.h        |  1 +
>  8 files changed, 50 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
> index 6a517282068d..f707ef7eda88 100644
> --- a/Documentation/ABI/testing/ima_policy
> +++ b/Documentation/ABI/testing/ima_policy
> @@ -24,7 +24,7 @@ Description:
>  				[euid=] [fowner=] [fsname=] [subtype=]]
>  			lsm:	[[subj_user=] [subj_role=] [subj_type=]
>  				 [obj_user=] [obj_role=] [obj_type=]]
> -			option:	[[appraise_type=] [permit_directio]
> +			option:	[[appraise_type=] [template=] [permit_directio]
>  			         [trust_vfs]]
> 
>  		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
> @@ -41,6 +41,7 @@ Description:
>  			fowner:= decimal value
>  		lsm:  	are LSM specific
>  		option:	appraise_type:= [imasig]
> +			template:= name of an IMA template type (eg, d-ng)
>  			pcr:= decimal value
>  			permit_directio:= allow directio accesses
>  			trust_vfs:= trust VFS-provided hash values
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index d99b867bdc53..29a71c2e6cfa 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -148,6 +148,7 @@ int ima_init_crypto(void);
>  void ima_putc(struct seq_file *m, void *data, int datalen);
>  void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
>  struct ima_template_desc *ima_template_desc_current(void);
> +struct ima_template_desc *lookup_template_desc(const char *name);
>  int ima_restore_measurement_entry(struct ima_template_entry *entry);
>  int ima_restore_measurement_list(loff_t bufsize, void *buf);
>  int ima_measurements_show(struct seq_file *m, void *v);
> @@ -194,7 +195,8 @@ enum ima_hooks {
> 
>  /* LIM API function definitions */
>  int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
> -		   int mask, enum ima_hooks func, int *pcr);
> +		   int mask, enum ima_hooks func, int *pcr,
> +		   struct ima_template_desc **template_desc);
>  int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
>  int ima_collect_measurement(struct integrity_iint_cache *iint,
>  			    struct file *file, void *buf, loff_t size,
> @@ -215,7 +217,8 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
> 
>  /* IMA policy related functions */
>  int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
> -		     enum ima_hooks func, int mask, int flags, int *pcr);
> +		     enum ima_hooks func, int mask, int flags, int *pcr,
> +		     struct ima_template_desc **template_desc);
>  void ima_init_policy(void);
>  void ima_update_policy(void);
>  void ima_update_policy_flag(void);
> diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
> index 55bafce3d9c0..457b071669ff 100644
> --- a/security/integrity/ima/ima_api.c
> +++ b/security/integrity/ima/ima_api.c
> @@ -164,6 +164,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
>   *        MAY_APPEND)
>   * @func: caller identifier
>   * @pcr: pointer filled in if matched measure policy sets pcr=
> + * @template_desc: pointer filled in if matched measure policy sets template=
>   *
>   * The policy is defined in terms of keypairs:
>   *		subj=, obj=, type=, func=, mask=, fsmagic=
> @@ -176,13 +177,15 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
>   *
>   */
>  int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
> -		   int mask, enum ima_hooks func, int *pcr)
> +		   int mask, enum ima_hooks func, int *pcr,
> +		   struct ima_template_desc **template_desc)
>  {
>  	int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH;
> 
>  	flags &= ima_policy_flag;
> 
> -	return ima_match_policy(inode, cred, secid, func, mask, flags, pcr);
> +	return ima_match_policy(inode, cred, secid, func, mask, flags, pcr,
> +				template_desc);
>  }
> 
>  /*
> diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> index 5fb7127bbe68..2f6536ab69e8 100644
> --- a/security/integrity/ima/ima_appraise.c
> +++ b/security/integrity/ima/ima_appraise.c
> @@ -57,7 +57,7 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
> 
>  	security_task_getsecid(current, &secid);
>  	return ima_match_policy(inode, current_cred(), secid, func, mask,
> -				IMA_APPRAISE | IMA_HASH, NULL);
> +				IMA_APPRAISE | IMA_HASH, NULL, NULL);
>  }
> 
>  static int ima_fix_xattr(struct dentry *dentry,
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 357edd140c09..f23069d9e43d 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -174,7 +174,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
>  {
>  	struct inode *inode = file_inode(file);
>  	struct integrity_iint_cache *iint = NULL;
> -	struct ima_template_desc *template_desc;
> +	struct ima_template_desc *template_desc = NULL;
>  	char *pathbuf = NULL;
>  	char filename[NAME_MAX];
>  	const char *pathname = NULL;
> @@ -192,7 +192,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
>  	 * bitmask based on the appraise/audit/measurement policy.
>  	 * Included is the appraise submask.
>  	 */
> -	action = ima_get_action(inode, cred, secid, mask, func, &pcr);
> +	action = ima_get_action(inode, cred, secid, mask, func, &pcr,
> +				&template_desc);
>  	violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
>  			   (ima_policy_flag & IMA_MEASURE));
>  	if (!action && !violation_check)
> @@ -275,7 +276,9 @@ static int process_measurement(struct file *file, const struct cred *cred,
>  		goto out_locked;
>  	}
> 
> -	template_desc = ima_template_desc_current();
> +	if (!template_desc)
> +		template_desc = ima_template_desc_current();
> +
>  	if ((action & IMA_APPRAISE_SUBMASK) ||
>  		    strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
>  		/* read 'security.ima' */
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index c293cbc6c578..33c52466bc8a 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -82,6 +82,7 @@ struct ima_rule_entry {
>  	} lsm[MAX_LSM_RULES];
>  	char *fsname;
>  	char *subtype;
> +	struct ima_template_desc *template;
>  };
> 
>  /*
> @@ -403,6 +404,7 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
>   * @func: IMA hook identifier
>   * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
>   * @pcr: set the pcr to extend
> + * @template_desc: the template that should be used for this rule
>   *
>   * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type)
>   * conditions.
> @@ -412,7 +414,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
>   * than writes so ima_match_policy() is classical RCU candidate.
>   */
>  int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
> -		     enum ima_hooks func, int mask, int flags, int *pcr)
> +		     enum ima_hooks func, int mask, int flags, int *pcr,
> +		     struct ima_template_desc **template_desc)
>  {
>  	struct ima_rule_entry *entry;
>  	int action = 0, actmask = flags | (flags << 1);
> @@ -444,6 +447,9 @@ int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
>  		if ((pcr) && (entry->flags & IMA_PCR))
>  			*pcr = entry->pcr;
> 
> +		if (template_desc && entry->flags & IMA_TEMPLATE)
> +			*template_desc = entry->template;
> +
>  		if (!actmask)
>  			break;
>  	}
> @@ -681,7 +687,7 @@ enum {
>  	Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
>  	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
>  	Opt_appraise_type, Opt_permit_directio,
> -	Opt_pcr, Opt_trust_vfs, Opt_err
> +	Opt_pcr, Opt_trust_vfs, Opt_template, Opt_err
>  };
> 
>  static const match_table_t policy_tokens = {
> @@ -717,6 +723,7 @@ static const match_table_t policy_tokens = {
>  	{Opt_permit_directio, "permit_directio"},
>  	{Opt_pcr, "pcr=%s"},
>  	{Opt_trust_vfs, "trust_vfs"},
> +	{Opt_template, "template=%s"},
>  	{Opt_err, NULL}
>  };
> 
> @@ -770,6 +777,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>  	char *from;
>  	char *p;
>  	bool uid_token;
> +	struct ima_template_desc *template_desc;
>  	int result = 0;
> 
>  	ab = integrity_audit_log_start(audit_context(), GFP_KERNEL,
> @@ -1079,6 +1087,16 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>  			else
>  				entry->flags |= IMA_PCR;
> 
> +			break;
> +		case Opt_template:
> +			ima_log_string(ab, "template", args[0].from);
> +			template_desc = lookup_template_desc(args[0].from);
> +			if (!template_desc) {
> +				result = -EINVAL;
> +			} else {
> +				entry->template = template_desc;
> +				entry->flags |= IMA_TEMPLATE;
> +			}
>  			break;
>  		case Opt_err:
>  			ima_log_string(ab, "UNKNOWN", p);
> @@ -1358,6 +1376,8 @@ int ima_policy_show(struct seq_file *m, void *v)
>  			}
>  		}
>  	}
> +	if (entry->flags & IMA_TEMPLATE)
> +		seq_printf(m, "template=%s ", entry->template->name);
>  	if (entry->flags & IMA_DIGSIG_REQUIRED)
>  		seq_puts(m, "appraise_type=imasig ");
>  	if (entry->flags & IMA_PERMIT_DIRECTIO)
> diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
> index 78bd8fea8b35..aea95754d523 100644
> --- a/security/integrity/ima/ima_template.c
> +++ b/security/integrity/ima/ima_template.c
> @@ -50,7 +50,6 @@ static const struct ima_template_field supported_fields[] = {
>  #define MAX_TEMPLATE_NAME_LEN 15
> 
>  static struct ima_template_desc *ima_template;
> -static struct ima_template_desc *lookup_template_desc(const char *name);
>  static int template_desc_init_fields(const char *template_fmt,
>  				     const struct ima_template_field ***fields,
>  				     int *num_fields);
> @@ -111,7 +110,7 @@ static int __init ima_template_fmt_setup(char *str)
>  }
>  __setup("ima_template_fmt=", ima_template_fmt_setup);
> 
> -static struct ima_template_desc *lookup_template_desc(const char *name)
> +struct ima_template_desc *lookup_template_desc(const char *name)
>  {
>  	struct ima_template_desc *template_desc;
>  	int found = 0;
> @@ -120,6 +119,13 @@ static struct ima_template_desc *lookup_template_desc(const char *name)
>  	list_for_each_entry_rcu(template_desc, &defined_templates, list) {
>  		if ((strcmp(template_desc->name, name) == 0) ||
>  		    (strcmp(template_desc->fmt, name) == 0)) {
> +			/*
> +			 * template_desc_init_fields() will return immediately
> +			 * if the template is already initialised
> +			 */
> +			template_desc_init_fields(template_desc->fmt,
> +						  &(template_desc->fields),
> +						  &(template_desc->num_fields));
>  			found = 1;
>  			break;
>  		}
> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> index 9d74119bcdfd..9f647b04fc23 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -37,6 +37,7 @@
>  #define EVM_IMMUTABLE_DIGSIG	0x08000000
>  #define IMA_FAIL_UNVERIFIABLE_SIGS	0x10000000
>  #define IMA_TRUST_VFS		0x20000000
> +#define IMA_TEMPLATE		0x40000000
> 
>  #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
>  				 IMA_HASH | IMA_APPRAISE_SUBMASK)


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

* Re: [PATCH V3 5/6] IMA: Add a ima-vfs-sig measurement template
  2019-05-17 21:24 ` [PATCH V3 5/6] IMA: Add a ima-vfs-sig measurement template Matthew Garrett
@ 2019-05-18 10:04   ` kbuild test robot
  0 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2019-05-18 10:04 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: kbuild-all, linux-integrity, zohar, dmitry.kasatkin, miklos,
	linux-fsdevel, viro, Matthew Garrett, Matthew Garrett

Hi Matthew,

I love your patch! Perhaps something to improve:

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

url:    https://github.com/0day-ci/linux/commits/Matthew-Garrett/IMA-Support-asking-the-VFS-for-a-file-hash/20190518-150531
base:   https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next-integrity
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)

   security/integrity/ima/ima_template_lib.c:110:60: sparse: sparse: restricted __le32 degrades to integer
   security/integrity/ima/ima_template_lib.c:193:49: sparse: sparse: cast to restricted __le32
>> security/integrity/ima/ima_template_lib.c:299:66: sparse: sparse: Using plain integer as NULL pointer

vim +299 security/integrity/ima/ima_template_lib.c

3ce1217d6 Roberto Sassu   2013-06-07  100  
3ce1217d6 Roberto Sassu   2013-06-07  101  static void ima_show_template_data_binary(struct seq_file *m,
3ce1217d6 Roberto Sassu   2013-06-07  102  					  enum ima_show_type show,
3ce1217d6 Roberto Sassu   2013-06-07  103  					  enum data_formats datafmt,
3ce1217d6 Roberto Sassu   2013-06-07  104  					  struct ima_field_data *field_data)
3ce1217d6 Roberto Sassu   2013-06-07  105  {
c019e307a Roberto Sassu   2014-02-03  106  	u32 len = (show == IMA_SHOW_BINARY_OLD_STRING_FMT) ?
c019e307a Roberto Sassu   2014-02-03  107  	    strlen(field_data->data) : field_data->len;
c019e307a Roberto Sassu   2014-02-03  108  
d68a6fe9f Mimi Zohar      2016-12-19  109  	if (show != IMA_SHOW_BINARY_NO_FIELD_LEN) {
d68a6fe9f Mimi Zohar      2016-12-19 @110  		u32 field_len = !ima_canonical_fmt ? len : cpu_to_le32(len);
d68a6fe9f Mimi Zohar      2016-12-19  111  
d68a6fe9f Mimi Zohar      2016-12-19  112  		ima_putc(m, &field_len, sizeof(field_len));
d68a6fe9f Mimi Zohar      2016-12-19  113  	}
3e8e5503a Roberto Sassu   2013-11-08  114  
c019e307a Roberto Sassu   2014-02-03  115  	if (!len)
3ce1217d6 Roberto Sassu   2013-06-07  116  		return;
3e8e5503a Roberto Sassu   2013-11-08  117  
c019e307a Roberto Sassu   2014-02-03  118  	ima_putc(m, field_data->data, len);
3ce1217d6 Roberto Sassu   2013-06-07  119  }
3ce1217d6 Roberto Sassu   2013-06-07  120  
3ce1217d6 Roberto Sassu   2013-06-07  121  static void ima_show_template_field_data(struct seq_file *m,
3ce1217d6 Roberto Sassu   2013-06-07  122  					 enum ima_show_type show,
3ce1217d6 Roberto Sassu   2013-06-07  123  					 enum data_formats datafmt,
3ce1217d6 Roberto Sassu   2013-06-07  124  					 struct ima_field_data *field_data)
3ce1217d6 Roberto Sassu   2013-06-07  125  {
3ce1217d6 Roberto Sassu   2013-06-07  126  	switch (show) {
3ce1217d6 Roberto Sassu   2013-06-07  127  	case IMA_SHOW_ASCII:
3ce1217d6 Roberto Sassu   2013-06-07  128  		ima_show_template_data_ascii(m, show, datafmt, field_data);
3ce1217d6 Roberto Sassu   2013-06-07  129  		break;
3ce1217d6 Roberto Sassu   2013-06-07  130  	case IMA_SHOW_BINARY:
3e8e5503a Roberto Sassu   2013-11-08  131  	case IMA_SHOW_BINARY_NO_FIELD_LEN:
c019e307a Roberto Sassu   2014-02-03  132  	case IMA_SHOW_BINARY_OLD_STRING_FMT:
3ce1217d6 Roberto Sassu   2013-06-07  133  		ima_show_template_data_binary(m, show, datafmt, field_data);
3ce1217d6 Roberto Sassu   2013-06-07  134  		break;
3ce1217d6 Roberto Sassu   2013-06-07  135  	default:
3ce1217d6 Roberto Sassu   2013-06-07  136  		break;
3ce1217d6 Roberto Sassu   2013-06-07  137  	}
3ce1217d6 Roberto Sassu   2013-06-07  138  }
3ce1217d6 Roberto Sassu   2013-06-07  139  
3ce1217d6 Roberto Sassu   2013-06-07  140  void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
3ce1217d6 Roberto Sassu   2013-06-07  141  			      struct ima_field_data *field_data)
3ce1217d6 Roberto Sassu   2013-06-07  142  {
3ce1217d6 Roberto Sassu   2013-06-07  143  	ima_show_template_field_data(m, show, DATA_FMT_DIGEST, field_data);
3ce1217d6 Roberto Sassu   2013-06-07  144  }
3ce1217d6 Roberto Sassu   2013-06-07  145  
4d7aeee73 Roberto Sassu   2013-06-07  146  void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
4d7aeee73 Roberto Sassu   2013-06-07  147  				 struct ima_field_data *field_data)
4d7aeee73 Roberto Sassu   2013-06-07  148  {
4d7aeee73 Roberto Sassu   2013-06-07  149  	ima_show_template_field_data(m, show, DATA_FMT_DIGEST_WITH_ALGO,
4d7aeee73 Roberto Sassu   2013-06-07  150  				     field_data);
4d7aeee73 Roberto Sassu   2013-06-07  151  }
4d7aeee73 Roberto Sassu   2013-06-07  152  
3ce1217d6 Roberto Sassu   2013-06-07  153  void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
3ce1217d6 Roberto Sassu   2013-06-07  154  			      struct ima_field_data *field_data)
3ce1217d6 Roberto Sassu   2013-06-07  155  {
3ce1217d6 Roberto Sassu   2013-06-07  156  	ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data);
3ce1217d6 Roberto Sassu   2013-06-07  157  }
3ce1217d6 Roberto Sassu   2013-06-07  158  
bcbc9b0cf Mimi Zohar      2013-07-23  159  void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
bcbc9b0cf Mimi Zohar      2013-07-23  160  			   struct ima_field_data *field_data)
bcbc9b0cf Mimi Zohar      2013-07-23  161  {
bcbc9b0cf Mimi Zohar      2013-07-23  162  	ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data);
bcbc9b0cf Mimi Zohar      2013-07-23  163  }
bcbc9b0cf Mimi Zohar      2013-07-23  164  
b17fd9ecf Roberto Sassu   2017-05-16  165  /**
b17fd9ecf Roberto Sassu   2017-05-16  166   * ima_parse_buf() - Parses lengths and data from an input buffer
b17fd9ecf Roberto Sassu   2017-05-16  167   * @bufstartp:       Buffer start address.
b17fd9ecf Roberto Sassu   2017-05-16  168   * @bufendp:         Buffer end address.
b17fd9ecf Roberto Sassu   2017-05-16  169   * @bufcurp:         Pointer to remaining (non-parsed) data.
b17fd9ecf Roberto Sassu   2017-05-16  170   * @maxfields:       Length of fields array.
b17fd9ecf Roberto Sassu   2017-05-16  171   * @fields:          Array containing lengths and pointers of parsed data.
b17fd9ecf Roberto Sassu   2017-05-16  172   * @curfields:       Number of array items containing parsed data.
b17fd9ecf Roberto Sassu   2017-05-16  173   * @len_mask:        Bitmap (if bit is set, data length should not be parsed).
b17fd9ecf Roberto Sassu   2017-05-16  174   * @enforce_mask:    Check if curfields == maxfields and/or bufcurp == bufendp.
b17fd9ecf Roberto Sassu   2017-05-16  175   * @bufname:         String identifier of the input buffer.
b17fd9ecf Roberto Sassu   2017-05-16  176   *
b17fd9ecf Roberto Sassu   2017-05-16  177   * Return: 0 on success, -EINVAL on error.
b17fd9ecf Roberto Sassu   2017-05-16  178   */
b17fd9ecf Roberto Sassu   2017-05-16  179  int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp,
b17fd9ecf Roberto Sassu   2017-05-16  180  		  int maxfields, struct ima_field_data *fields, int *curfields,
b17fd9ecf Roberto Sassu   2017-05-16  181  		  unsigned long *len_mask, int enforce_mask, char *bufname)
b17fd9ecf Roberto Sassu   2017-05-16  182  {
b17fd9ecf Roberto Sassu   2017-05-16  183  	void *bufp = bufstartp;
b17fd9ecf Roberto Sassu   2017-05-16  184  	int i;
b17fd9ecf Roberto Sassu   2017-05-16  185  
b17fd9ecf Roberto Sassu   2017-05-16  186  	for (i = 0; i < maxfields; i++) {
b17fd9ecf Roberto Sassu   2017-05-16  187  		if (len_mask == NULL || !test_bit(i, len_mask)) {
b17fd9ecf Roberto Sassu   2017-05-16  188  			if (bufp > (bufendp - sizeof(u32)))
b17fd9ecf Roberto Sassu   2017-05-16  189  				break;
b17fd9ecf Roberto Sassu   2017-05-16  190  
b17fd9ecf Roberto Sassu   2017-05-16  191  			fields[i].len = *(u32 *)bufp;
b17fd9ecf Roberto Sassu   2017-05-16  192  			if (ima_canonical_fmt)
b17fd9ecf Roberto Sassu   2017-05-16  193  				fields[i].len = le32_to_cpu(fields[i].len);
b17fd9ecf Roberto Sassu   2017-05-16  194  
b17fd9ecf Roberto Sassu   2017-05-16  195  			bufp += sizeof(u32);
b17fd9ecf Roberto Sassu   2017-05-16  196  		}
b17fd9ecf Roberto Sassu   2017-05-16  197  
b17fd9ecf Roberto Sassu   2017-05-16  198  		if (bufp > (bufendp - fields[i].len))
b17fd9ecf Roberto Sassu   2017-05-16  199  			break;
b17fd9ecf Roberto Sassu   2017-05-16  200  
b17fd9ecf Roberto Sassu   2017-05-16  201  		fields[i].data = bufp;
b17fd9ecf Roberto Sassu   2017-05-16  202  		bufp += fields[i].len;
b17fd9ecf Roberto Sassu   2017-05-16  203  	}
b17fd9ecf Roberto Sassu   2017-05-16  204  
b17fd9ecf Roberto Sassu   2017-05-16  205  	if ((enforce_mask & ENFORCE_FIELDS) && i != maxfields) {
b17fd9ecf Roberto Sassu   2017-05-16  206  		pr_err("%s: nr of fields mismatch: expected: %d, current: %d\n",
b17fd9ecf Roberto Sassu   2017-05-16  207  		       bufname, maxfields, i);
b17fd9ecf Roberto Sassu   2017-05-16  208  		return -EINVAL;
b17fd9ecf Roberto Sassu   2017-05-16  209  	}
b17fd9ecf Roberto Sassu   2017-05-16  210  
b17fd9ecf Roberto Sassu   2017-05-16  211  	if ((enforce_mask & ENFORCE_BUFEND) && bufp != bufendp) {
b17fd9ecf Roberto Sassu   2017-05-16  212  		pr_err("%s: buf end mismatch: expected: %p, current: %p\n",
b17fd9ecf Roberto Sassu   2017-05-16  213  		       bufname, bufendp, bufp);
b17fd9ecf Roberto Sassu   2017-05-16  214  		return -EINVAL;
b17fd9ecf Roberto Sassu   2017-05-16  215  	}
b17fd9ecf Roberto Sassu   2017-05-16  216  
b17fd9ecf Roberto Sassu   2017-05-16  217  	if (curfields)
b17fd9ecf Roberto Sassu   2017-05-16  218  		*curfields = i;
b17fd9ecf Roberto Sassu   2017-05-16  219  
b17fd9ecf Roberto Sassu   2017-05-16  220  	if (bufcurp)
b17fd9ecf Roberto Sassu   2017-05-16  221  		*bufcurp = bufp;
b17fd9ecf Roberto Sassu   2017-05-16  222  
b17fd9ecf Roberto Sassu   2017-05-16  223  	return 0;
b17fd9ecf Roberto Sassu   2017-05-16  224  }
b17fd9ecf Roberto Sassu   2017-05-16  225  
4d7aeee73 Roberto Sassu   2013-06-07  226  static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
b0b4536f1 Matthew Garrett 2019-05-17  227  				       struct ima_event_data *event_data,
b0b4536f1 Matthew Garrett 2019-05-17  228  				       struct ima_field_data *field_data,
b0b4536f1 Matthew Garrett 2019-05-17  229  				       bool from_vfs)
4d7aeee73 Roberto Sassu   2013-06-07  230  {
3ce1217d6 Roberto Sassu   2013-06-07  231  	/*
4d7aeee73 Roberto Sassu   2013-06-07  232  	 * digest formats:
4d7aeee73 Roberto Sassu   2013-06-07  233  	 *  - DATA_FMT_DIGEST: digest
4d7aeee73 Roberto Sassu   2013-06-07  234  	 *  - DATA_FMT_DIGEST_WITH_ALGO: [<hash algo>] + ':' + '\0' + digest,
4d7aeee73 Roberto Sassu   2013-06-07  235  	 *    where <hash algo> is provided if the hash algoritm is not
4d7aeee73 Roberto Sassu   2013-06-07  236  	 *    SHA1 or MD5
4d7aeee73 Roberto Sassu   2013-06-07  237  	 */
4d7aeee73 Roberto Sassu   2013-06-07  238  	u8 buffer[CRYPTO_MAX_ALG_NAME + 2 + IMA_MAX_DIGEST_SIZE] = { 0 };
4d7aeee73 Roberto Sassu   2013-06-07  239  	enum data_formats fmt = DATA_FMT_DIGEST;
4d7aeee73 Roberto Sassu   2013-06-07  240  	u32 offset = 0;
4d7aeee73 Roberto Sassu   2013-06-07  241  
b0b4536f1 Matthew Garrett 2019-05-17  242  	if (from_vfs)
b0b4536f1 Matthew Garrett 2019-05-17  243  		offset += snprintf(buffer, 5, "vfs:");
b0b4536f1 Matthew Garrett 2019-05-17  244  
dcf4e3928 Roberto Sassu   2013-11-08  245  	if (hash_algo < HASH_ALGO__LAST) {
4d7aeee73 Roberto Sassu   2013-06-07  246  		fmt = DATA_FMT_DIGEST_WITH_ALGO;
b0b4536f1 Matthew Garrett 2019-05-17  247  		offset += snprintf(buffer + offset, CRYPTO_MAX_ALG_NAME + 1,
b0b4536f1 Matthew Garrett 2019-05-17  248  				   "%s", hash_algo_name[hash_algo]);
4d7aeee73 Roberto Sassu   2013-06-07  249  		buffer[offset] = ':';
4d7aeee73 Roberto Sassu   2013-06-07  250  		offset += 2;
4d7aeee73 Roberto Sassu   2013-06-07  251  	}
4d7aeee73 Roberto Sassu   2013-06-07  252  
4d7aeee73 Roberto Sassu   2013-06-07  253  	if (digest)
4d7aeee73 Roberto Sassu   2013-06-07  254  		memcpy(buffer + offset, digest, digestsize);
4d7aeee73 Roberto Sassu   2013-06-07  255  	else
4d7aeee73 Roberto Sassu   2013-06-07  256  		/*
4d7aeee73 Roberto Sassu   2013-06-07  257  		 * If digest is NULL, the event being recorded is a violation.
4d7aeee73 Roberto Sassu   2013-06-07  258  		 * Make room for the digest by increasing the offset of
4d7aeee73 Roberto Sassu   2013-06-07  259  		 * IMA_DIGEST_SIZE.
4d7aeee73 Roberto Sassu   2013-06-07  260  		 */
4d7aeee73 Roberto Sassu   2013-06-07  261  		offset += IMA_DIGEST_SIZE;
4d7aeee73 Roberto Sassu   2013-06-07  262  
4d7aeee73 Roberto Sassu   2013-06-07  263  	return ima_write_template_field_data(buffer, offset + digestsize,
4d7aeee73 Roberto Sassu   2013-06-07  264  					     fmt, field_data);
4d7aeee73 Roberto Sassu   2013-06-07  265  }
4d7aeee73 Roberto Sassu   2013-06-07  266  
4d7aeee73 Roberto Sassu   2013-06-07  267  /*
4d7aeee73 Roberto Sassu   2013-06-07  268   * This function writes the digest of an event (with size limit).
3ce1217d6 Roberto Sassu   2013-06-07  269   */
23b574193 Roberto Sassu   2015-04-11  270  int ima_eventdigest_init(struct ima_event_data *event_data,
3ce1217d6 Roberto Sassu   2013-06-07  271  			 struct ima_field_data *field_data)
3ce1217d6 Roberto Sassu   2013-06-07  272  {
3ce1217d6 Roberto Sassu   2013-06-07  273  	struct {
3ce1217d6 Roberto Sassu   2013-06-07  274  		struct ima_digest_data hdr;
3ce1217d6 Roberto Sassu   2013-06-07  275  		char digest[IMA_MAX_DIGEST_SIZE];
3ce1217d6 Roberto Sassu   2013-06-07  276  	} hash;
4d7aeee73 Roberto Sassu   2013-06-07  277  	u8 *cur_digest = NULL;
4d7aeee73 Roberto Sassu   2013-06-07  278  	u32 cur_digestsize = 0;
3ce1217d6 Roberto Sassu   2013-06-07  279  	struct inode *inode;
3ce1217d6 Roberto Sassu   2013-06-07  280  	int result;
3ce1217d6 Roberto Sassu   2013-06-07  281  
3ce1217d6 Roberto Sassu   2013-06-07  282  	memset(&hash, 0, sizeof(hash));
3ce1217d6 Roberto Sassu   2013-06-07  283  
8d94eb9b5 Roberto Sassu   2015-04-11  284  	if (event_data->violation)	/* recording a violation. */
3ce1217d6 Roberto Sassu   2013-06-07  285  		goto out;
3ce1217d6 Roberto Sassu   2013-06-07  286  
23b574193 Roberto Sassu   2015-04-11  287  	if (ima_template_hash_algo_allowed(event_data->iint->ima_hash->algo)) {
23b574193 Roberto Sassu   2015-04-11  288  		cur_digest = event_data->iint->ima_hash->digest;
23b574193 Roberto Sassu   2015-04-11  289  		cur_digestsize = event_data->iint->ima_hash->length;
3ce1217d6 Roberto Sassu   2013-06-07  290  		goto out;
3ce1217d6 Roberto Sassu   2013-06-07  291  	}
3ce1217d6 Roberto Sassu   2013-06-07  292  
23b574193 Roberto Sassu   2015-04-11  293  	if (!event_data->file)	/* missing info to re-calculate the digest */
3ce1217d6 Roberto Sassu   2013-06-07  294  		return -EINVAL;
3ce1217d6 Roberto Sassu   2013-06-07  295  
23b574193 Roberto Sassu   2015-04-11  296  	inode = file_inode(event_data->file);
4d7aeee73 Roberto Sassu   2013-06-07  297  	hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
4d7aeee73 Roberto Sassu   2013-06-07  298  	    ima_hash_algo : HASH_ALGO_SHA1;
16bcdb6da Matthew Garrett 2019-05-17 @299  	result = ima_calc_file_hash(event_data->file, &hash.hdr, false);
3ce1217d6 Roberto Sassu   2013-06-07  300  	if (result) {
3ce1217d6 Roberto Sassu   2013-06-07  301  		integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
23b574193 Roberto Sassu   2015-04-11  302  				    event_data->filename, "collect_data",
3ce1217d6 Roberto Sassu   2013-06-07  303  				    "failed", result, 0);
3ce1217d6 Roberto Sassu   2013-06-07  304  		return result;
3ce1217d6 Roberto Sassu   2013-06-07  305  	}
4d7aeee73 Roberto Sassu   2013-06-07  306  	cur_digest = hash.hdr.digest;
4d7aeee73 Roberto Sassu   2013-06-07  307  	cur_digestsize = hash.hdr.length;
3ce1217d6 Roberto Sassu   2013-06-07  308  out:
712a49bd7 Roberto Sassu   2013-11-08  309  	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
b0b4536f1 Matthew Garrett 2019-05-17  310  			       HASH_ALGO__LAST, event_data, field_data, false);
3ce1217d6 Roberto Sassu   2013-06-07  311  }
3ce1217d6 Roberto Sassu   2013-06-07  312  

:::::: The code at line 299 was first introduced by commit
:::::: 16bcdb6da2aa16a1457c8023e4b2efd9cfba5107 IMA: Optionally make use of filesystem-provided hashes

:::::: TO: Matthew Garrett <mjg59@google.com>
:::::: CC: 0day robot <lkp@intel.com>

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

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

* Re: [PATCH V3 1/6] VFS: Add a call to obtain a file's hash
  2019-05-17 21:24 ` [PATCH V3 1/6] VFS: Add a call to obtain a file's hash Matthew Garrett
@ 2019-05-18 11:25   ` kbuild test robot
  2019-05-20  7:10   ` Johannes Thumshirn
  1 sibling, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2019-05-18 11:25 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: kbuild-all, linux-integrity, zohar, dmitry.kasatkin, miklos,
	linux-fsdevel, viro, Matthew Garrett

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

Hi Matthew,

I love your patch! Yet something to improve:

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

url:    https://github.com/0day-ci/linux/commits/Matthew-Garrett/IMA-Support-asking-the-VFS-for-a-file-hash/20190518-150531
base:   https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next-integrity
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.2.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/crypto/ux500/hash/hash_core.c:39:0:
>> drivers/crypto/ux500/hash/hash_alg.h:272:6: error: nested redefinition of 'enum hash_algo'
    enum hash_algo {
         ^~~~~~~~~
>> drivers/crypto/ux500/hash/hash_alg.h:272:6: error: redeclaration of 'enum hash_algo'
   In file included from include/linux/fs.h:46:0,
                    from include/linux/huge_mm.h:8,
                    from include/linux/mm.h:527,
                    from include/linux/scatterlist.h:8,
                    from include/linux/dmaengine.h:24,
                    from drivers/crypto/ux500/hash/hash_core.c:29:
   include/uapi/linux/hash_info.h:17:6: note: originally defined here
    enum hash_algo {
         ^~~~~~~~~
   In file included from drivers/crypto/ux500/hash/hash_core.c:39:0:
>> drivers/crypto/ux500/hash/hash_alg.h:273:2: error: redeclaration of enumerator 'HASH_ALGO_SHA1'
     HASH_ALGO_SHA1  = 0x0,
     ^~~~~~~~~~~~~~
   In file included from include/linux/fs.h:46:0,
                    from include/linux/huge_mm.h:8,
                    from include/linux/mm.h:527,
                    from include/linux/scatterlist.h:8,
                    from include/linux/dmaengine.h:24,
                    from drivers/crypto/ux500/hash/hash_core.c:29:
   include/uapi/linux/hash_info.h:20:2: note: previous definition of 'HASH_ALGO_SHA1' was here
     HASH_ALGO_SHA1,
     ^~~~~~~~~~~~~~
   In file included from drivers/crypto/ux500/hash/hash_core.c:39:0:
>> drivers/crypto/ux500/hash/hash_alg.h:274:2: error: redeclaration of enumerator 'HASH_ALGO_SHA256'
     HASH_ALGO_SHA256 = 0x1
     ^~~~~~~~~~~~~~~~
   In file included from include/linux/fs.h:46:0,
                    from include/linux/huge_mm.h:8,
                    from include/linux/mm.h:527,
                    from include/linux/scatterlist.h:8,
                    from include/linux/dmaengine.h:24,
                    from drivers/crypto/ux500/hash/hash_core.c:29:
   include/uapi/linux/hash_info.h:22:2: note: previous definition of 'HASH_ALGO_SHA256' was here
     HASH_ALGO_SHA256,
     ^~~~~~~~~~~~~~~~

vim +272 drivers/crypto/ux500/hash/hash_alg.h

8a63b199 Andreas Westin 2012-04-30  266  
8a63b199 Andreas Westin 2012-04-30  267  /**
8a63b199 Andreas Westin 2012-04-30  268   * enum hash_algo - Enumeration for selecting between SHA1 or SHA2 algorithm.
8a63b199 Andreas Westin 2012-04-30  269   * @HASH_ALGO_SHA1: Indicates that SHA1 is used.
8a63b199 Andreas Westin 2012-04-30  270   * @HASH_ALGO_SHA2: Indicates that SHA2 (SHA256) is used.
8a63b199 Andreas Westin 2012-04-30  271   */
8a63b199 Andreas Westin 2012-04-30 @272  enum hash_algo {
8a63b199 Andreas Westin 2012-04-30 @273  	HASH_ALGO_SHA1		= 0x0,
8a63b199 Andreas Westin 2012-04-30 @274  	HASH_ALGO_SHA256	= 0x1
8a63b199 Andreas Westin 2012-04-30  275  };
8a63b199 Andreas Westin 2012-04-30  276  

:::::: The code at line 272 was first introduced by commit
:::::: 8a63b1994c500d4825ee73dc71502deffe5b135b crypto: ux500 - Add driver for HASH hardware

:::::: TO: Andreas Westin <andreas.westin@stericsson.com>
:::::: CC: Herbert Xu <herbert@gondor.apana.org.au>

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

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

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

* Re: [PATCH V3 1/6] VFS: Add a call to obtain a file's hash
  2019-05-17 21:24 ` [PATCH V3 1/6] VFS: Add a call to obtain a file's hash Matthew Garrett
  2019-05-18 11:25   ` kbuild test robot
@ 2019-05-20  7:10   ` Johannes Thumshirn
  1 sibling, 0 replies; 14+ messages in thread
From: Johannes Thumshirn @ 2019-05-20  7:10 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: linux-integrity, zohar, dmitry.kasatkin, miklos, linux-fsdevel,
	viro, Matthew Garrett

On Fri, May 17, 2019 at 02:24:43PM -0700, Matthew Garrett wrote:
> + * vfs_gethash - obtain a file's hash
[...]
> +int vfs_get_hash(struct file *file, enum hash_algo hash, uint8_t *buf,

Nit: the kernel-doc says it's called vfs_gethash(), but the function is called
vfs_get_hash().
-- 
Johannes Thumshirn                            SUSE Labs Filesystems
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

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

* Re: [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template
  2019-05-17 23:47   ` Mimi Zohar
@ 2019-05-20 20:59     ` Matthew Garrett
  2019-05-20 21:26       ` Mimi Zohar
  0 siblings, 1 reply; 14+ messages in thread
From: Matthew Garrett @ 2019-05-20 20:59 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-integrity, prakhar srivastava, Thiago Jung Bauermann,
	Roberto Sassu, Mimi Zohar, Dmitry Kasatkin, miklos,
	linux-fsdevel, Alexander Viro

On Fri, May 17, 2019 at 4:47 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
> Matthew, I'm going to ask you to separate out this patch from this
> patch set.  Roberto, Thiago, Prakhar, I'm going to ask you to review
> Matthew's patch.  I'm expecting all of the patchsets will be re-posted
> based on it.

Would you like something along these lines merged before reviewing the
rest of them, or is adding the ima-vfs-ng template and allowing admins
to configure it as default sufficient?

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

* Re: [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template
  2019-05-20 20:59     ` Matthew Garrett
@ 2019-05-20 21:26       ` Mimi Zohar
  2019-05-21  0:10         ` prakhar srivastava
  0 siblings, 1 reply; 14+ messages in thread
From: Mimi Zohar @ 2019-05-20 21:26 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: linux-integrity, prakhar srivastava, Thiago Jung Bauermann,
	Roberto Sassu, Mimi Zohar, Dmitry Kasatkin, miklos,
	linux-fsdevel, Alexander Viro

On Mon, 2019-05-20 at 13:59 -0700, Matthew Garrett wrote:
> On Fri, May 17, 2019 at 4:47 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
> > Matthew, I'm going to ask you to separate out this patch from this
> > patch set.  Roberto, Thiago, Prakhar, I'm going to ask you to review
> > Matthew's patch.  I'm expecting all of the patchsets will be re-posted
> > based on it.
> 
> Would you like something along these lines merged before reviewing the
> rest of them, or is adding the ima-vfs-ng template and allowing admins
> to configure it as default sufficient?

This patch is really independent of the patch set.  I'd really like it
as a separate, independent patch in case it needs to be back ported.
 It will also make it easier to review.

Mimi


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

* Re: [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template
  2019-05-20 21:26       ` Mimi Zohar
@ 2019-05-21  0:10         ` prakhar srivastava
  0 siblings, 0 replies; 14+ messages in thread
From: prakhar srivastava @ 2019-05-21  0:10 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: Matthew Garrett, linux-integrity, Thiago Jung Bauermann,
	Roberto Sassu, Mimi Zohar, Dmitry Kasatkin, miklos,
	linux-fsdevel, Alexander Viro

Hi Matthew,Roberto,Thiago,

If you have a branch setup i can then add my patches onto yours?
OR
We can create a new branch to consolidate all changes?

I also sent out v6 of changes it will great if you can take a look.

Thanks,
Prakhar Srivastava
On Mon, May 20, 2019 at 2:27 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
>
> On Mon, 2019-05-20 at 13:59 -0700, Matthew Garrett wrote:
> > On Fri, May 17, 2019 at 4:47 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
> > > Matthew, I'm going to ask you to separate out this patch from this
> > > patch set.  Roberto, Thiago, Prakhar, I'm going to ask you to review
> > > Matthew's patch.  I'm expecting all of the patchsets will be re-posted
> > > based on it.
> >
> > Would you like something along these lines merged before reviewing the
> > rest of them, or is adding the ima-vfs-ng template and allowing admins
> > to configure it as default sufficient?
>
> This patch is really independent of the patch set.  I'd really like it
> as a separate, independent patch in case it needs to be back ported.
>  It will also make it easier to review.
>
> Mimi
>

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

end of thread, other threads:[~2019-05-21  0:10 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-17 21:24 [PATCH V3 0/6] IMA: Support asking the VFS for a file hash Matthew Garrett
2019-05-17 21:24 ` [PATCH V3 1/6] VFS: Add a call to obtain a file's hash Matthew Garrett
2019-05-18 11:25   ` kbuild test robot
2019-05-20  7:10   ` Johannes Thumshirn
2019-05-17 21:24 ` [PATCH V3 2/6] FUSE: Allow filesystems to provide gethash methods Matthew Garrett
2019-05-17 21:24 ` [PATCH V3 3/6] IMA: Allow rule matching on filesystem subtype Matthew Garrett
2019-05-17 21:24 ` [PATCH V3 4/6] IMA: Optionally make use of filesystem-provided hashes Matthew Garrett
2019-05-17 21:24 ` [PATCH V3 5/6] IMA: Add a ima-vfs-sig measurement template Matthew Garrett
2019-05-18 10:04   ` kbuild test robot
2019-05-17 21:24 ` [PATCH V3 6/6] IMA: Allow profiles to define the desired IMA template Matthew Garrett
2019-05-17 23:47   ` Mimi Zohar
2019-05-20 20:59     ` Matthew Garrett
2019-05-20 21:26       ` Mimi Zohar
2019-05-21  0:10         ` prakhar srivastava

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).