From: Peter M. <pm...@go...> - 2014-11-04 23:18:04
|
It's useful to be able to get the hash of a previously measured file. Querying IMA directly is more efficient than grepping the ascii measurements of the audit logs. --- include/linux/ima.h | 6 ++++++ security/integrity/ima/ima_main.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/include/linux/ima.h b/include/linux/ima.h index 120ccc5..27cc4f6 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -20,6 +20,7 @@ extern void ima_file_free(struct file *file); extern int ima_file_mmap(struct file *file, unsigned long prot); extern int ima_module_check(struct file *file); extern int ima_fw_from_file(struct file *file, char *buf, size_t size); +extern char *ima_file_hash(struct file *file, char *buf, size_t size); #else static inline int ima_bprm_check(struct linux_binprm *bprm) @@ -52,6 +53,11 @@ static inline int ima_fw_from_file(struct file *file, char *buf, size_t size) return 0; } +static inline char *ima_file_hash(struct file *file, char *buf, size_t size) +{ + return NULL; +} + #endif /* CONFIG_IMA */ #ifdef CONFIG_IMA_APPRAISE diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 62f59ec..896c27b 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -309,6 +309,45 @@ int ima_file_check(struct file *file, int mask, int opened) EXPORT_SYMBOL_GPL(ima_file_check); /** + * ima_file_hash - return the stored measurement if a file's been hashed. + * @file: pointer to the file. + * @buf: buffer in which to store the hash. + * @size: length of the buffer. + * + * On success returns the buffer. Otherwise returns NULL. If the hash is larger + * than buffer, then only size bytes will be copied. It generally just makes + * sense to pass a buffer capable of holding the largest possible hash string. + * This is currently 135 (IMA_MAX_DIGEST_SIZE * 2 + 6 + 1). + */ +char *ima_file_hash(struct file *file, char *buf, size_t size) +{ + struct inode *inode; + struct integrity_iint_cache *iint; + + if (!file) + return NULL; + + inode = file_inode(file); + + mutex_lock(&inode->i_mutex); + iint = integrity_iint_find(inode); + + if (iint && (iint->flags & IMA_COLLECTED)) { + const char *algo_name = hash_algo_name[iint->ima_hash->algo]; + + snprintf(buf, size, "%s:%*phN", + algo_name, iint->ima_hash->length, iint->ima_hash->digest); + + mutex_unlock(&inode->i_mutex); + return buf; + } + + mutex_unlock(&inode->i_mutex); + return NULL; +} +EXPORT_SYMBOL_GPL(ima_file_hash); + +/** * ima_module_check - based on policy, collect/store/appraise measurement. * @file: pointer to the file to be measured/appraised * -- 2.1.0.rc2.206.gedb03e5 |