diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /security/integrity | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz |
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'security/integrity')
-rw-r--r-- | security/integrity/digsig.c | 7 | ||||
-rw-r--r-- | security/integrity/digsig_asymmetric.c | 11 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 4 | ||||
-rw-r--r-- | security/integrity/evm/evm_posix_acl.c | 3 | ||||
-rw-r--r-- | security/integrity/iint.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/Kconfig | 64 | ||||
-rw-r--r-- | security/integrity/ima/Makefile | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 106 | ||||
-rw-r--r-- | security/integrity/ima/ima_api.c | 154 | ||||
-rw-r--r-- | security/integrity/ima/ima_appraise.c | 106 | ||||
-rw-r--r-- | security/integrity/ima/ima_crypto.c | 141 | ||||
-rw-r--r-- | security/integrity/ima/ima_fs.c | 75 | ||||
-rw-r--r-- | security/integrity/ima/ima_init.c | 40 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 63 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 1 | ||||
-rw-r--r-- | security/integrity/ima/ima_queue.c | 10 | ||||
-rw-r--r-- | security/integrity/ima/ima_template.c | 187 | ||||
-rw-r--r-- | security/integrity/ima/ima_template_lib.c | 351 | ||||
-rw-r--r-- | security/integrity/ima/ima_template_lib.h | 49 | ||||
-rw-r--r-- | security/integrity/integrity.h | 40 |
20 files changed, 185 insertions, 1231 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index b4af4eb..0b759e1 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -28,7 +28,7 @@ static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { }; int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, - const char *digest, int digestlen) + const char *digest, int digestlen) { if (id >= INTEGRITY_KEYRING_MAX) return -EINVAL; @@ -44,10 +44,9 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, } } - switch (sig[1]) { + switch (sig[0]) { case 1: - /* v1 API expect signature without xattr type */ - return digsig_verify(keyring[id], sig + 1, siglen - 1, + return digsig_verify(keyring[id], sig, siglen, digest, digestlen); case 2: return asymmetric_verify(keyring[id], sig, siglen, diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index 9eae480..b475466 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -20,6 +20,17 @@ #include "integrity.h" /* + * signature format v2 - for using with asymmetric keys + */ +struct signature_v2_hdr { + uint8_t version; /* signature format version */ + uint8_t hash_algo; /* Digest algorithm [enum pkey_hash_algo] */ + uint32_t keyid; /* IMA key identifier - not X509/PGP specific*/ + uint16_t sig_size; /* signature size */ + uint8_t sig[0]; /* signature payload */ +} __packed; + +/* * Request an asymmetric key. */ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 336b3dd..af9b685 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -123,7 +123,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, goto out; } - xattr_len = rc; + xattr_len = rc - 1; /* check value type */ switch (xattr_data->type) { @@ -143,7 +143,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, if (rc) break; rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM, - (const char *)xattr_data, xattr_len, + xattr_data->digest, xattr_len, calc.digest, sizeof(calc.digest)); if (!rc) { /* we probably want to replace rsa with hmac here */ diff --git a/security/integrity/evm/evm_posix_acl.c b/security/integrity/evm/evm_posix_acl.c index 46408b9..b1753e9 100644 --- a/security/integrity/evm/evm_posix_acl.c +++ b/security/integrity/evm/evm_posix_acl.c @@ -11,9 +11,8 @@ #include <linux/module.h> #include <linux/xattr.h> -#include <linux/evm.h> -int posix_xattr_acl(const char *xattr) +int posix_xattr_acl(char *xattr) { int xattr_len = strlen(xattr); diff --git a/security/integrity/iint.c b/security/integrity/iint.c index c49d3f1..74522db 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -70,8 +70,6 @@ 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/Kconfig b/security/integrity/ima/Kconfig index 81a2797..39196ab 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -9,7 +9,6 @@ config IMA select CRYPTO_HMAC select CRYPTO_MD5 select CRYPTO_SHA1 - select CRYPTO_HASH_INFO select TCG_TPM if HAS_IOMEM && !UML select TCG_TIS if TCG_TPM && X86 select TCG_IBMVTPM if TCG_TPM && PPC64 @@ -46,69 +45,6 @@ config IMA_LSM_RULES help Disabling this option will disregard LSM based policy rules. -choice - prompt "Default template" - default IMA_NG_TEMPLATE - depends on IMA - help - Select the default IMA measurement template. - - The original 'ima' measurement list template contains a - hash, defined as 20 bytes, and a null terminated pathname, - limited to 255 characters. The 'ima-ng' measurement list - template permits both larger hash digests and longer - pathnames. - - config IMA_TEMPLATE - bool "ima" - config IMA_NG_TEMPLATE - bool "ima-ng (default)" - config IMA_SIG_TEMPLATE - bool "ima-sig" -endchoice - -config IMA_DEFAULT_TEMPLATE - string - depends on IMA - default "ima" if IMA_TEMPLATE - default "ima-ng" if IMA_NG_TEMPLATE - default "ima-sig" if IMA_SIG_TEMPLATE - -choice - prompt "Default integrity hash algorithm" - default IMA_DEFAULT_HASH_SHA1 - depends on IMA - help - Select the default hash algorithm used for the measurement - list, integrity appraisal and audit log. The compiled default - hash algorithm can be overwritten using the kernel command - line 'ima_hash=' option. - - config IMA_DEFAULT_HASH_SHA1 - bool "SHA1 (default)" - depends on CRYPTO_SHA1 - - config IMA_DEFAULT_HASH_SHA256 - bool "SHA256" - depends on CRYPTO_SHA256 && !IMA_TEMPLATE - - config IMA_DEFAULT_HASH_SHA512 - bool "SHA512" - depends on CRYPTO_SHA512 && !IMA_TEMPLATE - - config IMA_DEFAULT_HASH_WP512 - bool "WP512" - depends on CRYPTO_WP512 && !IMA_TEMPLATE -endchoice - -config IMA_DEFAULT_HASH - string - depends on IMA - default "sha1" if IMA_DEFAULT_HASH_SHA1 - default "sha256" if IMA_DEFAULT_HASH_SHA256 - default "sha512" if IMA_DEFAULT_HASH_SHA512 - default "wp512" if IMA_DEFAULT_HASH_WP512 - config IMA_APPRAISE bool "Appraise integrity measurements" depends on IMA diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index d79263d..56dfee7 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile @@ -6,5 +6,5 @@ obj-$(CONFIG_IMA) += ima.o ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ - ima_policy.o ima_template.o ima_template_lib.o + ima_policy.o ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 0356e1d..b3dd616 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -26,8 +26,7 @@ #include "../integrity.h" -enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN, - IMA_SHOW_ASCII }; +enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII }; enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; /* digest size for IMA, fits SHA1 or MD5 */ @@ -37,48 +36,23 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; #define IMA_HASH_BITS 9 #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) -#define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16 -#define IMA_TEMPLATE_NUM_FIELDS_MAX 15 - -#define IMA_TEMPLATE_IMA_NAME "ima" -#define IMA_TEMPLATE_IMA_FMT "d|n" - /* set during initialization */ extern int ima_initialized; extern int ima_used_chip; -extern int ima_hash_algo; +extern char *ima_hash; extern int ima_appraise; -/* IMA template field data definition */ -struct ima_field_data { - u8 *data; - u32 len; -}; - -/* IMA template field definition */ -struct ima_template_field { - const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; - int (*field_init) (struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len, struct ima_field_data *field_data); - void (*field_show) (struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data); -}; - -/* IMA template descriptor definition */ -struct ima_template_desc { - char *name; - char *fmt; - int num_fields; - struct ima_template_field **fields; +/* IMA inode template definition */ +struct ima_template_data { + u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */ + char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */ }; struct ima_template_entry { - u8 digest[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ - struct ima_template_desc *template_desc; /* template descriptor */ - u32 template_data_len; - struct ima_field_data template_data[0]; /* template related data */ + u8 digest[IMA_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ + const char *template_name; + int template_len; + struct ima_template_data template; }; struct ima_queue_entry { @@ -95,22 +69,13 @@ int ima_fs_init(void); void ima_fs_cleanup(void); int ima_inode_alloc(struct inode *inode); int ima_add_template_entry(struct ima_template_entry *entry, int violation, - const char *op, struct inode *inode, - const unsigned char *filename); -int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash); -int ima_calc_field_array_hash(struct ima_field_data *field_data, - struct ima_template_desc *desc, int num_fields, - 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, + const char *op, struct inode *inode); +int ima_calc_file_hash(struct file *file, char *digest); +int ima_calc_buffer_hash(const void *data, int len, char *digest); +int ima_calc_boot_aggregate(char *digest); +void ima_add_violation(struct inode *inode, const unsigned char *filename, const char *op, const char *cause); int ima_init_crypto(void); -void ima_putc(struct seq_file *m, void *data, int datalen); -void ima_print_digest(struct seq_file *m, u8 *digest, int size); -struct ima_template_desc *ima_template_desc_current(void); -int ima_init_template(void); - -int ima_init_template(void); /* * used to protect h_table and sha_table @@ -133,22 +98,14 @@ static inline unsigned long ima_hash_key(u8 *digest) int ima_get_action(struct inode *inode, int mask, int function); int ima_must_measure(struct inode *inode, int mask, int function); int ima_collect_measurement(struct integrity_iint_cache *iint, - struct file *file, - struct evm_ima_xattr_data **xattr_value, - int *xattr_len); + struct file *file); void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len); + const unsigned char *filename); void ima_audit_measurement(struct integrity_iint_cache *iint, const unsigned char *filename); -int ima_alloc_init_template(struct integrity_iint_cache *iint, - struct file *file, const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len, struct ima_template_entry **entry); int ima_store_template(struct ima_template_entry *entry, int violation, - struct inode *inode, const unsigned char *filename); -void ima_free_template_entry(struct ima_template_entry *entry); + struct inode *inode); +void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); const char *ima_d_path(struct path *path, char **pathbuf); /* rbtree tree calls to lookup, insert, delete @@ -174,25 +131,17 @@ void ima_delete_rules(void); #ifdef CONFIG_IMA_APPRAISE int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, - struct file *file, const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len); + struct file *file, const unsigned char *filename); int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, int func); -void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_digest_data *hash); -int ima_read_xattr(struct dentry *dentry, - struct evm_ima_xattr_data **xattr_value); #else static inline int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len) + const unsigned char *filename) { return INTEGRITY_UNKNOWN; } @@ -213,19 +162,6 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c { return INTEGRITY_UNKNOWN; } - -static inline void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, - int xattr_len, - struct ima_digest_data *hash) -{ -} - -static inline int ima_read_xattr(struct dentry *dentry, - struct evm_ima_xattr_data **xattr_value) -{ - return 0; -} - #endif /* LSM based policy rules require audit */ diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index c38bbce..1c03e8f1 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -18,59 +18,9 @@ #include <linux/fs.h> #include <linux/xattr.h> #include <linux/evm.h> -#include <crypto/hash_info.h> #include "ima.h" -/* - * ima_free_template_entry - free an existing template entry - */ -void ima_free_template_entry(struct ima_template_entry *entry) -{ - int i; - - for (i = 0; i < entry->template_desc->num_fields; i++) - kfree(entry->template_data[i].data); - - kfree(entry); -} - -/* - * ima_alloc_init_template - create and initialize a new template entry - */ -int ima_alloc_init_template(struct integrity_iint_cache *iint, - struct file *file, const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len, struct ima_template_entry **entry) -{ - struct ima_template_desc *template_desc = ima_template_desc_current(); - int i, result = 0; - - *entry = kzalloc(sizeof(**entry) + template_desc->num_fields * - sizeof(struct ima_field_data), GFP_NOFS); - if (!*entry) - return -ENOMEM; - - (*entry)->template_desc = template_desc; - for (i = 0; i < template_desc->num_fields; i++) { - struct ima_template_field *field = template_desc->fields[i]; - u32 len; - - result = field->field_init(iint, file, filename, - xattr_value, xattr_len, - &((*entry)->template_data[i])); - if (result != 0) - goto out; - - len = (*entry)->template_data[i].len; - (*entry)->template_data_len += sizeof(len); - (*entry)->template_data_len += len; - } - return 0; -out: - ima_free_template_entry(*entry); - *entry = NULL; - return result; -} +static const char *IMA_TEMPLATE_NAME = "ima"; /* * ima_store_template - store ima template measurements @@ -89,35 +39,28 @@ out: * Returns 0 on success, error code otherwise */ int ima_store_template(struct ima_template_entry *entry, - int violation, struct inode *inode, - const unsigned char *filename) + int violation, struct inode *inode) { const char *op = "add_template_measure"; const char *audit_cause = "hashing_error"; - char *template_name = entry->template_desc->name; int result; - struct { - struct ima_digest_data hdr; - char digest[TPM_DIGEST_SIZE]; - } hash; - if (!violation) { - int num_fields = entry->template_desc->num_fields; + memset(entry->digest, 0, sizeof(entry->digest)); + entry->template_name = IMA_TEMPLATE_NAME; + entry->template_len = sizeof(entry->template); - /* this function uses default algo */ - hash.hdr.algo = HASH_ALGO_SHA1; - result = ima_calc_field_array_hash(&entry->template_data[0], - entry->template_desc, - num_fields, &hash.hdr); + if (!violation) { + result = ima_calc_buffer_hash(&entry->template, + entry->template_len, + entry->digest); if (result < 0) { integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, - template_name, op, + entry->template_name, op, audit_cause, result, 0); return result; } - memcpy(entry->digest, hash.hdr.digest, hash.hdr.length); } - result = ima_add_template_entry(entry, violation, op, inode, filename); + result = ima_add_template_entry(entry, violation, op, inode); return result; } @@ -128,26 +71,26 @@ int ima_store_template(struct ima_template_entry *entry, * By extending the PCR with 0xFF's instead of with zeroes, the PCR * value is invalidated. */ -void ima_add_violation(struct file *file, const unsigned char *filename, +void ima_add_violation(struct inode *inode, const unsigned char *filename, const char *op, const char *cause) { struct ima_template_entry *entry; - struct inode *inode = file->f_dentry->d_inode; int violation = 1; int result; /* can overflow, only indicator */ atomic_long_inc(&ima_htable.violations); - result = ima_alloc_init_template(NULL, file, filename, - NULL, 0, &entry); - if (result < 0) { + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) { result = -ENOMEM; goto err_out; } - result = ima_store_template(entry, violation, inode, filename); + memset(&entry->template, 0, sizeof(entry->template)); + strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); + result = ima_store_template(entry, violation, inode); if (result < 0) - ima_free_template_entry(entry); + kfree(entry); err_out: integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, op, cause, result, 0); @@ -195,42 +138,20 @@ int ima_must_measure(struct inode *inode, int mask, int function) * Return 0 on success, error code otherwise */ int ima_collect_measurement(struct integrity_iint_cache *iint, - struct file *file, - struct evm_ima_xattr_data **xattr_value, - int *xattr_len) + struct file *file) { 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); if (!(iint->flags & IMA_COLLECTED)) { u64 i_version = file_inode(file)->i_version; - /* use default hash algorithm */ - hash.hdr.algo = ima_hash_algo; - - if (xattr_value) - ima_get_hash_algo(*xattr_value, *xattr_len, &hash.hdr); - - result = ima_calc_file_hash(file, &hash.hdr); + iint->ima_xattr.type = IMA_XATTR_DIGEST; + result = ima_calc_file_hash(file, iint->ima_xattr.digest); if (!result) { - 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; + iint->version = i_version; + iint->flags |= IMA_COLLECTED; } } if (result) @@ -256,9 +177,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, * Must be called with iint->mutex held. */ void ima_store_measurement(struct integrity_iint_cache *iint, - struct file *file, const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len) + struct file *file, const unsigned char *filename) { const char *op = "add_template_measure"; const char *audit_cause = "ENOMEM"; @@ -270,35 +189,37 @@ void ima_store_measurement(struct integrity_iint_cache *iint, if (iint->flags & IMA_MEASURED) return; - result = ima_alloc_init_template(iint, file, filename, - xattr_value, xattr_len, &entry); - if (result < 0) { + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) { integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, op, audit_cause, result, 0); return; } + memset(&entry->template, 0, sizeof(entry->template)); + memcpy(entry->template.digest, iint->ima_xattr.digest, IMA_DIGEST_SIZE); + strcpy(entry->template.file_name, + (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ? + file->f_dentry->d_name.name : filename); - result = ima_store_template(entry, violation, inode, filename); + result = ima_store_template(entry, violation, inode); if (!result || result == -EEXIST) iint->flags |= IMA_MEASURED; if (result < 0) - ima_free_template_entry(entry); + kfree(entry); } 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]; - const char *algo_name = hash_algo_name[iint->ima_hash->algo]; - char algo_hash[sizeof(hash) + strlen(algo_name) + 2]; + char hash[(IMA_DIGEST_SIZE * 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 < IMA_DIGEST_SIZE; i++) + hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]); hash[i * 2] = '\0'; ab = audit_log_start(current->audit_context, GFP_KERNEL, @@ -309,8 +230,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, audit_log_format(ab, "file="); audit_log_untrustedstring(ab, filename); audit_log_format(ab, " hash="); - snprintf(algo_hash, sizeof(algo_hash), "%s:%s", algo_name, hash); - audit_log_untrustedstring(ab, algo_hash); + audit_log_untrustedstring(ab, hash); audit_log_task_info(ab, current); audit_log_end(ab); diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 734e946..2d4beca 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -15,7 +15,6 @@ #include <linux/magic.h> #include <linux/ima.h> #include <linux/evm.h> -#include <crypto/hash_info.h> #include "ima.h" @@ -44,31 +43,19 @@ 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) + struct integrity_iint_cache *iint) { - int rc, offset; - u8 algo = iint->ima_hash->algo; - - if (algo <= HASH_ALGO_SHA1) { - offset = 1; - iint->ima_hash->xattr.sha1.type = IMA_XATTR_DIGEST; - } else { - offset = 0; - iint->ima_hash->xattr.ng.type = IMA_XATTR_DIGEST_NG; - iint->ima_hash->xattr.ng.algo = algo; - } - rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA, - &iint->ima_hash->xattr.data[offset], - (sizeof(iint->ima_hash->xattr) - offset) + - iint->ima_hash->length, 0); - return rc; + iint->ima_xattr.type = IMA_XATTR_DIGEST; + return __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA, + (u8 *)&iint->ima_xattr, + sizeof(iint->ima_xattr), 0); } /* Return specific func appraised cached result */ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, int func) { - switch (func) { + switch(func) { case MMAP_CHECK: return iint->ima_mmap_status; case BPRM_CHECK: @@ -84,7 +71,7 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, static void ima_set_cache_status(struct integrity_iint_cache *iint, int func, enum integrity_status status) { - switch (func) { + switch(func) { case MMAP_CHECK: iint->ima_mmap_status = status; break; @@ -103,7 +90,7 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint, static void ima_cache_flags(struct integrity_iint_cache *iint, int func) { - switch (func) { + switch(func) { case MMAP_CHECK: iint->flags |= (IMA_MMAP_APPRAISED | IMA_APPRAISED); break; @@ -120,50 +107,6 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func) } } -void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_digest_data *hash) -{ - struct signature_v2_hdr *sig; - - if (!xattr_value || xattr_len < 2) - return; - - switch (xattr_value->type) { - case EVM_IMA_XATTR_DIGSIG: - sig = (typeof(sig))xattr_value; - if (sig->version != 2 || xattr_len <= sizeof(*sig)) - return; - hash->algo = sig->hash_algo; - break; - case IMA_XATTR_DIGEST_NG: - hash->algo = xattr_value->digest[0]; - break; - case IMA_XATTR_DIGEST: - /* this is for backward compatibility */ - if (xattr_len == 21) { - unsigned int zero = 0; - if (!memcmp(&xattr_value->digest[16], &zero, 4)) - hash->algo = HASH_ALGO_MD5; - else - hash->algo = HASH_ALGO_SHA1; - } else if (xattr_len == 17) - hash->algo = HASH_ALGO_MD5; - break; - } -} - -int ima_read_xattr(struct dentry *dentry, - struct evm_ima_xattr_data **xattr_value) -{ - struct inode *inode = dentry->d_inode; - - if (!inode->i_op->getxattr) - return 0; - - return vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value, - 0, GFP_NOFS); -} - /* * ima_appraise_measurement - appraise file measurement * @@ -173,22 +116,23 @@ int ima_read_xattr(struct dentry *dentry, * Return 0 on success, error code otherwise */ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, - struct file *file, const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len) + struct file *file, const unsigned char *filename) { struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; + struct evm_ima_xattr_data *xattr_value = NULL; enum integrity_status status = INTEGRITY_UNKNOWN; const char *op = "appraise_data"; char *cause = "unknown"; - int rc = xattr_len, hash_start = 0; + int rc; if (!ima_appraise) return 0; if (!inode->i_op->getxattr) return INTEGRITY_UNKNOWN; + rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value, + 0, GFP_NOFS); if (rc <= 0) { if (rc && rc != -ENODATA) goto out; @@ -209,25 +153,14 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, goto out; } switch (xattr_value->type) { - case IMA_XATTR_DIGEST_NG: - /* first byte contains algorithm id */ - hash_start = 1; case IMA_XATTR_DIGEST: if (iint->flags & IMA_DIGSIG_REQUIRED) { cause = "IMA signature required"; status = INTEGRITY_FAIL; break; } - if (xattr_len - sizeof(xattr_value->type) - hash_start >= - 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[hash_start], - iint->ima_hash->digest, - iint->ima_hash->length); - else - rc = -EINVAL; + rc = memcmp(xattr_value->digest, iint->ima_xattr.digest, + IMA_DIGEST_SIZE); if (rc) { cause = "invalid-hash"; status = INTEGRITY_FAIL; @@ -238,9 +171,9 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, case EVM_IMA_XATTR_DIGSIG: iint->flags |= IMA_DIGSIG; rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA, - (const char *)xattr_value, rc, - iint->ima_hash->digest, - iint->ima_hash->length); + xattr_value->digest, rc - 1, + iint->ima_xattr.digest, + IMA_DIGEST_SIZE); if (rc == -EOPNOTSUPP) { status = INTEGRITY_UNKNOWN; } else if (rc) { @@ -270,6 +203,7 @@ out: ima_cache_flags(iint, func); } ima_set_cache_status(iint, func, status); + kfree(xattr_value); return status; } @@ -285,7 +219,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file) if (iint->flags & IMA_DIGSIG) return; - rc = ima_collect_measurement(iint, file, NULL, NULL); + rc = ima_collect_measurement(iint, file); if (rc < 0) return; diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index fdf60de..a02e079 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -20,7 +20,6 @@ #include <linux/err.h> #include <linux/slab.h> #include <crypto/hash.h> -#include <crypto/hash_info.h> #include "ima.h" static struct crypto_shash *ima_shash_tfm; @@ -29,58 +28,31 @@ int ima_init_crypto(void) { long rc; - ima_shash_tfm = crypto_alloc_shash(hash_algo_name[ima_hash_algo], 0, 0); + ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0); if (IS_ERR(ima_shash_tfm)) { rc = PTR_ERR(ima_shash_tfm); - pr_err("Can not allocate %s (reason: %ld)\n", - hash_algo_name[ima_hash_algo], rc); + pr_err("Can not allocate %s (reason: %ld)\n", ima_hash, rc); return rc; } return 0; } -static struct crypto_shash *ima_alloc_tfm(enum hash_algo algo) -{ - struct crypto_shash *tfm = ima_shash_tfm; - int rc; - - if (algo != ima_hash_algo && algo < HASH_ALGO__LAST) { - tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0); - if (IS_ERR(tfm)) { - rc = PTR_ERR(tfm); - pr_err("Can not allocate %s (reason: %d)\n", - hash_algo_name[algo], rc); - } - } - return tfm; -} - -static void ima_free_tfm(struct crypto_shash *tfm) -{ - if (tfm != ima_shash_tfm) - crypto_free_shash(tfm); -} - /* * Calculate the MD5/SHA1 file digest */ -static int ima_calc_file_hash_tfm(struct file *file, - struct ima_digest_data *hash, - struct crypto_shash *tfm) +int ima_calc_file_hash(struct file *file, char *digest) { loff_t i_size, offset = 0; char *rbuf; int rc, read = 0; struct { struct shash_desc shash; - char ctx[crypto_shash_descsize(tfm)]; + char ctx[crypto_shash_descsize(ima_shash_tfm)]; } desc; - desc.shash.tfm = tfm; + desc.shash.tfm = ima_shash_tfm; desc.shash.flags = 0; - hash->length = crypto_shash_digestsize(tfm); - rc = crypto_shash_init(&desc.shash); if (rc != 0) return rc; @@ -113,90 +85,27 @@ static int ima_calc_file_hash_tfm(struct file *file, } kfree(rbuf); if (!rc) - rc = crypto_shash_final(&desc.shash, hash->digest); + rc = crypto_shash_final(&desc.shash, digest); if (read) file->f_mode &= ~FMODE_READ; out: return rc; } -int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) -{ - struct crypto_shash *tfm; - int rc; - - tfm = ima_alloc_tfm(hash->algo); - if (IS_ERR(tfm)) - return PTR_ERR(tfm); - - rc = ima_calc_file_hash_tfm(file, hash, tfm); - - ima_free_tfm(tfm); - - return rc; -} - /* - * Calculate the hash of template data + * Calculate the hash of a given buffer */ -static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data, - struct ima_template_desc *td, - int num_fields, - struct ima_digest_data *hash, - struct crypto_shash *tfm) +int ima_calc_buffer_hash(const void *data, int len, char *digest) { struct { struct shash_desc shash; - char ctx[crypto_shash_descsize(tfm)]; + char ctx[crypto_shash_descsize(ima_shash_tfm)]; } desc; - int rc, i; - desc.shash.tfm = tfm; + desc.shash.tfm = ima_shash_tfm; desc.shash.flags = 0; - hash->length = crypto_shash_digestsize(tfm); - - rc = crypto_shash_init(&desc.shash); - if (rc != 0) - return rc; - - for (i = 0; i < num_fields; i++) { - if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) { - rc = crypto_shash_update(&desc.shash, - (const u8 *) &field_data[i].len, - sizeof(field_data[i].len)); - if (rc) - break; - } - rc = crypto_shash_update(&desc.shash, field_data[i].data, - field_data[i].len); - if (rc) - break; - } - - if (!rc) - rc = crypto_shash_final(&desc.shash, hash->digest); - - return rc; -} - -int ima_calc_field_array_hash(struct ima_field_data *field_data, - struct ima_template_desc *desc, int num_fields, - struct ima_digest_data *hash) -{ - struct crypto_shash *tfm; - int rc; - - tfm = ima_alloc_tfm(hash->algo); - if (IS_ERR(tfm)) - return PTR_ERR(tfm); - - rc = ima_calc_field_array_hash_tfm(field_data, desc, num_fields, - hash, tfm); - - ima_free_tfm(tfm); - - return rc; + return crypto_shash_digest(&desc.shash, data, len, digest); } static void __init ima_pcrread(int idx, u8 *pcr) @@ -211,17 +120,16 @@ static void __init ima_pcrread(int idx, u8 *pcr) /* * Calculate the boot aggregate hash */ -static int __init ima_calc_boot_aggregate_tfm(char *digest, - struct crypto_shash *tfm) +int __init ima_calc_boot_aggregate(char *digest) { - u8 pcr_i[TPM_DIGEST_SIZE]; + u8 pcr_i[IMA_DIGEST_SIZE]; int rc, i; struct { struct shash_desc shash; - char ctx[crypto_shash_descsize(tfm)]; + char ctx[crypto_shash_descsize(ima_shash_tfm)]; } desc; - desc.shash.tfm = tfm; + desc.shash.tfm = ima_shash_tfm; desc.shash.flags = 0; rc = crypto_shash_init(&desc.shash); @@ -232,26 +140,9 @@ static int __init ima_calc_boot_aggregate_tfm(char *digest, for (i = TPM_PCR0; i < TPM_PCR8; i++) { ima_pcrread(i, pcr_i); /* now accumulate with current aggregate */ - rc = crypto_shash_update(&desc.shash, pcr_i, TPM_DIGEST_SIZE); + rc = crypto_shash_update(&desc.shash, pcr_i, IMA_DIGEST_SIZE); } if (!rc) crypto_shash_final(&desc.shash, digest); return rc; } - -int __init ima_calc_boot_aggregate(struct ima_digest_data *hash) -{ - struct crypto_shash *tfm; - int rc; - - tfm = ima_alloc_tfm(hash->algo); - if (IS_ERR(tfm)) - return PTR_ERR(tfm); - - hash->length = crypto_shash_digestsize(tfm); - rc = ima_calc_boot_aggregate_tfm(hash->digest, tfm); - - ima_free_tfm(tfm); - - return rc; -} diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index db01125..38477c9 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -88,7 +88,8 @@ static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos) * against concurrent list-extension */ rcu_read_lock(); - qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later); + qe = list_entry_rcu(qe->later.next, + struct ima_queue_entry, later); rcu_read_unlock(); (*pos)++; @@ -99,7 +100,7 @@ static void ima_measurements_stop(struct seq_file *m, void *v) { } -void ima_putc(struct seq_file *m, void *data, int datalen) +static void ima_putc(struct seq_file *m, void *data, int datalen) { while (datalen--) seq_putc(m, *(char *)data++); @@ -110,7 +111,6 @@ void ima_putc(struct seq_file *m, void *data, int datalen) * char[20]=template digest * 32bit-le=template name size * char[n]=template name - * [eventdata length] * eventdata[n]=template specific data */ static int ima_measurements_show(struct seq_file *m, void *v) @@ -120,8 +120,6 @@ static int ima_measurements_show(struct seq_file *m, void *v) struct ima_template_entry *e; int namelen; u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX; - bool is_ima_template = false; - int i; /* get entry */ e = qe->entry; @@ -136,32 +134,18 @@ static int ima_measurements_show(struct seq_file *m, void *v) ima_putc(m, &pcr, sizeof pcr); /* 2nd: template digest */ - ima_putc(m, e->digest, TPM_DIGEST_SIZE); + ima_putc(m, e->digest, IMA_DIGEST_SIZE); /* 3rd: template name size */ - namelen = strlen(e->template_desc->name); + namelen = strlen(e->template_name); ima_putc(m, &namelen, sizeof namelen); /* 4th: template name */ - ima_putc(m, e->template_desc->name, namelen); - - /* 5th: template length (except for 'ima' template) */ - if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) - is_ima_template = true; - - if (!is_ima_template) - ima_putc(m, &e->template_data_len, - sizeof(e->template_data_len)); - - /* 6th: template specific data */ - for (i = 0; i < e->template_desc->num_fields; i++) { - enum ima_show_type show = IMA_SHOW_BINARY; - struct ima_template_field *field = e->template_desc->fields[i]; + ima_putc(m, (void *)e->template_name, namelen); - if (is_ima_template && strcmp(field->field_id, "d") == 0) - show = IMA_SHOW_BINARY_NO_FIELD_LEN; - field->field_show(m, show, &e->template_data[i]); - } + /* 5th: template specific data */ + ima_template_show(m, (struct ima_template_data *)&e->template, + IMA_SHOW_BINARY); return 0; } @@ -184,21 +168,41 @@ static const struct file_operations ima_measurements_ops = { .release = seq_release, }; -void ima_print_digest(struct seq_file *m, u8 *digest, int size) +static void ima_print_digest(struct seq_file *m, u8 *digest) { int i; - for (i = 0; i < size; i++) + for (i = 0; i < IMA_DIGEST_SIZE; i++) seq_printf(m, "%02x", *(digest + i)); } +void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show) +{ + struct ima_template_data *entry = e; + int namelen; + + switch (show) { + case IMA_SHOW_ASCII: + ima_print_digest(m, entry->digest); + seq_printf(m, " %s\n", entry->file_name); + break; + case IMA_SHOW_BINARY: + ima_putc(m, entry->digest, IMA_DIGEST_SIZE); + + namelen = strlen(entry->file_name); + ima_putc(m, &namelen, sizeof namelen); + ima_putc(m, entry->file_name, namelen); + default: + break; + } +} + /* print in ascii */ static int ima_ascii_measurements_show(struct seq_file *m, void *v) { /* the list never shrinks, so we don't need a lock here */ struct ima_queue_entry *qe = v; struct ima_template_entry *e; - int i; /* get entry */ e = qe->entry; @@ -209,21 +213,14 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v) seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX); /* 2nd: SHA1 template hash */ - ima_print_digest(m, e->digest, TPM_DIGEST_SIZE); + ima_print_digest(m, e->digest); /* 3th: template name */ - seq_printf(m, " %s", e->template_desc->name); + seq_printf(m, " %s ", e->template_name); /* 4th: template specific data */ - for (i = 0; i < e->template_desc->num_fields; i++) { - seq_puts(m, " "); - if (e->template_data[i].len == 0) - continue; - - e->template_desc->fields[i]->field_show(m, IMA_SHOW_ASCII, - &e->template_data[i]); - } - seq_puts(m, "\n"); + ima_template_show(m, (struct ima_template_data *)&e->template, + IMA_SHOW_ASCII); return 0; } diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 3712276..162ea72 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -18,7 +18,6 @@ #include <linux/scatterlist.h> #include <linux/slab.h> #include <linux/err.h> -#include <crypto/hash_info.h> #include "ima.h" /* name for boot aggregate entry */ @@ -43,39 +42,30 @@ int ima_used_chip; static void __init ima_add_boot_aggregate(void) { struct ima_template_entry *entry; - struct integrity_iint_cache tmp_iint, *iint = &tmp_iint; const char *op = "add_boot_aggregate"; const char *audit_cause = "ENOMEM"; int result = -ENOMEM; - int violation = 0; - struct { - struct ima_digest_data hdr; - char digest[TPM_DIGEST_SIZE]; - } hash; + int violation = 1; - memset(iint, 0, sizeof(*iint)); - memset(&hash, 0, sizeof(hash)); - iint->ima_hash = &hash.hdr; - iint->ima_hash->algo = HASH_ALGO_SHA1; - iint->ima_hash->length = SHA1_DIGEST_SIZE; + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + goto err_out; + memset(&entry->template, 0, sizeof(entry->template)); + strncpy(entry->template.file_name, boot_aggregate_name, + IMA_EVENT_NAME_LEN_MAX); if (ima_used_chip) { - result = ima_calc_boot_aggregate(&hash.hdr); + violation = 0; + result = ima_calc_boot_aggregate(entry->template.digest); if (result < 0) { audit_cause = "hashing_error"; + kfree(entry); goto err_out; } } - - result = ima_alloc_init_template(iint, NULL, boot_aggregate_name, - NULL, 0, &entry); - if (result < 0) - return; - - result = ima_store_template(entry, violation, NULL, - boot_aggregate_name); + result = ima_store_template(entry, violation, NULL); if (result < 0) - ima_free_template_entry(entry); + kfree(entry); return; err_out: integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op, @@ -84,7 +74,7 @@ err_out: int __init ima_init(void) { - u8 pcr_i[TPM_DIGEST_SIZE]; + u8 pcr_i[IMA_DIGEST_SIZE]; int rc; ima_used_chip = 0; @@ -98,10 +88,6 @@ int __init ima_init(void) rc = ima_init_crypto(); if (rc) return rc; - rc = ima_init_template(); - if (rc != 0) - return rc; - ima_add_boot_aggregate(); /* boot aggregate must be first entry */ ima_init_policy(); diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 149ee11..e9508d5 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -24,7 +24,6 @@ #include <linux/slab.h> #include <linux/xattr.h> #include <linux/ima.h> -#include <crypto/hash_info.h> #include "ima.h" @@ -36,33 +35,11 @@ int ima_appraise = IMA_APPRAISE_ENFORCE; int ima_appraise; #endif -int ima_hash_algo = HASH_ALGO_SHA1; -static int hash_setup_done; - +char *ima_hash = "sha1"; static int __init hash_setup(char *str) { - struct ima_template_desc *template_desc = ima_template_desc_current(); - int i; - - if (hash_setup_done) - return 1; - - if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { - if (strncmp(str, "sha1", 4) == 0) - ima_hash_algo = HASH_ALGO_SHA1; - else if (strncmp(str, "md5", 3) == 0) - ima_hash_algo = HASH_ALGO_MD5; - goto out; - } - - for (i = 0; i < HASH_ALGO__LAST; i++) { - if (strcmp(str, hash_algo_name[i]) == 0) { - ima_hash_algo = i; - break; - } - } -out: - hash_setup_done = 1; + if (strncmp(str, "md5", 3) == 0) + ima_hash = "md5"; return 1; } __setup("ima_hash=", hash_setup); @@ -115,9 +92,10 @@ out: pathname = dentry->d_name.name; if (send_tomtou) - ima_add_violation(file, pathname, "invalid_pcr", "ToMToU"); + ima_add_violation(inode, pathname, + "invalid_pcr", "ToMToU"); if (send_writers) - ima_add_violation(file, pathname, + ima_add_violation(inode, pathname, "invalid_pcr", "open_writers"); kfree(pathbuf); } @@ -166,12 +144,9 @@ static int process_measurement(struct file *file, const char *filename, { struct inode *inode = file_inode(file); struct integrity_iint_cache *iint; - struct ima_template_desc *template_desc = ima_template_desc_current(); char *pathbuf = NULL; const char *pathname = NULL; int rc = -ENOMEM, action, must_appraise, _func; - struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; - int xattr_len = 0; if (!ima_initialized || !S_ISREG(inode->i_mode)) return 0; @@ -210,13 +185,7 @@ static int process_measurement(struct file *file, const char *filename, goto out_digsig; } - if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { - if (action & IMA_APPRAISE_SUBMASK) - xattr_ptr = &xattr_value; - } else - xattr_ptr = &xattr_value; - - rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len); + rc = ima_collect_measurement(iint, file); if (rc != 0) goto out_digsig; @@ -225,11 +194,9 @@ static int process_measurement(struct file *file, const char *filename, pathname = (const char *)file->f_dentry->d_name.name; if (action & IMA_MEASURE) - ima_store_measurement(iint, file, pathname, - xattr_value, xattr_len); + ima_store_measurement(iint, file, pathname); if (action & IMA_APPRAISE_SUBMASK) - rc = ima_appraise_measurement(_func, iint, file, pathname, - xattr_value, xattr_len); + rc = ima_appraise_measurement(_func, iint, file, pathname); if (action & IMA_AUDIT) ima_audit_measurement(iint, pathname); kfree(pathbuf); @@ -238,7 +205,6 @@ out_digsig: rc = -EACCES; out: mutex_unlock(&inode->i_mutex); - kfree(xattr_value); if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) return -EACCES; return 0; @@ -278,9 +244,9 @@ int ima_file_mmap(struct file *file, unsigned long prot) int ima_bprm_check(struct linux_binprm *bprm) { return process_measurement(bprm->file, - (strcmp(bprm->filename, bprm->interp) == 0) ? - bprm->filename : bprm->interp, - MAY_EXEC, BPRM_CHECK); + (strcmp(bprm->filename, bprm->interp) == 0) ? + bprm->filename : bprm->interp, + MAY_EXEC, BPRM_CHECK); } /** @@ -297,8 +263,8 @@ int ima_file_check(struct file *file, int mask) { ima_rdwr_violation_check(file); return process_measurement(file, NULL, - mask & (MAY_READ | MAY_WRITE | MAY_EXEC), - FILE_CHECK); + mask & (MAY_READ | MAY_WRITE | MAY_EXEC), + FILE_CHECK); } EXPORT_SYMBOL_GPL(ima_file_check); @@ -328,7 +294,6 @@ static int __init init_ima(void) { int error; - hash_setup(CONFIG_IMA_DEFAULT_HASH); error = ima_init(); if (!error) ima_initialized = 1; diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index a9c3d3c..399433a 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -73,6 +73,7 @@ static struct ima_rule_entry default_rules[] = { {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, + {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, {.action = DONT_MEASURE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC}, {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC}, {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index d85e997..ff63fe0 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -50,7 +50,7 @@ static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value) key = ima_hash_key(digest_value); rcu_read_lock(); hlist_for_each_entry_rcu(qe, &ima_htable.queue[key], hnext) { - rc = memcmp(qe->entry->digest, digest_value, TPM_DIGEST_SIZE); + rc = memcmp(qe->entry->digest, digest_value, IMA_DIGEST_SIZE); if (rc == 0) { ret = qe; break; @@ -104,10 +104,9 @@ static int ima_pcr_extend(const u8 *hash) * and extend the pcr. */ int ima_add_template_entry(struct ima_template_entry *entry, int violation, - const char *op, struct inode *inode, - const unsigned char *filename) + const char *op, struct inode *inode) { - u8 digest[TPM_DIGEST_SIZE]; + u8 digest[IMA_DIGEST_SIZE]; const char *audit_cause = "hash_added"; char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX]; int audit_info = 1; @@ -142,7 +141,8 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, } out: mutex_unlock(&ima_extend_list_mutex); - integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, + integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, + entry->template.file_name, op, audit_cause, result, audit_info); return result; } diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c deleted file mode 100644 index 635695f..0000000 --- a/security/integrity/ima/ima_template.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2013 Politecnico di Torino, Italy - * TORSEC group -- http://security.polito.it - * - * Author: Roberto Sassu <roberto.sassu@polito.it> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima_template.c - * Helpers to manage template descriptors. - */ -#include <crypto/hash_info.h> - -#include "ima.h" -#include "ima_template_lib.h" - -static struct ima_template_desc defined_templates[] = { - {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, - {.name = "ima-ng",.fmt = "d-ng|n-ng"}, - {.name = "ima-sig",.fmt = "d-ng|n-ng|sig"}, -}; - -static struct ima_template_field supported_fields[] = { - {.field_id = "d",.field_init = ima_eventdigest_init, - .field_show = ima_show_template_digest}, - {.field_id = "n",.field_init = ima_eventname_init, - .field_show = ima_show_template_string}, - {.field_id = "d-ng",.field_init = ima_eventdigest_ng_init, - .field_show = ima_show_template_digest_ng}, - {.field_id = "n-ng",.field_init = ima_eventname_ng_init, - .field_show = ima_show_template_string}, - {.field_id = "sig",.field_init = ima_eventsig_init, - .field_show = ima_show_template_sig}, -}; - -static struct ima_template_desc *ima_template; -static struct ima_template_desc *lookup_template_desc(const char *name); - -static int __init ima_template_setup(char *str) -{ - struct ima_template_desc *template_desc; - int template_len = strlen(str); - - /* - * Verify that a template with the supplied name exists. - * If not, use CONFIG_IMA_DEFAULT_TEMPLATE. - */ - template_desc = lookup_template_desc(str); - if (!template_desc) - return 1; - - /* - * Verify whether the current hash algorithm is supported - * by the 'ima' template. - */ - if (template_len == 3 && strcmp(str, IMA_TEMPLATE_IMA_NAME) == 0 && - ima_hash_algo != HASH_ALGO_SHA1 && ima_hash_algo != HASH_ALGO_MD5) { - pr_err("IMA: template does not support hash alg\n"); - return 1; - } - - ima_template = template_desc; - return 1; -} -__setup("ima_template=", ima_template_setup); - -static struct ima_template_desc *lookup_template_desc(const char *name) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(defined_templates); i++) { - if (strcmp(defined_templates[i].name, name) == 0) - return defined_templates + i; - } - - return NULL; -} - -static struct ima_template_field *lookup_template_field(const char *field_id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(supported_fields); i++) - if (strncmp(supported_fields[i].field_id, field_id, - IMA_TEMPLATE_FIELD_ID_MAX_LEN) == 0) - return &supported_fields[i]; - return NULL; -} - -static int template_fmt_size(const char *template_fmt) -{ - char c; - int template_fmt_len = strlen(template_fmt); - int i = 0, j = 0; - - while (i < template_fmt_len) { - c = template_fmt[i]; - if (c == '|') - j++; - i++; - } - - return j + 1; -} - -static int template_desc_init_fields(const char *template_fmt, - struct ima_template_field ***fields, - int *num_fields) -{ - char *c, *template_fmt_copy, *template_fmt_ptr; - int template_num_fields = template_fmt_size(template_fmt); - int i, result = 0; - - if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) - return -EINVAL; - - /* copying is needed as strsep() modifies the original buffer */ - template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL); - if (template_fmt_copy == NULL) - return -ENOMEM; - - *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL); - if (*fields == NULL) { - result = -ENOMEM; - goto out; - } - - template_fmt_ptr = template_fmt_copy; - for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL && - i < template_num_fields; i++) { - struct ima_template_field *f = lookup_template_field(c); - - if (!f) { - result = -ENOENT; - goto out; - } - (*fields)[i] = f; - } - *num_fields = i; -out: - if (result < 0) { - kfree(*fields); - *fields = NULL; - } - kfree(template_fmt_copy); - return result; -} - -static int init_defined_templates(void) -{ - int i = 0; - int result = 0; - - /* Init defined templates. */ - for (i = 0; i < ARRAY_SIZE(defined_templates); i++) { - struct ima_template_desc *template = &defined_templates[i]; - - result = template_desc_init_fields(template->fmt, - &(template->fields), - &(template->num_fields)); - if (result < 0) - return result; - } - return result; -} - -struct ima_template_desc *ima_template_desc_current(void) -{ - if (!ima_template) - ima_template = - lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE); - return ima_template; -} - -int ima_init_template(void) -{ - int result; - - result = init_defined_templates(); - if (result < 0) - return result; - - return 0; -} diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c deleted file mode 100644 index c38adcc..0000000 --- a/security/integrity/ima/ima_template_lib.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2013 Politecnico di Torino, Italy - * TORSEC group -- http://security.polito.it - * - * Author: Roberto Sassu <roberto.sassu@polito.it> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima_template_lib.c - * Library of supported template fields. - */ -#include <crypto/hash_info.h> - -#include "ima_template_lib.h" - -static bool ima_template_hash_algo_allowed(u8 algo) -{ - if (algo == HASH_ALGO_SHA1 || algo == HASH_ALGO_MD5) - return true; - - return false; -} - -enum data_formats { - DATA_FMT_DIGEST = 0, - DATA_FMT_DIGEST_WITH_ALGO, - DATA_FMT_EVENT_NAME, - DATA_FMT_STRING, - DATA_FMT_HEX -}; - -static int ima_write_template_field_data(const void *data, const u32 datalen, - enum data_formats datafmt, - struct ima_field_data *field_data) -{ - u8 *buf, *buf_ptr; - u32 buflen; - - switch (datafmt) { - case DATA_FMT_EVENT_NAME: - buflen = IMA_EVENT_NAME_LEN_MAX + 1; - break; - case DATA_FMT_STRING: - buflen = datalen + 1; - break; - default: - buflen = datalen; - } - - buf = kzalloc(buflen, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - memcpy(buf, data, datalen); - - /* - * Replace all space characters with underscore for event names and - * strings. This avoid that, during the parsing of a measurements list, - * filenames with spaces or that end with the suffix ' (deleted)' are - * split into multiple template fields (the space is the delimitator - * character for measurements lists in ASCII format). - */ - if (datafmt == DATA_FMT_EVENT_NAME || datafmt == DATA_FMT_STRING) { - for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++) - if (*buf_ptr == ' ') - *buf_ptr = '_'; - } - - field_data->data = buf; - field_data->len = buflen; - return 0; -} - -static void ima_show_template_data_ascii(struct seq_file *m, - enum ima_show_type show, - enum data_formats datafmt, - struct ima_field_data *field_data) -{ - u8 *buf_ptr = field_data->data, buflen = field_data->len; - - switch (datafmt) { - case DATA_FMT_DIGEST_WITH_ALGO: - buf_ptr = strnchr(field_data->data, buflen, ':'); - if (buf_ptr != field_data->data) - seq_printf(m, "%s", field_data->data); - - /* skip ':' and '\0' */ - buf_ptr += 2; - buflen -= buf_ptr - field_data->data; - case DATA_FMT_DIGEST: - case DATA_FMT_HEX: - if (!buflen) - break; - ima_print_digest(m, buf_ptr, buflen); - break; - case DATA_FMT_STRING: - seq_printf(m, "%s", buf_ptr); - break; - default: - break; - } -} - -static void ima_show_template_data_binary(struct seq_file *m, - enum ima_show_type show, - enum data_formats datafmt, - struct ima_field_data *field_data) -{ - if (show != IMA_SHOW_BINARY_NO_FIELD_LEN) - ima_putc(m, &field_data->len, sizeof(u32)); - - if (!field_data->len) - return; - - ima_putc(m, field_data->data, field_data->len); -} - -static void ima_show_template_field_data(struct seq_file *m, - enum ima_show_type show, - enum data_formats datafmt, - struct ima_field_data *field_data) -{ - switch (show) { - case IMA_SHOW_ASCII: - ima_show_template_data_ascii(m, show, datafmt, field_data); - break; - case IMA_SHOW_BINARY: - case IMA_SHOW_BINARY_NO_FIELD_LEN: - ima_show_template_data_binary(m, show, datafmt, field_data); - break; - default: - break; - } -} - -void ima_show_template_digest(struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data) -{ - ima_show_template_field_data(m, show, DATA_FMT_DIGEST, field_data); -} - -void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data) -{ - ima_show_template_field_data(m, show, DATA_FMT_DIGEST_WITH_ALGO, - field_data); -} - -void ima_show_template_string(struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data) -{ - ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data); -} - -void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data) -{ - ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data); -} - -static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, - struct ima_field_data *field_data, - bool size_limit) -{ - /* - * digest formats: - * - DATA_FMT_DIGEST: digest - * - DATA_FMT_DIGEST_WITH_ALGO: [<hash algo>] + ':' + '\0' + digest, - * where <hash algo> is provided if the hash algoritm is not - * SHA1 or MD5 - */ - u8 buffer[CRYPTO_MAX_ALG_NAME + 2 + IMA_MAX_DIGEST_SIZE] = { 0 }; - enum data_formats fmt = DATA_FMT_DIGEST; - u32 offset = 0; - - if (!size_limit) { - fmt = DATA_FMT_DIGEST_WITH_ALGO; - if (hash_algo < HASH_ALGO__LAST) - offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, - "%s", hash_algo_name[hash_algo]); - buffer[offset] = ':'; - offset += 2; - } - - if (digest) - memcpy(buffer + offset, digest, digestsize); - else - /* - * If digest is NULL, the event being recorded is a violation. - * Make room for the digest by increasing the offset of - * IMA_DIGEST_SIZE. - */ - offset += IMA_DIGEST_SIZE; - - return ima_write_template_field_data(buffer, offset + digestsize, - fmt, field_data); -} - -/* - * This function writes the digest of an event (with size limit). - */ -int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_field_data *field_data) -{ - struct { - struct ima_digest_data hdr; - char digest[IMA_MAX_DIGEST_SIZE]; - } hash; - u8 *cur_digest = NULL; - u32 cur_digestsize = 0; - struct inode *inode; - int result; - - memset(&hash, 0, sizeof(hash)); - - if (!iint) /* recording a violation. */ - goto out; - - if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) { - cur_digest = iint->ima_hash->digest; - cur_digestsize = iint->ima_hash->length; - goto out; - } - - if (!file) /* missing info to re-calculate the digest */ - return -EINVAL; - - inode = file_inode(file); - hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ? - ima_hash_algo : HASH_ALGO_SHA1; - result = ima_calc_file_hash(file, &hash.hdr); - if (result) { - integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, - filename, "collect_data", - "failed", result, 0); - return result; - } - cur_digest = hash.hdr.digest; - cur_digestsize = hash.hdr.length; -out: - return ima_eventdigest_init_common(cur_digest, cur_digestsize, -1, - field_data, true); -} - -/* - * This function writes the digest of an event (without size limit). - */ -int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, - struct file *file, const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len, struct ima_field_data *field_data) -{ - u8 *cur_digest = NULL, hash_algo = HASH_ALGO__LAST; - u32 cur_digestsize = 0; - - /* If iint is NULL, we are recording a violation. */ - if (!iint) - goto out; - - cur_digest = iint->ima_hash->digest; - cur_digestsize = iint->ima_hash->length; - - hash_algo = iint->ima_hash->algo; -out: - return ima_eventdigest_init_common(cur_digest, cur_digestsize, - hash_algo, field_data, false); -} - -static int ima_eventname_init_common(struct integrity_iint_cache *iint, - struct file *file, - const unsigned char *filename, - struct ima_field_data *field_data, - bool size_limit) -{ - const char *cur_filename = NULL; - u32 cur_filename_len = 0; - enum data_formats fmt = size_limit ? - DATA_FMT_EVENT_NAME : DATA_FMT_STRING; - - BUG_ON(filename == NULL && file == NULL); - - if (filename) { - cur_filename = filename; - cur_filename_len = strlen(filename); - - if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX) - goto out; - } - - if (file) { - cur_filename = file->f_dentry->d_name.name; - cur_filename_len = strlen(cur_filename); - } else - /* - * Truncate filename if the latter is too long and - * the file descriptor is not available. - */ - cur_filename_len = IMA_EVENT_NAME_LEN_MAX; -out: - return ima_write_template_field_data(cur_filename, cur_filename_len, - fmt, field_data); -} - -/* - * This function writes the name of an event (with size limit). - */ -int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_field_data *field_data) -{ - return ima_eventname_init_common(iint, file, filename, - field_data, true); -} - -/* - * This function writes the name of an event (without size limit). - */ -int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_field_data *field_data) -{ - return ima_eventname_init_common(iint, file, filename, - field_data, false); -} - -/* - * ima_eventsig_init - include the file signature as part of the template data - */ -int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_field_data *field_data) -{ - enum data_formats fmt = DATA_FMT_HEX; - int rc = 0; - - if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) - goto out; - - rc = ima_write_template_field_data(xattr_value, xattr_len, fmt, - field_data); -out: - return rc; -} diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h deleted file mode 100644 index 63f6b52..0000000 --- a/security/integrity/ima/ima_template_lib.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2013 Politecnico di Torino, Italy - * TORSEC group -- http://security.polito.it - * - * Author: Roberto Sassu <roberto.sassu@polito.it> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * File: ima_template_lib.h - * Header for the library of supported template fields. - */ -#ifndef __LINUX_IMA_TEMPLATE_LIB_H -#define __LINUX_IMA_TEMPLATE_LIB_H - -#include <linux/seq_file.h> -#include "ima.h" - -void ima_show_template_digest(struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data); -void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data); -void ima_show_template_string(struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data); -void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, - struct ima_field_data *field_data); -int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_field_data *field_data); -int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_field_data *field_data); -int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, - struct file *file, const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, - int xattr_len, struct ima_field_data *field_data); -int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_field_data *field_data); -int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file, - const unsigned char *filename, - struct evm_ima_xattr_data *xattr_value, int xattr_len, - struct ima_field_data *field_data); -#endif /* __LINUX_IMA_TEMPLATE_LIB_H */ diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 2fb5e53..c42fb7a 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -54,57 +54,25 @@ enum evm_ima_xattr_type { IMA_XATTR_DIGEST = 0x01, EVM_XATTR_HMAC, EVM_IMA_XATTR_DIGSIG, - IMA_XATTR_DIGEST_NG, }; struct evm_ima_xattr_data { u8 type; u8 digest[SHA1_DIGEST_SIZE]; -} __packed; - -#define IMA_MAX_DIGEST_SIZE 64 - -struct ima_digest_data { - u8 algo; - u8 length; - union { - struct { - u8 unused; - u8 type; - } sha1; - struct { - u8 type; - u8 algo; - } ng; - u8 data[2]; - } xattr; - u8 digest[0]; -} __packed; - -/* - * signature format v2 - for using with asymmetric keys - */ -struct signature_v2_hdr { - uint8_t type; /* xattr type */ - uint8_t version; /* signature format version */ - uint8_t hash_algo; /* Digest algorithm [enum pkey_hash_algo] */ - uint32_t keyid; /* IMA key identifier - not X509/PGP specific */ - uint16_t sig_size; /* signature size */ - uint8_t sig[0]; /* signature payload */ -} __packed; +} __attribute__((packed)); /* integrity data associated with an inode */ struct integrity_iint_cache { - struct rb_node rb_node; /* rooted in integrity_iint_tree */ + struct rb_node rb_node; /* rooted in integrity_iint_tree */ struct inode *inode; /* back pointer to inode in question */ u64 version; /* track inode changes */ unsigned long flags; + struct evm_ima_xattr_data ima_xattr; enum integrity_status ima_file_status:4; enum integrity_status ima_mmap_status:4; 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; }; /* rbtree tree calls to lookup, insert, delete @@ -121,7 +89,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode); #ifdef CONFIG_INTEGRITY_SIGNATURE int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, - const char *digest, int digestlen); + const char *digest, int digestlen); #else |