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

Commit 23b57419 authored by Roberto Sassu's avatar Roberto Sassu Committed by Mimi Zohar
Browse files

ima: wrap event related data to the new ima_event_data structure



All event related data has been wrapped into the new 'ima_event_data'
structure. The main benefit of this patch is that a new information
can be made available to template fields initialization functions
by simply adding a new field to the new structure instead of modifying
the definition of those functions.

Changelog:
 - v2:
   - f_dentry replaced with f_path.dentry (Roberto Sassu)
   - removed declaration of temporary variables in template field functions
     when possible (suggested by Dmitry Kasatkin)

Signed-off-by: default avatarRoberto Sassu <rsassu@suse.de>
Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
parent 9d03a721
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -52,6 +52,15 @@ extern int ima_used_chip;
extern int ima_hash_algo;
extern int ima_appraise;

/* IMA event related data */
struct ima_event_data {
	struct integrity_iint_cache *iint;
	struct file *file;
	const unsigned char *filename;
	struct evm_ima_xattr_data *xattr_value;
	int xattr_len;
};

/* IMA template field data definition */
struct ima_field_data {
	u8 *data;
@@ -61,10 +70,8 @@ struct ima_field_data {
/* IMA template field definition */
struct ima_template_field {
	const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN];
	int (*field_init) (struct integrity_iint_cache *iint, struct file *file,
			   const unsigned char *filename,
			   struct evm_ima_xattr_data *xattr_value,
			   int xattr_len, struct ima_field_data *field_data);
	int (*field_init)(struct ima_event_data *event_data,
			  struct ima_field_data *field_data);
	void (*field_show)(struct seq_file *m, enum ima_show_type show,
			   struct ima_field_data *field_data);
};
@@ -140,10 +147,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
			   int xattr_len);
void ima_audit_measurement(struct integrity_iint_cache *iint,
			   const unsigned char *filename);
int ima_alloc_init_template(struct integrity_iint_cache *iint,
			    struct file *file, const unsigned char *filename,
			    struct evm_ima_xattr_data *xattr_value,
			    int xattr_len, struct ima_template_entry **entry);
int ima_alloc_init_template(struct ima_event_data *event_data,
			    struct ima_template_entry **entry);
int ima_store_template(struct ima_template_entry *entry, int violation,
		       struct inode *inode, const unsigned char *filename);
void ima_free_template_entry(struct ima_template_entry *entry);
+8 −10
Original line number Diff line number Diff line
@@ -37,10 +37,8 @@ void ima_free_template_entry(struct ima_template_entry *entry)
/*
 * ima_alloc_init_template - create and initialize a new template entry
 */
int ima_alloc_init_template(struct integrity_iint_cache *iint,
			    struct file *file, const unsigned char *filename,
			    struct evm_ima_xattr_data *xattr_value,
			    int xattr_len, struct ima_template_entry **entry)
int ima_alloc_init_template(struct ima_event_data *event_data,
			    struct ima_template_entry **entry)
{
	struct ima_template_desc *template_desc = ima_template_desc_current();
	int i, result = 0;
@@ -55,8 +53,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
		struct ima_template_field *field = template_desc->fields[i];
		u32 len;

		result = field->field_init(iint, file, filename,
					   xattr_value, xattr_len,
		result = field->field_init(event_data,
					   &((*entry)->template_data[i]));
		if (result != 0)
			goto out;
@@ -133,14 +130,14 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
{
	struct ima_template_entry *entry;
	struct inode *inode = file_inode(file);
	struct ima_event_data event_data = {NULL, file, filename, NULL, 0};
	int violation = 1;
	int result;

	/* can overflow, only indicator */
	atomic_long_inc(&ima_htable.violations);

	result = ima_alloc_init_template(NULL, file, filename,
					 NULL, 0, &entry);
	result = ima_alloc_init_template(&event_data, &entry);
	if (result < 0) {
		result = -ENOMEM;
		goto err_out;
@@ -267,13 +264,14 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
	int result = -ENOMEM;
	struct inode *inode = file_inode(file);
	struct ima_template_entry *entry;
	struct ima_event_data event_data = {iint, file, filename,
					    xattr_value, xattr_len};
	int violation = 0;

	if (iint->flags & IMA_MEASURED)
		return;

	result = ima_alloc_init_template(iint, file, filename,
					 xattr_value, xattr_len, &entry);
	result = ima_alloc_init_template(&event_data, &entry);
	if (result < 0) {
		integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
				    op, audit_cause, result, 0);
+3 −2
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ static int __init ima_add_boot_aggregate(void)
	const char *audit_cause = "ENOMEM";
	struct ima_template_entry *entry;
	struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
	struct ima_event_data event_data = {iint, NULL, boot_aggregate_name,
					    NULL, 0};
	int result = -ENOMEM;
	int violation = 0;
	struct {
@@ -70,8 +72,7 @@ static int __init ima_add_boot_aggregate(void)
		}
	}

	result = ima_alloc_init_template(iint, NULL, boot_aggregate_name,
					 NULL, 0, &entry);
	result = ima_alloc_init_template(&event_data, &entry);
	if (result < 0) {
		audit_cause = "alloc_entry";
		goto err_out;
+29 −41
Original line number Diff line number Diff line
@@ -195,9 +195,7 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
/*
 * This function writes the digest of an event (with size limit).
 */
int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
			 const unsigned char *filename,
			 struct evm_ima_xattr_data *xattr_value, int xattr_len,
int ima_eventdigest_init(struct ima_event_data *event_data,
			 struct ima_field_data *field_data)
{
	struct {
@@ -211,25 +209,25 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,

	memset(&hash, 0, sizeof(hash));

	if (!iint)		/* recording a violation. */
	if (!event_data->iint)		/* recording a violation. */
		goto out;

	if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) {
		cur_digest = iint->ima_hash->digest;
		cur_digestsize = iint->ima_hash->length;
	if (ima_template_hash_algo_allowed(event_data->iint->ima_hash->algo)) {
		cur_digest = event_data->iint->ima_hash->digest;
		cur_digestsize = event_data->iint->ima_hash->length;
		goto out;
	}

	if (!file)		/* missing info to re-calculate the digest */
	if (!event_data->file)	/* missing info to re-calculate the digest */
		return -EINVAL;

	inode = file_inode(file);
	inode = file_inode(event_data->file);
	hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
	    ima_hash_algo : HASH_ALGO_SHA1;
	result = ima_calc_file_hash(file, &hash.hdr);
	result = ima_calc_file_hash(event_data->file, &hash.hdr);
	if (result) {
		integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
				    filename, "collect_data",
				    event_data->filename, "collect_data",
				    "failed", result, 0);
		return result;
	}
@@ -243,48 +241,44 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
/*
 * This function writes the digest of an event (without size limit).
 */
int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
			    struct file *file, const unsigned char *filename,
			    struct evm_ima_xattr_data *xattr_value,
			    int xattr_len, struct ima_field_data *field_data)
int ima_eventdigest_ng_init(struct ima_event_data *event_data,
			    struct ima_field_data *field_data)
{
	u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1;
	u32 cur_digestsize = 0;

	/* If iint is NULL, we are recording a violation. */
	if (!iint)
	if (!event_data->iint)
		goto out;

	cur_digest = iint->ima_hash->digest;
	cur_digestsize = iint->ima_hash->length;
	cur_digest = event_data->iint->ima_hash->digest;
	cur_digestsize = event_data->iint->ima_hash->length;

	hash_algo = iint->ima_hash->algo;
	hash_algo = event_data->iint->ima_hash->algo;
out:
	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
					   hash_algo, field_data);
}

static int ima_eventname_init_common(struct integrity_iint_cache *iint,
				     struct file *file,
				     const unsigned char *filename,
static int ima_eventname_init_common(struct ima_event_data *event_data,
				     struct ima_field_data *field_data,
				     bool size_limit)
{
	const char *cur_filename = NULL;
	u32 cur_filename_len = 0;

	BUG_ON(filename == NULL && file == NULL);
	BUG_ON(event_data->filename == NULL && event_data->file == NULL);

	if (filename) {
		cur_filename = filename;
		cur_filename_len = strlen(filename);
	if (event_data->filename) {
		cur_filename = event_data->filename;
		cur_filename_len = strlen(event_data->filename);

		if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX)
			goto out;
	}

	if (file) {
		cur_filename = file->f_path.dentry->d_name.name;
	if (event_data->file) {
		cur_filename = event_data->file->f_path.dentry->d_name.name;
		cur_filename_len = strlen(cur_filename);
	} else
		/*
@@ -300,36 +294,30 @@ static int ima_eventname_init_common(struct integrity_iint_cache *iint,
/*
 * This function writes the name of an event (with size limit).
 */
int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
		       const unsigned char *filename,
		       struct evm_ima_xattr_data *xattr_value, int xattr_len,
int ima_eventname_init(struct ima_event_data *event_data,
		       struct ima_field_data *field_data)
{
	return ima_eventname_init_common(iint, file, filename,
					 field_data, true);
	return ima_eventname_init_common(event_data, field_data, true);
}

/*
 * This function writes the name of an event (without size limit).
 */
int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
			  const unsigned char *filename,
			  struct evm_ima_xattr_data *xattr_value, int xattr_len,
int ima_eventname_ng_init(struct ima_event_data *event_data,
			  struct ima_field_data *field_data)
{
	return ima_eventname_init_common(iint, file, filename,
					 field_data, false);
	return ima_eventname_init_common(event_data, field_data, false);
}

/*
 *  ima_eventsig_init - include the file signature as part of the template data
 */
int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
		      const unsigned char *filename,
		      struct evm_ima_xattr_data *xattr_value, int xattr_len,
int ima_eventsig_init(struct ima_event_data *event_data,
		      struct ima_field_data *field_data)
{
	enum data_formats fmt = DATA_FMT_HEX;
	struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;
	int xattr_len = event_data->xattr_len;
	int rc = 0;

	if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
+6 −16
Original line number Diff line number Diff line
@@ -26,24 +26,14 @@ void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
			      struct ima_field_data *field_data);
void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
			   struct ima_field_data *field_data);
int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
			 const unsigned char *filename,
			 struct evm_ima_xattr_data *xattr_value, int xattr_len,
			 struct ima_field_data *field_data);
int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
		       const unsigned char *filename,
		       struct evm_ima_xattr_data *xattr_value, int xattr_len,
		       struct ima_field_data *field_data);
int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
			    struct file *file, const unsigned char *filename,
			    struct evm_ima_xattr_data *xattr_value,
			    int xattr_len, struct ima_field_data *field_data);
int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
			  const unsigned char *filename,
			  struct evm_ima_xattr_data *xattr_value, int xattr_len,
			  struct ima_field_data *field_data);
int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
		      const unsigned char *filename,
		      struct evm_ima_xattr_data *xattr_value, int xattr_len,
int ima_eventdigest_init(struct ima_event_data *event_data,
			 struct ima_field_data *field_data);
int ima_eventname_init(struct ima_event_data *event_data,
		       struct ima_field_data *field_data);
int ima_eventdigest_ng_init(struct ima_event_data *event_data,
			    struct ima_field_data *field_data);
int ima_eventname_ng_init(struct ima_event_data *event_data,
			  struct ima_field_data *field_data);
int ima_eventsig_init(struct ima_event_data *event_data,
		      struct ima_field_data *field_data);
#endif /* __LINUX_IMA_TEMPLATE_LIB_H */