@@ -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)