[PATCH 0/4] define new fs integrity_read method

STALE3386d SUPERSEDED

Revision v1 of 6 in this series.

19 messages, 4 authors, 2017-07-10 · open the first message on its own page

[PATCH 0/4] define new fs integrity_read method

From: Mimi Zohar <hidden>
Date: 2017-06-09 18:03:52

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.  Originally, the presence
of the integrity_read file operation method, as seen in Christoph's
patch, was intended to signify that the file system supports IMA.

Other than fixing this locking problem, the filesystem should be
able to detect when a file changes and re-measure/re-appraise the
file afterwards.  IMA makes the determination of when a file
changes based on the file system being mounted with i_version, but
even without i_version, files would still be measured/appraised
initially.  Detecting and notifying when a file system is mounted
without i_version should be considered a separate issue and
posted as a separate patch set, independently of this one. (A very
preliminary version is available from
https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git/ 
next-log-iversion-experimental.)

The large majority of filesystems in the fs directory call
generic_file_read_iter() directly (eg. reiserfs, 9p, adfs, affs,
afs, bfs, btrfs, exofs, f2fs, fat, gf2, hfs, hfsplus, hpfs, jfs, minix,
nifs2, omfs, ramfs, romfs, sysv, ubifs, udf, ufs).  Only
filesystems that define their own ->read_iter method, whether it
takes the i_rwsem or not, should be required to define their own
->integrity_read method.

This patch set defines the ->integrity_read file operation method
for xfs, ext4, and tpmfs.  Ceph, cifs, ecryptfs, ext2, fuse, ocfs2
have their own read_iter, but eventually call generic_file_read_iter(),
still need to be converted.  Coda and hugetlbfs have their own
read_iter functions, which do not call generic_file_read_iter().

Although this patch set addresses the locking issue, until the remaining
filesystem define their own ->integrity_read, it introduces the
situation where files that were previously measured, might now not be
measured and files that were previously appraised, might fail to be
appraised properly, even when properly signed/hashed.

Mimi


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

Mimi Zohar (5):
  tmpfs: define integrity_read file operation method
  ima: use existing read file operation method to calculate file hash
  ima: use read_iter (generic_file_read_iter) to calculate file hash
  security: define new LSM sb_post_new_mount hook
  ima: indicate possibly missing file measurements or verification

 fs/btrfs/file.c                   |  1 +
 fs/ext4/file.c                    |  1 +
 fs/namespace.c                    |  2 ++
 fs/xfs/xfs_file.c                 | 21 +++++++++++++++++++++
 include/linux/fs.h                |  1 +
 include/linux/ima.h               |  7 +++++++
 include/linux/lsm_hooks.h         |  9 +++++++++
 include/linux/security.h          |  3 +++
 mm/shmem.c                        |  1 +
 security/integrity/iint.c         | 34 +++++++++++++++++++++++++++-------
 security/integrity/ima/ima_main.c | 31 +++++++++++++++++++++++++++++++
 security/security.c               |  7 +++++++
 12 files changed, 111 insertions(+), 7 deletions(-)

-- 
2.7.4




====
*** BLURB HERE ***

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

Mimi Zohar (3):
  tmpfs: define integrity_read file operation method
  ima: use existing read file operation method to calculate file hash
  ima: use read_iter (generic_file_read_iter) to calculate file hash

 fs/btrfs/file.c           |  1 +
 fs/ext4/file.c            |  1 +
 fs/xfs/xfs_file.c         | 21 +++++++++++++++++++++
 include/linux/fs.h        |  1 +
 mm/shmem.c                |  1 +
 security/integrity/iint.c | 34 +++++++++++++++++++++++++++-------
 6 files changed, 52 insertions(+), 7 deletions(-)

-- 
2.7.4

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

[PATCH 1/4] ima: use fs method to read integrity data

From: Mimi Zohar <hidden>
Date: 2017-06-09 18:03:54

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.

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Mimi Zohar <redacted>
---
 fs/btrfs/file.c           |  1 +
 fs/ext4/file.c            |  1 +
 fs/xfs/xfs_file.c         | 21 +++++++++++++++++++++
 include/linux/fs.h        |  1 +
 security/integrity/iint.c | 20 ++++++++++++++------
 5 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index da1096eb1a40..003e859b56c4 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -3087,6 +3087,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/ext4/file.c b/fs/ext4/file.c
index 831fd6beebf0..e7b2bd43cdc4 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -753,6 +753,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_read_iter,
 };
 
 const struct inode_operations ext4_file_inode_operations = {
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 35703a801372..3d6ace2a79bc 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -288,6 +288,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.
  *
@@ -1534,6 +1554,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 803e5a9b2654..36edfe84c4bf 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1690,6 +1690,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 *);
 };
 
 struct inode_operations {
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index c710d22042f9..c5489672b5aa 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,
 			  char *addr, unsigned long count)
 {
-	mm_segment_t old_fs;
-	char __user *buf = (char __user *)addr;
+	struct inode *inode = file_inode(file);
+	struct iovec 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_init(&iter, READ | ITER_KVEC, &iov, 1, count);
 
+	ret = file->f_op->integrity_read(&kiocb, &iter);
+	BUG_ON(ret == -EIOCBQUEUED);
 	return ret;
 }
 
-- 
2.7.4

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

[PATCH 2/4] tmpfs: define integrity_read file operation method

From: Mimi Zohar <hidden>
Date: 2017-06-09 18:03:58

Although temporary filesystems for the most part are not something
that we're interested in measuring or appraising, we do want to at least
measure, and at some point appraise, files on the rootfs.

This patch defines an integrity_read file operation method used for
calculating the file hash.

Signed-off-by: Mimi Zohar <redacted>
---
 mm/shmem.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/mm/shmem.c b/mm/shmem.c
index e67d6ba4e98e..16958b20946f 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3846,6 +3846,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
 };
 
-- 
2.7.4

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

[PATCH 3/4] ima: use existing read file operation method to calculate file hash

From: Mimi Zohar <hidden>
Date: 2017-06-09 18:04:01

The few filesystems that currently define the read file operation
method, either call seq_read() or have a filesystem specific read
method.  None of them, at least in the fs directory, take the
i_rwsem.

Since some files on these filesystems were previously
measured/appraised, not measuring them would change the PCR hash
value(s), possibly breaking userspace.  For filesystems that do
not define the integrity_read file operation method and have a
read method, use the read method to calculate the file hash.

Signed-off-by: Mimi Zohar <redacted>
---
 security/integrity/iint.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index c5489672b5aa..e3ef3fba16dc 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -189,20 +189,29 @@ int integrity_kernel_read(struct file *file, loff_t offset,
 	struct iovec iov = { .iov_base = addr, .iov_len = count };
 	struct kiocb kiocb;
 	struct iov_iter iter;
-	ssize_t ret;
+	ssize_t ret = -EBADF;
 
 	lockdep_assert_held(&inode->i_rwsem);
 
 	if (!(file->f_mode & FMODE_READ))
 		return -EBADF;
-	if (!file->f_op->integrity_read)
-		return -EBADF;
 
 	init_sync_kiocb(&kiocb, file);
 	kiocb.ki_pos = offset;
 	iov_iter_init(&iter, READ | ITER_KVEC, &iov, 1, count);
 
-	ret = file->f_op->integrity_read(&kiocb, &iter);
+	if (file->f_op->integrity_read) {
+		ret = file->f_op->integrity_read(&kiocb, &iter);
+	} else if (file->f_op->read) {
+		mm_segment_t old_fs;
+		char __user *buf = (char __user *)addr;
+
+		old_fs = get_fs();
+		set_fs(get_ds());
+		ret = file->f_op->read(file, buf, count, &offset);
+		set_fs(old_fs);
+	}
+
 	BUG_ON(ret == -EIOCBQUEUED);
 	return ret;
 }
-- 
2.7.4

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

[PATCH 4/4] ima: use read_iter (generic_file_read_iter) to calculate file hash

From: Mimi Zohar <hidden>
Date: 2017-06-09 18:04:03

The large marjority of filesystems in the fs directory define
generic_file_read_iter as the read_iter file operation method.

Instead of specifying the integrity_read file operation method
for all of these file systems, continue to calculate the file
hash using the read_iter method, when defined as
generic_file_read_iter.

For all other read_iter methods, define an integrity_read
method.

Signed-off-by: Mimi Zohar <redacted>
---
 security/integrity/iint.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index e3ef3fba16dc..8164f57f5cea 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -202,6 +202,9 @@ int integrity_kernel_read(struct file *file, loff_t offset,
 
 	if (file->f_op->integrity_read) {
 		ret = file->f_op->integrity_read(&kiocb, &iter);
+	} else if (file->f_op->read_iter &&
+		   file->f_op->read_iter == generic_file_read_iter) {
+		ret = file->f_op->read_iter(&kiocb, &iter);
 	} else if (file->f_op->read) {
 		mm_segment_t old_fs;
 		char __user *buf = (char __user *)addr;
-- 
2.7.4

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

[PATCH] sample xfstests IMA-appraisal test module

From: Mimi Zohar <hidden>
Date: 2017-06-09 19:47:28

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

[PATCH] sample xfstests IMA-appraisal test module (resending)

From: Mimi Zohar <hidden>
Date: 2017-06-09 19:56:45

On systems where IMA-appraisal is configured, the file system properly
labeled and the system booted with the "ima_tcb ima_appraise_tcb" boot
command line options, new files created by root will have a file hash
written out as security.ima.

This xfstests creates a file and compares the security.ima before and
after modifying the file.  The results are compared with the "good"
file.

(For filesystems that are configured with IMA-appraisal, but aren't
labeled properly, boot the system with the "ima_appraise=tcb" boot
command line option as well.)

Mimi Zohar [off-list ref]
---
 tests/generic/440     | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/440.out | 13 ++++++++
 tests/generic/group   |  1 +
 3 files changed, 103 insertions(+)
 create mode 100755 tests/generic/440
 create mode 100644 tests/generic/440.out
diff --git a/tests/generic/440 b/tests/generic/440
new file mode 100755
index 0000000..8616a48
--- /dev/null
+++ b/tests/generic/440
@@ -0,0 +1,89 @@
+#! /bin/bash
+# FS QA Test No. 440
+#
+# Tests IMA-appraisal
+# Derived from 062 tests
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+
+if [ "$FSTYP" = "btrfs" ]; then
+. ./common/btrfs
+elif [ "$FSTYP" = "xfs" ]; then
+. ./common/xfs
+fi
+
+_cleanup()
+{
+        cd /
+	echo; echo "*** unmount"
+	_scratch_unmount 2>/dev/null
+	rm -f $tmp.*
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+getfattr()
+{
+    $GETFATTR_PROG --absolute-names -dh $@ 2>&1 | _filter_scratch
+}
+
+setfattr()
+{
+    $SETFATTR_PROG $@ 2>&1 | _filter_scratch
+}
+
+_create_test_bed()
+{
+	echo "*** create temporary file"
+	echo "Hello" >  $SCRATCH_MNT/hello.txt
+}
+
+# real QA test starts here
+_supported_fs generic
+_supported_os Linux
+
+_require_scratch
+_require_attrs
+_require_command "$(which timeout)" "timeout"
+
+# real QA test starts here
+_scratch_mkfs > /dev/null 2>&1 || _fail "mkfs failed"
+_scratch_mount || _fail "mount failed"
+_create_test_bed
+
+xattr="security.ima"
+testfile="hello.txt"
+
+if [ ! -f $SCRATCH_MNT/$testfile ]; then
+	echo "File $testfile does not exist"
+	msleep 1
+fi
+
+echo "*** Reading $SCRATCH_MNT"
+timeout -s KILL 2 cat $SCRATCH_MNT/$testfile > /dev/null
+if [ $? -ne 0 ]; then
+	echo "Failed to read $SCRATCH_MNT/$testfile"
+fi
+
+echo "*** initial security.ima hash"
+getfattr -e hex -n $xattr $SCRATCH_MNT/$testfile
+
+echo " World!" >> $SCRATCH_MNT/$testfile
+
+echo "*** updated security.ima hash"
+getfattr -e hex -n $xattr $SCRATCH_MNT/$testfile
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/440.out b/tests/generic/440.out
new file mode 100644
index 0000000..a827377
--- /dev/null
+++ b/tests/generic/440.out
@@ -0,0 +1,13 @@
+QA output created by 440
+*** create temporary file
+*** Reading /mnt/scratch
+*** initial security.ima hash
+# file: SCRATCH_MNT/hello.txt
+security.ima=0x040466a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18
+
+*** updated security.ima hash
+# file: SCRATCH_MNT/hello.txt
+security.ima=0x0404cddd9990ad741e165a6a50990afe969c2233fc8794d027cdbf382f698a62a22f
+
+
+*** unmount
diff --git a/tests/generic/group b/tests/generic/group
index 5d3e4dc..c1ecc23 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -442,3 +442,4 @@
 437 auto quick
 438 auto
 439 auto quick punch
+440 attr
-- 
2.9.3

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

Re: [PATCH 3/4] ima: use existing read file operation method to calculate file hash

From: Christoph Hellwig <hch@lst.de>
Date: 2017-06-13 06:47:00

A strong and a weak NAK on this.  For one thing you should not
call ->read for fs code at all - use read_iter where it fits
(it does here) or the kernel_read() helper otherwise.

But once again I don't think this is correct - it's a potentially
unsafe default, so please wire up the file systems actually tested
and known to work manually.

E.g. this does the wrong thing for at least NFS and OCFS2.
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [PATCH] sample xfstests IMA-appraisal test module (resending)

From: Christoph Hellwig <hch@lst.de>
Date: 2017-06-13 06:47:29

Adding the fstests list..

On Fri, Jun 09, 2017 at 03:55:43PM -0400, Mimi Zohar wrote:
quoted hunk
On systems where IMA-appraisal is configured, the file system properly
labeled and the system booted with the "ima_tcb ima_appraise_tcb" boot
command line options, new files created by root will have a file hash
written out as security.ima.

This xfstests creates a file and compares the security.ima before and
after modifying the file.  The results are compared with the "good"
file.

(For filesystems that are configured with IMA-appraisal, but aren't
labeled properly, boot the system with the "ima_appraise=tcb" boot
command line option as well.)

Mimi Zohar [off-list ref]
---
 tests/generic/440     | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/generic/440.out | 13 ++++++++
 tests/generic/group   |  1 +
 3 files changed, 103 insertions(+)
 create mode 100755 tests/generic/440
 create mode 100644 tests/generic/440.out
diff --git a/tests/generic/440 b/tests/generic/440
new file mode 100755
index 0000000..8616a48
--- /dev/null
+++ b/tests/generic/440
@@ -0,0 +1,89 @@
+#! /bin/bash
+# FS QA Test No. 440
+#
+# Tests IMA-appraisal
+# Derived from 062 tests
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/attr
+
+if [ "$FSTYP" = "btrfs" ]; then
+. ./common/btrfs
+elif [ "$FSTYP" = "xfs" ]; then
+. ./common/xfs
+fi
+
+_cleanup()
+{
+        cd /
+	echo; echo "*** unmount"
+	_scratch_unmount 2>/dev/null
+	rm -f $tmp.*
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+getfattr()
+{
+    $GETFATTR_PROG --absolute-names -dh $@ 2>&1 | _filter_scratch
+}
+
+setfattr()
+{
+    $SETFATTR_PROG $@ 2>&1 | _filter_scratch
+}
+
+_create_test_bed()
+{
+	echo "*** create temporary file"
+	echo "Hello" >  $SCRATCH_MNT/hello.txt
+}
+
+# real QA test starts here
+_supported_fs generic
+_supported_os Linux
+
+_require_scratch
+_require_attrs
+_require_command "$(which timeout)" "timeout"
+
+# real QA test starts here
+_scratch_mkfs > /dev/null 2>&1 || _fail "mkfs failed"
+_scratch_mount || _fail "mount failed"
+_create_test_bed
+
+xattr="security.ima"
+testfile="hello.txt"
+
+if [ ! -f $SCRATCH_MNT/$testfile ]; then
+	echo "File $testfile does not exist"
+	msleep 1
+fi
+
+echo "*** Reading $SCRATCH_MNT"
+timeout -s KILL 2 cat $SCRATCH_MNT/$testfile > /dev/null
+if [ $? -ne 0 ]; then
+	echo "Failed to read $SCRATCH_MNT/$testfile"
+fi
+
+echo "*** initial security.ima hash"
+getfattr -e hex -n $xattr $SCRATCH_MNT/$testfile
+
+echo " World!" >> $SCRATCH_MNT/$testfile
+
+echo "*** updated security.ima hash"
+getfattr -e hex -n $xattr $SCRATCH_MNT/$testfile
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/440.out b/tests/generic/440.out
new file mode 100644
index 0000000..a827377
--- /dev/null
+++ b/tests/generic/440.out
@@ -0,0 +1,13 @@
+QA output created by 440
+*** create temporary file
+*** Reading /mnt/scratch
+*** initial security.ima hash
+# file: SCRATCH_MNT/hello.txt
+security.ima=0x040466a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18
+
+*** updated security.ima hash
+# file: SCRATCH_MNT/hello.txt
+security.ima=0x0404cddd9990ad741e165a6a50990afe969c2233fc8794d027cdbf382f698a62a22f
+
+
+*** unmount
diff --git a/tests/generic/group b/tests/generic/group
index 5d3e4dc..c1ecc23 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -442,3 +442,4 @@
 437 auto quick
 438 auto
 439 auto quick punch
+440 attr
-- 
2.9.3
---end quoted text---
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [PATCH 3/4] ima: use existing read file operation method to calculate file hash

From: Mimi Zohar <hidden>
Date: 2017-06-13 14:17:55

On Tue, 2017-06-13 at 08:46 +0200, Christoph Hellwig wrote:
A strong and a weak NAK on this.  For one thing you should not
call ->read for fs code at all - use read_iter where it fits
(it does here) or the kernel_read() helper otherwise.
Calling ->read directly is intentional. ?Commit C0430e49b6e7c "ima:
introduce ima_kernel_read()" replaced the call to kernel_read with
ima_kernel_read(), the non-security checking version of kernel_read().
?Subsequently, commit e3c4abbfa97e "integrity: define a new function
integrity_read_file()" renamed ima_read_file() to
integrity_read_file().
But once again I don't think this is correct - it's a potentially
unsafe default, so please wire up the file systems actually tested
and known to work manually.

E.g. this does the wrong thing for at least NFS and OCFS2.
Both NFS and OCFS define their own specific read_iter(),
nfs_file_read() and ocfs2_file_read_iter() respectively. ?As these
file systems have not yet been converted to use ->read_integrity, the
xfstests fail.

Mimi

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

Re: [PATCH 3/4] ima: use existing read file operation method to calculate file hash

From: Christoph Hellwig <hch@lst.de>
Date: 2017-06-13 14:22:10

On Tue, Jun 13, 2017 at 10:17:45AM -0400, Mimi Zohar wrote:
Calling ->read directly is intentional. ?Commit C0430e49b6e7c "ima:
introduce ima_kernel_read()" replaced the call to kernel_read with
ima_kernel_read(), the non-security checking version of kernel_read().
?Subsequently, commit e3c4abbfa97e "integrity: define a new function
integrity_read_file()" renamed ima_read_file() to
integrity_read_file().
Again, the point is you should not call ->read for in-kernel reads.
Both NFS and OCFS define their own specific read_iter(),
nfs_file_read() and ocfs2_file_read_iter() respectively. ?As these
file systems have not yet been converted to use ->read_integrity, the
xfstests fail.
So they will need to be converted.  The xfstests will not just fail,
it will deadlock the calling process with this code.
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [PATCH 3/4] ima: use existing read file operation method to calculate file hash

From: Mimi Zohar <hidden>
Date: 2017-06-13 15:07:46

On Tue, 2017-06-13 at 16:22 +0200, Christoph Hellwig wrote:
On Tue, Jun 13, 2017 at 10:17:45AM -0400, Mimi Zohar wrote:
quoted
Calling ->read directly is intentional. ?Commit C0430e49b6e7c "ima:
introduce ima_kernel_read()" replaced the call to kernel_read with
ima_kernel_read(), the non-security checking version of kernel_read().
?Subsequently, commit e3c4abbfa97e "integrity: define a new function
integrity_read_file()" renamed ima_read_file() to
integrity_read_file().
Again, the point is you should not call ->read for in-kernel reads.
Ok, there was a reason for restoring this behavior. ?Perhaps,
something that was previously being measured wasn't being measured
without it. ?Looking ...
quoted
Both NFS and OCFS define their own specific read_iter(),
nfs_file_read() and ocfs2_file_read_iter() respectively. ?As these
file systems have not yet been converted to use ->read_integrity, the
xfstests fail.
So they will need to be converted.  The xfstests will not just fail,
it will deadlock the calling process with this code.
Right, process_measurement() is fail safe, meaning that any file,
which matches a rule in the IMA policy, that isn't appraised properly
fails.

from ima_main: process_measurement(
out:
        inode_unlock(inode);
        if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
                return -EACCES;
        return 0;

With your patch, we now need to take into consideration that the file
system doesn't support IMA-appraisal. ?We can't just change the
existing behavior, so we will probably need the ability to override
the fail safe behavior for file systems that do not support IMA.

The bigger problem is that files that were previously measured, might
now not be measured, without any indication in the audit logs or the
IMA measurement list.

Mimi

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

Re: [PATCH 3/4] ima: use existing read file operation method to calculate file hash

From: Christoph Hellwig <hch@lst.de>
Date: 2017-06-14 07:03:27

On Tue, Jun 13, 2017 at 11:07:29AM -0400, Mimi Zohar wrote:
The bigger problem is that files that were previously measured, might
now not be measured, without any indication in the audit logs or the
IMA measurement list.
And that's exactly what I've been preaching for a long time - you
need to decide on what your requirements for IMA are and check
for them when enabling it, not just have things sort of work
or not at runtime.
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [PATCH 1/4] ima: use fs method to read integrity data

From: kbuild test robot <hidden>
Date: 2017-06-15 23:49:57

Hi Christoph,

[auto build test WARNING on security/next]
[also build test WARNING on v4.12-rc5 next-20170615]
[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/Mimi-Zohar/ima-use-fs-method-to-read-integrity-data/20170611-062655
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)
quoted
security//integrity/iint.c:189:42: sparse: incorrect type in initializer (different address spaces)
   security//integrity/iint.c:189:42:    expected void [noderef] <asn:1>*iov_base
   security//integrity/iint.c:189:42:    got char *addr

vim +189 security//integrity/iint.c

   173	}
   174	security_initcall(integrity_iintcache_init);
   175	
   176	
   177	/*
   178	 * integrity_kernel_read - read data from the file
   179	 *
   180	 * This is a function for reading file content instead of kernel_read().
   181	 * It does not perform locking checks to ensure it cannot be blocked.
   182	 * It does not perform security checks because it is irrelevant for IMA.
   183	 *
   184	 */
   185	int integrity_kernel_read(struct file *file, loff_t offset,
   186				  char *addr, unsigned long count)
   187	{
   188		struct inode *inode = file_inode(file);
 > 189		struct iovec iov = { .iov_base = addr, .iov_len = count };
   190		struct kiocb kiocb;
   191		struct iov_iter iter;
   192		ssize_t ret;
   193	
   194		lockdep_assert_held(&inode->i_rwsem);
   195	
   196		if (!(file->f_mode & FMODE_READ))
   197			return -EBADF;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [PATCH 1/4] ima: use fs method to read integrity data

From: Christoph Hellwig <hch@lst.de>
Date: 2017-06-16 06:18:45

Yeah, the iovec there should be a kvec..
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [Linux-ima-devel] [PATCH 3/4] ima: use existing read file operation method to calculate file hash

From: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Date: 2017-07-10 14:03:46

On Fri, Jun 9, 2017 at 9:02 PM, Mimi Zohar [off-list ref] wrote:
quoted hunk
The few filesystems that currently define the read file operation
method, either call seq_read() or have a filesystem specific read
method.  None of them, at least in the fs directory, take the
i_rwsem.

Since some files on these filesystems were previously
measured/appraised, not measuring them would change the PCR hash
value(s), possibly breaking userspace.  For filesystems that do
not define the integrity_read file operation method and have a
read method, use the read method to calculate the file hash.

Signed-off-by: Mimi Zohar <redacted>
---
 security/integrity/iint.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index c5489672b5aa..e3ef3fba16dc 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -189,20 +189,29 @@ int integrity_kernel_read(struct file *file, loff_t offset,
        struct iovec iov = { .iov_base = addr, .iov_len = count };
        struct kiocb kiocb;
        struct iov_iter iter;
-       ssize_t ret;
+       ssize_t ret = -EBADF;

        lockdep_assert_held(&inode->i_rwsem);

        if (!(file->f_mode & FMODE_READ))
                return -EBADF;
-       if (!file->f_op->integrity_read)
-               return -EBADF;

        init_sync_kiocb(&kiocb, file);
        kiocb.ki_pos = offset;
        iov_iter_init(&iter, READ | ITER_KVEC, &iov, 1, count);

-       ret = file->f_op->integrity_read(&kiocb, &iter);
+       if (file->f_op->integrity_read) {
+               ret = file->f_op->integrity_read(&kiocb, &iter);
+       } else if (file->f_op->read) {
+               mm_segment_t old_fs;
+               char __user *buf = (char __user *)addr;
+
+               old_fs = get_fs();
+               set_fs(get_ds());
+               ret = file->f_op->read(file, buf, count, &offset);
+               set_fs(old_fs);
+       }
Hi,

Original code was using "__vfs_read()".
Patch 1 replaced use of it by ->integrity_read.
This patch re-added f_op->read() directly...

While __vfs_read() did it differently

if (file->f_op->read)
         return file->f_op->read(file, buf, count, pos);
else if (file->f_op->read_iter)
         return new_sync_read(file, buf, count, pos);


Is avoiding use of __vfs_read() is intentional?

Dmitry

+
        BUG_ON(ret == -EIOCBQUEUED);
        return ret;
 }
--
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linux-ima-devel mailing list
Linux-ima-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-ima-devel


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

Re: [Linux-ima-devel] [PATCH 4/4] ima: use read_iter (generic_file_read_iter) to calculate file hash

From: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
Date: 2017-07-10 14:07:48

On Fri, Jun 9, 2017 at 9:02 PM, Mimi Zohar [off-list ref] wrote:
quoted hunk
The large marjority of filesystems in the fs directory define
generic_file_read_iter as the read_iter file operation method.

Instead of specifying the integrity_read file operation method
for all of these file systems, continue to calculate the file
hash using the read_iter method, when defined as
generic_file_read_iter.

For all other read_iter methods, define an integrity_read
method.

Signed-off-by: Mimi Zohar <redacted>
---
 security/integrity/iint.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index e3ef3fba16dc..8164f57f5cea 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -202,6 +202,9 @@ int integrity_kernel_read(struct file *file, loff_t offset,

        if (file->f_op->integrity_read) {
                ret = file->f_op->integrity_read(&kiocb, &iter);
+       } else if (file->f_op->read_iter &&
+                  file->f_op->read_iter == generic_file_read_iter) {
+               ret = file->f_op->read_iter(&kiocb, &iter);
        } else if (file->f_op->read) {
                mm_segment_t old_fs;
                char __user *buf = (char __user *)addr;
Why not __vfs_read()?? it uses new_sync_read()

else if (file->f_op->read_iter)
    return new_sync_read(file, buf, count, pos);
--
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linux-ima-devel mailing list
Linux-ima-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-ima-devel


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

Re: [Linux-ima-devel] [PATCH 3/4] ima: use existing read file operation method to calculate file hash

From: Mimi Zohar <hidden>
Date: 2017-07-10 15:15:19

On Mon, 2017-07-10 at 17:03 +0300, Dmitry Kasatkin wrote:
On Fri, Jun 9, 2017 at 9:02 PM, Mimi Zohar [off-list ref] wrote:
quoted
The few filesystems that currently define the read file operation
method, either call seq_read() or have a filesystem specific read
method.  None of them, at least in the fs directory, take the
i_rwsem.

Since some files on these filesystems were previously
measured/appraised, not measuring them would change the PCR hash
value(s), possibly breaking userspace.  For filesystems that do
not define the integrity_read file operation method and have a
read method, use the read method to calculate the file hash.

Signed-off-by: Mimi Zohar <redacted>
---
 security/integrity/iint.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index c5489672b5aa..e3ef3fba16dc 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -189,20 +189,29 @@ int integrity_kernel_read(struct file *file, loff_t offset,
        struct iovec iov = { .iov_base = addr, .iov_len = count };
        struct kiocb kiocb;
        struct iov_iter iter;
-       ssize_t ret;
+       ssize_t ret = -EBADF;

        lockdep_assert_held(&inode->i_rwsem);

        if (!(file->f_mode & FMODE_READ))
                return -EBADF;
-       if (!file->f_op->integrity_read)
-               return -EBADF;

        init_sync_kiocb(&kiocb, file);
        kiocb.ki_pos = offset;
        iov_iter_init(&iter, READ | ITER_KVEC, &iov, 1, count);

-       ret = file->f_op->integrity_read(&kiocb, &iter);
+       if (file->f_op->integrity_read) {
+               ret = file->f_op->integrity_read(&kiocb, &iter);
+       } else if (file->f_op->read) {
+               mm_segment_t old_fs;
+               char __user *buf = (char __user *)addr;
+
+               old_fs = get_fs();
+               set_fs(get_ds());
+               ret = file->f_op->read(file, buf, count, &offset);
+               set_fs(old_fs);
+       }
Hi,

Original code was using "__vfs_read()".
Patch 1 replaced use of it by ->integrity_read.
This patch re-added f_op->read() directly...

While __vfs_read() did it differently

if (file->f_op->read)
         return file->f_op->read(file, buf, count, pos);
else if (file->f_op->read_iter)
         return new_sync_read(file, buf, count, pos);


Is avoiding use of __vfs_read() is intentional?
Yes, some filesystems ->read_iter attempt to take the i_rwsem, which
IMA has already taken. ?This patch set introduces a new file operation
method ->integrity_read, which reads the file without re-taking the
lock. ?(This method should probably be renamed ->integrity_read_iter.)

The next version of this patch set will remove this patch, unless
someone provides a reason for needing it. ?At that point, a new method
equivalent to ->read would need to be defined.

Mimi

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

Re: [Linux-ima-devel] [PATCH 4/4] ima: use read_iter (generic_file_read_iter) to calculate file hash

From: Mimi Zohar <hidden>
Date: 2017-07-10 15:23:56

On Mon, 2017-07-10 at 17:07 +0300, Dmitry Kasatkin wrote:
On Fri, Jun 9, 2017 at 9:02 PM, Mimi Zohar [off-list ref] wrote:
quoted
The large marjority of filesystems in the fs directory define
generic_file_read_iter as the read_iter file operation method.

Instead of specifying the integrity_read file operation method
for all of these file systems, continue to calculate the file
hash using the read_iter method, when defined as
generic_file_read_iter.

For all other read_iter methods, define an integrity_read
method.

Signed-off-by: Mimi Zohar <redacted>
---
 security/integrity/iint.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index e3ef3fba16dc..8164f57f5cea 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -202,6 +202,9 @@ int integrity_kernel_read(struct file *file, loff_t offset,

        if (file->f_op->integrity_read) {
                ret = file->f_op->integrity_read(&kiocb, &iter);
+       } else if (file->f_op->read_iter &&
+                  file->f_op->read_iter == generic_file_read_iter) {
+               ret = file->f_op->read_iter(&kiocb, &iter);
        } else if (file->f_op->read) {
                mm_segment_t old_fs;
                char __user *buf = (char __user *)addr;
Why not __vfs_read()?? it uses new_sync_read()
and that calls read_sync_iter(), which calls ->read_iter. ? Is there a
problem with directly calling ->integrity_read instead?

Mimi
else if (file->f_op->read_iter)
    return new_sync_read(file, buf, count, pos);
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help