Skip to content

Commit 2c2b1e0

Browse files
Kipp N. Davispcmoore
authored andcommitted
selinux: add permission checks for loading other kinds of kernel files
Although the LSM hooks for loading kernel modules were later generalized to cover loading other kinds of files, SELinux didn't implement corresponding permission checks, leaving only the module case covered. Define and add new permission checks for these other cases. Signed-off-by: Cameron K. Williams <[email protected]> Signed-off-by: Kipp N. Davis <[email protected]> Acked-by: Stephen Smalley <[email protected]> [PM: merge fuzz, line length, and spacing fixes] Signed-off-by: Paul Moore <[email protected]>
1 parent 5fc80fb commit 2c2b1e0

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

security/selinux/hooks.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4096,20 +4096,16 @@ static int selinux_kernel_module_request(char *kmod_name)
40964096
SYSTEM__MODULE_REQUEST, &ad);
40974097
}
40984098

4099-
static int selinux_kernel_module_from_file(struct file *file)
4099+
static int selinux_kernel_load_from_file(struct file *file, u32 requested)
41004100
{
41014101
struct common_audit_data ad;
41024102
struct inode_security_struct *isec;
41034103
struct file_security_struct *fsec;
41044104
u32 sid = current_sid();
41054105
int rc;
41064106

4107-
/* init_module */
41084107
if (file == NULL)
4109-
return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
4110-
SYSTEM__MODULE_LOAD, NULL);
4111-
4112-
/* finit_module */
4108+
return avc_has_perm(sid, sid, SECCLASS_SYSTEM, requested, NULL);
41134109

41144110
ad.type = LSM_AUDIT_DATA_FILE;
41154111
ad.u.file = file;
@@ -4122,8 +4118,7 @@ static int selinux_kernel_module_from_file(struct file *file)
41224118
}
41234119

41244120
isec = inode_security(file_inode(file));
4125-
return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
4126-
SYSTEM__MODULE_LOAD, &ad);
4121+
return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM, requested, &ad);
41274122
}
41284123

41294124
static int selinux_kernel_read_file(struct file *file,
@@ -4132,9 +4127,30 @@ static int selinux_kernel_read_file(struct file *file,
41324127
{
41334128
int rc = 0;
41344129

4130+
BUILD_BUG_ON_MSG(READING_MAX_ID > 7,
4131+
"New kernel_read_file_id introduced; update SELinux!");
4132+
41354133
switch (id) {
4134+
case READING_FIRMWARE:
4135+
rc = selinux_kernel_load_from_file(file, SYSTEM__FIRMWARE_LOAD);
4136+
break;
41364137
case READING_MODULE:
4137-
rc = selinux_kernel_module_from_file(file);
4138+
rc = selinux_kernel_load_from_file(file, SYSTEM__MODULE_LOAD);
4139+
break;
4140+
case READING_KEXEC_IMAGE:
4141+
rc = selinux_kernel_load_from_file(file,
4142+
SYSTEM__KEXEC_IMAGE_LOAD);
4143+
break;
4144+
case READING_KEXEC_INITRAMFS:
4145+
rc = selinux_kernel_load_from_file(file,
4146+
SYSTEM__KEXEC_INITRAMFS_LOAD);
4147+
break;
4148+
case READING_POLICY:
4149+
rc = selinux_kernel_load_from_file(file, SYSTEM__POLICY_LOAD);
4150+
break;
4151+
case READING_X509_CERTIFICATE:
4152+
rc = selinux_kernel_load_from_file(file,
4153+
SYSTEM__X509_CERTIFICATE_LOAD);
41384154
break;
41394155
default:
41404156
break;
@@ -4147,9 +4163,31 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
41474163
{
41484164
int rc = 0;
41494165

4166+
BUILD_BUG_ON_MSG(LOADING_MAX_ID > 7,
4167+
"New kernel_load_data_id introduced; update SELinux!");
4168+
41504169
switch (id) {
4170+
case LOADING_FIRMWARE:
4171+
rc = selinux_kernel_load_from_file(NULL, SYSTEM__FIRMWARE_LOAD);
4172+
break;
41514173
case LOADING_MODULE:
4152-
rc = selinux_kernel_module_from_file(NULL);
4174+
rc = selinux_kernel_load_from_file(NULL, SYSTEM__MODULE_LOAD);
4175+
break;
4176+
case LOADING_KEXEC_IMAGE:
4177+
rc = selinux_kernel_load_from_file(NULL,
4178+
SYSTEM__KEXEC_IMAGE_LOAD);
4179+
break;
4180+
case LOADING_KEXEC_INITRAMFS:
4181+
rc = selinux_kernel_load_from_file(NULL,
4182+
SYSTEM__KEXEC_INITRAMFS_LOAD);
4183+
break;
4184+
case LOADING_POLICY:
4185+
rc = selinux_kernel_load_from_file(NULL,
4186+
SYSTEM__POLICY_LOAD);
4187+
break;
4188+
case LOADING_X509_CERTIFICATE:
4189+
rc = selinux_kernel_load_from_file(NULL,
4190+
SYSTEM__X509_CERTIFICATE_LOAD);
41534191
break;
41544192
default:
41554193
break;

security/selinux/include/classmap.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ const struct security_class_mapping secclass_map[] = {
6363
{ "process2", { "nnp_transition", "nosuid_transition", NULL } },
6464
{ "system",
6565
{ "ipc_info", "syslog_read", "syslog_mod", "syslog_console",
66-
"module_request", "module_load", NULL } },
66+
"module_request", "module_load", "firmware_load",
67+
"kexec_image_load", "kexec_initramfs_load", "policy_load",
68+
"x509_certificate_load", NULL } },
6769
{ "capability", { COMMON_CAP_PERMS, NULL } },
6870
{ "filesystem",
6971
{ "mount", "remount", "unmount", "getattr", "relabelfrom",

0 commit comments

Comments
 (0)