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>
This commit is contained in:
parent
1625cee56f
commit
fdf90729e5
|
@ -23,7 +23,7 @@ Description:
|
|||
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
||||
[obj_user=] [obj_role=] [obj_type=]]
|
||||
|
||||
base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK]
|
||||
base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK][MODULE_CHECK]
|
||||
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
|
||||
fsmagic:= hex value
|
||||
uid:= decimal value
|
||||
|
@ -53,6 +53,7 @@ Description:
|
|||
measure func=BPRM_CHECK
|
||||
measure func=FILE_MMAP mask=MAY_EXEC
|
||||
measure func=FILE_CHECK mask=MAY_READ uid=0
|
||||
measure func=MODULE_CHECK uid=0
|
||||
appraise fowner=0
|
||||
|
||||
The default policy measures all executables in bprm_check,
|
||||
|
|
|
@ -18,6 +18,7 @@ extern int ima_bprm_check(struct linux_binprm *bprm);
|
|||
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 int ima_module_check(struct file *file);
|
||||
|
||||
#else
|
||||
static inline int ima_bprm_check(struct linux_binprm *bprm)
|
||||
|
@ -40,6 +41,11 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int ima_module_check(struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IMA_H */
|
||||
|
||||
#ifdef CONFIG_IMA_APPRAISE
|
||||
|
|
|
@ -127,7 +127,7 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
|
|||
struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
|
||||
|
||||
/* IMA policy related functions */
|
||||
enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR };
|
||||
enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, MODULE_CHECK, POST_SETATTR };
|
||||
|
||||
int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
|
||||
int flags);
|
||||
|
|
|
@ -100,12 +100,12 @@ err_out:
|
|||
* ima_get_action - appraise & measure decision based on policy.
|
||||
* @inode: pointer to inode to measure
|
||||
* @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
|
||||
* @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
|
||||
* @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP, MODULE_CHECK)
|
||||
*
|
||||
* The policy is defined in terms of keypairs:
|
||||
* subj=, obj=, type=, func=, mask=, fsmagic=
|
||||
* subj,obj, and type: are LSM specific.
|
||||
* func: FILE_CHECK | BPRM_CHECK | FILE_MMAP
|
||||
* func: FILE_CHECK | BPRM_CHECK | FILE_MMAP | MODULE_CHECK
|
||||
* mask: contains the permission mask
|
||||
* fsmagic: hex value
|
||||
*
|
||||
|
|
|
@ -280,6 +280,27 @@ int ima_file_check(struct file *file, int mask)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(ima_file_check);
|
||||
|
||||
/**
|
||||
* ima_module_check - based on policy, collect/store/appraise measurement.
|
||||
* @file: pointer to the file to be measured/appraised
|
||||
*
|
||||
* Measure/appraise kernel modules based on policy.
|
||||
*
|
||||
* Always return 0 and audit dentry_open failures.
|
||||
* Return code is based upon measurement appraisal.
|
||||
*/
|
||||
int ima_module_check(struct file *file)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!file)
|
||||
rc = INTEGRITY_UNKNOWN;
|
||||
else
|
||||
rc = process_measurement(file, file->f_dentry->d_name.name,
|
||||
MAY_EXEC, MODULE_CHECK);
|
||||
return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
|
||||
}
|
||||
|
||||
static int __init init_ima(void)
|
||||
{
|
||||
int error;
|
||||
|
|
|
@ -80,6 +80,7 @@ static struct ima_rule_entry default_rules[] = {
|
|||
.flags = IMA_FUNC | IMA_MASK},
|
||||
{.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID,
|
||||
.flags = IMA_FUNC | IMA_MASK | IMA_UID},
|
||||
{.action = MEASURE,.func = MODULE_CHECK, .flags = IMA_FUNC},
|
||||
};
|
||||
|
||||
static struct ima_rule_entry default_appraise_rules[] = {
|
||||
|
@ -401,6 +402,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
|||
/* PATH_CHECK is for backwards compat */
|
||||
else if (strcmp(args[0].from, "PATH_CHECK") == 0)
|
||||
entry->func = FILE_CHECK;
|
||||
else if (strcmp(args[0].from, "MODULE_CHECK") == 0)
|
||||
entry->func = MODULE_CHECK;
|
||||
else if (strcmp(args[0].from, "FILE_MMAP") == 0)
|
||||
entry->func = FILE_MMAP;
|
||||
else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
|
||||
|
|
|
@ -822,7 +822,12 @@ int security_kernel_module_request(char *kmod_name)
|
|||
|
||||
int security_kernel_module_from_file(struct file *file)
|
||||
{
|
||||
return security_ops->kernel_module_from_file(file);
|
||||
int ret;
|
||||
|
||||
ret = security_ops->kernel_module_from_file(file);
|
||||
if (ret)
|
||||
return ret;
|
||||
return ima_module_check(file);
|
||||
}
|
||||
|
||||
int security_task_fix_setuid(struct cred *new, const struct cred *old,
|
||||
|
|
Loading…
Reference in New Issue