ima_process_measurements() reads and calculates the file's hash, only if the file is in policy. When a file is read by the kernel, the file contents need to be loaded into memory regardless of the policy.
This patch defines a new IMA hook named ima_read_and_process_file() to load and, at the same time, hash a file. After reading and hashing the file, ima_read_and_process_file() calls ima_process_measurement() with the file hash. If the file is in policy, an iint is created with the hash value. This patch defines two new policy hooks named KEXEC_CHECK and INITRAMFS_CHECK. Based on policy, the kexec image and initramfs files are measured/appraised. Signed-off-by: Mimi Zohar <zo...@linux.vnet.ibm.com> --- Documentation/ABI/testing/ima_policy | 2 +- include/linux/ima.h | 12 +++++++ kernel/kexec_file.c | 28 +++++++++------- security/integrity/iint.c | 1 + security/integrity/ima/ima.h | 8 +++-- security/integrity/ima/ima_api.c | 36 ++++++++++++++++++++- security/integrity/ima/ima_appraise.c | 11 +++++++ security/integrity/ima/ima_crypto.c | 54 ++++++++++++++++++++----------- security/integrity/ima/ima_main.c | 44 +++++++++++++++++++++---- security/integrity/ima/ima_policy.c | 34 +++++++++++++++---- security/integrity/ima/ima_template_lib.c | 2 +- security/integrity/integrity.h | 7 ++-- 12 files changed, 191 insertions(+), 48 deletions(-) diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index 0a378a8..e80f767 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -26,7 +26,7 @@ Description: option: [[appraise_type=]] [permit_directio] base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK] - [FIRMWARE_CHECK] + [FIRMWARE_CHECK] [KEXEC_CHECK] [INITRAMFS_CHECK] mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] [[^]MAY_EXEC] fsmagic:= hex value diff --git a/include/linux/ima.h b/include/linux/ima.h index 120ccc5..5d83ecf 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -13,6 +13,8 @@ #include <linux/fs.h> struct linux_binprm; +enum ima_read_hooks { KEXEC_CHECK = 1, INITRAMFS_CHECK, IMA_MAX_READ_CHECK}; + #ifdef CONFIG_IMA extern int ima_bprm_check(struct linux_binprm *bprm); extern int ima_file_check(struct file *file, int mask, int opened); @@ -20,6 +22,9 @@ 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 int ima_read_and_process_file(struct file *file, + enum ima_read_hooks read_func, + void *buf, size_t size); #else static inline int ima_bprm_check(struct linux_binprm *bprm) @@ -52,6 +57,13 @@ static inline int ima_fw_from_file(struct file *file, char *buf, size_t size) return 0; } +static inline int ima_read_and_process_file(struct file *file, + enum ima_read_hooks read_func, + void *buf, size_t size) +{ + return -EOPNOTSUPP; +} + #endif /* CONFIG_IMA */ #ifdef CONFIG_IMA_APPRAISE diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index b70ada0..18c4a84 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -18,6 +18,7 @@ #include <linux/kexec.h> #include <linux/mutex.h> #include <linux/list.h> +#include <linux/ima.h> #include <crypto/hash.h> #include <crypto/sha.h> #include <linux/syscalls.h> @@ -33,7 +34,8 @@ size_t __weak kexec_purgatory_size = 0; static int kexec_calculate_store_digests(struct kimage *image); -static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len) +static int copy_file_from_fd(int fd, enum ima_read_hooks read_func, + void **buf, unsigned long *buf_len) { struct fd f = fdget(fd); int ret; @@ -65,14 +67,17 @@ static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len) goto out; } + ret = ima_read_and_process_file(f.file, read_func, *buf, stat.size); + if (ret != -EOPNOTSUPP) + goto out_free; + pos = 0; while (pos < stat.size) { bytes = kernel_read(f.file, pos, (char *)(*buf) + pos, stat.size - pos); if (bytes < 0) { - vfree(*buf); ret = bytes; - goto out; + goto out_free; } if (bytes == 0) @@ -80,13 +85,13 @@ static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len) pos += bytes; } - if (pos != stat.size) { + if (pos != stat.size) ret = -EBADF; + else + *buf_len = pos; +out_free: + if (ret < 0) vfree(*buf); - goto out; - } - - *buf_len = pos; out: fdput(f); return ret; @@ -181,8 +186,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, int ret = 0; void *ldata; - ret = copy_file_from_fd(kernel_fd, &image->kernel_buf, - &image->kernel_buf_len); + ret = copy_file_from_fd(kernel_fd, KEXEC_CHECK, + &image->kernel_buf, &image->kernel_buf_len); if (ret) return ret; @@ -204,7 +209,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, #endif /* It is possible that there no initramfs is being loaded */ if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { - ret = copy_file_from_fd(initrd_fd, &image->initrd_buf, + ret = copy_file_from_fd(initrd_fd, INITRAMFS_CHECK, + &image->initrd_buf, &image->initrd_buf_len); if (ret) goto out; diff --git a/security/integrity/iint.c b/security/integrity/iint.c index 54b51a4..8a45576 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -158,6 +158,7 @@ static void init_once(void *foo) iint->ima_mmap_status = INTEGRITY_UNKNOWN; iint->ima_bprm_status = INTEGRITY_UNKNOWN; iint->ima_module_status = INTEGRITY_UNKNOWN; + iint->ima_read_status = INTEGRITY_UNKNOWN; iint->evm_status = INTEGRITY_UNKNOWN; } diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 9ebfec1..8dc9077 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -20,6 +20,7 @@ #include <linux/types.h> #include <linux/crypto.h> #include <linux/security.h> +#include <linux/ima.h> #include <linux/hash.h> #include <linux/tpm.h> #include <linux/audit.h> @@ -106,7 +107,8 @@ int ima_fs_init(void); 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_file_hash(struct file *file, struct ima_digest_data *hash, + void *buf, unsigned long buf_len); 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); @@ -142,6 +144,8 @@ 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, enum hash_algo algo); +int ima_collected_measurement(struct integrity_iint_cache *iint, + struct file *file, struct ima_digest_data *hash); void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, const unsigned char *filename, struct evm_ima_xattr_data *xattr_value, @@ -156,7 +160,7 @@ void ima_free_template_entry(struct ima_template_entry *entry); const char *ima_d_path(struct path *path, char **pathbuf); /* IMA policy related functions */ -enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR }; +enum ima_hooks { FILE_CHECK = IMA_MAX_READ_CHECK, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR}; int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, int flags); diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index e7c7a5d..9559e6d 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -210,7 +210,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, hash.hdr.algo = algo; - result = ima_calc_file_hash(file, &hash.hdr); + result = ima_calc_file_hash(file, &hash.hdr, NULL, 0); if (!result) { int length = sizeof(hash.hdr) + hash.hdr.length; void *tmpbuf = krealloc(iint->ima_hash, length, @@ -233,6 +233,40 @@ out: } /* + * ima_collected_measurement - save the "collected" file hash + * + * The file hash has already been "collected". Save the file hash + * in the iint and clear the measured/appraised flags. + */ +int ima_collected_measurement(struct integrity_iint_cache *iint, + struct file *file, struct ima_digest_data *hash) +{ + const char *audit_cause = "failed"; + const char *filename = file->f_path.dentry->d_name.name; + int length = sizeof(struct ima_digest_data) + hash->length; + int result = -ENOMEM; + void *tmpbuf = krealloc(iint->ima_hash, length, GFP_KERNEL); + + if (!tmpbuf) + goto out; + + iint->ima_hash = tmpbuf; + memcpy(iint->ima_hash, hash, length); + iint->version = file_inode(file)->i_version; + iint->flags &= ~(IMA_MEASURED | IMA_AUDITED| IMA_READ_APPRAISED); + iint->flags |= IMA_COLLECTED; + result = 0; + +out: + if (result) + integrity_audit_msg(AUDIT_INTEGRITY_DATA, + d_inode(file->f_path.dentry), + filename, "collected_data", audit_cause, + result, 0); + return result; +} + +/* * ima_store_measurement - store file measurement * * Create an "ima" template and then store the template by calling diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 9c2b46b..e58df45 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -78,6 +78,9 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, return iint->ima_module_status; case FIRMWARE_CHECK: return iint->ima_firmware_status; + case KEXEC_CHECK: + case INITRAMFS_CHECK: + return iint->ima_read_status; case FILE_CHECK: default: return iint->ima_file_status; @@ -100,6 +103,10 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint, case FIRMWARE_CHECK: iint->ima_firmware_status = status; break; + case KEXEC_CHECK: + case INITRAMFS_CHECK: + iint->ima_read_status = status; + break; case FILE_CHECK: default: iint->ima_file_status = status; @@ -122,6 +129,10 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func) case FIRMWARE_CHECK: iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED); break; + case KEXEC_CHECK: + case INITRAMFS_CHECK: + iint->flags |= (IMA_READ_APPRAISED | IMA_APPRAISED); + break; case FILE_CHECK: default: iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED); diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index fb30ce4..cc0da02 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -352,10 +352,11 @@ static int ima_calc_file_ahash(struct file *file, struct ima_digest_data *hash) static int ima_calc_file_hash_tfm(struct file *file, struct ima_digest_data *hash, + void *buf, unsigned long buf_len, struct crypto_shash *tfm) { - loff_t i_size, offset = 0; - char *rbuf; + loff_t i_size = buf_len, offset = 0; + char *rbuf = buf; int rc, read = 0; SHASH_DESC_ON_STACK(shash, tfm); @@ -368,14 +369,16 @@ static int ima_calc_file_hash_tfm(struct file *file, if (rc != 0) return rc; - i_size = i_size_read(file_inode(file)); + if (!buf) { + i_size = i_size_read(file_inode(file)); - if (i_size == 0) - goto out; + if (i_size == 0) + goto out; - rbuf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!rbuf) - return -ENOMEM; + rbuf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!rbuf) + return -ENOMEM; + } if (!(file->f_mode & FMODE_READ)) { file->f_mode |= FMODE_READ; @@ -383,31 +386,42 @@ static int ima_calc_file_hash_tfm(struct file *file, } while (offset < i_size) { - int rbuf_len; + int rbuf_len, len = buf ? buf_len : PAGE_SIZE; - rbuf_len = integrity_kernel_read(file, offset, rbuf, PAGE_SIZE); + rbuf_len = integrity_kernel_read(file, offset, + !buf ? rbuf : rbuf + offset, + len); if (rbuf_len < 0) { rc = rbuf_len; break; } if (rbuf_len == 0) break; - offset += rbuf_len; - rc = crypto_shash_update(shash, rbuf, rbuf_len); + rc = crypto_shash_update(shash, !buf ? rbuf : rbuf + offset, + rbuf_len); + offset += rbuf_len; if (rc) break; } if (read) file->f_mode &= ~FMODE_READ; - kfree(rbuf); + + if (!buf) + kfree(rbuf); out: if (!rc) rc = crypto_shash_final(shash, hash->digest); return rc; } -static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash) +/* + * ima_calc_file_shash calculates a file hash. When the caller specfies + * a buffer, read the file data into memory, calculating the file hash, + * and return the buffer. + */ +static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash, + void *buf, unsigned long buf_len) { struct crypto_shash *tfm; int rc; @@ -416,7 +430,7 @@ static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash) if (IS_ERR(tfm)) return PTR_ERR(tfm); - rc = ima_calc_file_hash_tfm(file, hash, tfm); + rc = ima_calc_file_hash_tfm(file, hash, buf, buf_len, tfm); ima_free_tfm(tfm); @@ -435,21 +449,25 @@ static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash) * If the ima.ahash_minsize parameter is not specified, this function uses * shash for the hash calculation. If ahash fails, it falls back to using * shash. + * + * When returning the file data to the caller, use shash to calculate the + * file hash. */ -int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) +int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash, + void *buf, unsigned long buf_len) { loff_t i_size; int rc; i_size = i_size_read(file_inode(file)); - if (ima_ahash_minsize && i_size >= ima_ahash_minsize) { + if (ima_ahash_minsize && i_size >= ima_ahash_minsize && !buf) { rc = ima_calc_file_ahash(file, hash); if (!rc) return 0; } - return ima_calc_file_shash(file, hash); + return ima_calc_file_shash(file, hash, buf, buf_len); } /* diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index d9fc463..b8b0b8c 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -22,6 +22,7 @@ #include <linux/mount.h> #include <linux/mman.h> #include <linux/slab.h> +#include <linux/vmalloc.h> #include <linux/xattr.h> #include <linux/ima.h> @@ -154,7 +155,7 @@ void ima_file_free(struct file *file) } static int process_measurement(struct file *file, int mask, int function, - int opened) + struct ima_digest_data *hash, int opened) { struct inode *inode = file_inode(file); struct integrity_iint_cache *iint = NULL; @@ -193,6 +194,11 @@ static int process_measurement(struct file *file, int mask, int function, if (!iint) goto out; } + if (hash) { + rc = ima_collected_measurement(iint, file, hash); + if (rc) + goto out; + } if (violation_check) { ima_rdwr_violation_check(file, iint, action & IMA_MEASURE, @@ -273,7 +279,7 @@ out: int ima_file_mmap(struct file *file, unsigned long prot) { if (file && (prot & PROT_EXEC)) - return process_measurement(file, MAY_EXEC, MMAP_CHECK, 0); + return process_measurement(file, MAY_EXEC, MMAP_CHECK, NULL, 0); return 0; } @@ -292,7 +298,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) */ int ima_bprm_check(struct linux_binprm *bprm) { - return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, 0); + return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, NULL, 0); } /** @@ -309,7 +315,7 @@ int ima_file_check(struct file *file, int mask, int opened) { return process_measurement(file, mask & (MAY_READ | MAY_WRITE | MAY_EXEC), - FILE_CHECK, opened); + FILE_CHECK, NULL, opened); } EXPORT_SYMBOL_GPL(ima_file_check); @@ -332,7 +338,33 @@ int ima_module_check(struct file *file) #endif return 0; /* We rely on module signature checking */ } - return process_measurement(file, MAY_EXEC, MODULE_CHECK, 0); + return process_measurement(file, MAY_EXEC, MODULE_CHECK, NULL, 0); +} + +int ima_read_and_process_file(struct file *file, enum ima_read_hooks read_func, + void *buf, size_t buf_len) +{ + struct evm_ima_xattr_data *xattr_value = NULL; + struct ima_template_desc *template_desc = ima_template_desc_current(); + int xattr_len = 0; + struct { + struct ima_digest_data hdr; + char digest[IMA_MAX_DIGEST_SIZE]; + } hash; + int ret; + + template_desc = ima_template_desc_current(); + if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) + xattr_len = ima_read_xattr(file->f_path.dentry, &xattr_value); + + hash.hdr.algo = ima_get_hash_algo(xattr_value, xattr_len); + + ret = ima_calc_file_hash(file, &hash.hdr, buf, buf_len); + if (!ret) + ret = process_measurement(file, MAY_READ, read_func, + &hash.hdr, 0); + kfree(xattr_value); + return ret; } int ima_fw_from_file(struct file *file, char *buf, size_t size) @@ -343,7 +375,7 @@ int ima_fw_from_file(struct file *file, char *buf, size_t size) return -EACCES; /* INTEGRITY_UNKNOWN */ return 0; } - return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, 0); + return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, NULL, 0); } static int __init init_ima(void) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index ba5d2fc..6fe0ab9 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -53,7 +53,10 @@ struct ima_rule_entry { struct list_head list; int action; unsigned int flags; - enum ima_hooks func; + union { + enum ima_hooks func; + enum ima_read_hooks read_func; + }; int mask; unsigned long fsmagic; u8 fsuuid[16]; @@ -303,6 +306,9 @@ static int get_subaction(struct ima_rule_entry *rule, int func) return IMA_MODULE_APPRAISE; case FIRMWARE_CHECK: return IMA_FIRMWARE_APPRAISE; + case KEXEC_CHECK: + case INITRAMFS_CHECK: + return IMA_READ_APPRAISE; case FILE_CHECK: default: return IMA_FILE_APPRAISE; @@ -604,6 +610,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->func = MMAP_CHECK; else if (strcmp(args[0].from, "BPRM_CHECK") == 0) entry->func = BPRM_CHECK; + else if (strcmp(args[0].from, "KEXEC_CHECK") == 0) + entry->read_func = KEXEC_CHECK; + else if (strcmp(args[0].from, "INITRAMFS_CHECK") == 0) + entry->read_func = INITRAMFS_CHECK; else result = -EINVAL; if (!result) @@ -847,7 +857,8 @@ static char *mask_tokens[] = { enum { func_file = 0, func_mmap, func_bprm, - func_module, func_firmware, func_post + func_module, func_firmware, func_post, + func_kexec, func_initramfs }; static char *func_tokens[] = { @@ -856,7 +867,9 @@ static char *func_tokens[] = { "BPRM_CHECK", "MODULE_CHECK", "FIRMWARE_CHECK", - "POST_SETATTR" + "POST_SETATTR", + "KEXEC_CHECK", + "INITRAMFS_CHECK", }; void *ima_policy_start(struct seq_file *m, loff_t *pos) @@ -937,9 +950,18 @@ int ima_policy_show(struct seq_file *m, void *v) seq_printf(m, pt(Opt_func), ft(func_post)); break; default: - snprintf(tbuf, sizeof(tbuf), "%d", entry->func); - seq_printf(m, pt(Opt_func), tbuf); - break; + switch (entry->read_func) { + case KEXEC_CHECK: + seq_printf(m, pt(Opt_func), ft(func_kexec)); + break; + case INITRAMFS_CHECK: + seq_printf(m, pt(Opt_func), ft(func_initramfs)); + break; + default: + snprintf(tbuf, sizeof(tbuf), "%d", entry->func); + seq_printf(m, pt(Opt_func), tbuf); + break; + } } seq_puts(m, " "); } diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index f9bae04..d0a155a 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c @@ -224,7 +224,7 @@ int ima_eventdigest_init(struct ima_event_data *event_data, inode = file_inode(event_data->file); hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ? ima_hash_algo : HASH_ALGO_SHA1; - result = ima_calc_file_hash(event_data->file, &hash.hdr); + result = ima_calc_file_hash(event_data->file, &hash.hdr, NULL, 0); if (result) { integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, event_data->filename, "collect_data", diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 5413f22..645d5be 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -49,12 +49,14 @@ #define IMA_MODULE_APPRAISED 0x00008000 #define IMA_FIRMWARE_APPRAISE 0x00010000 #define IMA_FIRMWARE_APPRAISED 0x00020000 +#define IMA_READ_APPRAISE 0x00040000 +#define IMA_READ_APPRAISED 0x00080000 #define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \ - IMA_FIRMWARE_APPRAISE) + IMA_FIRMWARE_APPRAISE | IMA_READ_APPRAISE) #define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \ - IMA_FIRMWARE_APPRAISED) + IMA_FIRMWARE_APPRAISED | IMA_READ_APPRAISED) enum evm_ima_xattr_type { IMA_XATTR_DIGEST = 0x01, @@ -111,6 +113,7 @@ struct integrity_iint_cache { enum integrity_status ima_bprm_status:4; enum integrity_status ima_module_status:4; enum integrity_status ima_firmware_status:4; + enum integrity_status ima_read_status:4; enum integrity_status evm_status:4; struct ima_digest_data *ima_hash; }; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html