aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2016-04-05 16:06:27 -0400
committerPaul Moore <paul@paul-moore.com>2016-04-05 16:11:56 -0400
commit61d612ea731e57dc510472fb746b55cdc017f371 (patch)
treeb44c2c0228284fffaa2f7a09de7bae85da0a3d72
parent0c6181cb301fd04a5800920ba423be753b0a4a01 (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.c47
-rw-r--r--security/selinux/include/classmap.h2
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
3725static 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
3755static 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
3725static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) 3771static 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",