diff options
Diffstat (limited to 'security/integrity/evm')
-rw-r--r-- | security/integrity/evm/evm.h | 3 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 2 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 3 | ||||
-rw-r--r-- | security/integrity/evm/evm_secfs.c | 29 |
4 files changed, 24 insertions, 13 deletions
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h index f5f12727771a..241aca315b0c 100644 --- a/security/integrity/evm/evm.h +++ b/security/integrity/evm/evm.h @@ -23,6 +23,9 @@ #define EVM_INIT_HMAC 0x0001 #define EVM_INIT_X509 0x0002 +#define EVM_SETUP 0x80000000 /* userland has signaled key load */ + +#define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP) extern int evm_initialized; extern char *evm_hmac; diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 1d32cd20009a..bcd64baf8788 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -80,7 +80,7 @@ static struct shash_desc *init_desc(char type) if (type == EVM_XATTR_HMAC) { if (!(evm_initialized & EVM_INIT_HMAC)) { - pr_err("HMAC key is not set\n"); + pr_err_once("HMAC key is not set\n"); return ERR_PTR(-ENOKEY); } tfm = &hmac_tfm; diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 063d38aef64e..9826c02e2db8 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -49,6 +49,9 @@ char *evm_config_xattrnames[] = { XATTR_NAME_SMACKMMAP, #endif #endif +#ifdef CONFIG_SECURITY_APPARMOR + XATTR_NAME_APPARMOR, +#endif #ifdef CONFIG_IMA_APPRAISE XATTR_NAME_IMA, #endif diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c index c8dccd54d501..319cf16d6603 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); + sprintf(temp, "%d", (evm_initialized & ~EVM_SETUP)); rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); return rc; @@ -61,24 +61,29 @@ static ssize_t evm_read_key(struct file *filp, char __user *buf, static ssize_t evm_write_key(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - char temp[80]; - int i; + int i, ret; - if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_INIT_HMAC)) + if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP)) return -EPERM; - if (count >= sizeof(temp) || count == 0) - return -EINVAL; - - if (copy_from_user(temp, buf, count) != 0) - return -EFAULT; + ret = kstrtoint_from_user(buf, count, 0, &i); - temp[count] = '\0'; + if (ret) + return ret; - if ((sscanf(temp, "%d", &i) != 1) || (i != 1)) + /* Reject invalid values */ + if (!i || (i & ~EVM_INIT_MASK) != 0) return -EINVAL; - evm_init_key(); + 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; + } + + evm_initialized |= i; return count; } |