summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2009-03-16 13:24:48 -0400
committerAdam Jackson <ajax@redhat.com>2009-03-16 13:24:48 -0400
commit3992dd38caf33b343affd8d732c94880d1099dcf (patch)
treef126747b1b9225c905fd4334fab36c675f2f0688
parentbe6dc9023b5fb3995a9ce56d607627e247918aef (diff)
selinux: Add support for avc_acquire_netlink_fd()
Requires libselinux 2.0.79 or newer. Without this, libselinux will check for policy updates on the netlink socket on basically every policy lookup. Statistically speaking, they never happen, and the check translates to at least one more syscall on basically every operation. Instead, take control of the fd from the library, and check it in WakeupHandler if it polls readable.
-rw-r--r--Xext/xselinux.c29
-rw-r--r--configure.ac4
-rw-r--r--include/dix-config.h.in2
3 files changed, 35 insertions, 0 deletions
diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index cc973194f..dfeef2f21 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -1886,6 +1886,22 @@ SProcSELinuxDispatch(ClientPtr client)
}
}
+#ifdef HAVE_AVC_NETLINK_ACQUIRE_FD
+static int netlink_fd;
+
+static void
+SELinuxBlockHandler(void *data, struct timeval **tv, void *read_mask)
+{
+}
+
+static void
+SELinuxWakeupHandler(void *data, int err, void *read_mask)
+{
+ if (FD_ISSET(netlink_fd, (fd_set *)read_mask))
+ avc_netlink_check_nb();
+}
+#endif
+
/*
* Extension Setup / Teardown
@@ -1916,6 +1932,12 @@ SELinuxResetProc(ExtensionEntry *extEntry)
label_hnd = NULL;
audit_close(audit_fd);
+#ifdef HAVE_AVC_NETLINK_ACQUIRE_FD
+ avc_netlink_release_fd();
+ RemoveBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
+ NULL);
+ RemoveGeneralSocket(netlink_fd);
+#endif
avc_destroy();
avc_active = 0;
@@ -2012,6 +2034,13 @@ SELinuxExtensionInit(INITARGS)
if (atom_client_ctx == BAD_RESOURCE)
FatalError("SELinux: Failed to create atom\n");
+#ifdef HAVE_AVC_NETLINK_ACQUIRE_FD
+ netlink_fd = avc_netlink_acquire_fd();
+ AddGeneralSocket(netlink_fd);
+ RegisterBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
+ NULL);
+#endif
+
/* Register callbacks */
ret &= dixRegisterPrivateInitFunc(subjectKey, SELinuxSubjectInit, NULL);
ret &= dixRegisterPrivateDeleteFunc(subjectKey, SELinuxSubjectFree, NULL);
diff --git a/configure.ac b/configure.ac
index f68843f03..f4e1dbb04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -940,6 +940,10 @@ if test "x$XSELINUX" = xyes; then
AC_CHECK_LIB(selinux, avc_init, [], AC_MSG_ERROR([SELinux library not found]))
AC_CHECK_HEADERS([libaudit.h], [], AC_MSG_ERROR([SELinux extension requires audit system headers]))
AC_CHECK_LIB(audit, audit_open, [], AC_MSG_ERROR([SELinux extension requires audit system library]))
+ AC_CHECK_DECL(avc_netlink_acquire_fd,
+ [AC_DEFINE(HAVE_AVC_NETLINK_ACQUIRE_FD, 1, "Have avc_netlink_acquire_fd")],
+ [],
+ [#include <selinux/avc.h>])
AC_DEFINE(XSELINUX, 1, [Build SELinux extension])
SELINUX_LIB="-lselinux -laudit"
fi
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 681fb0503..26ac22388 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -425,4 +425,6 @@
#include "dix-config-apple-verbatim.h"
#endif
+#undef HAVE_AVC_NETLINK_ACQUIRE_FD
+
#endif /* _DIX_CONFIG_H_ */