linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/4] define new fs integrity_read method
@ 2017-08-10 23:41 Mimi Zohar
  2017-08-10 23:41 ` [PATCH v5 1/4] ima: always measure and audit files in policy Mimi Zohar
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Mimi Zohar @ 2017-08-10 23:41 UTC (permalink / raw)
  To: Christoph Hellwig, Al Viro
  Cc: Mimi Zohar, James Morris, linux-fsdevel, linux-ima-devel,
	linux-security-module

With the introduction of IMA-appraisal and the need to write file
hashes as security xattrs, IMA needed to take the global i_mutex
lock.  process_measurement() took the iint->mutex first and then
the i_mutex, while setxattr, chmod and chown took the locks in
reverse order.  To resolve this potential deadlock, the iint->mutex
was removed.

Some filesystems have recently replaced their filesystem dependent
lock with the global i_rwsem (formerly the i_mutex) to read a file.
As a result, when IMA attempts to calculate the file hash, reading
the file attempts to take the i_rwsem again.

To resolve this locking problem, this patch set introduces a new
->integrity_read file operation method.  Until all filesystems
define the new ->integrity_read method, files that were previously
measured might not be currently measured and files that were
previously appraised might fail to be appraised properly.

Version 2 of this patch set, introduced measurement entries and
IMA-audit messages containing file hash values of 0's, instead
of the actual file hash, to indicate that the file hash could not
be calculated.  Like for any other file signature verification
error, file access/execute permission is denied.

To override the IMA policy, allowing unverified code to be
accessed/executed on filesystems not supported by IMA, version 2 of
this patch set defined a new policy "action" named "dont_failsafe"
and a new builtin policy named "fs_unsafe", which can be specified
on the boot command line.

Direct Access:
Although the new integrity_read method works for files opened with
the "O_DIRECT" flag on block devices that support DAX, for consistency
instead of failing just the buffered read, this patch set fails both
buffered read and DAX.  (Refer to commit f9b2a735bddd "ima: audit log
files opened with O_DIRECT flag" for an explanation of the buffered
read locking issues.)


Change log v5:
- fail files opened O_DIRECT, but include access attempt in measurement
list.
- removed ocf2 and gfs2 integrity_read support.

Change log v4:
- define ext2/4 specific ->integrity_read functions based Jan Kara's
review.
- properly fail file open with O_DIRECT on filesystems not mounted
with "-o dax".
- remove the "permit_directio" IMA policy option.

Change log v3:
- define simple_read_iter_from_buffer
- replace the existing efivarfs ->read method with ->read_iter method.
- squashed other fs definitions of ->integrity_read with this patch.
- include dont_failsafe rule when displaying policy.
- fail attempt to add dont_failsafe rule when appending to the policy.
- moved '---' divider before change log, as requested in review.

Mimi

Christoph Hellwig (1):
  ima: use fs method to read integrity data

Mimi Zohar (3):
  ima: always measure and audit files in policy
  ima: define "dont_failsafe" policy action rule
  ima: define "fs_unsafe" builtin policy

 Documentation/ABI/testing/ima_policy            |  3 +-
 Documentation/admin-guide/kernel-parameters.txt |  8 +++-
 fs/btrfs/file.c                                 |  1 +
 fs/efivarfs/file.c                              | 12 ++---
 fs/ext2/file.c                                  | 17 +++++++
 fs/ext4/file.c                                  | 20 +++++++++
 fs/f2fs/file.c                                  |  1 +
 fs/jffs2/file.c                                 |  1 +
 fs/jfs/file.c                                   |  1 +
 fs/libfs.c                                      | 32 +++++++++++++
 fs/nilfs2/file.c                                |  1 +
 fs/ramfs/file-mmu.c                             |  1 +
 fs/ramfs/file-nommu.c                           |  1 +
 fs/ubifs/file.c                                 |  1 +
 fs/xfs/xfs_file.c                               | 21 +++++++++
 include/linux/fs.h                              |  3 ++
 mm/shmem.c                                      |  1 +
 security/integrity/iint.c                       | 20 ++++++---
 security/integrity/ima/ima.h                    |  1 +
 security/integrity/ima/ima_api.c                | 60 ++++++++++++++-----------
 security/integrity/ima/ima_crypto.c             | 10 +++++
 security/integrity/ima/ima_main.c               | 19 +++++---
 security/integrity/ima/ima_policy.c             | 41 ++++++++++++++++-
 23 files changed, 231 insertions(+), 45 deletions(-)

-- 
2.7.4

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

* [PATCH v5 1/4] ima: always measure and audit files in policy
  2017-08-10 23:41 [PATCH v5 0/4] define new fs integrity_read method Mimi Zohar
@ 2017-08-10 23:41 ` Mimi Zohar
  2017-08-11 10:18   ` Christoph Hellwig
  2017-08-10 23:41 ` [PATCH v5 2/4] ima: use fs method to read integrity data Mimi Zohar
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Mimi Zohar @ 2017-08-10 23:41 UTC (permalink / raw)
  To: Christoph Hellwig, Al Viro
  Cc: Mimi Zohar, James Morris, linux-fsdevel, linux-ima-devel,
	linux-security-module

All files matching a "measure" rule must be included in the IMA
measurement list, even when the file hash cannot be calculated.
Similarly, all files matching an "audit" rule must be audited, even
when the file hash can not be calculated.

The file data hash field contained in the IMA measurement list template
data will contain 0's instead of the actual file hash digest.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

---
Changelog v5:
- Fail files opened O_DIRECT, but include attempt in measurement list.

Changelog v4:
- Based on both -EBADF and -EINVAL
- clean up ima_collect_measurement()

 security/integrity/ima/ima_api.c    | 60 +++++++++++++++++++++----------------
 security/integrity/ima/ima_crypto.c | 10 +++++++
 security/integrity/ima/ima_main.c   |  7 ++---
 3 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index c2edba8de35e..f110a60e5db6 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -199,42 +199,52 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 	struct inode *inode = file_inode(file);
 	const char *filename = file->f_path.dentry->d_name.name;
 	int result = 0;
+	int length;
+	void *tmpbuf;
+	u64 i_version;
 	struct {
 		struct ima_digest_data hdr;
 		char digest[IMA_MAX_DIGEST_SIZE];
 	} hash;
 
-	if (!(iint->flags & IMA_COLLECTED)) {
-		u64 i_version = file_inode(file)->i_version;
+	if (iint->flags & IMA_COLLECTED)
+		goto out;
 
-		if (file->f_flags & O_DIRECT) {
-			audit_cause = "failed(directio)";
-			result = -EACCES;
-			goto out;
-		}
+	i_version = file_inode(file)->i_version;
+	hash.hdr.algo = algo;
 
-		hash.hdr.algo = algo;
-
-		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,
-						GFP_NOFS);
-			if (tmpbuf) {
-				iint->ima_hash = tmpbuf;
-				memcpy(iint->ima_hash, &hash, length);
-				iint->version = i_version;
-				iint->flags |= IMA_COLLECTED;
-			} else
-				result = -ENOMEM;
-		}
+	/* Initialize hash digest to 0's in case of failure */
+	memset(&hash.digest, 0, sizeof(hash.digest));
+
+	result = (!buf) ?  ima_calc_file_hash(file, &hash.hdr) :
+		ima_calc_buffer_hash(buf, size, &hash.hdr);
+
+	if (result && result != -EBADF && result != -EINVAL)
+		goto out;
+
+	length = sizeof(hash.hdr) + hash.hdr.length;
+	tmpbuf = krealloc(iint->ima_hash, length, GFP_NOFS);
+	if (!tmpbuf) {
+		result = -ENOMEM;
+		goto out;
 	}
+
+	iint->ima_hash = tmpbuf;
+	memcpy(iint->ima_hash, &hash, length);
+	iint->version = i_version;
+
+	/* Possibly temporary failure due to type of read (eg. DAX, O_DIRECT) */
+	if (result != -EBADF && result != -EINVAL)
+		iint->flags |= IMA_COLLECTED;
 out:
-	if (result)
+	if (result) {
+		if (file->f_flags & O_DIRECT)
+			audit_cause = "failed(directio)";
+
 		integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
 				    filename, "collect_data", audit_cause,
 				    result, 0);
+	}
 	return result;
 }
 
@@ -278,7 +288,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
 	}
 
 	result = ima_store_template(entry, violation, inode, filename, pcr);
-	if (!result || result == -EEXIST) {
+	if ((!result || result == -EEXIST) && !(file->f_flags & O_DIRECT)) {
 		iint->flags |= IMA_MEASURED;
 		iint->measured_pcrs |= (0x1 << pcr);
 	}
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 802d5d20f36f..afdc8da1269c 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -441,6 +441,16 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
 	loff_t i_size;
 	int rc;
 
+	/*
+	 * O_DIRECT not supported for buffered read. For consistency,
+	 * don't support O_DIRECT on DAX either.
+	 */
+	if (file->f_flags & O_DIRECT) {
+		hash->length = hash_digest_size[ima_hash_algo];
+		hash->algo = ima_hash_algo;
+		return -EINVAL;
+	}
+
 	i_size = i_size_read(file_inode(file));
 
 	if (ima_ahash_minsize && i_size >= ima_ahash_minsize) {
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 2aebb7984437..eccac00c7e94 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -235,11 +235,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
 	hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
 
 	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;
+	if (rc != 0 && rc != -EBADF && rc != -EINVAL)
 		goto out_digsig;
-	}
 
 	if (!pathbuf)	/* ima_rdwr_violation possibly pre-fetched */
 		pathname = ima_d_path(&file->f_path, &pathbuf, filename);
@@ -247,7 +244,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
 	if (action & IMA_MEASURE)
 		ima_store_measurement(iint, file, pathname,
 				      xattr_value, xattr_len, pcr);
-	if (action & IMA_APPRAISE_SUBMASK)
+	if ((rc == 0) && (action & IMA_APPRAISE_SUBMASK))
 		rc = ima_appraise_measurement(func, iint, file, pathname,
 					      xattr_value, xattr_len, opened);
 	if (action & IMA_AUDIT)
-- 
2.7.4

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

* [PATCH v5 2/4] ima: use fs method to read integrity data
  2017-08-10 23:41 [PATCH v5 0/4] define new fs integrity_read method Mimi Zohar
  2017-08-10 23:41 ` [PATCH v5 1/4] ima: always measure and audit files in policy Mimi Zohar
@ 2017-08-10 23:41 ` Mimi Zohar
  2017-08-11 10:21   ` Christoph Hellwig
  2017-08-10 23:41 ` [PATCH v5 3/4] ima: define "dont_failsafe" policy action rule Mimi Zohar
  2017-08-10 23:41 ` [PATCH v5 4/4] ima: define "fs_unsafe" builtin policy Mimi Zohar
  3 siblings, 1 reply; 11+ messages in thread
From: Mimi Zohar @ 2017-08-10 23:41 UTC (permalink / raw)
  To: Christoph Hellwig, Al Viro
  Cc: James Morris, linux-fsdevel, linux-ima-devel,
	linux-security-module, Matthew Garrett, Jan Kara,
	Theodore Ts'o, Andreas Dilger, Jaegeuk Kim, Chao Yu,
	Steven Whitehouse, Bob Peterson, David Woodhouse, Dave Kleikamp,
	Ryusuke Konishi, Mark Fasheh, Joel Becker, Richard Weinberger,
	Darrick J. Wong, Hugh Dickins, Chris Mason, Mimi Zohar

From: Christoph Hellwig <hch@lst.de>

Add a new ->integrity_read file operation to read data for integrity
hash collection.  This is defined to be equivalent to ->read_iter,
except that it will be called with the i_rwsem held exclusively.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: Matthew Garrett <matthew.garrett@nebula.com>
Cc: Jan Kara <jack@suse.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: Chao Yu <yuchao0@huawei.com>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Bob Peterson <rpeterso@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Dave Kleikamp <shaggy@kernel.org>
Cc: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Cc: Mark Fasheh <mfasheh@versity.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Richard Weinberger <richard@nod.at>
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Chris Mason <clm@fb.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

---
Changelog v5:
- removed ocf2 and gfs2 integrity_read support.
- removed ext4 special case to fail O_DIRECT open for buffered read.

Changelog v4:
- define ext2/4 specific ->integrity_read functions.
- properly fail file open with O_DIRECT on filesystem not mounted
with "-o dax".

Changelog v3:
- define simple_read_iter_from_buffer
- replace the existing efivarfs ->read method with ->read_iter method.
- squashed other fs definitions of ->integrity_read with this patch.

Changelog v2:
- change iovec to kvec

Changelog v1:
- update the patch description, removing the concept that the presence of
->integrity_read indicates that the file system can support IMA. (Mimi)

 fs/btrfs/file.c           |  1 +
 fs/efivarfs/file.c        | 12 +++++++-----
 fs/ext2/file.c            | 17 +++++++++++++++++
 fs/ext4/file.c            | 20 ++++++++++++++++++++
 fs/f2fs/file.c            |  1 +
 fs/jffs2/file.c           |  1 +
 fs/jfs/file.c             |  1 +
 fs/libfs.c                | 32 ++++++++++++++++++++++++++++++++
 fs/nilfs2/file.c          |  1 +
 fs/ramfs/file-mmu.c       |  1 +
 fs/ramfs/file-nommu.c     |  1 +
 fs/ubifs/file.c           |  1 +
 fs/xfs/xfs_file.c         | 21 +++++++++++++++++++++
 include/linux/fs.h        |  3 +++
 mm/shmem.c                |  1 +
 security/integrity/iint.c | 20 ++++++++++++++------
 16 files changed, 123 insertions(+), 11 deletions(-)

diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 9e75d8a39aac..2542dc66c85c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -3125,6 +3125,7 @@ const struct file_operations btrfs_file_operations = {
 #endif
 	.clone_file_range = btrfs_clone_file_range,
 	.dedupe_file_range = btrfs_dedupe_file_range,
+	.integrity_read = generic_file_read_iter,
 };
 
 void btrfs_auto_defrag_exit(void)
diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c
index 5f22e74bbade..17955a92a5b3 100644
--- a/fs/efivarfs/file.c
+++ b/fs/efivarfs/file.c
@@ -64,9 +64,10 @@ static ssize_t efivarfs_file_write(struct file *file,
 	return bytes;
 }
 
-static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
-		size_t count, loff_t *ppos)
+static ssize_t efivarfs_file_read_iter(struct kiocb *iocb,
+				       struct iov_iter *iter)
 {
+	struct file *file = iocb->ki_filp;
 	struct efivar_entry *var = file->private_data;
 	unsigned long datasize = 0;
 	u32 attributes;
@@ -96,8 +97,8 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
 		goto out_free;
 
 	memcpy(data, &attributes, sizeof(attributes));
-	size = simple_read_from_buffer(userbuf, count, ppos,
-				       data, datasize + sizeof(attributes));
+	size = simple_read_iter_from_buffer(iocb, iter, data,
+					    datasize + sizeof(attributes));
 out_free:
 	kfree(data);
 
@@ -174,8 +175,9 @@ efivarfs_file_ioctl(struct file *file, unsigned int cmd, unsigned long p)
 
 const struct file_operations efivarfs_file_operations = {
 	.open	= simple_open,
-	.read	= efivarfs_file_read,
+	.read_iter = efivarfs_file_read_iter,
 	.write	= efivarfs_file_write,
 	.llseek	= no_llseek,
 	.unlocked_ioctl = efivarfs_file_ioctl,
+	.integrity_read	= efivarfs_file_read_iter,
 };
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index d34d32bdc944..111069de1973 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -192,6 +192,22 @@ static ssize_t ext2_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 	return generic_file_read_iter(iocb, to);
 }
 
+static ssize_t ext2_file_integrity_read_iter(struct kiocb *iocb,
+					     struct iov_iter *to)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+
+	lockdep_assert_held(&inode->i_rwsem);
+#ifdef CONFIG_FS_DAX
+	if (!iov_iter_count(to))
+		return 0; /* skip atime */
+
+	if (IS_DAX(iocb->ki_filp->f_mapping->host))
+		return dax_iomap_rw(iocb, to, &ext2_iomap_ops);
+#endif
+	return generic_file_read_iter(iocb, to);
+}
+
 static ssize_t ext2_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
 #ifdef CONFIG_FS_DAX
@@ -216,6 +232,7 @@ const struct file_operations ext2_file_operations = {
 	.get_unmapped_area = thp_get_unmapped_area,
 	.splice_read	= generic_file_splice_read,
 	.splice_write	= iter_file_splice_write,
+	.integrity_read	= ext2_file_integrity_read_iter,
 };
 
 const struct inode_operations ext2_file_inode_operations = {
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 58294c9a7e1d..3ab4105c8578 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -74,6 +74,25 @@ static ssize_t ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 	return generic_file_read_iter(iocb, to);
 }
 
+static ssize_t ext4_file_integrity_read_iter(struct kiocb *iocb,
+					     struct iov_iter *to)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+
+	lockdep_assert_held(&inode->i_rwsem);
+	if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
+		return -EIO;
+
+	if (!iov_iter_count(to))
+		return 0; /* skip atime */
+
+#ifdef CONFIG_FS_DAX
+	if (IS_DAX(inode))
+		return dax_iomap_rw(iocb, to, &ext4_iomap_ops);
+#endif
+	return generic_file_read_iter(iocb, to);
+}
+
 /*
  * Called when an inode is released. Note that this is different
  * from ext4_file_open: open gets called at every open, but release
@@ -747,6 +766,7 @@ const struct file_operations ext4_file_operations = {
 	.splice_read	= generic_file_splice_read,
 	.splice_write	= iter_file_splice_write,
 	.fallocate	= ext4_fallocate,
+	.integrity_read	= ext4_file_integrity_read_iter,
 };
 
 const struct inode_operations ext4_file_inode_operations = {
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 2706130c261b..82ea81da0b2d 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2514,4 +2514,5 @@ const struct file_operations f2fs_file_operations = {
 #endif
 	.splice_read	= generic_file_splice_read,
 	.splice_write	= iter_file_splice_write,
+	.integrity_read	= generic_file_read_iter,
 };
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index c12476e309c6..5a63034cccf5 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -57,6 +57,7 @@ const struct file_operations jffs2_file_operations =
 	.mmap =		generic_file_readonly_mmap,
 	.fsync =	jffs2_fsync,
 	.splice_read =	generic_file_splice_read,
+	.integrity_read = generic_file_read_iter,
 };
 
 /* jffs2_file_inode_operations */
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 739492c7a3fd..423512a810e4 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -162,4 +162,5 @@ const struct file_operations jfs_file_operations = {
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= jfs_compat_ioctl,
 #endif
+	.integrity_read	= generic_file_read_iter,
 };
diff --git a/fs/libfs.c b/fs/libfs.c
index 3aabe553fc45..b6e304c6828b 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -16,6 +16,7 @@
 #include <linux/exportfs.h>
 #include <linux/writeback.h>
 #include <linux/buffer_head.h> /* sync_mapping_buffers */
+#include <linux/uio.h>
 
 #include <linux/uaccess.h>
 
@@ -676,6 +677,37 @@ ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
 EXPORT_SYMBOL(simple_write_to_buffer);
 
 /**
+ * simple_read_iter_from_buffer - copy data from the buffer to user space
+ * @iocb: struct containing the file, the current position and other info
+ * @to: the user space buffer to read to
+ * @from: the buffer to read from
+ * @available: the size of the buffer
+ *
+ * The simple_read_iter_from_buffer() function reads up to @available bytes
+ * from the current buffer into the user space buffer.
+ *
+ * On success, the current buffer offset is advanced by the number of bytes
+ * read, or a negative value is returned on error.
+ **/
+ssize_t simple_read_iter_from_buffer(struct kiocb *iocb, struct iov_iter *to,
+				     const void *from, size_t available)
+{
+	loff_t pos = iocb->ki_pos;
+	size_t ret;
+
+	if (pos < 0)
+		return -EINVAL;
+	if (pos >= available)
+		return 0;
+	ret = copy_to_iter(from + pos, available - pos, to);
+	if (!ret && iov_iter_count(to))
+		return -EFAULT;
+	iocb->ki_pos = pos + ret;
+	return ret;
+}
+EXPORT_SYMBOL(simple_read_iter_from_buffer);
+
+/**
  * memory_read_from_buffer - copy data from the buffer
  * @to: the kernel space buffer to read to
  * @count: the maximum number of bytes to read
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index c5fa3dee72fc..55e058ac487f 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -150,6 +150,7 @@ const struct file_operations nilfs_file_operations = {
 	/* .release	= nilfs_release_file, */
 	.fsync		= nilfs_sync_file,
 	.splice_read	= generic_file_splice_read,
+	.integrity_read	= generic_file_read_iter,
 };
 
 const struct inode_operations nilfs_file_inode_operations = {
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 12af0490322f..4f24d1b589b1 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -47,6 +47,7 @@ const struct file_operations ramfs_file_operations = {
 	.splice_write	= iter_file_splice_write,
 	.llseek		= generic_file_llseek,
 	.get_unmapped_area	= ramfs_mmu_get_unmapped_area,
+	.integrity_read	= generic_file_read_iter,
 };
 
 const struct inode_operations ramfs_file_inode_operations = {
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 2ef7ce75c062..5ee704fa84e0 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -50,6 +50,7 @@ const struct file_operations ramfs_file_operations = {
 	.splice_read		= generic_file_splice_read,
 	.splice_write		= iter_file_splice_write,
 	.llseek			= generic_file_llseek,
+	.integrity_read		= generic_file_read_iter,
 };
 
 const struct inode_operations ramfs_file_inode_operations = {
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 8cad0b19b404..5e52a315e18b 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1747,4 +1747,5 @@ const struct file_operations ubifs_file_operations = {
 #ifdef CONFIG_COMPAT
 	.compat_ioctl   = ubifs_compat_ioctl,
 #endif
+	.integrity_read = generic_file_read_iter,
 };
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index c4893e226fd8..0a6704b563d6 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -292,6 +292,26 @@ xfs_file_read_iter(
 	return ret;
 }
 
+static ssize_t
+xfs_integrity_read(
+	struct kiocb		*iocb,
+	struct iov_iter		*to)
+{
+	struct inode		*inode = file_inode(iocb->ki_filp);
+	struct xfs_mount	*mp = XFS_I(inode)->i_mount;
+
+	lockdep_assert_held(&inode->i_rwsem);
+
+	XFS_STATS_INC(mp, xs_read_calls);
+
+	if (XFS_FORCED_SHUTDOWN(mp))
+		return -EIO;
+
+	if (IS_DAX(inode))
+		return dax_iomap_rw(iocb, to, &xfs_iomap_ops);
+	return generic_file_read_iter(iocb, to);
+}
+
 /*
  * Zero any on disk space between the current EOF and the new, larger EOF.
  *
@@ -1175,6 +1195,7 @@ const struct file_operations xfs_file_operations = {
 	.fallocate	= xfs_file_fallocate,
 	.clone_file_range = xfs_file_clone_range,
 	.dedupe_file_range = xfs_file_dedupe_range,
+	.integrity_read	= xfs_integrity_read,
 };
 
 const struct file_operations xfs_dir_file_operations = {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6e1fd5d21248..8d0d10e1dd93 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1699,6 +1699,7 @@ struct file_operations {
 			u64);
 	ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
 			u64);
+	ssize_t (*integrity_read)(struct kiocb *, struct iov_iter *);
 } __randomize_layout;
 
 struct inode_operations {
@@ -3097,6 +3098,8 @@ extern void simple_release_fs(struct vfsmount **mount, int *count);
 
 extern ssize_t simple_read_from_buffer(void __user *to, size_t count,
 			loff_t *ppos, const void *from, size_t available);
+extern ssize_t simple_read_iter_from_buffer(struct kiocb *iocb,
+		struct iov_iter *to, const void *from, size_t available);
 extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
 		const void __user *from, size_t count);
 
diff --git a/mm/shmem.c b/mm/shmem.c
index b0aa6075d164..805d99011ca4 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3849,6 +3849,7 @@ static const struct file_operations shmem_file_operations = {
 	.splice_read	= generic_file_splice_read,
 	.splice_write	= iter_file_splice_write,
 	.fallocate	= shmem_fallocate,
+	.integrity_read	= shmem_file_read_iter,
 #endif
 };
 
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 6fc888ca468e..df04f35a1d40 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -21,6 +21,7 @@
 #include <linux/rbtree.h>
 #include <linux/file.h>
 #include <linux/uaccess.h>
+#include <linux/uio.h>
 #include "integrity.h"
 
 static struct rb_root integrity_iint_tree = RB_ROOT;
@@ -184,18 +185,25 @@ security_initcall(integrity_iintcache_init);
 int integrity_kernel_read(struct file *file, loff_t offset,
 			  void *addr, unsigned long count)
 {
-	mm_segment_t old_fs;
-	char __user *buf = (char __user *)addr;
+	struct inode *inode = file_inode(file);
+	struct kvec iov = { .iov_base = addr, .iov_len = count };
+	struct kiocb kiocb;
+	struct iov_iter iter;
 	ssize_t ret;
 
+	lockdep_assert_held(&inode->i_rwsem);
+
 	if (!(file->f_mode & FMODE_READ))
 		return -EBADF;
+	if (!file->f_op->integrity_read)
+		return -EBADF;
 
-	old_fs = get_fs();
-	set_fs(get_ds());
-	ret = __vfs_read(file, buf, count, &offset);
-	set_fs(old_fs);
+	init_sync_kiocb(&kiocb, file);
+	kiocb.ki_pos = offset;
+	iov_iter_kvec(&iter, READ | ITER_KVEC, &iov, 1, count);
 
+	ret = file->f_op->integrity_read(&kiocb, &iter);
+	BUG_ON(ret == -EIOCBQUEUED);
 	return ret;
 }
 
-- 
2.7.4

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

* [PATCH v5 3/4] ima: define "dont_failsafe" policy action rule
  2017-08-10 23:41 [PATCH v5 0/4] define new fs integrity_read method Mimi Zohar
  2017-08-10 23:41 ` [PATCH v5 1/4] ima: always measure and audit files in policy Mimi Zohar
  2017-08-10 23:41 ` [PATCH v5 2/4] ima: use fs method to read integrity data Mimi Zohar
@ 2017-08-10 23:41 ` Mimi Zohar
  2017-08-10 23:41 ` [PATCH v5 4/4] ima: define "fs_unsafe" builtin policy Mimi Zohar
  3 siblings, 0 replies; 11+ messages in thread
From: Mimi Zohar @ 2017-08-10 23:41 UTC (permalink / raw)
  To: Christoph Hellwig, Al Viro
  Cc: Mimi Zohar, James Morris, linux-fsdevel, linux-ima-devel,
	linux-security-module

Permit normally denied access/execute permission for files in policy
on IMA unsupported filesystems.  This patch defines the "dont_failsafe"
policy action rule.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

---
Changelog v3:
- include dont_failsafe rule when displaying policy
- fail attempt to add dont_failsafe rule when appending to the policy

 Documentation/ABI/testing/ima_policy |  3 ++-
 security/integrity/ima/ima.h         |  1 +
 security/integrity/ima/ima_main.c    | 12 +++++++++++-
 security/integrity/ima/ima_policy.c  | 29 ++++++++++++++++++++++++++++-
 4 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index e76432b9954d..f271207743e5 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -17,7 +17,8 @@ Description:
 
 		rule format: action [condition ...]
 
-		action: measure | dont_measure | appraise | dont_appraise | audit
+		action: measure | dont_meaure | appraise | dont_appraise |
+			audit | dont_failsafe
 		condition:= base | lsm  [option]
 			base:	[[func=] [mask=] [fsmagic=] [fsuuid=] [uid=]
 				[euid=] [fowner=]]
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index d52b487ad259..c5f34f7c5b0f 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -224,6 +224,7 @@ void *ima_policy_start(struct seq_file *m, loff_t *pos);
 void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos);
 void ima_policy_stop(struct seq_file *m, void *v);
 int ima_policy_show(struct seq_file *m, void *v);
+void set_failsafe(bool flag);
 
 /* Appraise integrity measurements */
 #define IMA_APPRAISE_ENFORCE	0x01
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index eccac00c7e94..7d0e50f28c14 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -38,6 +38,12 @@ int ima_appraise;
 int ima_hash_algo = HASH_ALGO_SHA1;
 static int hash_setup_done;
 
+static bool ima_failsafe = 1;
+void set_failsafe(bool flag)
+{
+	ima_failsafe = flag;
+}
+
 static int __init hash_setup(char *str)
 {
 	struct ima_template_desc *template_desc = ima_template_desc_current();
@@ -260,8 +266,12 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
 		__putname(pathbuf);
 out:
 	inode_unlock(inode);
-	if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
+	if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) {
+		if (!ima_failsafe && rc == -EBADF)
+			return 0;
+
 		return -EACCES;
+	}
 	return 0;
 }
 
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 95209a5f8595..43b85a4fb8e8 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -40,12 +40,14 @@
 #define APPRAISE	0x0004	/* same as IMA_APPRAISE */
 #define DONT_APPRAISE	0x0008
 #define AUDIT		0x0040
+#define DONT_FAILSAFE	0x0400
 
 #define INVALID_PCR(a) (((a) < 0) || \
 	(a) >= (FIELD_SIZEOF(struct integrity_iint_cache, measured_pcrs) * 8))
 
 int ima_policy_flag;
 static int temp_ima_appraise;
+static bool temp_failsafe = 1;
 
 #define MAX_LSM_RULES 6
 enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
@@ -513,6 +515,9 @@ void ima_update_policy(void)
 	if (ima_rules != policy) {
 		ima_policy_flag = 0;
 		ima_rules = policy;
+
+		/* Only update on initial policy replacement, not append */
+		set_failsafe(temp_failsafe);
 	}
 	ima_update_policy_flag();
 }
@@ -529,7 +534,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_pcr, Opt_dont_failsafe
 };
 
 static match_table_t policy_tokens = {
@@ -560,6 +565,7 @@ static match_table_t policy_tokens = {
 	{Opt_appraise_type, "appraise_type=%s"},
 	{Opt_permit_directio, "permit_directio"},
 	{Opt_pcr, "pcr=%s"},
+	{Opt_dont_failsafe, "dont_failsafe"},
 	{Opt_err, NULL}
 };
 
@@ -630,6 +636,11 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 		if ((*p == '\0') || (*p == ' ') || (*p == '\t'))
 			continue;
 		token = match_token(p, policy_tokens, args);
+		if (entry->action == DONT_FAILSAFE) {
+			/* no args permitted, force invalid rule */
+			token = Opt_dont_failsafe;
+		}
+
 		switch (token) {
 		case Opt_measure:
 			ima_log_string(ab, "action", "measure");
@@ -671,6 +682,19 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 
 			entry->action = AUDIT;
 			break;
+		case Opt_dont_failsafe:
+			ima_log_string(ab, "action", "dont_failsafe");
+
+			if (entry->action != UNKNOWN)
+				result = -EINVAL;
+
+			/* Permit on initial policy replacement only */
+			if (ima_rules != &ima_policy_rules)
+				temp_failsafe = 0;
+			else
+				result = -EINVAL;
+			entry->action = DONT_FAILSAFE;
+			break;
 		case Opt_func:
 			ima_log_string(ab, "func", args[0].from);
 
@@ -949,6 +973,7 @@ void ima_delete_rules(void)
 	int i;
 
 	temp_ima_appraise = 0;
+	temp_failsafe = 1;
 	list_for_each_entry_safe(entry, tmp, &ima_temp_rules, list) {
 		for (i = 0; i < MAX_LSM_RULES; i++)
 			kfree(entry->lsm[i].args_p);
@@ -1040,6 +1065,8 @@ int ima_policy_show(struct seq_file *m, void *v)
 		seq_puts(m, pt(Opt_dont_appraise));
 	if (entry->action & AUDIT)
 		seq_puts(m, pt(Opt_audit));
+	if (entry->action & DONT_FAILSAFE)
+		seq_puts(m, pt(Opt_dont_failsafe));
 
 	seq_puts(m, " ");
 
-- 
2.7.4

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

* [PATCH v5 4/4] ima: define "fs_unsafe" builtin policy
  2017-08-10 23:41 [PATCH v5 0/4] define new fs integrity_read method Mimi Zohar
                   ` (2 preceding siblings ...)
  2017-08-10 23:41 ` [PATCH v5 3/4] ima: define "dont_failsafe" policy action rule Mimi Zohar
@ 2017-08-10 23:41 ` Mimi Zohar
  3 siblings, 0 replies; 11+ messages in thread
From: Mimi Zohar @ 2017-08-10 23:41 UTC (permalink / raw)
  To: Christoph Hellwig, Al Viro
  Cc: Mimi Zohar, James Morris, linux-fsdevel, linux-ima-devel,
	linux-security-module

Permit normally denied access/execute permission for files in policy
on IMA unsupported filesystems.  This patch defines "fs_unsafe", a
builtin policy.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

---
Changelog v3:
- include dont_failsafe rule when displaying policy

 Documentation/admin-guide/kernel-parameters.txt |  8 +++++++-
 security/integrity/ima/ima_policy.c             | 12 ++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index d9c171ce4190..4e303be83df6 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1502,7 +1502,7 @@
 
 	ima_policy=	[IMA]
 			The builtin policies to load during IMA setup.
-			Format: "tcb | appraise_tcb | secure_boot"
+			Format: "tcb | appraise_tcb | secure_boot | fs_unsafe"
 
 			The "tcb" policy measures all programs exec'd, files
 			mmap'd for exec, and all files opened with the read
@@ -1517,6 +1517,12 @@
 			of files (eg. kexec kernel image, kernel modules,
 			firmware, policy, etc) based on file signatures.
 
+			The "fs_unsafe" policy permits normally denied
+			access/execute permission for files in policy on IMA
+			unsupported filesystems.  Note this option, as the
+			name implies, is not safe and not recommended for
+			any environments other than testing.
+
 	ima_tcb		[IMA] Deprecated.  Use ima_policy= instead.
 			Load a policy which meets the needs of the Trusted
 			Computing Base.  This means IMA will measure all
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 43b85a4fb8e8..cddd9dfb01e1 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -169,6 +169,10 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = {
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 };
 
+static struct ima_rule_entry dont_failsafe_rules[] __ro_after_init = {
+	{.action = DONT_FAILSAFE}
+};
+
 static LIST_HEAD(ima_default_rules);
 static LIST_HEAD(ima_policy_rules);
 static LIST_HEAD(ima_temp_rules);
@@ -188,6 +192,7 @@ __setup("ima_tcb", default_measure_policy_setup);
 
 static bool ima_use_appraise_tcb __initdata;
 static bool ima_use_secure_boot __initdata;
+static bool ima_use_dont_failsafe __initdata;
 static int __init policy_setup(char *str)
 {
 	char *p;
@@ -201,6 +206,10 @@ static int __init policy_setup(char *str)
 			ima_use_appraise_tcb = 1;
 		else if (strcmp(p, "secure_boot") == 0)
 			ima_use_secure_boot = 1;
+		else if (strcmp(p, "fs_unsafe") == 0) {
+			ima_use_dont_failsafe = 1;
+			set_failsafe(0);
+		}
 	}
 
 	return 1;
@@ -470,6 +479,9 @@ void __init ima_init_policy(void)
 			temp_ima_appraise |= IMA_APPRAISE_POLICY;
 	}
 
+	if (ima_use_dont_failsafe)
+		list_add_tail(&dont_failsafe_rules[0].list, &ima_default_rules);
+
 	ima_rules = &ima_default_rules;
 	ima_update_policy_flag();
 }
-- 
2.7.4

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

* Re: [PATCH v5 1/4] ima: always measure and audit files in policy
  2017-08-10 23:41 ` [PATCH v5 1/4] ima: always measure and audit files in policy Mimi Zohar
@ 2017-08-11 10:18   ` Christoph Hellwig
  2017-08-11 12:34     ` Mimi Zohar
  0 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2017-08-11 10:18 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: Christoph Hellwig, Al Viro, James Morris, linux-fsdevel,
	linux-ima-devel, linux-security-module

> +	i_version = file_inode(file)->i_version;

This probably wants a comment that i_version might be unreliable
unless the file system supports the change attribute.

> +	result = (!buf) ?  ima_calc_file_hash(file, &hash.hdr) :
> +		ima_calc_buffer_hash(buf, size, &hash.hdr);

Please write this like proper C code:

	if (buf)
		result = ima_calc_buffer_hash(buf, size, &hash.hdr);
	else
		result = ima_calc_file_hash(file, &hash.hdr);

> +++ b/security/integrity/ima/ima_crypto.c
> @@ -441,6 +441,16 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
>  	loff_t i_size;
>  	int rc;
>  
> +	/*
> +	 * O_DIRECT not supported for buffered read. For consistency,
> +	 * don't support O_DIRECT on DAX either.
> +	 */

I can't parse this - O_DIRECT is the opposite of a buffered I/O, including
reads.

> +	if ((rc == 0) && (action & IMA_APPRAISE_SUBMASK))

no need for the first set of inner braces.

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

* Re: [PATCH v5 2/4] ima: use fs method to read integrity data
  2017-08-10 23:41 ` [PATCH v5 2/4] ima: use fs method to read integrity data Mimi Zohar
@ 2017-08-11 10:21   ` Christoph Hellwig
  2017-08-11 13:20     ` Mimi Zohar
  0 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2017-08-11 10:21 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: Christoph Hellwig, Al Viro, James Morris, linux-fsdevel,
	linux-ima-devel, linux-security-module, Matthew Garrett, Jan Kara,
	Theodore Ts'o, Andreas Dilger, Jaegeuk Kim, Chao Yu,
	Steven Whitehouse, Bob Peterson, David Woodhouse, Dave Kleikamp,
	Ryusuke Konishi, Mark Fasheh, Joel Becker, Richard Weinberger,
	Darrick J. Wong, Hugh Dickins, Chris Mason

On Thu, Aug 10, 2017 at 07:41:45PM -0400, Mimi Zohar wrote:
> From: Christoph Hellwig <hch@lst.de>
> 
> Add a new ->integrity_read file operation to read data for integrity
> hash collection.  This is defined to be equivalent to ->read_iter,
> except that it will be called with the i_rwsem held exclusively.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Btw, most of this is yours now, feel free to take over the authorship
with a little credit to me for the initial patch if you want.

> Cc: Matthew Garrett <matthew.garrett@nebula.com>

I don't think that will reach Matthew anymore :)

> -static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
> -		size_t count, loff_t *ppos)
> +static ssize_t efivarfs_file_read_iter(struct kiocb *iocb,
> +				       struct iov_iter *iter)

The efivars switch to read_iter should be a separate patch before
this one.

>  /**
> + * simple_read_iter_from_buffer - copy data from the buffer to user space
> + * @iocb: struct containing the file, the current position and other info
> + * @to: the user space buffer to read to
> + * @from: the buffer to read from
> + * @available: the size of the buffer
> + *
> + * The simple_read_iter_from_buffer() function reads up to @available bytes
> + * from the current buffer into the user space buffer.
> + *
> + * On success, the current buffer offset is advanced by the number of bytes
> + * read, or a negative value is returned on error.
> + **/
> +ssize_t simple_read_iter_from_buffer(struct kiocb *iocb, struct iov_iter *to,
> +				     const void *from, size_t available)

The addition of simple_read_iter_from_buffer should be another separate
patch, before efivars starts using it.

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

* Re: [PATCH v5 1/4] ima: always measure and audit files in policy
  2017-08-11 10:18   ` Christoph Hellwig
@ 2017-08-11 12:34     ` Mimi Zohar
  0 siblings, 0 replies; 11+ messages in thread
From: Mimi Zohar @ 2017-08-11 12:34 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Al Viro, James Morris, linux-fsdevel, linux-ima-devel,
	linux-security-module

On Fri, 2017-08-11 at 12:18 +0200, Christoph Hellwig wrote:
> > +	i_version = file_inode(file)->i_version;
> 
> This probably wants a comment that i_version might be unreliable
> unless the file system supports the change attribute.
> 
> > +	result = (!buf) ?  ima_calc_file_hash(file, &hash.hdr) :
> > +		ima_calc_buffer_hash(buf, size, &hash.hdr);
> 
> Please write this like proper C code:
> 
> 	if (buf)
> 		result = ima_calc_buffer_hash(buf, size, &hash.hdr);
> 	else
> 		result = ima_calc_file_hash(file, &hash.hdr);

Sure

> 
> > +++ b/security/integrity/ima/ima_crypto.c
> > @@ -441,6 +441,16 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
> >  	loff_t i_size;
> >  	int rc;
> >  
> > +	/*
> > +	 * O_DIRECT not supported for buffered read. For consistency,
> > +	 * don't support O_DIRECT on DAX either.
> > +	 */
> 
> I can't parse this - O_DIRECT is the opposite of a buffered I/O, including
> reads.

Right. I'm trying to differentiate between a file opened with the
O_DIRECT flag on a filesystem mounted with/without DAX.  For
consistency, it was recommended to fail both.

> 
> > +	if ((rc == 0) && (action & IMA_APPRAISE_SUBMASK))
> 
> no need for the first set of inner braces.

thanks,

Mimi

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

* Re: [PATCH v5 2/4] ima: use fs method to read integrity data
  2017-08-11 10:21   ` Christoph Hellwig
@ 2017-08-11 13:20     ` Mimi Zohar
  2017-08-11 17:11       ` Mimi Zohar
  0 siblings, 1 reply; 11+ messages in thread
From: Mimi Zohar @ 2017-08-11 13:20 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Al Viro, James Morris, linux-fsdevel, linux-ima-devel,
	linux-security-module, Jan Kara, Theodore Ts'o,
	Andreas Dilger, Jaegeuk Kim, Chao Yu, Steven Whitehouse,
	Bob Peterson, David Woodhouse, Dave Kleikamp, Ryusuke Konishi,
	Mark Fasheh, Joel Becker, Richard Weinberger, Darrick J. Wong,
	Hugh Dickins, Chris Mason, Matthew Garrett

On Fri, 2017-08-11 at 12:21 +0200, Christoph Hellwig wrote:
> On Thu, Aug 10, 2017 at 07:41:45PM -0400, Mimi Zohar wrote:
> > From: Christoph Hellwig <hch@lst.de>
> > 
> > Add a new ->integrity_read file operation to read data for integrity
> > hash collection.  This is defined to be equivalent to ->read_iter,
> > except that it will be called with the i_rwsem held exclusively.
> > 
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Btw, most of this is yours now, feel free to take over the authorship
> with a little credit to me for the initial patch if you want.

Thank you so much for the initial design and patch!

> > Cc: Matthew Garrett <matthew.garrett@nebula.com>
> 
> I don't think that will reach Matthew anymore :)

Trying his other address as listed in MAINTAINERS.

> 
> > -static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
> > -		size_t count, loff_t *ppos)
> > +static ssize_t efivarfs_file_read_iter(struct kiocb *iocb,
> > +				       struct iov_iter *iter)
> 
> The efivars switch to read_iter should be a separate patch before
> this one.

Agreed

> >  /**
> > + * simple_read_iter_from_buffer - copy data from the buffer to user space
> > + * @iocb: struct containing the file, the current position and other info
> > + * @to: the user space buffer to read to
> > + * @from: the buffer to read from
> > + * @available: the size of the buffer
> > + *
> > + * The simple_read_iter_from_buffer() function reads up to @available bytes
> > + * from the current buffer into the user space buffer.
> > + *
> > + * On success, the current buffer offset is advanced by the number of bytes
> > + * read, or a negative value is returned on error.
> > + **/
> > +ssize_t simple_read_iter_from_buffer(struct kiocb *iocb, struct iov_iter *to,
> > +				     const void *from, size_t available)
> 
> The addition of simple_read_iter_from_buffer should be another separate
> patch, before efivars starts using it.

Agreed

Mimi

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

* Re: [PATCH v5 2/4] ima: use fs method to read integrity data
  2017-08-11 13:20     ` Mimi Zohar
@ 2017-08-11 17:11       ` Mimi Zohar
  2017-08-11 17:15         ` Christoph Hellwig
  0 siblings, 1 reply; 11+ messages in thread
From: Mimi Zohar @ 2017-08-11 17:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Al Viro, James Morris, linux-fsdevel, linux-ima-devel,
	linux-security-module, Jan Kara, Theodore Ts'o,
	Andreas Dilger, Jaegeuk Kim, Chao Yu, Steven Whitehouse,
	Bob Peterson, David Woodhouse, Dave Kleikamp, Ryusuke Konishi,
	Mark Fasheh, Joel Becker, Richard Weinberger, Darrick J. Wong,
	Hugh Dickins, Chris Mason, Matthew Garrett

On Fri, 2017-08-11 at 09:20 -0400, Mimi Zohar wrote:
> On Fri, 2017-08-11 at 12:21 +0200, Christoph Hellwig wrote:
> > On Thu, Aug 10, 2017 at 07:41:45PM -0400, Mimi Zohar wrote:
> > > From: Christoph Hellwig <hch@lst.de>
> > > 
> > > Add a new ->integrity_read file operation to read data for integrity
> > > hash collection.  This is defined to be equivalent to ->read_iter,
> > > except that it will be called with the i_rwsem held exclusively.
> > > 
> > > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > 
> > Btw, most of this is yours now, feel free to take over the authorship
> > with a little credit to me for the initial patch if you want.
> 
> Thank you so much for the initial design and patch!

After moving the libfs and efivarfs code to separate patches, the
patch hasn't changed all that much, just additional file systems.  If
you don't object, I'll leave you as the author.

Mimi

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

* Re: [PATCH v5 2/4] ima: use fs method to read integrity data
  2017-08-11 17:11       ` Mimi Zohar
@ 2017-08-11 17:15         ` Christoph Hellwig
  0 siblings, 0 replies; 11+ messages in thread
From: Christoph Hellwig @ 2017-08-11 17:15 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: Christoph Hellwig, Al Viro, James Morris, linux-fsdevel,
	linux-ima-devel, linux-security-module, Jan Kara,
	Theodore Ts'o, Andreas Dilger, Jaegeuk Kim, Chao Yu,
	Steven Whitehouse, Bob Peterson, David Woodhouse, Dave Kleikamp,
	Ryusuke Konishi, Mark Fasheh, Joel Becker, Richard Weinberger,
	Darrick J. Wong, Hugh Dickins, Chris Mason, Matthew Garrett

On Fri, Aug 11, 2017 at 01:11:44PM -0400, Mimi Zohar wrote:
> After moving the libfs and efivarfs code to separate patches, the
> patch hasn't changed all that much, just additional file systems. �If
> you don't object, I'll leave you as the author.

Sure - feel free to handle it whichever way you want.

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

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

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-10 23:41 [PATCH v5 0/4] define new fs integrity_read method Mimi Zohar
2017-08-10 23:41 ` [PATCH v5 1/4] ima: always measure and audit files in policy Mimi Zohar
2017-08-11 10:18   ` Christoph Hellwig
2017-08-11 12:34     ` Mimi Zohar
2017-08-10 23:41 ` [PATCH v5 2/4] ima: use fs method to read integrity data Mimi Zohar
2017-08-11 10:21   ` Christoph Hellwig
2017-08-11 13:20     ` Mimi Zohar
2017-08-11 17:11       ` Mimi Zohar
2017-08-11 17:15         ` Christoph Hellwig
2017-08-10 23:41 ` [PATCH v5 3/4] ima: define "dont_failsafe" policy action rule Mimi Zohar
2017-08-10 23:41 ` [PATCH v5 4/4] ima: define "fs_unsafe" builtin policy Mimi Zohar

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