ima: pass iint to ima_add_violation()

This patch adds the iint associated to the current inode as a new
parameter of ima_add_violation(). The passed iint is always not NULL
if a violation is detected. This modification will be used to determine
the inode for which there is a violation.

Since the 'd' and 'd-ng' template field init() functions were detecting
a violation from the value of the iint pointer, they now check the new
field 'violation', added to the 'ima_event_data' structure.

Changelog:
 - v1:
   - modified an old comment (Roberto Sassu)

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index e13ae546..c996f7e 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -59,6 +59,7 @@
 	const unsigned char *filename;
 	struct evm_ima_xattr_data *xattr_value;
 	int xattr_len;
+	const char *violation;
 };
 
 /* IMA template field data definition */
@@ -110,6 +111,7 @@
 			      struct ima_digest_data *hash);
 int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
 void ima_add_violation(struct file *file, const unsigned char *filename,
+		       struct integrity_iint_cache *iint,
 		       const char *op, const char *cause);
 int ima_init_crypto(void);
 void ima_putc(struct seq_file *m, void *data, int datalen);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 789179b..da3e9a7d 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -126,11 +126,13 @@
  * value is invalidated.
  */
 void ima_add_violation(struct file *file, const unsigned char *filename,
+		       struct integrity_iint_cache *iint,
 		       const char *op, const char *cause)
 {
 	struct ima_template_entry *entry;
 	struct inode *inode = file_inode(file);
-	struct ima_event_data event_data = {NULL, file, filename, NULL, 0};
+	struct ima_event_data event_data = {iint, file, filename, NULL, 0,
+					    cause};
 	int violation = 1;
 	int result;
 
@@ -264,8 +266,8 @@
 	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};
+	struct ima_event_data event_data = {iint, file, filename, xattr_value,
+					    xattr_len, NULL};
 	int violation = 0;
 
 	if (iint->flags & IMA_MEASURED)
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 40e7d2a..69b9235 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -56,7 +56,7 @@
 	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};
+					    NULL, 0, NULL};
 	int result = -ENOMEM;
 	int violation = 0;
 	struct {
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index eeee00dc..c21f09b 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -106,9 +106,10 @@
 	*pathname = ima_d_path(&file->f_path, pathbuf);
 
 	if (send_tomtou)
-		ima_add_violation(file, *pathname, "invalid_pcr", "ToMToU");
+		ima_add_violation(file, *pathname, iint,
+				  "invalid_pcr", "ToMToU");
 	if (send_writers)
-		ima_add_violation(file, *pathname,
+		ima_add_violation(file, *pathname, iint,
 				  "invalid_pcr", "open_writers");
 }
 
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 9472e9d..ea0f8ed 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -211,7 +211,7 @@
 
 	memset(&hash, 0, sizeof(hash));
 
-	if (!iint)		/* recording a violation. */
+	if (event_data->violation)	/* recording a violation. */
 		goto out;
 
 	if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) {
@@ -250,8 +250,7 @@
 	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->violation)	/* recording a violation. */
 		goto out;
 
 	cur_digest = iint->ima_hash->digest;