summaryrefslogtreecommitdiffstats
path: root/security/integrity/evm/evm_secfs.c
diff options
context:
space:
mode:
authorMatthew Garrett <mjg59@google.com>2017-11-07 07:18:35 -0800
committerMimi Zohar <zohar@linux.vnet.ibm.com>2017-12-11 14:27:31 -0500
commitae1ba1676b88e6c62368a433c7e2d0417e9879fd (patch)
treebcbb1a5cba2e439031db519e846f89a91a8b8b2d /security/integrity/evm/evm_secfs.c
parentb7e27bc1d42e8e0cc58b602b529c25cd0071b336 (diff)
EVM: Allow userland to permit modification of EVM-protected metadata
When EVM is enabled it forbids modification of metadata protected by EVM unless there is already a valid EVM signature. If any modification is made, the kernel will then generate a new EVM HMAC. However, this does not map well on use cases which use only asymmetric EVM signatures, as in this scenario the kernel is unable to generate new signatures. This patch extends the /sys/kernel/security/evm interface to allow userland to request that modification of these xattrs be permitted. This is only permitted if no keys have already been loaded. In this configuration, modifying the metadata will invalidate the EVM appraisal on the file in question. This allows packaging systems to write out new files, set the relevant extended attributes and then move them into place. There's also some refactoring of the use of evm_initialized in order to avoid heading down codepaths that assume there's a key available. Signed-off-by: Matthew Garrett <mjg59@google.com> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/integrity/evm/evm_secfs.c')
-rw-r--r--security/integrity/evm/evm_secfs.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index 319cf16d6603..feba03bbedae 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -40,7 +40,7 @@ static ssize_t evm_read_key(struct file *filp, char __user *buf,
if (*ppos != 0)
return 0;
- sprintf(temp, "%d", (evm_initialized & ~EVM_SETUP));
+ sprintf(temp, "%d", (evm_initialized & ~EVM_SETUP_COMPLETE));
rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
return rc;
@@ -63,7 +63,7 @@ static ssize_t evm_write_key(struct file *file, const char __user *buf,
{
int i, ret;
- if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP))
+ if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP_COMPLETE))
return -EPERM;
ret = kstrtoint_from_user(buf, count, 0, &i);
@@ -75,16 +75,30 @@ static ssize_t evm_write_key(struct file *file, const char __user *buf,
if (!i || (i & ~EVM_INIT_MASK) != 0)
return -EINVAL;
+ /* Don't allow a request to freshly enable metadata writes if
+ * keys are loaded.
+ */
+ if ((i & EVM_ALLOW_METADATA_WRITES) &&
+ ((evm_initialized & EVM_KEY_MASK) != 0) &&
+ !(evm_initialized & EVM_ALLOW_METADATA_WRITES))
+ return -EPERM;
+
if (i & EVM_INIT_HMAC) {
ret = evm_init_key();
if (ret != 0)
return ret;
/* Forbid further writes after the symmetric key is loaded */
- i |= EVM_SETUP;
+ i |= EVM_SETUP_COMPLETE;
}
evm_initialized |= i;
+ /* Don't allow protected metadata modification if a symmetric key
+ * is loaded
+ */
+ if (evm_initialized & EVM_INIT_HMAC)
+ evm_initialized &= ~(EVM_ALLOW_METADATA_WRITES);
+
return count;
}