Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb723180 authored by Mimi Zohar's avatar Mimi Zohar
Browse files

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: default avatarMimi Zohar <zohar@us.ibm.com>
parent 975d2943
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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 */
+3 −0
Original line number Diff line number Diff line
@@ -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);
+20 −0
Original line number Diff line number Diff line
@@ -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
 */
+38 −0
Original line number Diff line number Diff line
@@ -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)
{