diff --git a/ima-allow-it-to-be-completely-disabled-and-default-off.patch b/ima-allow-it-to-be-completely-disabled-and-default-off.patch new file mode 100644 index 000000000..91bdb7528 --- /dev/null +++ b/ima-allow-it-to-be-completely-disabled-and-default-off.patch @@ -0,0 +1,275 @@ +From 6887ac55c66179ecd6191c21cf9c629cb2317ca4 Mon Sep 17 00:00:00 2001 +From: Kyle McMartin +Date: Mon, 18 Oct 2010 02:08:35 -0400 +Subject: [PATCH] ima: allow it to be completely disabled (and default to off) + +Allow IMA to be entirely disabled, don't even bother calling into +the provided hooks, and avoid initializing caches. + +(A lot of the hooks will test iint_initialized, and so this doubly + disables them, since the iint cache won't be enabled. But hey, we + avoid a pointless branch...) + +Signed-off-by: Kyle McMartin +--- + include/linux/ima.h | 66 +++++++++++++++++++++++++++++++++---- + security/integrity/ima/ima_iint.c | 13 +++++-- + security/integrity/ima/ima_main.c | 34 +++++++++++++------ + 3 files changed, 91 insertions(+), 22 deletions(-) + +diff --git a/include/linux/ima.h b/include/linux/ima.h +index 975837e..2fa456d 100644 +--- a/include/linux/ima.h ++++ b/include/linux/ima.h +@@ -14,13 +14,65 @@ + struct linux_binprm; + + #ifdef CONFIG_IMA +-extern int ima_bprm_check(struct linux_binprm *bprm); +-extern int ima_inode_alloc(struct inode *inode); +-extern void ima_inode_free(struct inode *inode); +-extern int ima_file_check(struct file *file, int mask); +-extern void ima_file_free(struct file *file); +-extern int ima_file_mmap(struct file *file, unsigned long prot); +-extern void ima_counts_get(struct file *file); ++ ++extern int ima_enabled; ++ ++extern int __ima_bprm_check(struct linux_binprm *bprm); ++extern int __ima_inode_alloc(struct inode *inode); ++extern void __ima_inode_free(struct inode *inode); ++extern int __ima_file_check(struct file *file, int mask); ++extern void __ima_file_free(struct file *file); ++extern int __ima_file_mmap(struct file *file, unsigned long prot); ++extern void __ima_counts_get(struct file *file); ++ ++static inline int ima_bprm_check(struct linux_binprm *bprm) ++{ ++ if (ima_enabled) ++ return __ima_bprm_check(bprm); ++ return 0; ++} ++ ++static inline int ima_inode_alloc(struct inode *inode) ++{ ++ if (ima_enabled) ++ return __ima_inode_alloc(inode); ++ return 0; ++} ++ ++static inline void ima_inode_free(struct inode *inode) ++{ ++ if (ima_enabled) ++ __ima_inode_free(inode); ++ return; ++} ++ ++static inline int ima_file_check(struct file *file, int mask) ++{ ++ if (ima_enabled) ++ return __ima_file_check(file, mask); ++ return 0; ++} ++ ++static inline void ima_file_free(struct file *file) ++{ ++ if (ima_enabled) ++ __ima_file_free(file); ++ return; ++} ++ ++static inline int ima_file_mmap(struct file *file, unsigned long prot) ++{ ++ if (ima_enabled) ++ return __ima_file_mmap(file, prot); ++ return 0; ++} ++ ++static inline void ima_counts_get(struct file *file) ++{ ++ if (ima_enabled) ++ return __ima_counts_get(file); ++ return; ++} + + #else + static inline int ima_bprm_check(struct linux_binprm *bprm) +diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c +index afba4ae..767f026 100644 +--- a/security/integrity/ima/ima_iint.c ++++ b/security/integrity/ima/ima_iint.c +@@ -46,10 +46,10 @@ out: + } + + /** +- * ima_inode_alloc - allocate an iint associated with an inode ++ * __ima_inode_alloc - allocate an iint associated with an inode + * @inode: pointer to the inode + */ +-int ima_inode_alloc(struct inode *inode) ++int __ima_inode_alloc(struct inode *inode) + { + struct ima_iint_cache *iint = NULL; + int rc = 0; +@@ -107,12 +107,12 @@ void iint_rcu_free(struct rcu_head *rcu_head) + } + + /** +- * ima_inode_free - called on security_inode_free ++ * __ima_inode_free - called on security_inode_free + * @inode: pointer to the inode + * + * Free the integrity information(iint) associated with an inode. + */ +-void ima_inode_free(struct inode *inode) ++void __ima_inode_free(struct inode *inode) + { + struct ima_iint_cache *iint; + +@@ -139,6 +139,11 @@ static void init_once(void *foo) + + static int __init ima_iintcache_init(void) + { ++ extern int ima_enabled; ++ ++ if (!ima_enabled) ++ return 0; ++ + iint_cache = + kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, + SLAB_PANIC, init_once); +diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c +index e662b89..92e084c 100644 +--- a/security/integrity/ima/ima_main.c ++++ b/security/integrity/ima/ima_main.c +@@ -26,6 +26,7 @@ + #include "ima.h" + + int ima_initialized; ++int ima_enabled = 0; + + char *ima_hash = "sha1"; + static int __init hash_setup(char *str) +@@ -36,6 +37,14 @@ static int __init hash_setup(char *str) + } + __setup("ima_hash=", hash_setup); + ++static int __init ima_enable(char *str) ++{ ++ if (strncmp(str, "on", 2) == 0) ++ ima_enabled = 1; ++ return 1; ++} ++__setup("ima=", ima_enable); ++ + struct ima_imbalance { + struct hlist_node node; + unsigned long fsmagic; +@@ -130,7 +139,7 @@ static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode) + } + + /* +- * ima_counts_get - increment file counts ++ * __ima_counts_get - increment file counts + * + * Maintain read/write counters for all files, but only + * invalidate the PCR for measured files: +@@ -140,7 +149,7 @@ static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode) + * could result in a file measurement error. + * + */ +-void ima_counts_get(struct file *file) ++void __ima_counts_get(struct file *file) + { + struct dentry *dentry = file->f_path.dentry; + struct inode *inode = dentry->d_inode; +@@ -204,13 +213,13 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode, + } + + /** +- * ima_file_free - called on __fput() ++ * __ima_file_free - called on __fput() + * @file: pointer to file structure being freed + * + * Flag files that changed, based on i_version; + * and decrement the iint readcount/writecount. + */ +-void ima_file_free(struct file *file) ++void __ima_file_free(struct file *file) + { + struct inode *inode = file->f_dentry->d_inode; + struct ima_iint_cache *iint; +@@ -255,7 +264,7 @@ out: + } + + /** +- * ima_file_mmap - based on policy, collect/store measurement. ++ * __ima_file_mmap - based on policy, collect/store measurement. + * @file: pointer to the file to be measured (May be NULL) + * @prot: contains the protection that will be applied by the kernel. + * +@@ -265,7 +274,7 @@ out: + * Return 0 on success, an error code on failure. + * (Based on the results of appraise_measurement().) + */ +-int ima_file_mmap(struct file *file, unsigned long prot) ++int __ima_file_mmap(struct file *file, unsigned long prot) + { + int rc; + +@@ -278,7 +287,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) + } + + /** +- * ima_bprm_check - based on policy, collect/store measurement. ++ * __ima_bprm_check - based on policy, collect/store measurement. + * @bprm: contains the linux_binprm structure + * + * The OS protects against an executable file, already open for write, +@@ -290,7 +299,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) + * Return 0 on success, an error code on failure. + * (Based on the results of appraise_measurement().) + */ +-int ima_bprm_check(struct linux_binprm *bprm) ++int __ima_bprm_check(struct linux_binprm *bprm) + { + int rc; + +@@ -300,7 +309,7 @@ int ima_bprm_check(struct linux_binprm *bprm) + } + + /** +- * ima_path_check - based on policy, collect/store measurement. ++ * __ima_path_check - based on policy, collect/store measurement. + * @file: pointer to the file to be measured + * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE + * +@@ -309,7 +318,7 @@ int ima_bprm_check(struct linux_binprm *bprm) + * Always return 0 and audit dentry_open failures. + * (Return code will be based upon measurement appraisal.) + */ +-int ima_file_check(struct file *file, int mask) ++int __ima_file_check(struct file *file, int mask) + { + int rc; + +@@ -318,12 +327,15 @@ int ima_file_check(struct file *file, int mask) + FILE_CHECK); + return 0; + } +-EXPORT_SYMBOL_GPL(ima_file_check); ++EXPORT_SYMBOL_GPL(__ima_file_check); + + static int __init init_ima(void) + { + int error; + ++ if (!ima_enabled) ++ return 0; ++ + error = ima_init(); + ima_initialized = 1; + return error; +-- +1.7.3.1 + diff --git a/kernel.spec b/kernel.spec index 3bb6f1e1a..e1faa1784 100644 --- a/kernel.spec +++ b/kernel.spec @@ -727,6 +727,8 @@ Patch12302: pnpacpi-cope-with-invalid-device-ids.patch Patch12303: dmar-disable-when-ricoh-multifunction.patch +Patch12304: ima-allow-it-to-be-completely-disabled-and-default-off.patch + %endif BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root @@ -1343,6 +1345,8 @@ ApplyPatch pnpacpi-cope-with-invalid-device-ids.patch # rhbz#605888 ApplyPatch dmar-disable-when-ricoh-multifunction.patch +ApplyPatch ima-allow-it-to-be-completely-disabled-and-default-off.patch + # END OF PATCH APPLICATIONS %endif @@ -1950,6 +1954,10 @@ fi # || || %changelog +* Mon Oct 18 2010 Kyle McMartin +- ima: Default it to off, pass ima=on to enable. Reduce impact of the option + when disabled. + * Mon Oct 18 2010 Kyle McMartin - Quirk to disable DMAR with Ricoh card reader/firewire. (rhbz#605888)