diff mbox

[3/6] EVM: Allow userland to override the default EVM attributes

Message ID 20170927221653.11219-4-mjg59@google.com (mailing list archive)
State New, archived
Headers show

Commit Message

Matthew Garrett Sept. 27, 2017, 10:16 p.m. UTC
Local policy may wish to provide a different set of metadata to measure
when compared to the kernel defaults. Allow this to be overridden before
the EVM key is initialised, giving userland an opportunity to define it
but locking it down after EVM is enabled.

Signed-off-by: Matthew Garrett <mjg59@google.com>
---
 security/integrity/evm/evm_secfs.c | 74 +++++++++++++++++++++++++++++++++++---
 1 file changed, 70 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index c8dccd54d501..b6678f01ec39 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -20,6 +20,7 @@ 
 #include "evm.h"
 
 static struct dentry *evm_init_tpm;
+static struct dentry *evm_init_flags;
 
 /**
  * evm_read_key - read() for <securityfs>/evm
@@ -88,13 +89,78 @@  static const struct file_operations evm_key_ops = {
 	.write		= evm_write_key,
 };
 
-int __init evm_init_secfs(void)
+/**
+ * evm_read_flags - read() for <securityfs>/evm_flags
+ *
+ * @filp: file pointer, not actually used
+ * @buf: where to put the result
+ * @count: maximum to send along
+ * @ppos: where to start
+ *
+ * Returns number of bytes read or error code, as appropriate
+ */
+static ssize_t evm_read_flags(struct file *filp, char __user *buf,
+			      size_t count, loff_t *ppos)
 {
-	int error = 0;
+	char temp[19];
+	ssize_t rc;
+
+	if (*ppos != 0)
+		return 0;
+
+	sprintf(temp, "0x%llx", evm_default_flags);
+	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
+
+	return rc;
+}
 
+/**
+ * evm_write_flags - write() for <securityfs>/evm_flags
+ * @file: file pointer, not actually used
+ * @buf: where to get the data from
+ * @count: bytes sent
+ * @ppos: where to start
+ *
+ * - sets the components that will be measured in the EVM hash
+ * Returns number of bytes written or error code, as appropriate
+ */
+static ssize_t evm_write_flags(struct file *file, const char __user *buf,
+			       size_t count, loff_t *ppos)
+{
+	int err;
+
+	if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_INIT_HMAC))
+		return -EPERM;
+
+	if (evm_initialized & EVM_INIT_HMAC)
+		return -EINVAL;
+
+	err = kstrtoull_from_user(buf, count, 0, &evm_default_flags);
+	if (err)
+		return err;
+
+	return count;
+}
+
+static const struct file_operations evm_flags_ops = {
+	.read		= evm_read_flags,
+	.write		= evm_write_flags,
+};
+
+int __init evm_init_secfs(void)
+{
 	evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP,
 					      NULL, NULL, &evm_key_ops);
 	if (!evm_init_tpm || IS_ERR(evm_init_tpm))
-		error = -EFAULT;
-	return error;
+		return -EFAULT;
+
+	evm_init_flags = securityfs_create_file("evm_flags", S_IRUSR | S_IRGRP,
+						NULL, NULL, &evm_flags_ops);
+
+	if (!evm_init_flags || IS_ERR(evm_init_flags)) {
+		securityfs_remove(evm_init_tpm);
+		return -EFAULT;
+	}
+
+	return 0;
 }