mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mimi Zohar <zohar@linux.vnet.ibm.com>
To: linux-security-module@vger.kernel.org
Cc: Dmitry Kasatkin <d.kasatkin@samsung.com>,
	linux-kernel@vger.kernel.org, James Morris <jmorris@namei.org>,
	David Howells <dhowells@redhat.com>,
	Mimi Zohar <zohar@linux.vnet.ibm.com>
Subject: [PATCH v2 06/23] ima: use dynamically allocated hash storage
Date: Mon, 21 Oct 2013 18:42:51 -0400	[thread overview]
Message-ID: <1382395388-8108-7-git-send-email-zohar@linux.vnet.ibm.com> (raw)
In-Reply-To: <1382395388-8108-1-git-send-email-zohar@linux.vnet.ibm.com>

From: Dmitry Kasatkin <d.kasatkin@samsung.com>

For each inode in the IMA policy, an iint is allocated.  To support
larger hash digests, the iint digest size changed from 20 bytes to
the maximum supported hash digest size.  Instead of allocating the
maximum size, which most likely is not needed, this patch dynamically
allocates the needed hash storage.

Changelog:
- fix krealloc bug

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/iint.c             |  2 ++
 security/integrity/ima/ima_api.c      | 57 +++++++++++++++++++++++------------
 security/integrity/ima/ima_appraise.c | 16 +++++-----
 security/integrity/integrity.h        |  4 +--
 4 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 74522db..c49d3f1 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -70,6 +70,8 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
 
 static void iint_free(struct integrity_iint_cache *iint)
 {
+	kfree(iint->ima_hash);
+	iint->ima_hash = NULL;
 	iint->version = 0;
 	iint->flags = 0UL;
 	iint->ima_file_status = INTEGRITY_UNKNOWN;
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 1dba98e..5a7942e 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -44,7 +44,10 @@ int ima_store_template(struct ima_template_entry *entry,
 	const char *op = "add_template_measure";
 	const char *audit_cause = "hashing_error";
 	int result;
-	struct ima_digest_data hash;
+	struct {
+		struct ima_digest_data hdr;
+		char digest[IMA_MAX_DIGEST_SIZE];
+	} hash;
 
 	memset(entry->digest, 0, sizeof(entry->digest));
 	entry->template_name = IMA_TEMPLATE_NAME;
@@ -52,14 +55,14 @@ int ima_store_template(struct ima_template_entry *entry,
 
 	if (!violation) {
 		result = ima_calc_buffer_hash(&entry->template,
-					      entry->template_len, &hash);
+					      entry->template_len, &hash.hdr);
 		if (result < 0) {
 			integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
 					    entry->template_name, op,
 					    audit_cause, result, 0);
 			return result;
 		}
-		memcpy(entry->digest, hash.digest, hash.length);
+		memcpy(entry->digest, hash.hdr.digest, hash.hdr.length);
 	}
 	result = ima_add_template_entry(entry, violation, op, inode);
 	return result;
@@ -146,6 +149,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 	struct inode *inode = file_inode(file);
 	const char *filename = file->f_dentry->d_name.name;
 	int result = 0;
+	struct {
+		struct ima_digest_data hdr;
+		char digest[IMA_MAX_DIGEST_SIZE];
+	} hash;
 
 	if (xattr_value)
 		*xattr_len = ima_read_xattr(file->f_dentry, xattr_value);
@@ -154,16 +161,23 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 		u64 i_version = file_inode(file)->i_version;
 
 		/* use default hash algorithm */
-		iint->ima_hash.algo = ima_hash_algo;
+		hash.hdr.algo = ima_hash_algo;
 
 		if (xattr_value)
-			ima_get_hash_algo(*xattr_value, *xattr_len,
-					  &iint->ima_hash);
+			ima_get_hash_algo(*xattr_value, *xattr_len, &hash.hdr);
 
-		result = ima_calc_file_hash(file, &iint->ima_hash);
+		result = ima_calc_file_hash(file, &hash.hdr);
 		if (!result) {
-			iint->version = i_version;
-			iint->flags |= IMA_COLLECTED;
+			int length = sizeof(hash.hdr) + hash.hdr.length;
+			void *tmpbuf = krealloc(iint->ima_hash, length,
+						GFP_NOFS);
+			if (tmpbuf) {
+				iint->ima_hash = tmpbuf;
+				memcpy(iint->ima_hash, &hash, length);
+				iint->version = i_version;
+				iint->flags |= IMA_COLLECTED;
+			} else
+				result = -ENOMEM;
 		}
 	}
 	if (result)
@@ -208,21 +222,24 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
 		return;
 	}
 	memset(&entry->template, 0, sizeof(entry->template));
-	if (iint->ima_hash.algo != ima_hash_algo) {
-		struct ima_digest_data hash;
+	if (iint->ima_hash->algo != ima_hash_algo) {
+		struct {
+			struct ima_digest_data hdr;
+			char digest[IMA_MAX_DIGEST_SIZE];
+		} hash;
 
-		hash.algo = ima_hash_algo;
-		result = ima_calc_file_hash(file, &hash);
+		hash.hdr.algo = ima_hash_algo;
+		result = ima_calc_file_hash(file, &hash.hdr);
 		if (result)
 			integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
 					    filename, "collect_data", "failed",
 					    result, 0);
 		else
-			memcpy(entry->template.digest, hash.digest,
-			       hash.length);
+			memcpy(entry->template.digest, hash.hdr.digest,
+			       hash.hdr.length);
 	} else
-		memcpy(entry->template.digest, iint->ima_hash.digest,
-		       iint->ima_hash.length);
+		memcpy(entry->template.digest, iint->ima_hash->digest,
+		       iint->ima_hash->length);
 	strcpy(entry->template.file_name,
 	       (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
 	       file->f_dentry->d_name.name : filename);
@@ -238,14 +255,14 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
 			   const unsigned char *filename)
 {
 	struct audit_buffer *ab;
-	char hash[(iint->ima_hash.length * 2) + 1];
+	char hash[(iint->ima_hash->length * 2) + 1];
 	int i;
 
 	if (iint->flags & IMA_AUDITED)
 		return;
 
-	for (i = 0; i < iint->ima_hash.length; i++)
-		hex_byte_pack(hash + (i * 2), iint->ima_hash.digest[i]);
+	for (i = 0; i < iint->ima_hash->length; i++)
+		hex_byte_pack(hash + (i * 2), iint->ima_hash->digest[i]);
 	hash[i * 2] = '\0';
 
 	ab = audit_log_start(current->audit_context, GFP_KERNEL,
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index e1865a6..116630c 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -45,10 +45,10 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
 static int ima_fix_xattr(struct dentry *dentry,
 			 struct integrity_iint_cache *iint)
 {
-	iint->ima_hash.type = IMA_XATTR_DIGEST;
+	iint->ima_hash->type = IMA_XATTR_DIGEST;
 	return __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
-				     &iint->ima_hash.type,
-				     1 + iint->ima_hash.length, 0);
+				     &iint->ima_hash->type,
+				     1 + iint->ima_hash->length, 0);
 }
 
 /* Return specific func appraised cached result */
@@ -186,13 +186,13 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
 			status = INTEGRITY_FAIL;
 			break;
 		}
-		if (xattr_len - 1 >= iint->ima_hash.length)
+		if (xattr_len - 1 >= iint->ima_hash->length)
 			/* xattr length may be longer. md5 hash in previous
 			   version occupied 20 bytes in xattr, instead of 16
 			 */
 			rc = memcmp(xattr_value->digest,
-				    iint->ima_hash.digest,
-				    iint->ima_hash.length);
+				    iint->ima_hash->digest,
+				    iint->ima_hash->length);
 		else
 			rc = -EINVAL;
 		if (rc) {
@@ -206,8 +206,8 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
 		iint->flags |= IMA_DIGSIG;
 		rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
 					     (const char *)xattr_value, rc,
-					     iint->ima_hash.digest,
-					     iint->ima_hash.length);
+					     iint->ima_hash->digest,
+					     iint->ima_hash->length);
 		if (rc == -EOPNOTSUPP) {
 			status = INTEGRITY_UNKNOWN;
 		} else if (rc) {
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index aead6b2..5429ca5 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -67,7 +67,7 @@ struct ima_digest_data {
 	u8 algo;
 	u8 length;
 	u8 type;
-	u8 digest[IMA_MAX_DIGEST_SIZE];
+	u8 digest[0];
 } __packed;
 
 /*
@@ -93,7 +93,7 @@ struct integrity_iint_cache {
 	enum integrity_status ima_bprm_status:4;
 	enum integrity_status ima_module_status:4;
 	enum integrity_status evm_status:4;
-	struct ima_digest_data ima_hash;
+	struct ima_digest_data *ima_hash;
 };
 
 /* rbtree tree calls to lookup, insert, delete
-- 
1.8.1.4


  parent reply	other threads:[~2013-10-21 22:51 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-21 22:42 [PATCH v2 00/23] ima: larger digests and extensible template support Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 01/23] crypto: provide single place for hash algo information Mimi Zohar
2013-10-22  5:24   ` Herbert Xu
2013-10-22 11:29     ` Dmitry Kasatkin
2013-10-22 11:32       ` Herbert Xu
2013-10-22 11:57         ` Dmitry Kasatkin
2013-10-22 12:07           ` Herbert Xu
2013-10-22 12:50             ` Mimi Zohar
2013-10-22 12:53               ` Herbert Xu
2013-10-21 22:42 ` [PATCH v2 02/23] keys: change asymmetric keys to use common hash definitions Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 03/23] ima: provide support for arbitrary hash algorithms Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 04/23] ima: read and use signature hash algorithm Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 05/23] ima: pass full xattr with the signature Mimi Zohar
2013-10-21 22:42 ` Mimi Zohar [this message]
2013-10-21 22:42 ` [PATCH v2 07/23] ima: differentiate between template hash and file data hash sizes Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 08/23] ima: provide dedicated hash algo allocation function Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 09/23] ima: support arbitrary hash algorithms in ima_calc_buffer_hash Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 10/23] ima: ima_calc_boot_agregate must use SHA1 Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 11/23] ima: pass the file descriptor to ima_add_violation() Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 12/23] ima: pass the filename argument up to ima_add_template_entry() Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 13/23] ima: define new function ima_alloc_init_template() to API Mimi Zohar
2013-10-21 22:42 ` [PATCH v2 14/23] ima: new templates management mechanism Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 15/23] ima: define template fields library and new helpers Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 16/23] ima: define new template ima-ng and template fields d-ng and n-ng Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 17/23] ima: switch to new template management mechanism Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 18/23] ima: add audit log support for larger hashes Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 19/23] ima: defer determining the appraisal hash algorithm for 'ima' template Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 20/23] ima: add Kconfig default measurement list template Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 21/23] ima: define kernel parameter 'ima_template=' to change configured default Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 22/23] ima: enable support for larger default filedata hash algorithms Mimi Zohar
2013-10-21 22:43 ` [PATCH v2 23/23] ima: provide hash algo info in the xattr Mimi Zohar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1382395388-8108-7-git-send-email-zohar@linux.vnet.ibm.com \
    --to=zohar@linux.vnet.ibm.com \
    --cc=d.kasatkin@samsung.com \
    --cc=dhowells@redhat.com \
    --cc=jmorris@namei.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®