Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ima: support new kernel module syscall

With the addition of the new kernel module syscall, which defines two
arguments - a file descriptor to the kernel module and a pointer to a NULL
terminated string of module arguments - it is now possible to measure and
appraise kernel modules like any other file on the file system.

This patch adds support to measure and appraise kernel modules in an
extensible and consistent manner.

To support filesystems without extended attribute support, additional
patches could pass the signature as the first parameter.

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

authored by

Mimi Zohar and committed by
Rusty Russell
fdf90729 1625cee5

+41 -5
+2 -1
Documentation/ABI/testing/ima_policy
··· 23 23 lsm: [[subj_user=] [subj_role=] [subj_type=] 24 24 [obj_user=] [obj_role=] [obj_type=]] 25 25 26 - base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK] 26 + base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK][MODULE_CHECK] 27 27 mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC] 28 28 fsmagic:= hex value 29 29 uid:= decimal value ··· 53 53 measure func=BPRM_CHECK 54 54 measure func=FILE_MMAP mask=MAY_EXEC 55 55 measure func=FILE_CHECK mask=MAY_READ uid=0 56 + measure func=MODULE_CHECK uid=0 56 57 appraise fowner=0 57 58 58 59 The default policy measures all executables in bprm_check,
+6
include/linux/ima.h
··· 18 18 extern int ima_file_check(struct file *file, int mask); 19 19 extern void ima_file_free(struct file *file); 20 20 extern int ima_file_mmap(struct file *file, unsigned long prot); 21 + extern int ima_module_check(struct file *file); 21 22 22 23 #else 23 24 static inline int ima_bprm_check(struct linux_binprm *bprm) ··· 37 36 } 38 37 39 38 static inline int ima_file_mmap(struct file *file, unsigned long prot) 39 + { 40 + return 0; 41 + } 42 + 43 + static inline int ima_module_check(struct file *file) 40 44 { 41 45 return 0; 42 46 }
+1 -1
security/integrity/ima/ima.h
··· 127 127 struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 128 128 129 129 /* IMA policy related functions */ 130 - enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR }; 130 + enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, MODULE_CHECK, POST_SETATTR }; 131 131 132 132 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 133 133 int flags);
+2 -2
security/integrity/ima/ima_api.c
··· 100 100 * ima_get_action - appraise & measure decision based on policy. 101 101 * @inode: pointer to inode to measure 102 102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) 103 - * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP) 103 + * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP, MODULE_CHECK) 104 104 * 105 105 * The policy is defined in terms of keypairs: 106 106 * subj=, obj=, type=, func=, mask=, fsmagic= 107 107 * subj,obj, and type: are LSM specific. 108 - * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP 108 + * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP | MODULE_CHECK 109 109 * mask: contains the permission mask 110 110 * fsmagic: hex value 111 111 *
+21
security/integrity/ima/ima_main.c
··· 280 280 } 281 281 EXPORT_SYMBOL_GPL(ima_file_check); 282 282 283 + /** 284 + * ima_module_check - based on policy, collect/store/appraise measurement. 285 + * @file: pointer to the file to be measured/appraised 286 + * 287 + * Measure/appraise kernel modules based on policy. 288 + * 289 + * Always return 0 and audit dentry_open failures. 290 + * Return code is based upon measurement appraisal. 291 + */ 292 + int ima_module_check(struct file *file) 293 + { 294 + int rc; 295 + 296 + if (!file) 297 + rc = INTEGRITY_UNKNOWN; 298 + else 299 + rc = process_measurement(file, file->f_dentry->d_name.name, 300 + MAY_EXEC, MODULE_CHECK); 301 + return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; 302 + } 303 + 283 304 static int __init init_ima(void) 284 305 { 285 306 int error;
+3
security/integrity/ima/ima_policy.c
··· 80 80 .flags = IMA_FUNC | IMA_MASK}, 81 81 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID, 82 82 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 83 + {.action = MEASURE,.func = MODULE_CHECK, .flags = IMA_FUNC}, 83 84 }; 84 85 85 86 static struct ima_rule_entry default_appraise_rules[] = { ··· 402 401 /* PATH_CHECK is for backwards compat */ 403 402 else if (strcmp(args[0].from, "PATH_CHECK") == 0) 404 403 entry->func = FILE_CHECK; 404 + else if (strcmp(args[0].from, "MODULE_CHECK") == 0) 405 + entry->func = MODULE_CHECK; 405 406 else if (strcmp(args[0].from, "FILE_MMAP") == 0) 406 407 entry->func = FILE_MMAP; 407 408 else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
+6 -1
security/security.c
··· 822 822 823 823 int security_kernel_module_from_file(struct file *file) 824 824 { 825 - return security_ops->kernel_module_from_file(file); 825 + int ret; 826 + 827 + ret = security_ops->kernel_module_from_file(file); 828 + if (ret) 829 + return ret; 830 + return ima_module_check(file); 826 831 } 827 832 828 833 int security_task_fix_setuid(struct cred *new, const struct cred *old,