diff options
author | Jeff Vander Stoep <jeffv@google.com> | 2016-04-05 16:06:27 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2016-04-05 16:11:56 -0400 |
commit | 61d612ea731e57dc510472fb746b55cdc017f371 (patch) | |
tree | b44c2c0228284fffaa2f7a09de7bae85da0a3d72 | |
parent | 0c6181cb301fd04a5800920ba423be753b0a4a01 (diff) |
selinux: restrict kernel module loading
Utilize existing kernel_read_file hook on kernel module load.
Add module_load permission to the system class.
Enforces restrictions on kernel module origin when calling the
finit_module syscall. The hook checks that source type has
permission module_load for the target type.
Example for finit_module:
allow foo bar_file:system module_load;
Similarly restrictions are enforced on kernel module loading when
calling the init_module syscall. The hook checks that source
type has permission module_load with itself as the target object
because the kernel module is sourced from the calling process.
Example for init_module:
allow foo foo:system module_load;
Signed-off-by: Jeff Vander Stoep <jeffv@google.com>
[PM: fixed return value of selinux_kernel_read_file()]
Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r-- | security/selinux/hooks.c | 47 | ||||
-rw-r--r-- | security/selinux/include/classmap.h | 2 |
2 files changed, 48 insertions, 1 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5003b5aa3b43..fce7dc81f2d9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3722,6 +3722,52 @@ static int selinux_kernel_module_request(char *kmod_name) | |||
3722 | SYSTEM__MODULE_REQUEST, &ad); | 3722 | SYSTEM__MODULE_REQUEST, &ad); |
3723 | } | 3723 | } |
3724 | 3724 | ||
3725 | static int selinux_kernel_module_from_file(struct file *file) | ||
3726 | { | ||
3727 | struct common_audit_data ad; | ||
3728 | struct inode_security_struct *isec; | ||
3729 | struct file_security_struct *fsec; | ||
3730 | u32 sid = current_sid(); | ||
3731 | int rc; | ||
3732 | |||
3733 | /* init_module */ | ||
3734 | if (file == NULL) | ||
3735 | return avc_has_perm(sid, sid, SECCLASS_SYSTEM, | ||
3736 | SYSTEM__MODULE_LOAD, NULL); | ||
3737 | |||
3738 | /* finit_module */ | ||
3739 | ad.type = LSM_AUDIT_DATA_PATH; | ||
3740 | ad.u.path = file->f_path; | ||
3741 | |||
3742 | isec = inode_security(file_inode(file)); | ||
3743 | fsec = file->f_security; | ||
3744 | |||
3745 | if (sid != fsec->sid) { | ||
3746 | rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); | ||
3747 | if (rc) | ||
3748 | return rc; | ||
3749 | } | ||
3750 | |||
3751 | return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM, | ||
3752 | SYSTEM__MODULE_LOAD, &ad); | ||
3753 | } | ||
3754 | |||
3755 | static int selinux_kernel_read_file(struct file *file, | ||
3756 | enum kernel_read_file_id id) | ||
3757 | { | ||
3758 | int rc = 0; | ||
3759 | |||
3760 | switch (id) { | ||
3761 | case READING_MODULE: | ||
3762 | rc = selinux_kernel_module_from_file(file); | ||
3763 | break; | ||
3764 | default: | ||
3765 | break; | ||
3766 | } | ||
3767 | |||
3768 | return rc; | ||
3769 | } | ||
3770 | |||
3725 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) | 3771 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) |
3726 | { | 3772 | { |
3727 | return current_has_perm(p, PROCESS__SETPGID); | 3773 | return current_has_perm(p, PROCESS__SETPGID); |
@@ -6018,6 +6064,7 @@ static struct security_hook_list selinux_hooks[] = { | |||
6018 | LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), | 6064 | LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), |
6019 | LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), | 6065 | LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), |
6020 | LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), | 6066 | LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), |
6067 | LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file), | ||
6021 | LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), | 6068 | LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), |
6022 | LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), | 6069 | LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), |
6023 | LSM_HOOK_INIT(task_getsid, selinux_task_getsid), | 6070 | LSM_HOOK_INIT(task_getsid, selinux_task_getsid), |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index ef83c4b85a33..8fbd1383d75e 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
@@ -32,7 +32,7 @@ struct security_class_mapping secclass_map[] = { | |||
32 | "setsockcreate", NULL } }, | 32 | "setsockcreate", NULL } }, |
33 | { "system", | 33 | { "system", |
34 | { "ipc_info", "syslog_read", "syslog_mod", | 34 | { "ipc_info", "syslog_read", "syslog_mod", |
35 | "syslog_console", "module_request", NULL } }, | 35 | "syslog_console", "module_request", "module_load", NULL } }, |
36 | { "capability", | 36 | { "capability", |
37 | { "chown", "dac_override", "dac_read_search", | 37 | { "chown", "dac_override", "dac_read_search", |
38 | "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", | 38 | "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", |