diff mbox series

[RFC] Add more inode fields to inode metadata signature

Message ID 20200331100551.GA8259@kl (mailing list archive)
State New, archived
Headers show
Series [RFC] Add more inode fields to inode metadata signature | expand

Commit Message

Lev R. Oshvang . March 31, 2020, 10:05 a.m. UTC
From b696085c6e65e82237150e13d14736a914a0b394 Mon Sep 17 00:00:00 2001
From: Lev Olshvang <levonshe@gmail.com>
Date: Mon, 30 Mar 2020 16:00:27 +0300
Subject: [PATCH] integrity - add more inode metadata to signature, handle
 errors

Add more inode fields to inode HMAC : times and flags.
File flags define (affect) how OS utilities and filesystem treats
them. For example immutable flag preserve file from removal or change.
It is important to verify these flags were not changed.
ctime and mtime may also affect programs that depends on files
timestamps.
File size might be used as a first indicator of file change and spare
from other IMA/EVM checks.

Function hmac_add_misc() ignored errors from crypto functions
This patch changes hmac_add_misc() not to be silent about errors

Signed-off-by: Lev Olshvang <levonshe@gmail.com>
---
 security/integrity/evm/evm_crypto.c | 34 ++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 6 deletions(-)

--
2.17.1
diff mbox series

Patch

diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index d485f6fc908e..9c71c321e988 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -139,15 +139,20 @@  static struct shash_desc *init_desc(char type, uint8_t hash_algo)
  * (Additional directory/file metadata needs to be added for more complete
  * protection.)
  */
-static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
+static int hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 			  char type, char *digest)
 {
+	int rc = 0;
 	struct h_misc {
 		unsigned long ino;
 		__u32 generation;
 		uid_t uid;
 		gid_t gid;
 		umode_t mode;
+		struct timespec64 ctime;
+		struct timespec64 mtime;
+		__u32   flags;
+		__u32 filesize;
 	} hmac_misc;

 	memset(&hmac_misc, 0, sizeof(hmac_misc));
@@ -169,11 +174,26 @@  static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 	hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
 	hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
 	hmac_misc.mode = inode->i_mode;
-	crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
+	hmac_misc.flags = inode->i_flags;
+	hmac_misc.ctime = inode->i_ctime;
+	hmac_misc.mtime = inode->i_mtime;
+
+	/* hardly imagine calculating hash for file  > 4G */
+	if (likely(inode->i_size < 0xFFFFFFFF))
+		hmac_misc.filesize = (__u32) inode->i_size;
+	else
+		return -E2BIG;
+	rc = crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
+	if (unlikely(!rc))
+		return rc;
 	if ((evm_hmac_attrs & EVM_ATTR_FSUUID) &&
-	    type != EVM_XATTR_PORTABLE_DIGSIG)
-		crypto_shash_update(desc, (u8 *)&inode->i_sb->s_uuid, UUID_SIZE);
-	crypto_shash_final(desc, digest);
+	    type != EVM_XATTR_PORTABLE_DIGSIG) {
+		rc = crypto_shash_update(desc, (u8 *)&inode->i_sb->s_uuid, UUID_SIZE);
+		if (unlikely(!rc))
+			return rc;
+	}
+	rc = crypto_shash_final(desc, digest);
+	return rc;
 }

 /*
@@ -239,7 +259,9 @@  static int evm_calc_hmac_or_hash(struct dentry *dentry,
 		if (is_ima)
 			ima_present = true;
 	}
-	hmac_add_misc(desc, inode, type, data->digest);
+	error = hmac_add_misc(desc, inode, type, data->digest);
+	if (error < 0)
+		return error;

 	/* Portable EVM signatures must include an IMA hash */
 	if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present)