evm: add evm_inode_init_security to initialize new files

Initialize 'security.evm' for new files.

Changelog v7:
- renamed evm_inode_post_init_security to evm_inode_init_security
- moved struct xattr definition to earlier patch
- allocate xattr name
Changelog v6:
- Use 'struct evm_ima_xattr_data'

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
This commit is contained in:
Mimi Zohar 2011-03-09 14:40:44 -05:00
parent 975d294373
commit cb72318069
4 changed files with 72 additions and 0 deletions

View file

@ -9,6 +9,7 @@
#define _LINUX_EVM_H
#include <linux/integrity.h>
#include <linux/xattr.h>
#ifdef CONFIG_EVM
extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
@ -25,6 +26,9 @@ extern void evm_inode_post_setxattr(struct dentry *dentry,
extern int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name);
extern void evm_inode_post_removexattr(struct dentry *dentry,
const char *xattr_name);
extern int evm_inode_init_security(struct inode *inode,
const struct xattr *xattr_array,
struct xattr *evm);
#else
#ifdef CONFIG_INTEGRITY
static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
@ -67,5 +71,12 @@ static inline void evm_inode_post_removexattr(struct dentry *dentry,
return;
}
static inline int evm_inode_init_security(struct inode *inode,
const struct xattr *xattr_array,
struct xattr *evm)
{
return -EOPNOTSUPP;
}
#endif /* CONFIG_EVM_H */
#endif /* LINUX_EVM_H */

View file

@ -12,6 +12,7 @@
* File: evm.h
*
*/
#include <linux/xattr.h>
#include <linux/security.h>
#include "../integrity.h"
@ -29,5 +30,7 @@ extern int evm_update_evmxattr(struct dentry *dentry,
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_init_hmac(struct inode *inode, const struct xattr *xattr,
char *hmac_val);
extern int evm_init_secfs(void);
extern void evm_cleanup_secfs(void);

View file

@ -157,6 +157,26 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
return rc;
}
int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
char *hmac_val)
{
struct hash_desc desc;
struct scatterlist sg[1];
int error;
error = init_desc(&desc);
if (error != 0) {
printk(KERN_INFO "init_desc failed\n");
return error;
}
sg_init_one(sg, lsm_xattr->value, lsm_xattr->value_len);
crypto_hash_update(&desc, sg, lsm_xattr->value_len);
hmac_add_misc(&desc, inode, hmac_val);
crypto_free_hash(desc.tfm);
return 0;
}
/*
* Get the key from the TPM for the SHA1-HMAC
*/

View file

@ -98,6 +98,12 @@ static int evm_protected_xattr(const char *req_xattr_name)
found = 1;
break;
}
if (strncmp(req_xattr_name,
*xattrname + XATTR_SECURITY_PREFIX_LEN,
strlen(req_xattr_name)) == 0) {
found = 1;
break;
}
}
return found;
}
@ -245,6 +251,38 @@ void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
return;
}
/*
* evm_inode_init_security - initializes security.evm
*/
int evm_inode_init_security(struct inode *inode,
const struct xattr *lsm_xattr,
struct xattr *evm_xattr)
{
struct evm_ima_xattr_data *xattr_data;
int rc;
if (!evm_initialized || !evm_protected_xattr(lsm_xattr->name))
return -EOPNOTSUPP;
xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
if (!xattr_data)
return -ENOMEM;
xattr_data->type = EVM_XATTR_HMAC;
rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
if (rc < 0)
goto out;
evm_xattr->value = xattr_data;
evm_xattr->value_len = sizeof(*xattr_data);
evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS);
return 0;
out:
kfree(xattr_data);
return rc;
}
EXPORT_SYMBOL_GPL(evm_inode_init_security);
static struct crypto_hash *tfm_hmac; /* preload crypto alg */
static int __init init_evm(void)
{