Commit 61d612ea authored by Jeff Vander Stoep's avatar Jeff Vander Stoep Committed by Paul Moore

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: default avatarJeff Vander Stoep <jeffv@google.com>
[PM: fixed return value of selinux_kernel_read_file()]
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 0c6181cb
...@@ -3722,6 +3722,52 @@ static int selinux_kernel_module_request(char *kmod_name) ...@@ -3722,6 +3722,52 @@ static int selinux_kernel_module_request(char *kmod_name)
SYSTEM__MODULE_REQUEST, &ad); SYSTEM__MODULE_REQUEST, &ad);
} }
static int selinux_kernel_module_from_file(struct file *file)
{
struct common_audit_data ad;
struct inode_security_struct *isec;
struct file_security_struct *fsec;
u32 sid = current_sid();
int rc;
/* init_module */
if (file == NULL)
return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
SYSTEM__MODULE_LOAD, NULL);
/* finit_module */
ad.type = LSM_AUDIT_DATA_PATH;
ad.u.path = file->f_path;
isec = inode_security(file_inode(file));
fsec = file->f_security;
if (sid != fsec->sid) {
rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
if (rc)
return rc;
}
return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
SYSTEM__MODULE_LOAD, &ad);
}
static int selinux_kernel_read_file(struct file *file,
enum kernel_read_file_id id)
{
int rc = 0;
switch (id) {
case READING_MODULE:
rc = selinux_kernel_module_from_file(file);
break;
default:
break;
}
return rc;
}
static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
{ {
return current_has_perm(p, PROCESS__SETPGID); return current_has_perm(p, PROCESS__SETPGID);
...@@ -6018,6 +6064,7 @@ static struct security_hook_list selinux_hooks[] = { ...@@ -6018,6 +6064,7 @@ static struct security_hook_list selinux_hooks[] = {
LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
LSM_HOOK_INIT(task_getsid, selinux_task_getsid), LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
......
...@@ -32,7 +32,7 @@ struct security_class_mapping secclass_map[] = { ...@@ -32,7 +32,7 @@ struct security_class_mapping secclass_map[] = {
"setsockcreate", NULL } }, "setsockcreate", NULL } },
{ "system", { "system",
{ "ipc_info", "syslog_read", "syslog_mod", { "ipc_info", "syslog_read", "syslog_mod",
"syslog_console", "module_request", NULL } }, "syslog_console", "module_request", "module_load", NULL } },
{ "capability", { "capability",
{ "chown", "dac_override", "dac_read_search", { "chown", "dac_override", "dac_read_search",
"fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment