[PATCH] selinux: add permission checks for loading other kinds of kernel files

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Kipp N. Davis" <kippndavis.work@xxxxxxx>

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 <ckwilliams.work@xxxxxxxxx>
Signed-off-by: Kipp N. Davis <kippndavis.work@xxxxxxx>
---
 security/selinux/hooks.c            | 54 ++++++++++++++++++++++++-----
 security/selinux/include/classmap.h |  4 ++-
 2 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7b867dfec88b..e96ade50c137 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4096,7 +4096,7 @@ static int selinux_kernel_module_request(char *kmod_name)
 			    SYSTEM__MODULE_REQUEST, &ad);
 }

-static int selinux_kernel_module_from_file(struct file *file)
+static int selinux_kernel_load_from_file(struct file *file, u32 requested)
 {
 	struct common_audit_data ad;
 	struct inode_security_struct *isec;
@@ -4104,12 +4104,9 @@ static int selinux_kernel_module_from_file(struct file *file)
 	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 */
+					requested, NULL);

 	ad.type = LSM_AUDIT_DATA_FILE;
 	ad.u.file = file;
@@ -4123,7 +4120,7 @@ static int selinux_kernel_module_from_file(struct file *file)

 	isec = inode_security(file_inode(file));
 	return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
-				SYSTEM__MODULE_LOAD, &ad);
+				requested, &ad);
 }

 static int selinux_kernel_read_file(struct file *file,
@@ -4133,10 +4130,33 @@ static int selinux_kernel_read_file(struct file *file,
 	int rc = 0;

 	switch (id) {
+	case READING_FIRMWARE:
+		rc = selinux_kernel_load_from_file(contents ? file : NULL,
+				SYSTEM__FIRMWARE_LOAD);
+		break;
 	case READING_MODULE:
-		rc = selinux_kernel_module_from_file(contents ? file : NULL);
+		rc = selinux_kernel_load_from_file(contents ? file : NULL,
+				SYSTEM__MODULE_LOAD);
+		break;
+	case READING_KEXEC_IMAGE:
+		rc = selinux_kernel_load_from_file(contents ? file : NULL,
+				SYSTEM__KEXEC_IMAGE_LOAD);
+		break;
+	case READING_KEXEC_INITRAMFS:
+		rc = selinux_kernel_load_from_file(contents ? file : NULL,
+				SYSTEM__KEXEC_INITRAMFS_LOAD);
+		break;
+	case READING_POLICY:
+		rc = selinux_kernel_load_from_file(contents ? file : NULL,
+				SYSTEM__POLICY_LOAD);
+		break;
+	case READING_X509_CERTIFICATE:
+		rc = selinux_kernel_load_from_file(contents ? file : NULL,
+				SYSTEM__X509_CERTIFICATE_LOAD);
 		break;
 	default:
+		pr_err("SELinux:  kernel_read_file_id unknown");
+		rc = -EACCES;
 		break;
 	}

@@ -4148,10 +4168,28 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
 	int rc = 0;

 	switch (id) {
+	case LOADING_FIRMWARE:
+		rc = selinux_kernel_load_from_file(NULL, SYSTEM__FIRMWARE_LOAD);
+		break;
 	case LOADING_MODULE:
-		rc = selinux_kernel_module_from_file(NULL);
+		rc = selinux_kernel_load_from_file(NULL, SYSTEM__MODULE_LOAD);
+		break;
+	case LOADING_KEXEC_IMAGE:
+		rc = selinux_kernel_load_from_file(NULL, SYSTEM__KEXEC_IMAGE_LOAD);
+		break;
+	case LOADING_KEXEC_INITRAMFS:
+		rc = selinux_kernel_load_from_file(NULL, SYSTEM__KEXEC_INITRAMFS_LOAD);
+		break;
+	case LOADING_POLICY:
+		rc = selinux_kernel_load_from_file(NULL, SYSTEM__POLICY_LOAD);
+		break;
+	case LOADING_X509_CERTIFICATE:
+		rc = selinux_kernel_load_from_file(NULL,
+				SYSTEM__X509_CERTIFICATE_LOAD);
 		break;
 	default:
+		pr_err("SELinux:  kernel_read_file_id unknown");
+		rc = -EACCES;
 		break;
 	}

diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 03e82477dce9..cfac41d12f7d 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -63,7 +63,9 @@ const struct security_class_mapping secclass_map[] = {
 	{ "process2", { "nnp_transition", "nosuid_transition", NULL } },
 	{ "system",
 	  { "ipc_info", "syslog_read", "syslog_mod", "syslog_console",
-	    "module_request", "module_load", NULL } },
+	    "module_request", "module_load", "firmware_load",
+	    "kexec_image_load", "kexec_initramfs_load", "policy_load",
+	    "x509_certificate_load", NULL } },
 	{ "capability", { COMMON_CAP_PERMS, NULL } },
 	{ "filesystem",
 	  { "mount", "remount", "unmount", "getattr", "relabelfrom",
--
2.48.1





[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux