diff options
Diffstat (limited to 'security/integrity/evm')
| -rw-r--r-- | security/integrity/evm/Kconfig | 48 | ||||
| -rw-r--r-- | security/integrity/evm/evm.h | 33 | ||||
| -rw-r--r-- | security/integrity/evm/evm_crypto.c | 12 | ||||
| -rw-r--r-- | security/integrity/evm/evm_main.c | 41 | ||||
| -rw-r--r-- | security/integrity/evm/evm_posix_acl.c | 3 | ||||
| -rw-r--r-- | security/integrity/evm/evm_secfs.c | 6 | 
6 files changed, 101 insertions, 42 deletions
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig index fea9749c375..d606f3d12d6 100644 --- a/security/integrity/evm/Kconfig +++ b/security/integrity/evm/Kconfig @@ -1,10 +1,10 @@  config EVM  	boolean "EVM support" -	depends on SECURITY && KEYS && (TRUSTED_KEYS=y || TRUSTED_KEYS=n) +	depends on SECURITY +	select KEYS +	select ENCRYPTED_KEYS  	select CRYPTO_HMAC -	select CRYPTO_MD5  	select CRYPTO_SHA1 -	select ENCRYPTED_KEYS  	default n  	help  	  EVM protects a file's security extended attributes against @@ -12,15 +12,41 @@ config EVM  	  If you are unsure how to answer this question, answer N. -config EVM_HMAC_VERSION -	int "EVM HMAC version" +if EVM + +menu "EVM options" + +config EVM_ATTR_FSUUID +	bool "FSUUID (version 2)" +	default y  	depends on EVM -	default 2  	help -	  This options adds EVM HMAC version support. -	  1 - original version -	  2 - add per filesystem unique identifier (UUID) (default) +	  Include filesystem UUID for HMAC calculation. -	  WARNING: changing the HMAC calculation method or adding  +	  Default value is 'selected', which is former version 2. +	  if 'not selected', it is former version 1 + +	  WARNING: changing the HMAC calculation method or adding  	  additional info to the calculation, requires existing EVM -	  labeled file systems to be relabeled.   +	  labeled file systems to be relabeled. + +config EVM_EXTRA_SMACK_XATTRS +	bool "Additional SMACK xattrs" +	depends on EVM && SECURITY_SMACK +	default n +	help +	  Include additional SMACK xattrs for HMAC calculation. + +	  In addition to the original security xattrs (eg. security.selinux, +	  security.SMACK64, security.capability, and security.ima) included +	  in the HMAC calculation, enabling this option includes newly defined +	  Smack xattrs: security.SMACK64EXEC, security.SMACK64TRANSMUTE and +	  security.SMACK64MMAP. + +	  WARNING: changing the HMAC calculation method or adding +	  additional info to the calculation, requires existing EVM +	  labeled file systems to be relabeled. + +endmenu + +endif diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h index 30bd1ec0232..88bfe77efa1 100644 --- a/security/integrity/evm/evm.h +++ b/security/integrity/evm/evm.h @@ -24,7 +24,10 @@  extern int evm_initialized;  extern char *evm_hmac;  extern char *evm_hash; -extern int evm_hmac_version; + +#define EVM_ATTR_FSUUID		0x0001 + +extern int evm_hmac_attrs;  extern struct crypto_shash *hmac_tfm;  extern struct crypto_shash *hash_tfm; @@ -32,19 +35,19 @@ extern struct crypto_shash *hash_tfm;  /* List of EVM protected security xattrs */  extern char *evm_config_xattrnames[]; -extern int evm_init_key(void); -extern int evm_update_evmxattr(struct dentry *dentry, -			       const char *req_xattr_name, -			       const char *req_xattr_value, -			       size_t req_xattr_value_len); -extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, -			 const char *req_xattr_value, -			 size_t req_xattr_value_len, char *digest); -extern int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, -			 const char *req_xattr_value, -			 size_t req_xattr_value_len, char *digest); -extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr, -			 char *hmac_val); -extern int evm_init_secfs(void); +int evm_init_key(void); +int evm_update_evmxattr(struct dentry *dentry, +			const char *req_xattr_name, +			const char *req_xattr_value, +			size_t req_xattr_value_len); +int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, +		  const char *req_xattr_value, +		  size_t req_xattr_value_len, char *digest); +int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, +		  const char *req_xattr_value, +		  size_t req_xattr_value_len, char *digest); +int evm_init_hmac(struct inode *inode, const struct xattr *xattr, +		  char *hmac_val); +int evm_init_secfs(void);  #endif diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 3bab89eb21d..5e9687f02e1 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -13,6 +13,8 @@   *	 Using root's kernel master key (kmk), calculate the HMAC   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/module.h>  #include <linux/crypto.h>  #include <linux/xattr.h> @@ -103,14 +105,14 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,  		umode_t mode;  	} hmac_misc; -	memset(&hmac_misc, 0, sizeof hmac_misc); +	memset(&hmac_misc, 0, sizeof(hmac_misc));  	hmac_misc.ino = inode->i_ino;  	hmac_misc.generation = inode->i_generation;  	hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);  	hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);  	hmac_misc.mode = inode->i_mode; -	crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc); -	if (evm_hmac_version > 1) +	crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc)); +	if (evm_hmac_attrs & EVM_ATTR_FSUUID)  		crypto_shash_update(desc, inode->i_sb->s_uuid,  				    sizeof(inode->i_sb->s_uuid));  	crypto_shash_final(desc, digest); @@ -137,7 +139,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,  	int error;  	int size; -	if (!inode->i_op || !inode->i_op->getxattr) +	if (!inode->i_op->getxattr)  		return -EOPNOTSUPP;  	desc = init_desc(type);  	if (IS_ERR(desc)) @@ -221,7 +223,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,  	desc = init_desc(EVM_XATTR_HMAC);  	if (IS_ERR(desc)) { -		printk(KERN_INFO "init_desc failed\n"); +		pr_info("init_desc failed\n");  		return PTR_ERR(desc);  	} diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index af9b6852f4e..3bcb80df4d0 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -14,6 +14,8 @@   *	evm_inode_removexattr, and evm_verifyxattr   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/module.h>  #include <linux/crypto.h>  #include <linux/audit.h> @@ -30,7 +32,7 @@ static char *integrity_status_msg[] = {  };  char *evm_hmac = "hmac(sha1)";  char *evm_hash = "sha1"; -int evm_hmac_version = CONFIG_EVM_HMAC_VERSION; +int evm_hmac_attrs;  char *evm_config_xattrnames[] = {  #ifdef CONFIG_SECURITY_SELINUX @@ -38,6 +40,11 @@ char *evm_config_xattrnames[] = {  #endif  #ifdef CONFIG_SECURITY_SMACK  	XATTR_NAME_SMACK, +#ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS +	XATTR_NAME_SMACKEXEC, +	XATTR_NAME_SMACKTRANSMUTE, +	XATTR_NAME_SMACKMMAP, +#endif  #endif  #ifdef CONFIG_IMA_APPRAISE  	XATTR_NAME_IMA, @@ -55,6 +62,14 @@ static int __init evm_set_fixmode(char *str)  }  __setup("evm=", evm_set_fixmode); +static void __init evm_init_config(void) +{ +#ifdef CONFIG_EVM_ATTR_FSUUID +	evm_hmac_attrs |= EVM_ATTR_FSUUID; +#endif +	pr_info("HMAC attrs: 0x%x\n", evm_hmac_attrs); +} +  static int evm_find_protected_xattrs(struct dentry *dentry)  {  	struct inode *inode = dentry->d_inode; @@ -62,7 +77,7 @@ static int evm_find_protected_xattrs(struct dentry *dentry)  	int error;  	int count = 0; -	if (!inode->i_op || !inode->i_op->getxattr) +	if (!inode->i_op->getxattr)  		return -EOPNOTSUPP;  	for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) { @@ -123,7 +138,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,  		goto out;  	} -	xattr_len = rc - 1; +	xattr_len = rc;  	/* check value type */  	switch (xattr_data->type) { @@ -143,7 +158,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,  		if (rc)  			break;  		rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM, -					xattr_data->digest, xattr_len, +					(const char *)xattr_data, xattr_len,  					calc.digest, sizeof(calc.digest));  		if (!rc) {  			/* we probably want to replace rsa with hmac here */ @@ -285,12 +300,20 @@ out:   * @xattr_value: pointer to the new extended attribute value   * @xattr_value_len: pointer to the new extended attribute value length   * - * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that - * the current value is valid. + * Before allowing the 'security.evm' protected xattr to be updated, + * verify the existing value is valid.  As only the kernel should have + * access to the EVM encrypted key needed to calculate the HMAC, prevent + * userspace from writing HMAC value.  Writing 'security.evm' requires + * requires CAP_SYS_ADMIN privileges.   */  int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,  		       const void *xattr_value, size_t xattr_value_len)  { +	const struct evm_ima_xattr_data *xattr_data = xattr_value; + +	if ((strcmp(xattr_name, XATTR_NAME_EVM) == 0) +	    && (xattr_data->type == EVM_XATTR_HMAC)) +		return -EPERM;  	return evm_protect_xattr(dentry, xattr_name, xattr_value,  				 xattr_value_len);  } @@ -430,9 +453,11 @@ static int __init init_evm(void)  {  	int error; +	evm_init_config(); +  	error = evm_init_secfs();  	if (error < 0) { -		printk(KERN_INFO "EVM: Error registering secfs\n"); +		pr_info("Error registering secfs\n");  		goto err;  	} @@ -449,7 +474,7 @@ static int __init evm_display_config(void)  	char **xattrname;  	for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) -		printk(KERN_INFO "EVM: %s\n", *xattrname); +		pr_info("%s\n", *xattrname);  	return 0;  } diff --git a/security/integrity/evm/evm_posix_acl.c b/security/integrity/evm/evm_posix_acl.c index b1753e98bf9..46408b9e62e 100644 --- a/security/integrity/evm/evm_posix_acl.c +++ b/security/integrity/evm/evm_posix_acl.c @@ -11,8 +11,9 @@  #include <linux/module.h>  #include <linux/xattr.h> +#include <linux/evm.h> -int posix_xattr_acl(char *xattr) +int posix_xattr_acl(const char *xattr)  {  	int xattr_len = strlen(xattr); diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c index 30f670ad6ac..cf12a04717d 100644 --- a/security/integrity/evm/evm_secfs.c +++ b/security/integrity/evm/evm_secfs.c @@ -13,6 +13,8 @@   *	- Get the key and enable EVM   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/uaccess.h>  #include <linux/module.h>  #include "evm.h" @@ -79,9 +81,9 @@ static ssize_t evm_write_key(struct file *file, const char __user *buf,  	error = evm_init_key();  	if (!error) {  		evm_initialized = 1; -		pr_info("EVM: initialized\n"); +		pr_info("initialized\n");  	} else -		pr_err("EVM: initialization failed\n"); +		pr_err("initialization failed\n");  	return count;  }  | 
