selinux: move status variables out of selinux_ss
authorOndrej Mosnacek <omosnace@redhat.com>
Fri, 17 Jan 2020 13:15:14 +0000 (14:15 +0100)
committerPaul Moore <paul@paul-moore.com>
Mon, 10 Feb 2020 15:49:01 +0000 (10:49 -0500)
It fits more naturally in selinux_state, since it reflects also global
state (the enforcing and policyload fields).

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Reviewed-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Paul Moore <paul@paul-moore.com>
security/selinux/Makefile
security/selinux/hooks.c
security/selinux/include/security.h
security/selinux/ss/services.c
security/selinux/ss/services.h
security/selinux/ss/status.c [deleted file]
security/selinux/status.c [new file with mode: 0644]

index 2000f95fb197751852a8ccdbfaad65341a586c87..0c77ede1cc1120f05d7d6f6d0eb4e50941e4340a 100644 (file)
@@ -6,9 +6,9 @@
 obj-$(CONFIG_SECURITY_SELINUX) := selinux.o
 
 selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
-            netnode.o netport.o \
+            netnode.o netport.o status.o \
             ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \
-            ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o
+            ss/policydb.o ss/services.o ss/conditional.o ss/mls.o
 
 selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
 
index 4b6991e178d37e5916f33bb6ec3911aa550985c7..b33cf155cc48c59ae8fa34137bf4989a0fce9061 100644 (file)
@@ -7161,6 +7161,7 @@ static __init int selinux_init(void)
        selinux_state.checkreqprot = selinux_checkreqprot_boot;
        selinux_ss_init(&selinux_state.ss);
        selinux_avc_init(&selinux_state.avc);
+       mutex_init(&selinux_state.status_lock);
 
        /* Set the security state for the initial task. */
        cred_init_security();
index a39f9565d80b7ee93e7427e41780241e746fb203..f3a621058abaebe2a8064c943dd7581c8bdaea11 100644 (file)
@@ -108,6 +108,10 @@ struct selinux_state {
        bool checkreqprot;
        bool initialized;
        bool policycap[__POLICYDB_CAPABILITY_MAX];
+
+       struct page *status_page;
+       struct mutex status_lock;
+
        struct selinux_avc *avc;
        struct selinux_ss *ss;
 } __randomize_layout;
index 216ce602a2b513aaad6a6e40bf900430423d5c3b..5cf491768142cbaaaec6befa0d0f3d5632450273 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/in.h>
 #include <linux/sched.h>
 #include <linux/audit.h>
-#include <linux/mutex.h>
 #include <linux/vmalloc.h>
 #include <net/netlabel.h>
 
@@ -81,7 +80,6 @@ static struct selinux_ss selinux_ss;
 void selinux_ss_init(struct selinux_ss **ss)
 {
        rwlock_init(&selinux_ss.policy_rwlock);
-       mutex_init(&selinux_ss.status_lock);
        *ss = &selinux_ss;
 }
 
index c5896f39e8f628cd57c922665bca108fe1199a71..e9bddf33e53d3ca5bbb8b7042509d2dd302b68de 100644 (file)
@@ -29,8 +29,6 @@ struct selinux_ss {
        rwlock_t policy_rwlock;
        u32 latest_granting;
        struct selinux_map map;
-       struct page *status_page;
-       struct mutex status_lock;
 } __randomize_layout;
 
 void services_compute_xperms_drivers(struct extended_perms *xperms,
diff --git a/security/selinux/ss/status.c b/security/selinux/ss/status.c
deleted file mode 100644 (file)
index 3c554a4..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * mmap based event notifications for SELinux
- *
- * Author: KaiGai Kohei <kaigai@ak.jp.nec.com>
- *
- * Copyright (C) 2010 NEC corporation
- */
-#include <linux/kernel.h>
-#include <linux/gfp.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include "avc.h"
-#include "services.h"
-
-/*
- * The selinux_status_page shall be exposed to userspace applications
- * using mmap interface on /selinux/status.
- * It enables to notify applications a few events that will cause reset
- * of userspace access vector without context switching.
- *
- * The selinux_kernel_status structure on the head of status page is
- * protected from concurrent accesses using seqlock logic, so userspace
- * application should reference the status page according to the seqlock
- * logic.
- *
- * Typically, application checks status->sequence at the head of access
- * control routine. If it is odd-number, kernel is updating the status,
- * so please wait for a moment. If it is changed from the last sequence
- * number, it means something happen, so application will reset userspace
- * avc, if needed.
- * In most cases, application shall confirm the kernel status is not
- * changed without any system call invocations.
- */
-
-/*
- * selinux_kernel_status_page
- *
- * It returns a reference to selinux_status_page. If the status page is
- * not allocated yet, it also tries to allocate it at the first time.
- */
-struct page *selinux_kernel_status_page(struct selinux_state *state)
-{
-       struct selinux_kernel_status   *status;
-       struct page                    *result = NULL;
-
-       mutex_lock(&state->ss->status_lock);
-       if (!state->ss->status_page) {
-               state->ss->status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
-
-               if (state->ss->status_page) {
-                       status = page_address(state->ss->status_page);
-
-                       status->version = SELINUX_KERNEL_STATUS_VERSION;
-                       status->sequence = 0;
-                       status->enforcing = enforcing_enabled(state);
-                       /*
-                        * NOTE: the next policyload event shall set
-                        * a positive value on the status->policyload,
-                        * although it may not be 1, but never zero.
-                        * So, application can know it was updated.
-                        */
-                       status->policyload = 0;
-                       status->deny_unknown =
-                               !security_get_allow_unknown(state);
-               }
-       }
-       result = state->ss->status_page;
-       mutex_unlock(&state->ss->status_lock);
-
-       return result;
-}
-
-/*
- * selinux_status_update_setenforce
- *
- * It updates status of the current enforcing/permissive mode.
- */
-void selinux_status_update_setenforce(struct selinux_state *state,
-                                     int enforcing)
-{
-       struct selinux_kernel_status   *status;
-
-       mutex_lock(&state->ss->status_lock);
-       if (state->ss->status_page) {
-               status = page_address(state->ss->status_page);
-
-               status->sequence++;
-               smp_wmb();
-
-               status->enforcing = enforcing;
-
-               smp_wmb();
-               status->sequence++;
-       }
-       mutex_unlock(&state->ss->status_lock);
-}
-
-/*
- * selinux_status_update_policyload
- *
- * It updates status of the times of policy reloaded, and current
- * setting of deny_unknown.
- */
-void selinux_status_update_policyload(struct selinux_state *state,
-                                     int seqno)
-{
-       struct selinux_kernel_status   *status;
-
-       mutex_lock(&state->ss->status_lock);
-       if (state->ss->status_page) {
-               status = page_address(state->ss->status_page);
-
-               status->sequence++;
-               smp_wmb();
-
-               status->policyload = seqno;
-               status->deny_unknown = !security_get_allow_unknown(state);
-
-               smp_wmb();
-               status->sequence++;
-       }
-       mutex_unlock(&state->ss->status_lock);
-}
diff --git a/security/selinux/status.c b/security/selinux/status.c
new file mode 100644 (file)
index 0000000..4bc8f80
--- /dev/null
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * mmap based event notifications for SELinux
+ *
+ * Author: KaiGai Kohei <kaigai@ak.jp.nec.com>
+ *
+ * Copyright (C) 2010 NEC corporation
+ */
+#include <linux/kernel.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include "avc.h"
+#include "security.h"
+
+/*
+ * The selinux_status_page shall be exposed to userspace applications
+ * using mmap interface on /selinux/status.
+ * It enables to notify applications a few events that will cause reset
+ * of userspace access vector without context switching.
+ *
+ * The selinux_kernel_status structure on the head of status page is
+ * protected from concurrent accesses using seqlock logic, so userspace
+ * application should reference the status page according to the seqlock
+ * logic.
+ *
+ * Typically, application checks status->sequence at the head of access
+ * control routine. If it is odd-number, kernel is updating the status,
+ * so please wait for a moment. If it is changed from the last sequence
+ * number, it means something happen, so application will reset userspace
+ * avc, if needed.
+ * In most cases, application shall confirm the kernel status is not
+ * changed without any system call invocations.
+ */
+
+/*
+ * selinux_kernel_status_page
+ *
+ * It returns a reference to selinux_status_page. If the status page is
+ * not allocated yet, it also tries to allocate it at the first time.
+ */
+struct page *selinux_kernel_status_page(struct selinux_state *state)
+{
+       struct selinux_kernel_status   *status;
+       struct page                    *result = NULL;
+
+       mutex_lock(&state->status_lock);
+       if (!state->status_page) {
+               state->status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
+
+               if (state->status_page) {
+                       status = page_address(state->status_page);
+
+                       status->version = SELINUX_KERNEL_STATUS_VERSION;
+                       status->sequence = 0;
+                       status->enforcing = enforcing_enabled(state);
+                       /*
+                        * NOTE: the next policyload event shall set
+                        * a positive value on the status->policyload,
+                        * although it may not be 1, but never zero.
+                        * So, application can know it was updated.
+                        */
+                       status->policyload = 0;
+                       status->deny_unknown =
+                               !security_get_allow_unknown(state);
+               }
+       }
+       result = state->status_page;
+       mutex_unlock(&state->status_lock);
+
+       return result;
+}
+
+/*
+ * selinux_status_update_setenforce
+ *
+ * It updates status of the current enforcing/permissive mode.
+ */
+void selinux_status_update_setenforce(struct selinux_state *state,
+                                     int enforcing)
+{
+       struct selinux_kernel_status   *status;
+
+       mutex_lock(&state->status_lock);
+       if (state->status_page) {
+               status = page_address(state->status_page);
+
+               status->sequence++;
+               smp_wmb();
+
+               status->enforcing = enforcing;
+
+               smp_wmb();
+               status->sequence++;
+       }
+       mutex_unlock(&state->status_lock);
+}
+
+/*
+ * selinux_status_update_policyload
+ *
+ * It updates status of the times of policy reloaded, and current
+ * setting of deny_unknown.
+ */
+void selinux_status_update_policyload(struct selinux_state *state,
+                                     int seqno)
+{
+       struct selinux_kernel_status   *status;
+
+       mutex_lock(&state->status_lock);
+       if (state->status_page) {
+               status = page_address(state->status_page);
+
+               status->sequence++;
+               smp_wmb();
+
+               status->policyload = seqno;
+               status->deny_unknown = !security_get_allow_unknown(state);
+
+               smp_wmb();
+               status->sequence++;
+       }
+       mutex_unlock(&state->status_lock);
+}