aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
authorKaiGai Kohei <kaigai@ak.jp.nec.com>2010-09-14 05:28:39 -0400
committerJames Morris <jmorris@namei.org>2010-10-20 19:12:36 -0400
commit119041672592d1890d89dd8f194bd0919d801dc8 (patch)
treeb994abb42446b8637f072194c57359fd80d52a97 /security/selinux/ss/services.c
parent4b04a7cfc5ccb573ca3752429c81d37f8dd2f7c6 (diff)
selinux: fast status update interface (/selinux/status)
This patch provides a new /selinux/status entry which allows applications read-only mmap(2). This region reflects selinux_kernel_status structure in kernel space. struct selinux_kernel_status { u32 length; /* length of this structure */ u32 sequence; /* sequence number of seqlock logic */ u32 enforcing; /* current setting of enforcing mode */ u32 policyload; /* times of policy reloaded */ u32 deny_unknown; /* current setting of deny_unknown */ }; When userspace object manager caches access control decisions provided by SELinux, it needs to invalidate the cache on policy reload and setenforce to keep consistency. However, the applications need to check the kernel state for each accesses on userspace avc, or launch a background worker process. In heuristic, frequency of invalidation is much less than frequency of making access control decision, so it is annoying to invoke a system call to check we don't need to invalidate the userspace cache. If we can use a background worker thread, it allows to receive invalidation messages from the kernel. But it requires us an invasive coding toward the base application in some cases; E.g, when we provide a feature performing with SELinux as a plugin module, it is unwelcome manner to launch its own worker thread from the module. If we could map /selinux/status to process memory space, application can know updates of selinux status; policy reload or setenforce. A typical application checks selinux_kernel_status::sequence when it tries to reference userspace avc. If it was changed from the last time when it checked userspace avc, it means something was updated in the kernel space. Then, the application can reset userspace avc or update current enforcing mode, without any system call invocations. This sequence number is updated according to the seqlock logic, so we need to wait for a while if it is odd number. Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com> Acked-by: Eric Paris <eparis@redhat.com> -- security/selinux/include/security.h | 21 ++++++ security/selinux/selinuxfs.c | 56 +++++++++++++++ security/selinux/ss/Makefile | 2 +- security/selinux/ss/services.c | 3 + security/selinux/ss/status.c | 129 +++++++++++++++++++++++++++++++++++ 5 files changed, 210 insertions(+), 1 deletions(-) Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 9ea2feca3cd4..494ff527c174 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1791,6 +1791,7 @@ int security_load_policy(void *data, size_t len)
1791 selinux_complete_init(); 1791 selinux_complete_init();
1792 avc_ss_reset(seqno); 1792 avc_ss_reset(seqno);
1793 selnl_notify_policyload(seqno); 1793 selnl_notify_policyload(seqno);
1794 selinux_status_update_policyload(seqno);
1794 selinux_netlbl_cache_invalidate(); 1795 selinux_netlbl_cache_invalidate();
1795 selinux_xfrm_notify_policyload(); 1796 selinux_xfrm_notify_policyload();
1796 return 0; 1797 return 0;
@@ -1870,6 +1871,7 @@ int security_load_policy(void *data, size_t len)
1870 1871
1871 avc_ss_reset(seqno); 1872 avc_ss_reset(seqno);
1872 selnl_notify_policyload(seqno); 1873 selnl_notify_policyload(seqno);
1874 selinux_status_update_policyload(seqno);
1873 selinux_netlbl_cache_invalidate(); 1875 selinux_netlbl_cache_invalidate();
1874 selinux_xfrm_notify_policyload(); 1876 selinux_xfrm_notify_policyload();
1875 1877
@@ -2374,6 +2376,7 @@ out:
2374 if (!rc) { 2376 if (!rc) {
2375 avc_ss_reset(seqno); 2377 avc_ss_reset(seqno);
2376 selnl_notify_policyload(seqno); 2378 selnl_notify_policyload(seqno);
2379 selinux_status_update_policyload(seqno);
2377 selinux_xfrm_notify_policyload(); 2380 selinux_xfrm_notify_policyload();
2378 } 2381 }
2379 return rc; 2382 return rc;