aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xext
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xext')
-rw-r--r--xorg-server/Xext/Makefile37
-rw-r--r--xorg-server/Xext/Makefile.am266
-rw-r--r--xorg-server/Xext/dpms.c2
-rw-r--r--xorg-server/Xext/saver.c6
-rw-r--r--xorg-server/Xext/security.c2
-rw-r--r--xorg-server/Xext/securitysrv.h5
-rw-r--r--xorg-server/Xext/shape.c2
-rw-r--r--xorg-server/Xext/shm.c19
-rw-r--r--xorg-server/Xext/sync.c4
-rw-r--r--xorg-server/Xext/xace.c2
-rw-r--r--xorg-server/Xext/xselinux_hooks.c1870
-rw-r--r--xorg-server/Xext/xvmain.c4
12 files changed, 1145 insertions, 1074 deletions
diff --git a/xorg-server/Xext/Makefile b/xorg-server/Xext/Makefile
new file mode 100644
index 000000000..1fd048d52
--- /dev/null
+++ b/xorg-server/Xext/Makefile
@@ -0,0 +1,37 @@
+CSRCS=\
+bigreq.c \
+dpms.c \
+dpmsstubs.c \
+saver.c \
+security.c \
+shape.c \
+sleepuntil.c \
+sync.c \
+xace.c \
+xcmisc.c \
+xres.c \
+xtest.c \
+geext.c \
+panoramiX.c \
+panoramiXprocs.c \
+panoramiXSwap.c
+
+#shm.c \
+#appgroup.c \
+#fontcache.c \
+#mbufbf.c \
+#mbufpx.c \
+#xcalibrate.c \
+#xf86bigfont.c \
+#xprint.c \
+#xselinux.c \
+#xvdisp.c \
+#xvmain.c \
+#xvmc.c
+
+LIBRARY=libxext
+
+INCLUDES += ..\hw\xfree86\dixmods\extmod ..\composite ..\miext\sync
+
+
+
diff --git a/xorg-server/Xext/Makefile.am b/xorg-server/Xext/Makefile.am
index cb432e00e..cb47d38cc 100644
--- a/xorg-server/Xext/Makefile.am
+++ b/xorg-server/Xext/Makefile.am
@@ -1,133 +1,133 @@
-# libXext.la: includes all extensions and should be linked into Xvfb,
-# Xnest, Xdmx and Xprt
-# libXextbuiltin.la: includes those extensions that are built directly into
-# Xorg by default
-# libXextmodule.la: includes those extensions that are built into a module
-# that Xorg loads
-if XORG
-noinst_LTLIBRARIES = libXext.la libXextbuiltin.la libXextmodule.la
-else
-noinst_LTLIBRARIES = libXext.la
-endif
-
-INCLUDES = -I$(top_srcdir)/hw/xfree86/dixmods/extmod
-
-AM_CFLAGS = $(DIX_CFLAGS)
-
-if XORG
-sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h syncsdk.h
-endif
-
-# Sources always included in libXextbuiltin.la & libXext.la
-BUILTIN_SRCS = \
- bigreq.c \
- geext.c \
- shape.c \
- sleepuntil.c \
- sleepuntil.h \
- sync.c \
- syncsdk.h \
- syncsrv.h \
- xcmisc.c \
- xtest.c
-
-# Sources always included in libXextmodule.la & libXext.la. That's right, zero.
-MODULE_SRCS =
-MODULE_LIBS =
-
-# Optional sources included if extension enabled by configure.ac rules
-
-# MIT Shared Memory extension
-MITSHM_SRCS = shm.c shmint.h
-if MITSHM
-BUILTIN_SRCS += $(MITSHM_SRCS)
-endif
-
-# XVideo extension
-XV_SRCS = xvmain.c xvdisp.c xvmc.c xvdix.h xvmcext.h xvdisp.h
-if XV
-MODULE_SRCS += $(XV_SRCS)
-endif
-
-# XResource extension: lets clients get data about per-client resource usage
-RES_SRCS = xres.c
-if RES
-MODULE_SRCS += $(RES_SRCS)
-endif
-
-# MIT ScreenSaver extension
-SCREENSAVER_SRCS = saver.c
-if SCREENSAVER
-MODULE_SRCS += $(SCREENSAVER_SRCS)
-endif
-
-# Xinerama extension: making multiple video devices act as one virtual screen
-XINERAMA_SRCS = panoramiX.c panoramiX.h panoramiXh.h panoramiXsrv.h panoramiXprocs.c panoramiXSwap.c
-if XINERAMA
-BUILTIN_SRCS += $(XINERAMA_SRCS)
-if XORG
-sdk_HEADERS += panoramiXsrv.h panoramiX.h
-endif
-endif
-
-# X-ACE extension: provides hooks for building security policy extensions
-# like XC-Security, X-SELinux & XTSol
-XACE_SRCS = xace.c xace.h xacestr.h
-if XACE
-BUILTIN_SRCS += $(XACE_SRCS)
-if XORG
-sdk_HEADERS += xace.h xacestr.h
-endif
-endif
-
-# SELinux extension: provides SELinux policy support for X objects
-# requires X-ACE extension
-XSELINUX_SRCS = xselinux_ext.c xselinux_hooks.c xselinux_label.c xselinux.h xselinuxint.h
-if XSELINUX
-MODULE_SRCS += $(XSELINUX_SRCS)
-MODULE_LIBS += $(SELINUX_LIBS)
-endif
-
-# Security extension: multi-level security to protect clients from each other
-XCSECURITY_SRCS = security.c securitysrv.h
-if XCSECURITY
-BUILTIN_SRCS += $(XCSECURITY_SRCS)
-endif
-
-# XF86 Big Font extension
-BIGFONT_SRCS = xf86bigfont.c xf86bigfontsrv.h
-if XF86BIGFONT
-BUILTIN_SRCS += $(BIGFONT_SRCS)
-endif
-
-# DPMS extension
-DPMS_SRCS = dpms.c dpmsproc.h
-if DPMSExtension
-MODULE_SRCS += $(DPMS_SRCS)
-endif
-
-# Now take all of the above, mix well, bake for 10 minutes and get libXext*.la
-
-libXext_la_SOURCES = $(BUILTIN_SRCS) $(MODULE_SRCS)
-libXext_la_LIBADD = $(MODULE_LIBS)
-
-if XORG
-libXextbuiltin_la_SOURCES = $(BUILTIN_SRCS)
-
-libXextmodule_la_SOURCES = $(MODULE_SRCS)
-libXextmodule_la_LIBADD = $(MODULE_LIBS)
-endif
-
-EXTRA_DIST = \
- $(MITSHM_SRCS) \
- $(XV_SRCS) \
- $(RES_SRCS) \
- $(SCREENSAVER_SRCS) \
- $(XACE_SRCS) \
- $(XCSECURITY_SRCS) \
- $(XSELINUX_SRCS) \
- $(XINERAMA_SRCS) \
- $(BIGFONT_SRCS) \
- $(DPMS_SRCS) \
- $(GE_SRCS)
-
+# libXext.la: includes all extensions and should be linked into Xvfb,
+# Xnest, Xdmx and Xprt
+# libXextbuiltin.la: includes those extensions that are built directly into
+# Xorg by default
+# libXextmodule.la: includes those extensions that are built into a module
+# that Xorg loads
+if XORG
+noinst_LTLIBRARIES = libXext.la libXextbuiltin.la libXextmodule.la
+else
+noinst_LTLIBRARIES = libXext.la
+endif
+
+INCLUDES = -I$(top_srcdir)/hw/xfree86/dixmods/extmod
+
+AM_CFLAGS = $(DIX_CFLAGS)
+
+if XORG
+sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h syncsdk.h
+endif
+
+# Sources always included in libXextbuiltin.la & libXext.la
+BUILTIN_SRCS = \
+ bigreq.c \
+ geext.c \
+ shape.c \
+ sleepuntil.c \
+ sleepuntil.h \
+ sync.c \
+ syncsdk.h \
+ syncsrv.h \
+ xcmisc.c \
+ xtest.c
+
+# Sources always included in libXextmodule.la & libXext.la. That's right, zero.
+MODULE_SRCS =
+MODULE_LIBS =
+
+# Optional sources included if extension enabled by configure.ac rules
+
+# MIT Shared Memory extension
+MITSHM_SRCS = shm.c shmint.h
+if MITSHM
+BUILTIN_SRCS += $(MITSHM_SRCS)
+endif
+
+# XVideo extension
+XV_SRCS = xvmain.c xvdisp.c xvmc.c xvdix.h xvmcext.h xvdisp.h
+if XV
+MODULE_SRCS += $(XV_SRCS)
+endif
+
+# XResource extension: lets clients get data about per-client resource usage
+RES_SRCS = xres.c
+if RES
+MODULE_SRCS += $(RES_SRCS)
+endif
+
+# MIT ScreenSaver extension
+SCREENSAVER_SRCS = saver.c
+if SCREENSAVER
+MODULE_SRCS += $(SCREENSAVER_SRCS)
+endif
+
+# Xinerama extension: making multiple video devices act as one virtual screen
+XINERAMA_SRCS = panoramiX.c panoramiX.h panoramiXh.h panoramiXsrv.h panoramiXprocs.c panoramiXSwap.c
+if XINERAMA
+BUILTIN_SRCS += $(XINERAMA_SRCS)
+if XORG
+sdk_HEADERS += panoramiXsrv.h panoramiX.h
+endif
+endif
+
+# X-ACE extension: provides hooks for building security policy extensions
+# like XC-Security, X-SELinux & XTSol
+XACE_SRCS = xace.c xace.h xacestr.h
+if XACE
+BUILTIN_SRCS += $(XACE_SRCS)
+if XORG
+sdk_HEADERS += xace.h xacestr.h
+endif
+endif
+
+# SELinux extension: provides SELinux policy support for X objects
+# requires X-ACE extension
+XSELINUX_SRCS = xselinux_ext.c xselinux_hooks.c xselinux_label.c xselinux.h xselinuxint.h
+if XSELINUX
+MODULE_SRCS += $(XSELINUX_SRCS)
+MODULE_LIBS += $(SELINUX_LIBS)
+endif
+
+# Security extension: multi-level security to protect clients from each other
+XCSECURITY_SRCS = security.c securitysrv.h
+if XCSECURITY
+BUILTIN_SRCS += $(XCSECURITY_SRCS)
+endif
+
+# XF86 Big Font extension
+BIGFONT_SRCS = xf86bigfont.c xf86bigfontsrv.h
+if XF86BIGFONT
+BUILTIN_SRCS += $(BIGFONT_SRCS)
+endif
+
+# DPMS extension
+DPMS_SRCS = dpms.c dpmsproc.h
+if DPMSExtension
+MODULE_SRCS += $(DPMS_SRCS)
+endif
+
+# Now take all of the above, mix well, bake for 10 minutes and get libXext*.la
+
+libXext_la_SOURCES = $(BUILTIN_SRCS) $(MODULE_SRCS)
+libXext_la_LIBADD = $(MODULE_LIBS)
+
+if XORG
+libXextbuiltin_la_SOURCES = $(BUILTIN_SRCS)
+
+libXextmodule_la_SOURCES = $(MODULE_SRCS)
+libXextmodule_la_LIBADD = $(MODULE_LIBS)
+endif
+
+EXTRA_DIST = \
+ $(MITSHM_SRCS) \
+ $(XV_SRCS) \
+ $(RES_SRCS) \
+ $(SCREENSAVER_SRCS) \
+ $(XACE_SRCS) \
+ $(XCSECURITY_SRCS) \
+ $(XSELINUX_SRCS) \
+ $(XINERAMA_SRCS) \
+ $(BIGFONT_SRCS) \
+ $(DPMS_SRCS) \
+ $(GE_SRCS)
+
diff --git a/xorg-server/Xext/dpms.c b/xorg-server/Xext/dpms.c
index 13854f704..79b2e2944 100644
--- a/xorg-server/Xext/dpms.c
+++ b/xorg-server/Xext/dpms.c
@@ -28,6 +28,8 @@ Equipment Corporation.
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
+#else
+#define DPMSExtension
#endif
#include <X11/X.h>
diff --git a/xorg-server/Xext/saver.c b/xorg-server/Xext/saver.c
index 3b8b6de59..5fd6c895d 100644
--- a/xorg-server/Xext/saver.c
+++ b/xorg-server/Xext/saver.c
@@ -29,6 +29,12 @@ in this Software without prior written authorization from the X Consortium.
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
+#else
+#define SCREENSAVER
+#endif
+
+#ifdef CreateWindow
+#undef CreateWindow
#endif
#include <X11/X.h>
diff --git a/xorg-server/Xext/security.c b/xorg-server/Xext/security.c
index d687926c6..ad6f9a3ef 100644
--- a/xorg-server/Xext/security.c
+++ b/xorg-server/Xext/security.c
@@ -26,6 +26,8 @@ in this Software without prior written authorization from The Open Group.
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
+#else
+#define XACE
#endif
#include "scrnintstr.h"
diff --git a/xorg-server/Xext/securitysrv.h b/xorg-server/Xext/securitysrv.h
index 3d3894a18..68f51d2f5 100644
--- a/xorg-server/Xext/securitysrv.h
+++ b/xorg-server/Xext/securitysrv.h
@@ -31,10 +31,7 @@ from The Open Group.
#define _SECURITY_SRV_H
/* Allow client side portions of <X11/extensions/security.h> to compile */
-#ifndef Status
-# define Status int
-# define NEED_UNDEF_Status
-#endif
+typedef int Status;
#ifndef Display
# define Display void
# define NEED_UNDEF_Display
diff --git a/xorg-server/Xext/shape.c b/xorg-server/Xext/shape.c
index 79dc77635..6a35a0451 100644
--- a/xorg-server/Xext/shape.c
+++ b/xorg-server/Xext/shape.c
@@ -26,6 +26,8 @@ in this Software without prior written authorization from The Open Group.
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
+#else
+#define SHAPE
#endif
#include <stdlib.h>
diff --git a/xorg-server/Xext/shm.c b/xorg-server/Xext/shm.c
index 8a048deb0..7099e8f36 100644
--- a/xorg-server/Xext/shm.c
+++ b/xorg-server/Xext/shm.c
@@ -34,8 +34,10 @@ in this Software without prior written authorization from The Open Group.
#endif
#include <sys/types.h>
+#if !defined(_MSC_VER)
#include <sys/ipc.h>
#include <sys/shm.h>
+#endif
#include <unistd.h>
#include <sys/stat.h>
#include <X11/X.h>
@@ -300,8 +302,10 @@ ProcShmQueryVersion(ClientPtr client)
rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0;
rep.majorVersion = SERVER_SHM_MAJOR_VERSION;
rep.minorVersion = SERVER_SHM_MINOR_VERSION;
+#ifndef _MSC_VER
rep.uid = geteuid();
rep.gid = getegid();
+#endif
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
@@ -351,6 +355,9 @@ shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
if (uid == 0) {
return 0;
}
+ #ifdef _MSC_VER
+ __asm int 3;
+ #else
/* Check the owner */
if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) {
mask = S_IRUSR;
@@ -359,10 +366,14 @@ shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
}
return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
}
+ #endif
}
if (gidset) {
/* Check the group */
+ #ifdef _MSC_VER
+ __asm int 3;
+ #else
if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) {
mask = S_IRGRP;
if (!readonly) {
@@ -370,14 +381,20 @@ shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
}
return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
}
+ #endif
}
}
+ #ifdef _MSC_VER
+ __asm int 3;
+ return -1;
+ #else
/* Otherwise, check everyone else */
mask = S_IROTH;
if (!readonly) {
mask |= S_IWOTH;
}
return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
+ #endif
}
static int
@@ -450,7 +467,9 @@ ShmDetachSegment(pointer value, /* must conform to DeleteType */
if (--shmdesc->refcnt)
return TRUE;
+#ifndef _MSC_VER
shmdt(shmdesc->addr);
+#endif
for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
;
*prev = shmdesc->next;
diff --git a/xorg-server/Xext/sync.c b/xorg-server/Xext/sync.c
index 4f80c7f30..60bcfe8d8 100644
--- a/xorg-server/Xext/sync.c
+++ b/xorg-server/Xext/sync.c
@@ -1235,6 +1235,10 @@ FreeAwait(void *addr, XID id)
return Success;
}
+#ifdef _MSC_VER
+#pragma warning(disable:4715) /* Not all control paths return a value */
+#endif
+
/* loosely based on dix/events.c/OtherClientGone */
static int
FreeAlarmClient(void *value, XID id)
diff --git a/xorg-server/Xext/xace.c b/xorg-server/Xext/xace.c
index 28c51687c..77b713ffb 100644
--- a/xorg-server/Xext/xace.c
+++ b/xorg-server/Xext/xace.c
@@ -19,6 +19,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
+#else
+#define XACE
#endif
#include <stdarg.h>
diff --git a/xorg-server/Xext/xselinux_hooks.c b/xorg-server/Xext/xselinux_hooks.c
index f1d8e5d2f..1c048bd68 100644
--- a/xorg-server/Xext/xselinux_hooks.c
+++ b/xorg-server/Xext/xselinux_hooks.c
@@ -1,935 +1,935 @@
-/************************************************************
-
-Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-this permission notice appear in supporting documentation. This permission
-notice shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-********************************************************/
-
-/*
- * Portions of this code copyright (c) 2005 by Trusted Computer Solutions, Inc.
- * All rights reserved.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <sys/socket.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include <libaudit.h>
-
-#include <X11/Xatom.h>
-#include "selection.h"
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "propertyst.h"
-#include "extnsionst.h"
-#include "xacestr.h"
-#include "client.h"
-#include "../os/osdep.h"
-#define _XSELINUX_NEED_FLASK_MAP
-#include "xselinuxint.h"
-
-
-/* structure passed to auditing callback */
-typedef struct {
- ClientPtr client; /* client */
- DeviceIntPtr dev; /* device */
- char *command; /* client's executable path */
- unsigned id; /* resource id, if any */
- int restype; /* resource type, if any */
- int event; /* event type, if any */
- Atom property; /* property name, if any */
- Atom selection; /* selection name, if any */
- char *extension; /* extension name, if any */
-} SELinuxAuditRec;
-
-/* private state keys */
-DevPrivateKeyRec subjectKeyRec;
-DevPrivateKeyRec objectKeyRec;
-DevPrivateKeyRec dataKeyRec;
-
-/* audit file descriptor */
-static int audit_fd;
-
-/* atoms for window label properties */
-static Atom atom_ctx;
-static Atom atom_client_ctx;
-
-/* The unlabeled SID */
-static security_id_t unlabeled_sid;
-
-/* forward declarations */
-static void SELinuxScreen(CallbackListPtr *, pointer, pointer);
-
-/* "true" pointer value for use as callback data */
-static pointer truep = (pointer)1;
-
-
-/*
- * Performs an SELinux permission check.
- */
-static int
-SELinuxDoCheck(SELinuxSubjectRec *subj, SELinuxObjectRec *obj,
- security_class_t class, Mask mode, SELinuxAuditRec *auditdata)
-{
- /* serverClient requests OK */
- if (subj->privileged)
- return Success;
-
- auditdata->command = subj->command;
- errno = 0;
-
- if (avc_has_perm(subj->sid, obj->sid, class, mode, &subj->aeref,
- auditdata) < 0) {
- if (mode == DixUnknownAccess)
- return Success; /* DixUnknownAccess requests OK ... for now */
- if (errno == EACCES)
- return BadAccess;
- ErrorF("SELinux: avc_has_perm: unexpected error %d\n", errno);
- return BadValue;
- }
-
- return Success;
-}
-
-/*
- * Labels a newly connected client.
- */
-static void
-SELinuxLabelClient(ClientPtr client)
-{
- int fd = XaceGetConnectionNumber(client);
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- security_context_t ctx;
-
- subj = dixLookupPrivate(&client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&client->devPrivates, objectKey);
-
- /* Try to get a context from the socket */
- if (fd < 0 || getpeercon_raw(fd, &ctx) < 0) {
- /* Otherwise, fall back to a default context */
- ctx = SELinuxDefaultClientLabel();
- }
-
- /* For local clients, try and determine the executable name */
- if (XaceIsLocal(client)) {
- /* Get cached command name if CLIENTIDS is enabled. */
- const char *cmdname = GetClientCmdName(client);
- Bool cached = (cmdname != NULL);
- /* If CLIENTIDS is disabled, figure out the command name from
- * scratch. */
- if (!cmdname)
- {
- pid_t pid = DetermineClientPid(client);
- if (pid != -1)
- DetermineClientCmd(pid, &cmdname, NULL);
- }
-
- if (!cmdname)
- goto finish;
-
- strncpy(subj->command, cmdname, COMMAND_LEN - 1);
-
- if (!cached)
- free((void *) cmdname); /* const char * */
- }
-
-finish:
- /* Get a SID from the context */
- if (avc_context_to_sid_raw(ctx, &subj->sid) < 0)
- FatalError("SELinux: client %d: context_to_sid_raw(%s) failed\n",
- client->index, ctx);
-
- obj->sid = subj->sid;
- freecon(ctx);
-}
-
-/*
- * Labels initial server objects.
- */
-static void
-SELinuxLabelInitial(void)
-{
- int i;
- XaceScreenAccessRec srec;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- security_context_t ctx;
- pointer unused;
-
- /* Do the serverClient */
- subj = dixLookupPrivate(&serverClient->devPrivates, subjectKey);
- obj = dixLookupPrivate(&serverClient->devPrivates, objectKey);
- subj->privileged = 1;
-
- /* Use the context of the X server process for the serverClient */
- if (getcon_raw(&ctx) < 0)
- FatalError("SELinux: couldn't get context of X server process\n");
-
- /* Get a SID from the context */
- if (avc_context_to_sid_raw(ctx, &subj->sid) < 0)
- FatalError("SELinux: serverClient: context_to_sid(%s) failed\n", ctx);
-
- obj->sid = subj->sid;
- freecon(ctx);
-
- srec.client = serverClient;
- srec.access_mode = DixCreateAccess;
- srec.status = Success;
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- /* Do the screen object */
- srec.screen = screenInfo.screens[i];
- SELinuxScreen(NULL, NULL, &srec);
-
- /* Do the default colormap */
- dixLookupResourceByType(&unused, screenInfo.screens[i]->defColormap,
- RT_COLORMAP, serverClient, DixCreateAccess);
- }
-}
-
-/*
- * Labels new resource objects.
- */
-static int
-SELinuxLabelResource(XaceResourceAccessRec *rec, SELinuxSubjectRec *subj,
- SELinuxObjectRec *obj, security_class_t class)
-{
- int offset;
- security_id_t tsid;
-
- /* Check for a create context */
- if (rec->rtype & RC_DRAWABLE && subj->win_create_sid) {
- obj->sid = subj->win_create_sid;
- return Success;
- }
-
- if (rec->parent)
- offset = dixLookupPrivateOffset(rec->ptype);
-
- if (rec->parent && offset >= 0) {
- /* Use the SID of the parent object in the labeling operation */
- PrivateRec **privatePtr = DEVPRIV_AT(rec->parent, offset);
- SELinuxObjectRec *pobj = dixLookupPrivate(privatePtr, objectKey);
- tsid = pobj->sid;
- } else {
- /* Use the SID of the subject */
- tsid = subj->sid;
- }
-
- /* Perform a transition to obtain the final SID */
- if (avc_compute_create(subj->sid, tsid, class, &obj->sid) < 0) {
- ErrorF("SELinux: a compute_create call failed!\n");
- return BadValue;
- }
-
- return Success;
-}
-
-
-/*
- * Libselinux Callbacks
- */
-
-static int
-SELinuxAudit(void *auditdata,
- security_class_t class,
- char *msgbuf,
- size_t msgbufsize)
-{
- SELinuxAuditRec *audit = auditdata;
- ClientPtr client = audit->client;
- char idNum[16];
- const char *propertyName, *selectionName;
- int major = -1, minor = -1;
-
- if (client) {
- REQUEST(xReq);
- if (stuff) {
- major = stuff->reqType;
- minor = MinorOpcodeOfRequest(client);
- }
- }
- if (audit->id)
- snprintf(idNum, 16, "%x", audit->id);
-
- propertyName = audit->property ? NameForAtom(audit->property) : NULL;
- selectionName = audit->selection ? NameForAtom(audit->selection) : NULL;
-
- return snprintf(msgbuf, msgbufsize,
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- (major >= 0) ? "request=" : "",
- (major >= 0) ? LookupRequestName(major, minor) : "",
- audit->command ? " comm=" : "",
- audit->command ? audit->command : "",
- audit->dev ? " xdevice=\"" : "",
- audit->dev ? audit->dev->name : "",
- audit->dev ? "\"" : "",
- audit->id ? " resid=" : "",
- audit->id ? idNum : "",
- audit->restype ? " restype=" : "",
- audit->restype ? LookupResourceName(audit->restype) : "",
- audit->event ? " event=" : "",
- audit->event ? LookupEventName(audit->event & 127) : "",
- audit->property ? " property=" : "",
- audit->property ? propertyName : "",
- audit->selection ? " selection=" : "",
- audit->selection ? selectionName : "",
- audit->extension ? " extension=" : "",
- audit->extension ? audit->extension : "");
-}
-
-static int
-SELinuxLog(int type, const char *fmt, ...)
-{
- va_list ap;
- char buf[MAX_AUDIT_MESSAGE_LENGTH];
- int rc, aut;
-
- switch (type) {
- case SELINUX_INFO:
- aut = AUDIT_USER_MAC_POLICY_LOAD;
- break;
- case SELINUX_AVC:
- aut = AUDIT_USER_AVC;
- break;
- default:
- aut = AUDIT_USER_SELINUX_ERR;
- break;
- }
-
- va_start(ap, fmt);
- vsnprintf(buf, MAX_AUDIT_MESSAGE_LENGTH, fmt, ap);
- rc = audit_log_user_avc_message(audit_fd, aut, buf, NULL, NULL, NULL, 0);
- va_end(ap);
- LogMessageVerb(X_WARNING, 0, "%s", buf);
- return 0;
-}
-
-/*
- * XACE Callbacks
- */
-
-static void
-SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XaceDeviceAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- SELinuxAuditRec auditdata = { .client = rec->client, .dev = rec->dev };
- security_class_t cls;
- int rc;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&rec->dev->devPrivates, objectKey);
-
- /* If this is a new object that needs labeling, do it now */
- if (rec->access_mode & DixCreateAccess) {
- SELinuxSubjectRec *dsubj;
- dsubj = dixLookupPrivate(&rec->dev->devPrivates, subjectKey);
-
- if (subj->dev_create_sid) {
- /* Label the device with the create context */
- obj->sid = subj->dev_create_sid;
- dsubj->sid = subj->dev_create_sid;
- } else {
- /* Label the device directly with the process SID */
- obj->sid = subj->sid;
- dsubj->sid = subj->sid;
- }
- }
-
- cls = IsPointerDevice(rec->dev) ? SECCLASS_X_POINTER : SECCLASS_X_KEYBOARD;
- rc = SELinuxDoCheck(subj, obj, cls, rec->access_mode, &auditdata);
- if (rc != Success)
- rec->status = rc;
-}
-
-static void
-SELinuxSend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XaceSendAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj, ev_sid;
- SELinuxAuditRec auditdata = { .client = rec->client, .dev = rec->dev };
- security_class_t class;
- int rc, i, type;
-
- if (rec->dev)
- subj = dixLookupPrivate(&rec->dev->devPrivates, subjectKey);
- else
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
-
- obj = dixLookupPrivate(&rec->pWin->devPrivates, objectKey);
-
- /* Check send permission on window */
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DRAWABLE, DixSendAccess,
- &auditdata);
- if (rc != Success)
- goto err;
-
- /* Check send permission on specific event types */
- for (i = 0; i < rec->count; i++) {
- type = rec->events[i].u.u.type;
- class = (type & 128) ? SECCLASS_X_FAKEEVENT : SECCLASS_X_EVENT;
-
- rc = SELinuxEventToSID(type, obj->sid, &ev_sid);
- if (rc != Success)
- goto err;
-
- auditdata.event = type;
- rc = SELinuxDoCheck(subj, &ev_sid, class, DixSendAccess, &auditdata);
- if (rc != Success)
- goto err;
- }
- return;
-err:
- rec->status = rc;
-}
-
-static void
-SELinuxReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XaceReceiveAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj, ev_sid;
- SELinuxAuditRec auditdata = { .client = NULL };
- security_class_t class;
- int rc, i, type;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&rec->pWin->devPrivates, objectKey);
-
- /* Check receive permission on window */
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DRAWABLE, DixReceiveAccess,
- &auditdata);
- if (rc != Success)
- goto err;
-
- /* Check receive permission on specific event types */
- for (i = 0; i < rec->count; i++) {
- type = rec->events[i].u.u.type;
- class = (type & 128) ? SECCLASS_X_FAKEEVENT : SECCLASS_X_EVENT;
-
- rc = SELinuxEventToSID(type, obj->sid, &ev_sid);
- if (rc != Success)
- goto err;
-
- auditdata.event = type;
- rc = SELinuxDoCheck(subj, &ev_sid, class, DixReceiveAccess, &auditdata);
- if (rc != Success)
- goto err;
- }
- return;
-err:
- rec->status = rc;
-}
-
-static void
-SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XaceExtAccessRec *rec = calldata;
- SELinuxSubjectRec *subj, *serv;
- SELinuxObjectRec *obj;
- SELinuxAuditRec auditdata = { .client = rec->client };
- int rc;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&rec->ext->devPrivates, objectKey);
-
- /* If this is a new object that needs labeling, do it now */
- /* XXX there should be a separate callback for this */
- if (obj->sid == NULL) {
- security_id_t sid;
-
- serv = dixLookupPrivate(&serverClient->devPrivates, subjectKey);
- rc = SELinuxExtensionToSID(rec->ext->name, &sid);
- if (rc != Success) {
- rec->status = rc;
- return;
- }
-
- /* Perform a transition to obtain the final SID */
- if (avc_compute_create(serv->sid, sid, SECCLASS_X_EXTENSION,
- &obj->sid) < 0) {
- ErrorF("SELinux: a SID transition call failed!\n");
- rec->status = BadValue;
- return;
- }
- }
-
- /* Perform the security check */
- auditdata.extension = rec->ext->name;
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_EXTENSION, rec->access_mode,
- &auditdata);
- if (rc != Success)
- rec->status = rc;
-}
-
-static void
-SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XaceSelectionAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj, *data;
- Selection *pSel = *rec->ppSel;
- Atom name = pSel->selection;
- Mask access_mode = rec->access_mode;
- SELinuxAuditRec auditdata = { .client = rec->client, .selection = name };
- security_id_t tsid;
- int rc;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&pSel->devPrivates, objectKey);
-
- /* If this is a new object that needs labeling, do it now */
- if (access_mode & DixCreateAccess) {
- rc = SELinuxSelectionToSID(name, subj, &obj->sid, &obj->poly);
- if (rc != Success)
- obj->sid = unlabeled_sid;
- access_mode = DixSetAttrAccess;
- }
- /* If this is a polyinstantiated object, find the right instance */
- else if (obj->poly) {
- rc = SELinuxSelectionToSID(name, subj, &tsid, NULL);
- if (rc != Success) {
- rec->status = rc;
- return;
- }
- while (pSel->selection != name || obj->sid != tsid) {
- if ((pSel = pSel->next) == NULL)
- break;
- obj = dixLookupPrivate(&pSel->devPrivates, objectKey);
- }
-
- if (pSel)
- *rec->ppSel = pSel;
- else {
- rec->status = BadMatch;
- return;
- }
- }
-
- /* Perform the security check */
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SELECTION, access_mode,
- &auditdata);
- if (rc != Success)
- rec->status = rc;
-
- /* Label the content (advisory only) */
- if (access_mode & DixSetAttrAccess) {
- data = dixLookupPrivate(&pSel->devPrivates, dataKey);
- if (subj->sel_create_sid)
- data->sid = subj->sel_create_sid;
- else
- data->sid = obj->sid;
- }
-}
-
-static void
-SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XacePropertyAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj, *data;
- PropertyPtr pProp = *rec->ppProp;
- Atom name = pProp->propertyName;
- SELinuxAuditRec auditdata = { .client = rec->client, .property = name };
- security_id_t tsid;
- int rc;
-
- /* Don't care about the new content check */
- if (rec->access_mode & DixPostAccess)
- return;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&pProp->devPrivates, objectKey);
-
- /* If this is a new object that needs labeling, do it now */
- if (rec->access_mode & DixCreateAccess) {
- rc = SELinuxPropertyToSID(name, subj, &obj->sid, &obj->poly);
- if (rc != Success) {
- rec->status = rc;
- return;
- }
- }
- /* If this is a polyinstantiated object, find the right instance */
- else if (obj->poly) {
- rc = SELinuxPropertyToSID(name, subj, &tsid, NULL);
- if (rc != Success) {
- rec->status = rc;
- return;
- }
- while (pProp->propertyName != name || obj->sid != tsid) {
- if ((pProp = pProp->next) == NULL)
- break;
- obj = dixLookupPrivate(&pProp->devPrivates, objectKey);
- }
-
- if (pProp)
- *rec->ppProp = pProp;
- else {
- rec->status = BadMatch;
- return;
- }
- }
-
- /* Perform the security check */
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_PROPERTY, rec->access_mode,
- &auditdata);
- if (rc != Success)
- rec->status = rc;
-
- /* Label the content (advisory only) */
- if (rec->access_mode & DixWriteAccess) {
- data = dixLookupPrivate(&pProp->devPrivates, dataKey);
- if (subj->prp_create_sid)
- data->sid = subj->prp_create_sid;
- else
- data->sid = obj->sid;
- }
-}
-
-static void
-SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XaceResourceAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- SELinuxAuditRec auditdata = { .client = rec->client };
- Mask access_mode = rec->access_mode;
- PrivateRec **privatePtr;
- security_class_t class;
- int rc, offset;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
-
- /* Determine if the resource object has a devPrivates field */
- offset = dixLookupPrivateOffset(rec->rtype);
- if (offset < 0) {
- /* No: use the SID of the owning client */
- class = SECCLASS_X_RESOURCE;
- privatePtr = &clients[CLIENT_ID(rec->id)]->devPrivates;
- obj = dixLookupPrivate(privatePtr, objectKey);
- } else {
- /* Yes: use the SID from the resource object itself */
- class = SELinuxTypeToClass(rec->rtype);
- privatePtr = DEVPRIV_AT(rec->res, offset);
- obj = dixLookupPrivate(privatePtr, objectKey);
- }
-
- /* If this is a new object that needs labeling, do it now */
- if (access_mode & DixCreateAccess && offset >= 0) {
- rc = SELinuxLabelResource(rec, subj, obj, class);
- if (rc != Success) {
- rec->status = rc;
- return;
- }
- }
-
- /* Collapse generic resource permissions down to read/write */
- if (class == SECCLASS_X_RESOURCE) {
- access_mode = !!(rec->access_mode & SELinuxReadMask); /* rd */
- access_mode |= !!(rec->access_mode & ~SELinuxReadMask) << 1; /* wr */
- }
-
- /* Perform the security check */
- auditdata.restype = rec->rtype;
- auditdata.id = rec->id;
- rc = SELinuxDoCheck(subj, obj, class, access_mode, &auditdata);
- if (rc != Success)
- rec->status = rc;
-
- /* Perform the background none check on windows */
- if (access_mode & DixCreateAccess && rec->rtype == RT_WINDOW) {
- rc = SELinuxDoCheck(subj, obj, class, DixBlendAccess, &auditdata);
- if (rc != Success)
- ((WindowPtr)rec->res)->forcedBG = TRUE;
- }
-}
-
-static void
-SELinuxScreen(CallbackListPtr *pcbl, pointer is_saver, pointer calldata)
-{
- XaceScreenAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- SELinuxAuditRec auditdata = { .client = rec->client };
- Mask access_mode = rec->access_mode;
- int rc;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&rec->screen->devPrivates, objectKey);
-
- /* If this is a new object that needs labeling, do it now */
- if (access_mode & DixCreateAccess) {
- /* Perform a transition to obtain the final SID */
- if (avc_compute_create(subj->sid, subj->sid, SECCLASS_X_SCREEN,
- &obj->sid) < 0) {
- ErrorF("SELinux: a compute_create call failed!\n");
- rec->status = BadValue;
- return;
- }
- }
-
- if (is_saver)
- access_mode <<= 2;
-
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SCREEN, access_mode, &auditdata);
- if (rc != Success)
- rec->status = rc;
-}
-
-static void
-SELinuxClient(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XaceClientAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- SELinuxAuditRec auditdata = { .client = rec->client };
- int rc;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&rec->target->devPrivates, objectKey);
-
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_CLIENT, rec->access_mode,
- &auditdata);
- if (rc != Success)
- rec->status = rc;
-}
-
-static void
-SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- XaceServerAccessRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- SELinuxAuditRec auditdata = { .client = rec->client };
- int rc;
-
- subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&serverClient->devPrivates, objectKey);
-
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SERVER, rec->access_mode,
- &auditdata);
- if (rc != Success)
- rec->status = rc;
-}
-
-
-/*
- * DIX Callbacks
- */
-
-static void
-SELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- NewClientInfoRec *pci = calldata;
-
- switch (pci->client->clientState) {
- case ClientStateInitial:
- SELinuxLabelClient(pci->client);
- break;
-
- default:
- break;
- }
-}
-
-static void
-SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
- ResourceStateInfoRec *rec = calldata;
- SELinuxSubjectRec *subj;
- SELinuxObjectRec *obj;
- WindowPtr pWin;
-
- if (rec->type != RT_WINDOW)
- return;
- if (rec->state != ResourceStateAdding)
- return;
-
- pWin = (WindowPtr)rec->value;
- subj = dixLookupPrivate(&wClient(pWin)->devPrivates, subjectKey);
-
- if (subj->sid) {
- security_context_t ctx;
- int rc = avc_sid_to_context_raw(subj->sid, &ctx);
- if (rc < 0)
- FatalError("SELinux: Failed to get security context!\n");
- rc = dixChangeWindowProperty(serverClient,
- pWin, atom_client_ctx, XA_STRING, 8,
- PropModeReplace, strlen(ctx), ctx, FALSE);
- if (rc != Success)
- FatalError("SELinux: Failed to set label property on window!\n");
- freecon(ctx);
- } else
- FatalError("SELinux: Unexpected unlabeled client found\n");
-
- obj = dixLookupPrivate(&pWin->devPrivates, objectKey);
-
- if (obj->sid) {
- security_context_t ctx;
- int rc = avc_sid_to_context_raw(obj->sid, &ctx);
- if (rc < 0)
- FatalError("SELinux: Failed to get security context!\n");
- rc = dixChangeWindowProperty(serverClient,
- pWin, atom_ctx, XA_STRING, 8,
- PropModeReplace, strlen(ctx), ctx, FALSE);
- if (rc != Success)
- FatalError("SELinux: Failed to set label property on window!\n");
- freecon(ctx);
- } else
- FatalError("SELinux: Unexpected unlabeled window found\n");
-}
-
-
-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();
-}
-
-void
-SELinuxFlaskReset(void)
-{
- /* Unregister callbacks */
- DeleteCallback(&ClientStateCallback, SELinuxClientState, NULL);
- DeleteCallback(&ResourceStateCallback, SELinuxResourceState, NULL);
-
- XaceDeleteCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL);
- XaceDeleteCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL);
- XaceDeleteCallback(XACE_DEVICE_ACCESS, SELinuxDevice, NULL);
- XaceDeleteCallback(XACE_PROPERTY_ACCESS, SELinuxProperty, NULL);
- XaceDeleteCallback(XACE_SEND_ACCESS, SELinuxSend, NULL);
- XaceDeleteCallback(XACE_RECEIVE_ACCESS, SELinuxReceive, NULL);
- XaceDeleteCallback(XACE_CLIENT_ACCESS, SELinuxClient, NULL);
- XaceDeleteCallback(XACE_EXT_ACCESS, SELinuxExtension, NULL);
- XaceDeleteCallback(XACE_SERVER_ACCESS, SELinuxServer, NULL);
- XaceDeleteCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
- XaceDeleteCallback(XACE_SCREEN_ACCESS, SELinuxScreen, NULL);
- XaceDeleteCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, truep);
-
- /* Tear down SELinux stuff */
- audit_close(audit_fd);
- avc_netlink_release_fd();
- RemoveBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
- NULL);
- RemoveGeneralSocket(netlink_fd);
-
- avc_destroy();
-}
-
-void
-SELinuxFlaskInit(void)
-{
- struct selinux_opt avc_option = { AVC_OPT_SETENFORCE, (char *)0 };
- security_context_t ctx;
- int ret = TRUE;
-
- switch(selinuxEnforcingState) {
- case SELINUX_MODE_ENFORCING:
- LogMessage(X_INFO, "SELinux: Configured in enforcing mode\n");
- avc_option.value = (char *)1;
- break;
- case SELINUX_MODE_PERMISSIVE:
- LogMessage(X_INFO, "SELinux: Configured in permissive mode\n");
- avc_option.value = (char *)0;
- break;
- default:
- avc_option.type = AVC_OPT_UNUSED;
- break;
- }
-
- /* Set up SELinux stuff */
- selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback)SELinuxLog);
- selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback)SELinuxAudit);
-
- if (selinux_set_mapping(map) < 0) {
- if (errno == EINVAL) {
- ErrorF("SELinux: Invalid object class mapping, disabling SELinux support.\n");
- return;
- }
- FatalError("SELinux: Failed to set up security class mapping\n");
- }
-
- if (avc_open(&avc_option, 1) < 0)
- FatalError("SELinux: Couldn't initialize SELinux userspace AVC\n");
-
- if (security_get_initial_context_raw("unlabeled", &ctx) < 0)
- FatalError("SELinux: Failed to look up unlabeled context\n");
- if (avc_context_to_sid_raw(ctx, &unlabeled_sid) < 0)
- FatalError("SELinux: a context_to_SID call failed!\n");
- freecon(ctx);
-
- /* Prepare for auditing */
- audit_fd = audit_open();
- if (audit_fd < 0)
- FatalError("SELinux: Failed to open the system audit log\n");
-
- /* Allocate private storage */
- if (!dixRegisterPrivateKey(subjectKey, PRIVATE_XSELINUX, sizeof(SELinuxSubjectRec)) ||
- !dixRegisterPrivateKey(objectKey, PRIVATE_XSELINUX, sizeof(SELinuxObjectRec)) ||
- !dixRegisterPrivateKey(dataKey, PRIVATE_XSELINUX, sizeof(SELinuxObjectRec)))
- FatalError("SELinux: Failed to allocate private storage.\n");
-
- /* Create atoms for doing window labeling */
- atom_ctx = MakeAtom("_SELINUX_CONTEXT", 16, TRUE);
- if (atom_ctx == BAD_RESOURCE)
- FatalError("SELinux: Failed to create atom\n");
- atom_client_ctx = MakeAtom("_SELINUX_CLIENT_CONTEXT", 23, TRUE);
- if (atom_client_ctx == BAD_RESOURCE)
- FatalError("SELinux: Failed to create atom\n");
-
- netlink_fd = avc_netlink_acquire_fd();
- AddGeneralSocket(netlink_fd);
- RegisterBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
- NULL);
-
- /* Register callbacks */
- ret &= AddCallback(&ClientStateCallback, SELinuxClientState, NULL);
- ret &= AddCallback(&ResourceStateCallback, SELinuxResourceState, NULL);
-
- ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL);
- ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL);
- ret &= XaceRegisterCallback(XACE_DEVICE_ACCESS, SELinuxDevice, NULL);
- ret &= XaceRegisterCallback(XACE_PROPERTY_ACCESS, SELinuxProperty, NULL);
- ret &= XaceRegisterCallback(XACE_SEND_ACCESS, SELinuxSend, NULL);
- ret &= XaceRegisterCallback(XACE_RECEIVE_ACCESS, SELinuxReceive, NULL);
- ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SELinuxClient, NULL);
- ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SELinuxExtension, NULL);
- ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SELinuxServer, NULL);
- ret &= XaceRegisterCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
- ret &= XaceRegisterCallback(XACE_SCREEN_ACCESS, SELinuxScreen, NULL);
- ret &= XaceRegisterCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, truep);
- if (!ret)
- FatalError("SELinux: Failed to register one or more callbacks\n");
-
- /* Label objects that were created before we could register ourself */
- SELinuxLabelInitial();
-}
+/************************************************************
+
+Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+this permission notice appear in supporting documentation. This permission
+notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+********************************************************/
+
+/*
+ * Portions of this code copyright (c) 2005 by Trusted Computer Solutions, Inc.
+ * All rights reserved.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <libaudit.h>
+
+#include <X11/Xatom.h>
+#include "selection.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "extnsionst.h"
+#include "xacestr.h"
+#include "client.h"
+#include "../os/osdep.h"
+#define _XSELINUX_NEED_FLASK_MAP
+#include "xselinuxint.h"
+
+
+/* structure passed to auditing callback */
+typedef struct {
+ ClientPtr client; /* client */
+ DeviceIntPtr dev; /* device */
+ char *command; /* client's executable path */
+ unsigned id; /* resource id, if any */
+ int restype; /* resource type, if any */
+ int event; /* event type, if any */
+ Atom property; /* property name, if any */
+ Atom selection; /* selection name, if any */
+ char *extension; /* extension name, if any */
+} SELinuxAuditRec;
+
+/* private state keys */
+DevPrivateKeyRec subjectKeyRec;
+DevPrivateKeyRec objectKeyRec;
+DevPrivateKeyRec dataKeyRec;
+
+/* audit file descriptor */
+static int audit_fd;
+
+/* atoms for window label properties */
+static Atom atom_ctx;
+static Atom atom_client_ctx;
+
+/* The unlabeled SID */
+static security_id_t unlabeled_sid;
+
+/* forward declarations */
+static void SELinuxScreen(CallbackListPtr *, pointer, pointer);
+
+/* "true" pointer value for use as callback data */
+static pointer truep = (pointer)1;
+
+
+/*
+ * Performs an SELinux permission check.
+ */
+static int
+SELinuxDoCheck(SELinuxSubjectRec *subj, SELinuxObjectRec *obj,
+ security_class_t class, Mask mode, SELinuxAuditRec *auditdata)
+{
+ /* serverClient requests OK */
+ if (subj->privileged)
+ return Success;
+
+ auditdata->command = subj->command;
+ errno = 0;
+
+ if (avc_has_perm(subj->sid, obj->sid, class, mode, &subj->aeref,
+ auditdata) < 0) {
+ if (mode == DixUnknownAccess)
+ return Success; /* DixUnknownAccess requests OK ... for now */
+ if (errno == EACCES)
+ return BadAccess;
+ ErrorF("SELinux: avc_has_perm: unexpected error %d\n", errno);
+ return BadValue;
+ }
+
+ return Success;
+}
+
+/*
+ * Labels a newly connected client.
+ */
+static void
+SELinuxLabelClient(ClientPtr client)
+{
+ int fd = XaceGetConnectionNumber(client);
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ security_context_t ctx;
+
+ subj = dixLookupPrivate(&client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&client->devPrivates, objectKey);
+
+ /* Try to get a context from the socket */
+ if (fd < 0 || getpeercon_raw(fd, &ctx) < 0) {
+ /* Otherwise, fall back to a default context */
+ ctx = SELinuxDefaultClientLabel();
+ }
+
+ /* For local clients, try and determine the executable name */
+ if (XaceIsLocal(client)) {
+ /* Get cached command name if CLIENTIDS is enabled. */
+ const char *cmdname = GetClientCmdName(client);
+ Bool cached = (cmdname != NULL);
+ /* If CLIENTIDS is disabled, figure out the command name from
+ * scratch. */
+ if (!cmdname)
+ {
+ pid_t pid = DetermineClientPid(client);
+ if (pid != -1)
+ DetermineClientCmd(pid, &cmdname, NULL);
+ }
+
+ if (!cmdname)
+ goto finish;
+
+ strncpy(subj->command, cmdname, COMMAND_LEN - 1);
+
+ if (!cached)
+ free((void *) cmdname); /* const char * */
+ }
+
+finish:
+ /* Get a SID from the context */
+ if (avc_context_to_sid_raw(ctx, &subj->sid) < 0)
+ FatalError("SELinux: client %d: context_to_sid_raw(%s) failed\n",
+ client->index, ctx);
+
+ obj->sid = subj->sid;
+ freecon(ctx);
+}
+
+/*
+ * Labels initial server objects.
+ */
+static void
+SELinuxLabelInitial(void)
+{
+ int i;
+ XaceScreenAccessRec srec;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ security_context_t ctx;
+ pointer unused;
+
+ /* Do the serverClient */
+ subj = dixLookupPrivate(&serverClient->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&serverClient->devPrivates, objectKey);
+ subj->privileged = 1;
+
+ /* Use the context of the X server process for the serverClient */
+ if (getcon_raw(&ctx) < 0)
+ FatalError("SELinux: couldn't get context of X server process\n");
+
+ /* Get a SID from the context */
+ if (avc_context_to_sid_raw(ctx, &subj->sid) < 0)
+ FatalError("SELinux: serverClient: context_to_sid(%s) failed\n", ctx);
+
+ obj->sid = subj->sid;
+ freecon(ctx);
+
+ srec.client = serverClient;
+ srec.access_mode = DixCreateAccess;
+ srec.status = Success;
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ /* Do the screen object */
+ srec.screen = screenInfo.screens[i];
+ SELinuxScreen(NULL, NULL, &srec);
+
+ /* Do the default colormap */
+ dixLookupResourceByType(&unused, screenInfo.screens[i]->defColormap,
+ RT_COLORMAP, serverClient, DixCreateAccess);
+ }
+}
+
+/*
+ * Labels new resource objects.
+ */
+static int
+SELinuxLabelResource(XaceResourceAccessRec *rec, SELinuxSubjectRec *subj,
+ SELinuxObjectRec *obj, security_class_t class)
+{
+ int offset;
+ security_id_t tsid;
+
+ /* Check for a create context */
+ if (rec->rtype & RC_DRAWABLE && subj->win_create_sid) {
+ obj->sid = subj->win_create_sid;
+ return Success;
+ }
+
+ if (rec->parent)
+ offset = dixLookupPrivateOffset(rec->ptype);
+
+ if (rec->parent && offset >= 0) {
+ /* Use the SID of the parent object in the labeling operation */
+ PrivateRec **privatePtr = DEVPRIV_AT(rec->parent, offset);
+ SELinuxObjectRec *pobj = dixLookupPrivate(privatePtr, objectKey);
+ tsid = pobj->sid;
+ } else {
+ /* Use the SID of the subject */
+ tsid = subj->sid;
+ }
+
+ /* Perform a transition to obtain the final SID */
+ if (avc_compute_create(subj->sid, tsid, class, &obj->sid) < 0) {
+ ErrorF("SELinux: a compute_create call failed!\n");
+ return BadValue;
+ }
+
+ return Success;
+}
+
+
+/*
+ * Libselinux Callbacks
+ */
+
+static int
+SELinuxAudit(void *auditdata,
+ security_class_t class,
+ char *msgbuf,
+ size_t msgbufsize)
+{
+ SELinuxAuditRec *audit = auditdata;
+ ClientPtr client = audit->client;
+ char idNum[16];
+ const char *propertyName, *selectionName;
+ int major = -1, minor = -1;
+
+ if (client) {
+ REQUEST(xReq);
+ if (stuff) {
+ major = stuff->reqType;
+ minor = MinorOpcodeOfRequest(client);
+ }
+ }
+ if (audit->id)
+ snprintf(idNum, 16, "%x", audit->id);
+
+ propertyName = audit->property ? NameForAtom(audit->property) : NULL;
+ selectionName = audit->selection ? NameForAtom(audit->selection) : NULL;
+
+ return snprintf(msgbuf, msgbufsize,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ (major >= 0) ? "request=" : "",
+ (major >= 0) ? LookupRequestName(major, minor) : "",
+ audit->command ? " comm=" : "",
+ audit->command ? audit->command : "",
+ audit->dev ? " xdevice=\"" : "",
+ audit->dev ? audit->dev->name : "",
+ audit->dev ? "\"" : "",
+ audit->id ? " resid=" : "",
+ audit->id ? idNum : "",
+ audit->restype ? " restype=" : "",
+ audit->restype ? LookupResourceName(audit->restype) : "",
+ audit->event ? " event=" : "",
+ audit->event ? LookupEventName(audit->event & 127) : "",
+ audit->property ? " property=" : "",
+ audit->property ? propertyName : "",
+ audit->selection ? " selection=" : "",
+ audit->selection ? selectionName : "",
+ audit->extension ? " extension=" : "",
+ audit->extension ? audit->extension : "");
+}
+
+static int
+SELinuxLog(int type, const char *fmt, ...)
+{
+ va_list ap;
+ char buf[MAX_AUDIT_MESSAGE_LENGTH];
+ int rc, aut;
+
+ switch (type) {
+ case SELINUX_INFO:
+ aut = AUDIT_USER_MAC_POLICY_LOAD;
+ break;
+ case SELINUX_AVC:
+ aut = AUDIT_USER_AVC;
+ break;
+ default:
+ aut = AUDIT_USER_SELINUX_ERR;
+ break;
+ }
+
+ va_start(ap, fmt);
+ vsnprintf(buf, MAX_AUDIT_MESSAGE_LENGTH, fmt, ap);
+ rc = audit_log_user_avc_message(audit_fd, aut, buf, NULL, NULL, NULL, 0);
+ va_end(ap);
+ LogMessageVerb(X_WARNING, 0, "%s", buf);
+ return 0;
+}
+
+/*
+ * XACE Callbacks
+ */
+
+static void
+SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceDeviceAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ SELinuxAuditRec auditdata = { .client = rec->client, .dev = rec->dev };
+ security_class_t cls;
+ int rc;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&rec->dev->devPrivates, objectKey);
+
+ /* If this is a new object that needs labeling, do it now */
+ if (rec->access_mode & DixCreateAccess) {
+ SELinuxSubjectRec *dsubj;
+ dsubj = dixLookupPrivate(&rec->dev->devPrivates, subjectKey);
+
+ if (subj->dev_create_sid) {
+ /* Label the device with the create context */
+ obj->sid = subj->dev_create_sid;
+ dsubj->sid = subj->dev_create_sid;
+ } else {
+ /* Label the device directly with the process SID */
+ obj->sid = subj->sid;
+ dsubj->sid = subj->sid;
+ }
+ }
+
+ cls = IsPointerDevice(rec->dev) ? SECCLASS_X_POINTER : SECCLASS_X_KEYBOARD;
+ rc = SELinuxDoCheck(subj, obj, cls, rec->access_mode, &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+}
+
+static void
+SELinuxSend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceSendAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj, ev_sid;
+ SELinuxAuditRec auditdata = { .client = rec->client, .dev = rec->dev };
+ security_class_t class;
+ int rc, i, type;
+
+ if (rec->dev)
+ subj = dixLookupPrivate(&rec->dev->devPrivates, subjectKey);
+ else
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+
+ obj = dixLookupPrivate(&rec->pWin->devPrivates, objectKey);
+
+ /* Check send permission on window */
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DRAWABLE, DixSendAccess,
+ &auditdata);
+ if (rc != Success)
+ goto err;
+
+ /* Check send permission on specific event types */
+ for (i = 0; i < rec->count; i++) {
+ type = rec->events[i].u.u.type;
+ class = (type & 128) ? SECCLASS_X_FAKEEVENT : SECCLASS_X_EVENT;
+
+ rc = SELinuxEventToSID(type, obj->sid, &ev_sid);
+ if (rc != Success)
+ goto err;
+
+ auditdata.event = type;
+ rc = SELinuxDoCheck(subj, &ev_sid, class, DixSendAccess, &auditdata);
+ if (rc != Success)
+ goto err;
+ }
+ return;
+err:
+ rec->status = rc;
+}
+
+static void
+SELinuxReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceReceiveAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj, ev_sid;
+ SELinuxAuditRec auditdata = { .client = NULL };
+ security_class_t class;
+ int rc, i, type;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&rec->pWin->devPrivates, objectKey);
+
+ /* Check receive permission on window */
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DRAWABLE, DixReceiveAccess,
+ &auditdata);
+ if (rc != Success)
+ goto err;
+
+ /* Check receive permission on specific event types */
+ for (i = 0; i < rec->count; i++) {
+ type = rec->events[i].u.u.type;
+ class = (type & 128) ? SECCLASS_X_FAKEEVENT : SECCLASS_X_EVENT;
+
+ rc = SELinuxEventToSID(type, obj->sid, &ev_sid);
+ if (rc != Success)
+ goto err;
+
+ auditdata.event = type;
+ rc = SELinuxDoCheck(subj, &ev_sid, class, DixReceiveAccess, &auditdata);
+ if (rc != Success)
+ goto err;
+ }
+ return;
+err:
+ rec->status = rc;
+}
+
+static void
+SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceExtAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj, *serv;
+ SELinuxObjectRec *obj;
+ SELinuxAuditRec auditdata = { .client = rec->client };
+ int rc;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&rec->ext->devPrivates, objectKey);
+
+ /* If this is a new object that needs labeling, do it now */
+ /* XXX there should be a separate callback for this */
+ if (obj->sid == NULL) {
+ security_id_t sid;
+
+ serv = dixLookupPrivate(&serverClient->devPrivates, subjectKey);
+ rc = SELinuxExtensionToSID(rec->ext->name, &sid);
+ if (rc != Success) {
+ rec->status = rc;
+ return;
+ }
+
+ /* Perform a transition to obtain the final SID */
+ if (avc_compute_create(serv->sid, sid, SECCLASS_X_EXTENSION,
+ &obj->sid) < 0) {
+ ErrorF("SELinux: a SID transition call failed!\n");
+ rec->status = BadValue;
+ return;
+ }
+ }
+
+ /* Perform the security check */
+ auditdata.extension = rec->ext->name;
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_EXTENSION, rec->access_mode,
+ &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+}
+
+static void
+SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceSelectionAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj, *data;
+ Selection *pSel = *rec->ppSel;
+ Atom name = pSel->selection;
+ Mask access_mode = rec->access_mode;
+ SELinuxAuditRec auditdata = { .client = rec->client, .selection = name };
+ security_id_t tsid;
+ int rc;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&pSel->devPrivates, objectKey);
+
+ /* If this is a new object that needs labeling, do it now */
+ if (access_mode & DixCreateAccess) {
+ rc = SELinuxSelectionToSID(name, subj, &obj->sid, &obj->poly);
+ if (rc != Success)
+ obj->sid = unlabeled_sid;
+ access_mode = DixSetAttrAccess;
+ }
+ /* If this is a polyinstantiated object, find the right instance */
+ else if (obj->poly) {
+ rc = SELinuxSelectionToSID(name, subj, &tsid, NULL);
+ if (rc != Success) {
+ rec->status = rc;
+ return;
+ }
+ while (pSel->selection != name || obj->sid != tsid) {
+ if ((pSel = pSel->next) == NULL)
+ break;
+ obj = dixLookupPrivate(&pSel->devPrivates, objectKey);
+ }
+
+ if (pSel)
+ *rec->ppSel = pSel;
+ else {
+ rec->status = BadMatch;
+ return;
+ }
+ }
+
+ /* Perform the security check */
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SELECTION, access_mode,
+ &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+
+ /* Label the content (advisory only) */
+ if (access_mode & DixSetAttrAccess) {
+ data = dixLookupPrivate(&pSel->devPrivates, dataKey);
+ if (subj->sel_create_sid)
+ data->sid = subj->sel_create_sid;
+ else
+ data->sid = obj->sid;
+ }
+}
+
+static void
+SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XacePropertyAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj, *data;
+ PropertyPtr pProp = *rec->ppProp;
+ Atom name = pProp->propertyName;
+ SELinuxAuditRec auditdata = { .client = rec->client, .property = name };
+ security_id_t tsid;
+ int rc;
+
+ /* Don't care about the new content check */
+ if (rec->access_mode & DixPostAccess)
+ return;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&pProp->devPrivates, objectKey);
+
+ /* If this is a new object that needs labeling, do it now */
+ if (rec->access_mode & DixCreateAccess) {
+ rc = SELinuxPropertyToSID(name, subj, &obj->sid, &obj->poly);
+ if (rc != Success) {
+ rec->status = rc;
+ return;
+ }
+ }
+ /* If this is a polyinstantiated object, find the right instance */
+ else if (obj->poly) {
+ rc = SELinuxPropertyToSID(name, subj, &tsid, NULL);
+ if (rc != Success) {
+ rec->status = rc;
+ return;
+ }
+ while (pProp->propertyName != name || obj->sid != tsid) {
+ if ((pProp = pProp->next) == NULL)
+ break;
+ obj = dixLookupPrivate(&pProp->devPrivates, objectKey);
+ }
+
+ if (pProp)
+ *rec->ppProp = pProp;
+ else {
+ rec->status = BadMatch;
+ return;
+ }
+ }
+
+ /* Perform the security check */
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_PROPERTY, rec->access_mode,
+ &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+
+ /* Label the content (advisory only) */
+ if (rec->access_mode & DixWriteAccess) {
+ data = dixLookupPrivate(&pProp->devPrivates, dataKey);
+ if (subj->prp_create_sid)
+ data->sid = subj->prp_create_sid;
+ else
+ data->sid = obj->sid;
+ }
+}
+
+static void
+SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceResourceAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ SELinuxAuditRec auditdata = { .client = rec->client };
+ Mask access_mode = rec->access_mode;
+ PrivateRec **privatePtr;
+ security_class_t class;
+ int rc, offset;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+
+ /* Determine if the resource object has a devPrivates field */
+ offset = dixLookupPrivateOffset(rec->rtype);
+ if (offset < 0) {
+ /* No: use the SID of the owning client */
+ class = SECCLASS_X_RESOURCE;
+ privatePtr = &clients[CLIENT_ID(rec->id)]->devPrivates;
+ obj = dixLookupPrivate(privatePtr, objectKey);
+ } else {
+ /* Yes: use the SID from the resource object itself */
+ class = SELinuxTypeToClass(rec->rtype);
+ privatePtr = DEVPRIV_AT(rec->res, offset);
+ obj = dixLookupPrivate(privatePtr, objectKey);
+ }
+
+ /* If this is a new object that needs labeling, do it now */
+ if (access_mode & DixCreateAccess && offset >= 0) {
+ rc = SELinuxLabelResource(rec, subj, obj, class);
+ if (rc != Success) {
+ rec->status = rc;
+ return;
+ }
+ }
+
+ /* Collapse generic resource permissions down to read/write */
+ if (class == SECCLASS_X_RESOURCE) {
+ access_mode = !!(rec->access_mode & SELinuxReadMask); /* rd */
+ access_mode |= !!(rec->access_mode & ~SELinuxReadMask) << 1; /* wr */
+ }
+
+ /* Perform the security check */
+ auditdata.restype = rec->rtype;
+ auditdata.id = rec->id;
+ rc = SELinuxDoCheck(subj, obj, class, access_mode, &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+
+ /* Perform the background none check on windows */
+ if (access_mode & DixCreateAccess && rec->rtype == RT_WINDOW) {
+ rc = SELinuxDoCheck(subj, obj, class, DixBlendAccess, &auditdata);
+ if (rc != Success)
+ ((WindowPtr)rec->res)->forcedBG = TRUE;
+ }
+}
+
+static void
+SELinuxScreen(CallbackListPtr *pcbl, pointer is_saver, pointer calldata)
+{
+ XaceScreenAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ SELinuxAuditRec auditdata = { .client = rec->client };
+ Mask access_mode = rec->access_mode;
+ int rc;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&rec->screen->devPrivates, objectKey);
+
+ /* If this is a new object that needs labeling, do it now */
+ if (access_mode & DixCreateAccess) {
+ /* Perform a transition to obtain the final SID */
+ if (avc_compute_create(subj->sid, subj->sid, SECCLASS_X_SCREEN,
+ &obj->sid) < 0) {
+ ErrorF("SELinux: a compute_create call failed!\n");
+ rec->status = BadValue;
+ return;
+ }
+ }
+
+ if (is_saver)
+ access_mode <<= 2;
+
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SCREEN, access_mode, &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+}
+
+static void
+SELinuxClient(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceClientAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ SELinuxAuditRec auditdata = { .client = rec->client };
+ int rc;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&rec->target->devPrivates, objectKey);
+
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_CLIENT, rec->access_mode,
+ &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+}
+
+static void
+SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceServerAccessRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ SELinuxAuditRec auditdata = { .client = rec->client };
+ int rc;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+ obj = dixLookupPrivate(&serverClient->devPrivates, objectKey);
+
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SERVER, rec->access_mode,
+ &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+}
+
+
+/*
+ * DIX Callbacks
+ */
+
+static void
+SELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ NewClientInfoRec *pci = calldata;
+
+ switch (pci->client->clientState) {
+ case ClientStateInitial:
+ SELinuxLabelClient(pci->client);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ ResourceStateInfoRec *rec = calldata;
+ SELinuxSubjectRec *subj;
+ SELinuxObjectRec *obj;
+ WindowPtr pWin;
+
+ if (rec->type != RT_WINDOW)
+ return;
+ if (rec->state != ResourceStateAdding)
+ return;
+
+ pWin = (WindowPtr)rec->value;
+ subj = dixLookupPrivate(&wClient(pWin)->devPrivates, subjectKey);
+
+ if (subj->sid) {
+ security_context_t ctx;
+ int rc = avc_sid_to_context_raw(subj->sid, &ctx);
+ if (rc < 0)
+ FatalError("SELinux: Failed to get security context!\n");
+ rc = dixChangeWindowProperty(serverClient,
+ pWin, atom_client_ctx, XA_STRING, 8,
+ PropModeReplace, strlen(ctx), ctx, FALSE);
+ if (rc != Success)
+ FatalError("SELinux: Failed to set label property on window!\n");
+ freecon(ctx);
+ } else
+ FatalError("SELinux: Unexpected unlabeled client found\n");
+
+ obj = dixLookupPrivate(&pWin->devPrivates, objectKey);
+
+ if (obj->sid) {
+ security_context_t ctx;
+ int rc = avc_sid_to_context_raw(obj->sid, &ctx);
+ if (rc < 0)
+ FatalError("SELinux: Failed to get security context!\n");
+ rc = dixChangeWindowProperty(serverClient,
+ pWin, atom_ctx, XA_STRING, 8,
+ PropModeReplace, strlen(ctx), ctx, FALSE);
+ if (rc != Success)
+ FatalError("SELinux: Failed to set label property on window!\n");
+ freecon(ctx);
+ } else
+ FatalError("SELinux: Unexpected unlabeled window found\n");
+}
+
+
+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();
+}
+
+void
+SELinuxFlaskReset(void)
+{
+ /* Unregister callbacks */
+ DeleteCallback(&ClientStateCallback, SELinuxClientState, NULL);
+ DeleteCallback(&ResourceStateCallback, SELinuxResourceState, NULL);
+
+ XaceDeleteCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL);
+ XaceDeleteCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL);
+ XaceDeleteCallback(XACE_DEVICE_ACCESS, SELinuxDevice, NULL);
+ XaceDeleteCallback(XACE_PROPERTY_ACCESS, SELinuxProperty, NULL);
+ XaceDeleteCallback(XACE_SEND_ACCESS, SELinuxSend, NULL);
+ XaceDeleteCallback(XACE_RECEIVE_ACCESS, SELinuxReceive, NULL);
+ XaceDeleteCallback(XACE_CLIENT_ACCESS, SELinuxClient, NULL);
+ XaceDeleteCallback(XACE_EXT_ACCESS, SELinuxExtension, NULL);
+ XaceDeleteCallback(XACE_SERVER_ACCESS, SELinuxServer, NULL);
+ XaceDeleteCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
+ XaceDeleteCallback(XACE_SCREEN_ACCESS, SELinuxScreen, NULL);
+ XaceDeleteCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, truep);
+
+ /* Tear down SELinux stuff */
+ audit_close(audit_fd);
+ avc_netlink_release_fd();
+ RemoveBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
+ NULL);
+ RemoveGeneralSocket(netlink_fd);
+
+ avc_destroy();
+}
+
+void
+SELinuxFlaskInit(void)
+{
+ struct selinux_opt avc_option = { AVC_OPT_SETENFORCE, (char *)0 };
+ security_context_t ctx;
+ int ret = TRUE;
+
+ switch(selinuxEnforcingState) {
+ case SELINUX_MODE_ENFORCING:
+ LogMessage(X_INFO, "SELinux: Configured in enforcing mode\n");
+ avc_option.value = (char *)1;
+ break;
+ case SELINUX_MODE_PERMISSIVE:
+ LogMessage(X_INFO, "SELinux: Configured in permissive mode\n");
+ avc_option.value = (char *)0;
+ break;
+ default:
+ avc_option.type = AVC_OPT_UNUSED;
+ break;
+ }
+
+ /* Set up SELinux stuff */
+ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback)SELinuxLog);
+ selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback)SELinuxAudit);
+
+ if (selinux_set_mapping(map) < 0) {
+ if (errno == EINVAL) {
+ ErrorF("SELinux: Invalid object class mapping, disabling SELinux support.\n");
+ return;
+ }
+ FatalError("SELinux: Failed to set up security class mapping\n");
+ }
+
+ if (avc_open(&avc_option, 1) < 0)
+ FatalError("SELinux: Couldn't initialize SELinux userspace AVC\n");
+
+ if (security_get_initial_context_raw("unlabeled", &ctx) < 0)
+ FatalError("SELinux: Failed to look up unlabeled context\n");
+ if (avc_context_to_sid_raw(ctx, &unlabeled_sid) < 0)
+ FatalError("SELinux: a context_to_SID call failed!\n");
+ freecon(ctx);
+
+ /* Prepare for auditing */
+ audit_fd = audit_open();
+ if (audit_fd < 0)
+ FatalError("SELinux: Failed to open the system audit log\n");
+
+ /* Allocate private storage */
+ if (!dixRegisterPrivateKey(subjectKey, PRIVATE_XSELINUX, sizeof(SELinuxSubjectRec)) ||
+ !dixRegisterPrivateKey(objectKey, PRIVATE_XSELINUX, sizeof(SELinuxObjectRec)) ||
+ !dixRegisterPrivateKey(dataKey, PRIVATE_XSELINUX, sizeof(SELinuxObjectRec)))
+ FatalError("SELinux: Failed to allocate private storage.\n");
+
+ /* Create atoms for doing window labeling */
+ atom_ctx = MakeAtom("_SELINUX_CONTEXT", 16, TRUE);
+ if (atom_ctx == BAD_RESOURCE)
+ FatalError("SELinux: Failed to create atom\n");
+ atom_client_ctx = MakeAtom("_SELINUX_CLIENT_CONTEXT", 23, TRUE);
+ if (atom_client_ctx == BAD_RESOURCE)
+ FatalError("SELinux: Failed to create atom\n");
+
+ netlink_fd = avc_netlink_acquire_fd();
+ AddGeneralSocket(netlink_fd);
+ RegisterBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
+ NULL);
+
+ /* Register callbacks */
+ ret &= AddCallback(&ClientStateCallback, SELinuxClientState, NULL);
+ ret &= AddCallback(&ResourceStateCallback, SELinuxResourceState, NULL);
+
+ ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL);
+ ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL);
+ ret &= XaceRegisterCallback(XACE_DEVICE_ACCESS, SELinuxDevice, NULL);
+ ret &= XaceRegisterCallback(XACE_PROPERTY_ACCESS, SELinuxProperty, NULL);
+ ret &= XaceRegisterCallback(XACE_SEND_ACCESS, SELinuxSend, NULL);
+ ret &= XaceRegisterCallback(XACE_RECEIVE_ACCESS, SELinuxReceive, NULL);
+ ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SELinuxClient, NULL);
+ ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SELinuxExtension, NULL);
+ ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SELinuxServer, NULL);
+ ret &= XaceRegisterCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
+ ret &= XaceRegisterCallback(XACE_SCREEN_ACCESS, SELinuxScreen, NULL);
+ ret &= XaceRegisterCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, truep);
+ if (!ret)
+ FatalError("SELinux: Failed to register one or more callbacks\n");
+
+ /* Label objects that were created before we could register ourself */
+ SELinuxLabelInitial();
+}
diff --git a/xorg-server/Xext/xvmain.c b/xorg-server/Xext/xvmain.c
index f3b6d84b9..7cd900117 100644
--- a/xorg-server/Xext/xvmain.c
+++ b/xorg-server/Xext/xvmain.c
@@ -282,7 +282,7 @@ XvScreenInit(ScreenPtr pScreen)
/* ALLOCATE SCREEN PRIVATE RECORD */
- pxvs = malloc(sizeof (XvScreenRec));
+ pxvs = calloc (1,sizeof (XvScreenRec));
if (!pxvs)
{
ErrorF("XvScreenInit: Unable to allocate screen private structure\n");
@@ -316,7 +316,7 @@ XvCloseScreen(
pScreen->DestroyWindow = pxvs->DestroyWindow;
pScreen->CloseScreen = pxvs->CloseScreen;
- (* pxvs->ddCloseScreen)(ii, pScreen);
+ if (pxvs->ddCloseScreen) (* pxvs->ddCloseScreen)(ii, pScreen);
free(pxvs);