diff options
Diffstat (limited to 'Xext')
-rw-r--r-- | Xext/panoramiX.c | 266 | ||||
-rw-r--r-- | Xext/panoramiXprocs.c | 7 | ||||
-rw-r--r-- | Xext/panoramiXsrv.h | 2 | ||||
-rw-r--r-- | Xext/saver.c | 3 | ||||
-rw-r--r-- | Xext/security.c | 54 | ||||
-rw-r--r-- | Xext/xace.c | 42 | ||||
-rw-r--r-- | Xext/xace.h | 18 | ||||
-rw-r--r-- | Xext/xacestr.h | 9 | ||||
-rw-r--r-- | Xext/xf86bigfont.c | 8 | ||||
-rw-r--r-- | Xext/xselinux.c | 360 | ||||
-rw-r--r-- | Xext/xselinux.h | 3 |
11 files changed, 454 insertions, 318 deletions
diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c index 87d52a9db..086de46ce 100644 --- a/Xext/panoramiX.c +++ b/Xext/panoramiX.c @@ -81,9 +81,6 @@ static DepthPtr PanoramiXDepths; static int PanoramiXNumVisuals; static VisualPtr PanoramiXVisuals; -/* We support at most 256 visuals */ -_X_EXPORT XID *PanoramiXVisualTable = NULL; - _X_EXPORT unsigned long XRC_DRAWABLE; _X_EXPORT unsigned long XRT_WINDOW; _X_EXPORT unsigned long XRT_PIXMAP; @@ -463,10 +460,8 @@ void PanoramiXExtensionInit(int argc, char *argv[]) ProcPanoramiXDispatch, SProcPanoramiXDispatch, PanoramiXResetProc, StandardMinorOpcode); - if (!extEntry) { - ErrorF("PanoramiXExtensionInit(): failed to AddExtension\n"); + if (!extEntry) break; - } /* * First make sure all the basic allocations succeed. If not, @@ -514,7 +509,7 @@ void PanoramiXExtensionInit(int argc, char *argv[]) if (!success) { noPanoramiXExtension = TRUE; - ErrorF("%s Extension failed to initialize\n", PANORAMIX_PROTOCOL_NAME); + ErrorF(PANORAMIX_PROTOCOL_NAME " extension failed to initialize\n"); return; } @@ -604,14 +599,14 @@ Bool PanoramiXCreateConnectionBlock(void) */ if(!PanoramiXNumDepths) { - ErrorF("PanoramiX error: Incompatible screens. No common visuals\n"); + ErrorF("Xinerama error: No common visuals\n"); return FALSE; } for(i = 1; i < screenInfo.numScreens; i++) { pScreen = screenInfo.screens[i]; if(pScreen->rootDepth != screenInfo.screens[0]->rootDepth) { - ErrorF("PanoramiX error: Incompatible screens. Root window depths differ\n"); + ErrorF("Xinerama error: Root window depths differ\n"); return FALSE; } if(pScreen->backingStoreSupport != screenInfo.screens[0]->backingStoreSupport) @@ -704,143 +699,133 @@ Bool PanoramiXCreateConnectionBlock(void) return TRUE; } -extern -void PanoramiXConsolidate(void) +/* + * This isn't just memcmp(), bitsPerRGBValue is skipped. markv made that + * change way back before xf86 4.0, but the comment for _why_ is a bit + * opaque, so I'm not going to question it for now. + * + * This is probably better done as a screen hook so DBE/EVI/GLX can add + * their own tests, and adding privates to VisualRec so they don't have to + * do their own back-mapping. + */ +static Bool +VisualsEqual(VisualPtr a, VisualPtr b) { - int i, j, k; - VisualPtr pVisual, pVisual2; - ScreenPtr pScreen, pScreen2; - DepthPtr pDepth, pDepth2; - PanoramiXRes *root, *defmap, *saver; - Bool foundDepth, missingDepth; - - if(!PanoramiXVisualTable) - PanoramiXVisualTable = xcalloc(256 * MAXSCREENS, sizeof(XID)); - - pScreen = screenInfo.screens[0]; - pVisual = pScreen->visuals; - pDepth = pScreen->allowedDepths; + return ((a->class == b->class) && + (a->ColormapEntries == b->ColormapEntries) && + (a->nplanes == b->nplanes) && + (a->redMask == b->redMask) && + (a->greenMask == b->greenMask) && + (a->blueMask == b->blueMask) && + (a->offsetRed == b->offsetRed) && + (a->offsetGreen == b->offsetGreen) && + (a->offsetBlue == b->offsetBlue)); +} - PanoramiXNumDepths = 0; - PanoramiXDepths = xcalloc(pScreen->numDepths,sizeof(DepthRec)); - PanoramiXNumVisuals = 0; - PanoramiXVisuals = xcalloc(pScreen->numVisuals,sizeof(VisualRec)); - - for (i = 0; i < pScreen->numDepths; i++, pDepth++) { - missingDepth = FALSE; - for (j = 1; j < PanoramiXNumScreens; j++) { - pScreen2 = screenInfo.screens[j]; - pDepth2 = pScreen2->allowedDepths; - - foundDepth = FALSE; - for (k = 0; k < pScreen2->numDepths; k++, pDepth2++) { - if(pDepth2->depth == pDepth->depth) { - foundDepth = TRUE; - break; - } - } - - if(!foundDepth) { - missingDepth = TRUE; - break; - } - } - - if(!missingDepth) { - PanoramiXDepths[PanoramiXNumDepths].depth = pDepth->depth; - PanoramiXDepths[PanoramiXNumDepths].numVids = 0; - if(pDepth->numVids) - PanoramiXDepths[PanoramiXNumDepths].vids = - xalloc(sizeof(VisualID) * pDepth->numVids); - else - PanoramiXDepths[PanoramiXNumDepths].vids = NULL; - PanoramiXNumDepths++; - } +static void +PanoramiXMaybeAddDepth(DepthPtr pDepth) +{ + ScreenPtr pScreen; + int j, k; + Bool found = FALSE; + + for (j = 1; j < PanoramiXNumScreens; j++) { + pScreen = screenInfo.screens[j]; + for (k = 0; k < pScreen->numDepths; k++) { + if (pScreen->allowedDepths[k].depth == pDepth->depth) { + found = TRUE; + break; + } + } } - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - PanoramiXVisualTable[pVisual->vid * MAXSCREENS] = pVisual->vid; + if (!found) + return; - /* check if the visual exists on all screens */ - for (j = 1; j < PanoramiXNumScreens; j++) { - pScreen2 = screenInfo.screens[j]; + j = PanoramiXNumDepths; + PanoramiXNumDepths++; + PanoramiXDepths = xrealloc(PanoramiXDepths, + PanoramiXNumDepths * sizeof(DepthRec)); + PanoramiXDepths[j].depth = pDepth->depth; + PanoramiXDepths[j].numVids = 0; + /* XXX suboptimal, should grow these dynamically */ + if(pDepth->numVids) + PanoramiXDepths[j].vids = xalloc(sizeof(VisualID) * pDepth->numVids); + else + PanoramiXDepths[j].vids = NULL; +} +static void +PanoramiXMaybeAddVisual(VisualPtr pVisual) +{ + ScreenPtr pScreen; + VisualPtr candidate = NULL; + int j, k; + Bool found = FALSE; + + for (j = 1; j < PanoramiXNumScreens; j++) { + pScreen = screenInfo.screens[j]; + found = FALSE; + + candidate = pScreen->visuals; + for (k = 0; k < pScreen->numVisuals; k++) { + candidate++; + if (VisualsEqual(pVisual, candidate) #ifdef GLXPROXY - pVisual2 = glxMatchVisual(pScreen, pVisual, pScreen2); - if (pVisual2) { - PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] = - pVisual2->vid; - continue; - } else if (glxMatchVisual(pScreen, pVisual, pScreen)) { - PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] = 0; - break; - } + && glxMatchVisual(screenInfo.screens[0], pVisual, pScreen) #endif - pVisual2 = pScreen2->visuals; - - for (k = 0; k < pScreen2->numVisuals; k++, pVisual2++) { - if ((pVisual->class == pVisual2->class) && - (pVisual->ColormapEntries == pVisual2->ColormapEntries) && - (pVisual->nplanes == pVisual2->nplanes) && - (pVisual->redMask == pVisual2->redMask) && - (pVisual->greenMask == pVisual2->greenMask) && - (pVisual->blueMask == pVisual2->blueMask) && - (pVisual->offsetRed == pVisual2->offsetRed) && - (pVisual->offsetGreen == pVisual2->offsetGreen) && - (pVisual->offsetBlue == pVisual2->offsetBlue)) - { - /* We merely assign the first visual that matches. OpenGL - will need to get involved at some point if you want - match GLX visuals */ - PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] = - pVisual2->vid; - break; - } - } - } - - /* if it doesn't exist on all screens we can't use it */ - for (j = 0; j < PanoramiXNumScreens; j++) { - if (!PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j]) { - PanoramiXVisualTable[pVisual->vid * MAXSCREENS] = 0; + ) { + found = TRUE; break; } } - /* if it does, make sure it's in the list of supported depths and visuals */ - if(PanoramiXVisualTable[pVisual->vid * MAXSCREENS]) { - PanoramiXVisuals[PanoramiXNumVisuals].vid = pVisual->vid; - PanoramiXVisuals[PanoramiXNumVisuals].class = pVisual->class; - PanoramiXVisuals[PanoramiXNumVisuals].bitsPerRGBValue = pVisual->bitsPerRGBValue; - PanoramiXVisuals[PanoramiXNumVisuals].ColormapEntries = pVisual->ColormapEntries; - PanoramiXVisuals[PanoramiXNumVisuals].nplanes = pVisual->nplanes; - PanoramiXVisuals[PanoramiXNumVisuals].redMask = pVisual->redMask; - PanoramiXVisuals[PanoramiXNumVisuals].greenMask = pVisual->greenMask; - PanoramiXVisuals[PanoramiXNumVisuals].blueMask = pVisual->blueMask; - PanoramiXVisuals[PanoramiXNumVisuals].offsetRed = pVisual->offsetRed; - PanoramiXVisuals[PanoramiXNumVisuals].offsetGreen = pVisual->offsetGreen; - PanoramiXVisuals[PanoramiXNumVisuals].offsetBlue = pVisual->offsetBlue; - PanoramiXNumVisuals++; - - for (j = 0; j < PanoramiXNumDepths; j++) { - if (PanoramiXDepths[j].depth == pVisual->nplanes) { - PanoramiXDepths[j].vids[PanoramiXDepths[j].numVids] = pVisual->vid; - PanoramiXDepths[j].numVids++; - break; - } - } - } - } + if (!found) + return; + } + + /* found a matching visual on all screens, add it to the subset list */ + j = PanoramiXNumVisuals; + PanoramiXNumVisuals++; + PanoramiXVisuals = xrealloc(PanoramiXVisuals, + PanoramiXNumVisuals * sizeof(VisualRec)); + + memcpy(&PanoramiXVisuals[j], pVisual, sizeof(VisualRec)); + + for (k = 0; k < PanoramiXNumDepths; k++) { + if (PanoramiXDepths[k].depth == pVisual->nplanes) { + PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid; + PanoramiXDepths[k].numVids++; + break; + } + } +} + +extern void +PanoramiXConsolidate(void) +{ + int i; + PanoramiXRes *root, *defmap, *saver; + ScreenPtr pScreen = screenInfo.screens[0]; + DepthPtr pDepth = pScreen->allowedDepths; + VisualPtr pVisual = pScreen->visuals; + + PanoramiXNumDepths = 0; + PanoramiXNumVisuals = 0; + for (i = 0; i < pScreen->numDepths; i++) + PanoramiXMaybeAddDepth(pDepth++); - root = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes)); + for (i = 0; i < pScreen->numVisuals; i++) + PanoramiXMaybeAddVisual(pVisual++); + + root = xalloc(sizeof(PanoramiXRes)); root->type = XRT_WINDOW; - defmap = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes)); + defmap = xalloc(sizeof(PanoramiXRes)); defmap->type = XRT_COLORMAP; - saver = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes)); + saver = xalloc(sizeof(PanoramiXRes)); saver->type = XRT_WINDOW; - for (i = 0; i < PanoramiXNumScreens; i++) { root->info[i].id = WindowTable[i]->drawable.id; root->u.win.class = InputOutput; @@ -856,6 +841,31 @@ void PanoramiXConsolidate(void) AddResource(defmap->info[0].id, XRT_COLORMAP, defmap); } +_X_EXPORT VisualID +PanoramiXTranslateVisualID(int screen, VisualID orig) +{ + VisualPtr pVisual = NULL; + int i, j; + + for (i = 0; i < PanoramiXNumVisuals; i++) { + if (orig == PanoramiXVisuals[i].vid) { + pVisual = &PanoramiXVisuals[i]; + break; + } + } + + if (!pVisual) + return 0; + + /* found the original, now translate it relative to the backend screen */ + for (i = 0; i < PanoramiXNumScreens; i++) + for (j = 0; j < screenInfo.screens[i]->numVisuals; j++) + if (VisualsEqual(pVisual, &screenInfo.screens[i]->visuals[j])) + return screenInfo.screens[i]->visuals[j].vid; + + return 0; +} + /* * PanoramiXResetProc() diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c index f9a579625..d19b3039a 100644 --- a/Xext/panoramiXprocs.c +++ b/Xext/panoramiXprocs.c @@ -150,7 +150,7 @@ int PanoramiXCreateWindow(ClientPtr client) if (cmap) *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id; if ( orig_visual != CopyFromParent ) - stuff->visual = PanoramiXVisualTable[(orig_visual*MAXSCREENS) + j]; + stuff->visual = PanoramiXTranslateVisualID(j, orig_visual); result = (*SavedProcVector[X_CreateWindow])(client); if(result != Success) break; } @@ -2077,9 +2077,6 @@ int PanoramiXCreateColormap(ClientPtr client) client, stuff->window, XRT_WINDOW, DixReadAccess))) return BadWindow; - if(!stuff->visual || (stuff->visual > 255)) - return BadValue; - if(!(newCmap = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes)))) return BadAlloc; @@ -2092,7 +2089,7 @@ int PanoramiXCreateColormap(ClientPtr client) FOR_NSCREENS_BACKWARD(j){ stuff->mid = newCmap->info[j].id; stuff->window = win->info[j].id; - stuff->visual = PanoramiXVisualTable[(orig_visual * MAXSCREENS) + j]; + stuff->visual = PanoramiXTranslateVisualID(j, orig_visual); result = (* SavedProcVector[X_CreateColormap])(client); if(result != Success) break; } diff --git a/Xext/panoramiXsrv.h b/Xext/panoramiXsrv.h index ae9024418..6d556e963 100644 --- a/Xext/panoramiXsrv.h +++ b/Xext/panoramiXsrv.h @@ -12,8 +12,8 @@ extern int PanoramiXNumScreens; extern PanoramiXData *panoramiXdataPtr; extern int PanoramiXPixWidth; extern int PanoramiXPixHeight; -extern XID *PanoramiXVisualTable; +extern VisualID PanoramiXTranslateVisualID(int screen, VisualID orig); extern void PanoramiXConsolidate(void); extern Bool PanoramiXCreateConnectionBlock(void); extern PanoramiXRes * PanoramiXFindIDByScrnum(RESTYPE, XID, int); diff --git a/Xext/saver.c b/Xext/saver.c index d4786b9b8..69a5fa140 100644 --- a/Xext/saver.c +++ b/Xext/saver.c @@ -1346,8 +1346,7 @@ ProcScreenSaverSetAttributes (ClientPtr client) *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id; if (orig_visual != CopyFromParent) - stuff->visualID = - PanoramiXVisualTable[(orig_visual*MAXSCREENS) + i]; + stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual); status = ScreenSaverSetAttributes(client); } diff --git a/Xext/security.c b/Xext/security.c index 914cec2f7..427be2f0c 100644 --- a/Xext/security.c +++ b/Xext/security.c @@ -29,6 +29,9 @@ in this Software without prior written authorization from The Open Group. #endif #include "scrnintstr.h" +#include "inputstr.h" +#include "windowstr.h" +#include "propertyst.h" #include "colormapst.h" #include "privates.h" #include "registry.h" @@ -67,10 +70,19 @@ static char *SecurityUntrustedExtensions[] = { NULL }; -/* Access modes that untrusted clients can do to trusted stuff */ -static const Mask SecurityAllowedMask = - DixGetAttrAccess | DixListPropAccess | DixGetPropAccess | - DixGetFocusAccess | DixListAccess | DixReceiveAccess; +/* + * Access modes that untrusted clients are allowed on trusted objects. + */ +static const Mask SecurityResourceMask = + DixGetAttrAccess | DixReceiveAccess | DixListPropAccess | + DixGetPropAccess | DixListAccess; +static const Mask SecurityRootWindowExtraMask = + DixReceiveAccess | DixSendAccess | DixAddAccess | DixRemoveAccess; +static const Mask SecurityDeviceMask = + DixGetAttrAccess | DixReceiveAccess | DixGetFocusAccess | + DixGrabAccess | DixSetAttrAccess | DixUseAccess; +static const Mask SecurityServerMask = DixGetAttrAccess | DixGrabAccess; +static const Mask SecurityClientMask = DixGetAttrAccess; /* SecurityAudit @@ -748,11 +760,15 @@ SecurityDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata) XaceDeviceAccessRec *rec = calldata; SecurityStateRec *subj, *obj; Mask requested = rec->access_mode; - Mask allowed = SecurityAllowedMask; + Mask allowed = SecurityDeviceMask; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); obj = dixLookupPrivate(&serverClient->devPrivates, stateKey); + if (rec->dev != inputInfo.keyboard) + /* this extension only supports the core keyboard */ + allowed = requested; + if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { SecurityAudit("Security denied client %d keyboard access on request " "%s\n", rec->client->index, @@ -789,20 +805,29 @@ SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) SecurityStateRec *subj, *obj; int cid = CLIENT_ID(rec->id); Mask requested = rec->access_mode; - Mask allowed = SecurityAllowedMask; + Mask allowed = SecurityResourceMask; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); obj = dixLookupPrivate(&clients[cid]->devPrivates, stateKey); + /* disable background None for untrusted windows */ + if ((requested & DixCreateAccess) && (rec->rtype == RT_WINDOW)) + if (subj->haveState && subj->trustLevel != XSecurityClientTrusted) + ((WindowPtr)rec->res)->forcedBG = TRUE; + /* special checks for server-owned resources */ if (cid == 0) { if (rec->rtype & RC_DRAWABLE) /* additional operations allowed on root windows */ - allowed |= DixReadAccess|DixSendAccess; + allowed |= SecurityRootWindowExtraMask; else if (rec->rtype == RT_COLORMAP) /* allow access to default colormaps */ allowed = requested; + + else + /* allow read access to other server-owned resources */ + allowed |= DixReadAccess; } if (SecurityDoCheck(subj, obj, requested, allowed) == Success) @@ -813,9 +838,10 @@ SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) return; #endif - SecurityAudit("Security: denied client %d access to resource 0x%x " - "of client %d on request %s\n", rec->client->index, rec->id, - cid, SecurityLookupRequestName(rec->client)); + SecurityAudit("Security: denied client %d access %x to resource 0x%x " + "of client %d on request %s\n", rec->client->index, + requested, rec->id, cid, + SecurityLookupRequestName(rec->client)); rec->status = BadAccess; /* deny access */ } @@ -847,7 +873,7 @@ SecurityServer(CallbackListPtr *pcbl, pointer unused, pointer calldata) XaceServerAccessRec *rec = calldata; SecurityStateRec *subj, *obj; Mask requested = rec->access_mode; - Mask allowed = SecurityAllowedMask; + Mask allowed = SecurityServerMask; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); obj = dixLookupPrivate(&serverClient->devPrivates, stateKey); @@ -866,7 +892,7 @@ SecurityClient(CallbackListPtr *pcbl, pointer unused, pointer calldata) XaceClientAccessRec *rec = calldata; SecurityStateRec *subj, *obj; Mask requested = rec->access_mode; - Mask allowed = SecurityAllowedMask; + Mask allowed = SecurityClientMask; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); obj = dixLookupPrivate(&rec->target->devPrivates, stateKey); @@ -886,7 +912,7 @@ SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) SecurityStateRec *subj, *obj; ATOM name = rec->pProp->propertyName; Mask requested = rec->access_mode; - Mask allowed = SecurityAllowedMask | DixReadAccess; + Mask allowed = SecurityResourceMask | DixReadAccess; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey); @@ -1079,6 +1105,8 @@ SecurityExtensionInit(INITARGS) return; RTEventClient |= RC_NEVERRETAIN; + RegisterResourceName(SecurityAuthorizationResType, "SecurityAuthorization"); + RegisterResourceName(RTEventClient, "SecurityEventClient"); /* Allocate the private storage */ if (!dixRequestPrivate(stateKey, sizeof(SecurityStateRec))) diff --git a/Xext/xace.c b/Xext/xace.c index 0470e44dd..e88debc5f 100644 --- a/Xext/xace.c +++ b/Xext/xace.c @@ -23,6 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <stdarg.h> #include "scrnintstr.h" +#include "extnsionst.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "gcstruct.h" #include "xacestr.h" CallbackListPtr XaceHooks[XACE_NUM_HOOKS] = {0}; @@ -51,6 +55,21 @@ int XaceHookDispatch(ClientPtr client, int major) } } +int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin, + PropertyPtr pProp, Mask access_mode) +{ + XacePropertyAccessRec rec = { client, pWin, pProp, access_mode, Success }; + CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec); + return rec.status; +} + +int XaceHookSelectionAccess(ClientPtr client, Atom name, Mask access_mode) +{ + XaceSelectionAccessRec rec = { client, name, access_mode, Success }; + CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec); + return rec.status; +} + void XaceHookAuditEnd(ClientPtr ptr, int result) { XaceAuditRec rec = { ptr, result }; @@ -100,18 +119,6 @@ int XaceHook(int hook, ...) prv = &rec.status; break; } - case XACE_PROPERTY_ACCESS: { - XacePropertyAccessRec rec = { - va_arg(ap, ClientPtr), - va_arg(ap, WindowPtr), - va_arg(ap, PropertyPtr), - va_arg(ap, Mask), - Success /* default allow */ - }; - calldata = &rec; - prv = &rec.status; - break; - } case XACE_SEND_ACCESS: { XaceSendAccessRec rec = { va_arg(ap, ClientPtr), @@ -169,17 +176,6 @@ int XaceHook(int hook, ...) prv = &rec.status; break; } - case XACE_SELECTION_ACCESS: { - XaceSelectionAccessRec rec = { - va_arg(ap, ClientPtr), - va_arg(ap, Atom), - va_arg(ap, Mask), - Success /* default allow */ - }; - calldata = &rec; - prv = &rec.status; - break; - } case XACE_SCREEN_ACCESS: case XACE_SCREENSAVER_ACCESS: { XaceScreenAccessRec rec = { diff --git a/Xext/xace.h b/Xext/xace.h index 4100ba16e..1f07d9fd2 100644 --- a/Xext/xace.h +++ b/Xext/xace.h @@ -25,11 +25,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XACE_MAJOR_VERSION 2 #define XACE_MINOR_VERSION 0 -#include "pixmap.h" /* for DrawablePtr */ -#include "regionstr.h" /* for RegionPtr */ +#include "pixmap.h" +#include "region.h" +#include "window.h" +#include "property.h" /* Default window background */ -#define XaceBackgroundNoneState None +#define XaceBackgroundNoneState(w) ((w)->forcedBG ? BackgroundPixel : None) /* security hooks */ /* Constants used to identify the available security hooks @@ -65,6 +67,10 @@ extern int XaceHook( /* Special-cased hook functions */ extern int XaceHookDispatch(ClientPtr ptr, int major); +extern int XaceHookPropertyAccess(ClientPtr ptr, WindowPtr pWin, + PropertyPtr pProp, Mask access_mode); +extern int XaceHookSelectionAccess(ClientPtr ptr, Atom name, + Mask access_mode); extern void XaceHookAuditEnd(ClientPtr ptr, int result); /* Register a callback for a given hook. @@ -94,18 +100,22 @@ extern void XaceCensorImage( #else /* XACE */ /* Default window background */ -#define XaceBackgroundNoneState None +#define XaceBackgroundNoneState(w) None /* Define calls away when XACE is not being built. */ #ifdef __GNUC__ #define XaceHook(args...) Success #define XaceHookDispatch(args...) Success +#define XaceHookPropertyAccess(args...) Success +#define XaceHookSelectionAccess(args...) Success #define XaceHookAuditEnd(args...) { ; } #define XaceCensorImage(args...) { ; } #else #define XaceHook(...) Success #define XaceHookDispatch(...) Success +#define XaceHookPropertyAccess(...) Success +#define XaceHookSelectionAccess(...) Success #define XaceHookAuditEnd(...) { ; } #define XaceCensorImage(...) { ; } #endif diff --git a/Xext/xacestr.h b/Xext/xacestr.h index 045f8364f..e31d4246a 100644 --- a/Xext/xacestr.h +++ b/Xext/xacestr.h @@ -20,13 +20,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _XACESTR_H #define _XACESTR_H -#include "dixstruct.h" +#include "dix.h" #include "resource.h" #include "extnsionst.h" -#include "gcstruct.h" -#include "windowstr.h" -#include "inputstr.h" -#include "propertyst.h" +#include "window.h" +#include "input.h" +#include "property.h" #include "selection.h" #include "xace.h" diff --git a/Xext/xf86bigfont.c b/Xext/xf86bigfont.c index 779f3b940..d5c5704de 100644 --- a/Xext/xf86bigfont.c +++ b/Xext/xf86bigfont.c @@ -236,15 +236,15 @@ shmalloc( size = (size + pagesize-1) & -pagesize; shmid = shmget(IPC_PRIVATE, size, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); if (shmid == -1) { - ErrorF(XF86BIGFONTNAME " extension: shmget() failed, size = %u, errno = %d\n", - size, errno); + ErrorF(XF86BIGFONTNAME " extension: shmget() failed, size = %u, %s\n", + size, strerror(errno)); xfree(pDesc); return (ShmDescPtr) NULL; } if ((addr = shmat(shmid, 0, 0)) == (char *)-1) { - ErrorF(XF86BIGFONTNAME " extension: shmat() failed, size = %u, errno = %d\n", - size, errno); + ErrorF(XF86BIGFONTNAME " extension: shmat() failed, size = %u, %s\n", + size, strerror(errno)); shmctl(shmid, IPC_RMID, (void *) 0); xfree(pDesc); return (ShmDescPtr) NULL; diff --git a/Xext/xselinux.c b/Xext/xselinux.c index a6e27e695..98e1ec563 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -22,21 +22,28 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * All rights reserved. */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <sys/socket.h> +#include <stdio.h> +#include <stdarg.h> + #include <selinux/selinux.h> #include <selinux/label.h> #include <selinux/avc.h> #include <libaudit.h> -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - #include <X11/Xatom.h> #include "resource.h" #include "privates.h" #include "registry.h" #include "dixstruct.h" +#include "inputstr.h" +#include "windowstr.h" +#include "propertyst.h" #include "extnsionst.h" #include "scrnintstr.h" #include "selection.h" @@ -46,8 +53,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define TRANS_SERVER #include <X11/Xtrans/Xtrans.h> #include "../os/osdep.h" -#include <stdio.h> -#include <stdarg.h> #include "modinit.h" @@ -56,7 +61,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* private state record */ -static DevPrivateKey stateKey = &stateKey; +static DevPrivateKey subjectKey = &subjectKey; +static DevPrivateKey objectKey = &objectKey; /* This is what we store for security state */ typedef struct { @@ -64,7 +70,12 @@ typedef struct { struct avc_entry_ref aeref; char *command; int privileged; -} SELinuxStateRec; +} SELinuxSubjectRec; + +typedef struct { + security_id_t sid; + int poly; +} SELinuxObjectRec; /* selection manager */ typedef struct { @@ -81,6 +92,7 @@ static int audit_fd; /* 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 */ @@ -122,11 +134,11 @@ static struct security_class_mapping map[] = { { "x_gc", { "", "", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_font", { "", "", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_glyph", "remove_glyph", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_colormap", { "read", "write", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_color", "remove_color", "", "", "", "", "", "", "install", "uninstall", "", "", "use", NULL }}, - { "x_property", { "read", "write", "destroy", "create", NULL }}, + { "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", NULL }}, { "x_selection", { "read", "", "", "", "getattr", "setattr", NULL }}, { "x_cursor", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_client", { "", "", "destroy", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "manage", NULL }}, - { "x_device", { "read", "write", "", "", "getattr", "setattr", "", "", "", "getfocus", "setfocus", "", "", "", "", "", "", "grab", "freeze", "force_cursor", "", "", "", "", "", "manage", "", "bell", NULL }}, + { "x_device", { "read", "write", "", "", "getattr", "setattr", "", "", "", "getfocus", "setfocus", "", "", "", "", "", "", "grab", "freeze", "force_cursor", "", "", "", "", "use", "manage", "", "bell", NULL }}, { "x_server", { "record", "", "", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "grab", "", "", "", "", "", "", "", "manage", "debug", NULL }}, { "x_extension", { "", "", "", "", "query", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_event", { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "send", "receive", NULL }}, @@ -150,7 +162,7 @@ static pointer truep = (pointer)1; * Looks up the SID corresponding to the given selection atom */ static int -SELinuxSelectionToSID(Atom selection, SELinuxStateRec *sid_return) +SELinuxSelectionToSID(Atom selection, SELinuxObjectRec *sid_return) { const char *name; unsigned i, size; @@ -197,7 +209,7 @@ SELinuxSelectionToSID(Atom selection, SELinuxStateRec *sid_return) */ static int SELinuxEventToSID(unsigned type, security_id_t sid_of_window, - SELinuxStateRec *sid_return) + SELinuxObjectRec *sid_return) { const char *name = LookupEventName(type); security_context_t con; @@ -288,7 +300,7 @@ SELinuxTypeToClass(RESTYPE type) * Performs an SELinux permission check. */ static int -SELinuxDoCheck(SELinuxStateRec *subj, SELinuxStateRec *obj, +SELinuxDoCheck(SELinuxSubjectRec *subj, SELinuxObjectRec *obj, security_class_t class, Mask mode, SELinuxAuditRec *auditdata) { /* serverClient requests OK */ @@ -300,9 +312,11 @@ SELinuxDoCheck(SELinuxStateRec *subj, SELinuxStateRec *obj, 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("ServerPerm: unexpected error %d\n", errno); + ErrorF("SELinux: avc_has_perm: unexpected error %d\n", errno); return BadValue; } @@ -316,11 +330,14 @@ static void SELinuxLabelClient(ClientPtr client) { XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn; - SELinuxStateRec *state; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; security_context_t ctx; - state = dixLookupPrivate(&client->devPrivates, stateKey); - sidput(state->sid); + subj = dixLookupPrivate(&client->devPrivates, subjectKey); + sidput(subj->sid); + obj = dixLookupPrivate(&client->devPrivates, objectKey); + sidput(obj->sid); if (_XSERVTransIsLocal(ci)) { int fd = _XSERVTransGetConnectionNumber(ci); @@ -331,7 +348,7 @@ SELinuxLabelClient(ClientPtr client) /* For local clients, can get context from the socket */ if (getpeercon(fd, &ctx) < 0) - FatalError("Client %d: couldn't get context from socket\n", + FatalError("SELinux: client %d: couldn't get context from socket\n", client->index); /* Try and determine the client's executable name */ @@ -349,24 +366,25 @@ SELinuxLabelClient(ClientPtr client) if (bytes <= 0) goto finish; - state->command = xalloc(bytes); - if (!state->command) + subj->command = xalloc(bytes); + if (!subj->command) goto finish; - memcpy(state->command, path, bytes); - state->command[bytes - 1] = 0; + memcpy(subj->command, path, bytes); + subj->command[bytes - 1] = 0; } else /* For remote clients, need to use a default context */ if (selabel_lookup(label_hnd, &ctx, NULL, SELABEL_X_CLIENT) < 0) - FatalError("Client %d: couldn't get default remote context\n", - client->index); + FatalError("SELinux: failed to look up remote-client context\n"); finish: /* Get a SID from the context */ - if (avc_context_to_sid(ctx, &state->sid) < 0) - FatalError("Client %d: context_to_sid(%s) failed\n", + if (avc_context_to_sid(ctx, &subj->sid) < 0) + FatalError("SELinux: client %d: context_to_sid(%s) failed\n", client->index, ctx); + sidget(subj->sid); + obj->sid = subj->sid; freecon(ctx); } @@ -378,23 +396,27 @@ SELinuxLabelInitial(void) { int i; XaceScreenAccessRec srec; - SELinuxStateRec *state; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; security_context_t ctx; pointer unused; /* Do the serverClient */ - state = dixLookupPrivate(&serverClient->devPrivates, stateKey); - state->privileged = 1; - sidput(state->sid); + subj = dixLookupPrivate(&serverClient->devPrivates, subjectKey); + obj = dixLookupPrivate(&serverClient->devPrivates, objectKey); + subj->privileged = 1; + sidput(subj->sid); /* Use the context of the X server process for the serverClient */ if (getcon(&ctx) < 0) - FatalError("Couldn't get context of X server process\n"); + FatalError("SELinux: couldn't get context of X server process\n"); /* Get a SID from the context */ - if (avc_context_to_sid(ctx, &state->sid) < 0) - FatalError("serverClient: context_to_sid(%s) failed\n", ctx); + if (avc_context_to_sid(ctx, &subj->sid) < 0) + FatalError("SELinux: serverClient: context_to_sid(%s) failed\n", ctx); + sidget(subj->sid); + obj->sid = subj->sid; freecon(ctx); srec.client = serverClient; @@ -441,11 +463,15 @@ SELinuxAudit(void *auditdata, 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", + 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=" : "", @@ -482,20 +508,27 @@ static void SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceDeviceAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj; - SELinuxAuditRec auditdata = { .client = rec->client }; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; + SELinuxAuditRec auditdata = { .client = rec->client, .dev = rec->dev }; int rc; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&rec->dev->devPrivates, stateKey); + 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); + + sidput(dsubj->sid); sidput(obj->sid); /* Label the device directly with the process SID */ sidget(subj->sid); obj->sid = subj->sid; + sidget(subj->sid); + dsubj->sid = subj->sid; } rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DEVICE, rec->access_mode, @@ -508,17 +541,18 @@ static void SELinuxSend(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceSendAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj, ev_sid; - SELinuxAuditRec auditdata = { .client = rec->client }; + 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, stateKey); + subj = dixLookupPrivate(&rec->dev->devPrivates, subjectKey); else - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); - obj = dixLookupPrivate(&rec->pWin->devPrivates, stateKey); + obj = dixLookupPrivate(&rec->pWin->devPrivates, objectKey); /* Check send permission on window */ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DRAWABLE, DixSendAccess, @@ -549,13 +583,14 @@ static void SELinuxReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceReceiveAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj, ev_sid; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj, ev_sid; SELinuxAuditRec auditdata = { .client = NULL }; security_class_t class; int rc, i, type; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&rec->pWin->devPrivates, stateKey); + 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, @@ -586,12 +621,13 @@ static void SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceExtAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj, *serv; + SELinuxSubjectRec *subj, *serv; + SELinuxObjectRec *obj; SELinuxAuditRec auditdata = { .client = rec->client }; int rc; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&rec->ext->devPrivates, stateKey); + 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 */ @@ -600,9 +636,9 @@ SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata) security_context_t con; security_id_t sid; - serv = dixLookupPrivate(&serverClient->devPrivates, stateKey); + serv = dixLookupPrivate(&serverClient->devPrivates, subjectKey); - /* Look in the mappings of property names to contexts */ + /* Look in the mappings of extension names to contexts */ if (selabel_lookup(label_hnd, &con, name, SELABEL_X_EXT) < 0) { ErrorF("SELinux: a property label lookup failed!\n"); rec->status = BadValue; @@ -640,12 +676,13 @@ static void SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XacePropertyAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; SELinuxAuditRec auditdata = { .client = rec->client }; int rc; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&rec->pProp->devPrivates, stateKey); + subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); + obj = dixLookupPrivate(&rec->pProp->devPrivates, objectKey); /* If this is a new object that needs labeling, do it now */ if (rec->access_mode & DixCreateAccess) { @@ -691,13 +728,15 @@ static void SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceResourceAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj, *pobj; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj, *sobj, *pobj; SELinuxAuditRec auditdata = { .client = rec->client }; PrivateRec **privatePtr; security_class_t class; int rc, offset; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); + sobj = dixLookupPrivate(&rec->client->devPrivates, objectKey); /* Determine if the resource object has a devPrivates field */ offset = dixLookupPrivateOffset(rec->rtype); @@ -705,12 +744,12 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) /* No: use the SID of the owning client */ class = SECCLASS_X_RESOURCE; privatePtr = &clients[CLIENT_ID(rec->id)]->devPrivates; - obj = dixLookupPrivate(privatePtr, stateKey); + 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, stateKey); + obj = dixLookupPrivate(privatePtr, objectKey); } /* If this is a new object that needs labeling, do it now */ @@ -719,10 +758,10 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) offset = dixLookupPrivateOffset(rec->ptype); if (rec->parent && offset >= 0) /* Use the SID of the parent object in the labeling operation */ - pobj = dixLookupPrivate(DEVPRIV_AT(rec->parent, offset), stateKey); + pobj = dixLookupPrivate(DEVPRIV_AT(rec->parent, offset), objectKey); else /* Use the SID of the subject */ - pobj = subj; + pobj = sobj; sidput(obj->sid); @@ -746,13 +785,14 @@ static void SELinuxScreen(CallbackListPtr *pcbl, pointer is_saver, pointer calldata) { XaceScreenAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; SELinuxAuditRec auditdata = { .client = rec->client }; Mask access_mode = rec->access_mode; int rc; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&rec->screen->devPrivates, stateKey); + 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) { @@ -779,12 +819,13 @@ static void SELinuxClient(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceClientAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; SELinuxAuditRec auditdata = { .client = rec->client }; int rc; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&rec->target->devPrivates, stateKey); + subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); + obj = dixLookupPrivate(&rec->target->devPrivates, objectKey); rc = SELinuxDoCheck(subj, obj, SECCLASS_X_CLIENT, rec->access_mode, &auditdata); @@ -796,12 +837,13 @@ static void SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceServerAccessRec *rec = calldata; - SELinuxStateRec *subj, *obj; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; SELinuxAuditRec auditdata = { .client = rec->client }; int rc; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&serverClient->devPrivates, stateKey); + subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); + obj = dixLookupPrivate(&serverClient->devPrivates, objectKey); rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SERVER, rec->access_mode, &auditdata); @@ -813,11 +855,12 @@ static void SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceSelectionAccessRec *rec = (XaceSelectionAccessRec *)calldata; - SELinuxStateRec *subj, sel_sid; + SELinuxSubjectRec *subj; + SELinuxObjectRec sel_sid; SELinuxAuditRec auditdata = { .client = rec->client }; int rc; - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); rc = SELinuxSelectionToSID(rec->name, &sel_sid); if (rc != Success) { @@ -864,18 +907,19 @@ static void SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata) { ResourceStateInfoRec *rec = calldata; - SELinuxStateRec *state; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; WindowPtr pWin; if (rec->type != RT_WINDOW) return; pWin = (WindowPtr)rec->value; - state = dixLookupPrivate(&wClient(pWin)->devPrivates, stateKey); + subj = dixLookupPrivate(&wClient(pWin)->devPrivates, subjectKey); - if (state->sid) { + if (subj->sid) { security_context_t ctx; - int rc = avc_sid_to_context(state->sid, &ctx); + int rc = avc_sid_to_context(subj->sid, &ctx); if (rc < 0) FatalError("SELinux: Failed to get security context!\n"); rc = dixChangeWindowProperty(serverClient, @@ -887,11 +931,11 @@ SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata) } else FatalError("SELinux: Unexpected unlabeled client found\n"); - state = dixLookupPrivate(&pWin->devPrivates, stateKey); + obj = dixLookupPrivate(&pWin->devPrivates, objectKey); - if (state->sid) { + if (obj->sid) { security_context_t ctx; - int rc = avc_sid_to_context(state->sid, &ctx); + int rc = avc_sid_to_context(obj->sid, &ctx); if (rc < 0) FatalError("SELinux: Failed to get security context!\n"); rc = dixChangeWindowProperty(serverClient, @@ -908,41 +952,11 @@ static void SELinuxSelectionState(CallbackListPtr *pcbl, pointer unused, pointer calldata) { SelectionInfoRec *rec = calldata; - SELinuxStateRec *subj, *obj; switch (rec->kind) { case SelectionSetOwner: - /* save off the "real" owner of the selection */ - rec->selection->alt_client = rec->selection->client; - rec->selection->alt_window = rec->selection->window; - - /* figure out the new label for the content */ - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&rec->selection->devPrivates, stateKey); - sidput(obj->sid); - - if (avc_compute_create(subj->sid, subj->sid, SECCLASS_X_SELECTION, - &obj->sid) < 0) { - ErrorF("SELinux: a compute_create call failed!\n"); - obj->sid = unlabeled_sid; - } - break; - case SelectionGetOwner: - /* restore the real owner */ - rec->selection->window = rec->selection->alt_window; - break; - case SelectionConvertSelection: - /* redirect the convert request if necessary */ - if (securityManager && securityManager != rec->client) { - rec->selection->client = securityManager; - rec->selection->window = securityWindow; - } else { - rec->selection->client = rec->selection->alt_client; - rec->selection->window = rec->selection->alt_window; - } - break; default: break; } @@ -954,27 +968,47 @@ SELinuxSelectionState(CallbackListPtr *pcbl, pointer unused, pointer calldata) */ static void -SELinuxStateInit(CallbackListPtr *pcbl, pointer unused, pointer calldata) +SELinuxSubjectInit(CallbackListPtr *pcbl, pointer unused, pointer calldata) { PrivateCallbackRec *rec = calldata; - SELinuxStateRec *state = *rec->value; + SELinuxSubjectRec *subj = *rec->value; sidget(unlabeled_sid); - state->sid = unlabeled_sid; + subj->sid = unlabeled_sid; - avc_entry_ref_init(&state->aeref); + avc_entry_ref_init(&subj->aeref); } static void -SELinuxStateFree(CallbackListPtr *pcbl, pointer unused, pointer calldata) +SELinuxSubjectFree(CallbackListPtr *pcbl, pointer unused, pointer calldata) { PrivateCallbackRec *rec = calldata; - SELinuxStateRec *state = *rec->value; + SELinuxSubjectRec *subj = *rec->value; - xfree(state->command); + xfree(subj->command); if (avc_active) - sidput(state->sid); + sidput(subj->sid); +} + +static void +SELinuxObjectInit(CallbackListPtr *pcbl, pointer unused, pointer calldata) +{ + PrivateCallbackRec *rec = calldata; + SELinuxObjectRec *obj = *rec->value; + + sidget(unlabeled_sid); + obj->sid = unlabeled_sid; +} + +static void +SELinuxObjectFree(CallbackListPtr *pcbl, pointer unused, pointer calldata) +{ + PrivateCallbackRec *rec = calldata; + SELinuxObjectRec *obj = *rec->value; + + if (avc_active) + sidput(obj->sid); } @@ -1065,7 +1099,8 @@ ProcSELinuxSetDeviceContext(ClientPtr client) char *ctx; security_id_t sid; DeviceIntPtr dev; - SELinuxStateRec *state; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj; int rc; REQUEST(SELinuxSetContextReq); @@ -1083,9 +1118,13 @@ ProcSELinuxSetDeviceContext(ClientPtr client) if (rc != Success) return BadValue; - state = dixLookupPrivate(&dev->devPrivates, stateKey); - sidput(state->sid); - state->sid = sid; + subj = dixLookupPrivate(&dev->devPrivates, subjectKey); + sidput(subj->sid); + subj->sid = sid; + obj = dixLookupPrivate(&dev->devPrivates, objectKey); + sidput(obj->sid); + obj->sid = sid; + return Success; } @@ -1094,7 +1133,7 @@ ProcSELinuxGetDeviceContext(ClientPtr client) { char *ctx; DeviceIntPtr dev; - SELinuxStateRec *state; + SELinuxSubjectRec *subj; SELinuxGetContextReply rep; int rc; @@ -1105,8 +1144,8 @@ ProcSELinuxGetDeviceContext(ClientPtr client) if (rc != Success) return rc; - state = dixLookupPrivate(&dev->devPrivates, stateKey); - rc = avc_sid_to_context(state->sid, &ctx); + subj = dixLookupPrivate(&dev->devPrivates, subjectKey); + rc = avc_sid_to_context(subj->sid, &ctx); if (rc != Success) return BadValue; @@ -1146,7 +1185,7 @@ ProcSELinuxGetPropertyContext(ClientPtr client) char *ctx; WindowPtr pWin; PropertyPtr pProp; - SELinuxStateRec *state; + SELinuxObjectRec *obj; SELinuxGetContextReply rep; int rc; @@ -1166,12 +1205,12 @@ ProcSELinuxGetPropertyContext(ClientPtr client) if (!pProp) return BadValue; - rc = XaceHook(XACE_PROPERTY_ACCESS, client, pWin, pProp, DixGetAttrAccess); + rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess); if (rc != Success) return rc; - state = dixLookupPrivate(&pProp->devPrivates, stateKey); - rc = avc_sid_to_context(state->sid, &ctx); + obj = dixLookupPrivate(&pProp->devPrivates, objectKey); + rc = avc_sid_to_context(obj->sid, &ctx); if (rc != Success) return BadValue; @@ -1210,7 +1249,7 @@ ProcSELinuxGetWindowContext(ClientPtr client) { char *ctx; WindowPtr pWin; - SELinuxStateRec *state; + SELinuxObjectRec *obj; SELinuxGetContextReply rep; int rc; @@ -1221,8 +1260,8 @@ ProcSELinuxGetWindowContext(ClientPtr client) if (rc != Success) return rc; - state = dixLookupPrivate(&pWin->devPrivates, stateKey); - rc = avc_sid_to_context(state->sid, &ctx); + obj = dixLookupPrivate(&pWin->devPrivates, objectKey); + rc = avc_sid_to_context(obj->sid, &ctx); if (rc != Success) return BadValue; @@ -1245,6 +1284,24 @@ ProcSELinuxGetWindowContext(ClientPtr client) } static int +ProcSELinuxSetSelectionCreateContext(ClientPtr client) +{ + return Success; +} + +static int +ProcSELinuxGetSelectionCreateContext(ClientPtr client) +{ + return Success; +} + +static int +ProcSELinuxGetSelectionContext(ClientPtr client) +{ + return Success; +} + +static int ProcSELinuxDispatch(ClientPtr client) { REQUEST(xReq); @@ -1275,6 +1332,12 @@ ProcSELinuxDispatch(ClientPtr client) return ProcSELinuxGetWindowCreateContext(client); case X_SELinuxGetWindowContext: return ProcSELinuxGetWindowContext(client); + case X_SELinuxSetSelectionCreateContext: + return ProcSELinuxSetSelectionCreateContext(client); + case X_SELinuxGetSelectionCreateContext: + return ProcSELinuxGetSelectionCreateContext(client); + case X_SELinuxGetSelectionContext: + return ProcSELinuxGetSelectionContext(client); default: return BadRequest; } @@ -1383,6 +1446,28 @@ SProcSELinuxGetWindowContext(ClientPtr client) } static int +SProcSELinuxSetSelectionCreateContext(ClientPtr client) +{ + REQUEST(SELinuxSetCreateContextReq); + int n; + + REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq); + swaps(&stuff->context_len, n); + return ProcSELinuxSetSelectionCreateContext(client); +} + +static int +SProcSELinuxGetSelectionContext(ClientPtr client) +{ + REQUEST(SELinuxGetContextReq); + int n; + + REQUEST_SIZE_MATCH(SELinuxGetContextReq); + swapl(&stuff->id, n); + return ProcSELinuxGetSelectionContext(client); +} + +static int SProcSELinuxDispatch(ClientPtr client) { REQUEST(xReq); @@ -1417,6 +1502,12 @@ SProcSELinuxDispatch(ClientPtr client) return ProcSELinuxGetWindowCreateContext(client); case X_SELinuxGetWindowContext: return SProcSELinuxGetWindowContext(client); + case X_SELinuxSetSelectionCreateContext: + return SProcSELinuxSetSelectionCreateContext(client); + case X_SELinuxGetSelectionCreateContext: + return ProcSELinuxGetSelectionCreateContext(client); + case X_SELinuxGetSelectionContext: + return SProcSELinuxGetSelectionContext(client); default: return BadRequest; } @@ -1516,7 +1607,8 @@ SELinuxExtensionInit(INITARGS) FatalError("SELinux: Failed to open the system audit log\n"); /* Allocate private storage */ - if (!dixRequestPrivate(stateKey, sizeof(SELinuxStateRec))) + if (!dixRequestPrivate(subjectKey, sizeof(SELinuxSubjectRec)) || + !dixRequestPrivate(objectKey, sizeof(SELinuxObjectRec))) FatalError("SELinux: Failed to allocate private storage.\n"); /* Create atoms for doing window labeling */ @@ -1528,8 +1620,10 @@ SELinuxExtensionInit(INITARGS) FatalError("SELinux: Failed to create atom\n"); /* Register callbacks */ - ret &= dixRegisterPrivateInitFunc(stateKey, SELinuxStateInit, NULL); - ret &= dixRegisterPrivateDeleteFunc(stateKey, SELinuxStateFree, NULL); + ret &= dixRegisterPrivateInitFunc(subjectKey, SELinuxSubjectInit, NULL); + ret &= dixRegisterPrivateDeleteFunc(subjectKey, SELinuxSubjectFree, NULL); + ret &= dixRegisterPrivateInitFunc(objectKey, SELinuxObjectInit, NULL); + ret &= dixRegisterPrivateDeleteFunc(objectKey, SELinuxObjectFree, NULL); ret &= AddCallback(&ClientStateCallback, SELinuxClientState, NULL); ret &= AddCallback(&ResourceStateCallback, SELinuxResourceState, NULL); diff --git a/Xext/xselinux.h b/Xext/xselinux.h index 7eeea5046..480276154 100644 --- a/Xext/xselinux.h +++ b/Xext/xselinux.h @@ -43,6 +43,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define X_SELinuxSetWindowCreateContext 10 #define X_SELinuxGetWindowCreateContext 11 #define X_SELinuxGetWindowContext 12 +#define X_SELinuxSetSelectionCreateContext 13 +#define X_SELinuxGetSelectionCreateContext 14 +#define X_SELinuxGetSelectionContext 15 typedef struct { CARD8 reqType; |