xace: change the semantics of the return value of XACE hooks to allow

arbitrary X status codes instead of just TRUE/FALSE.

The dix layer in most cases still does not propagate the return value of
XACE hooks back to the client, however.  There is more error propagation
work to do.
This commit is contained in:
Eamon Walsh 2007-04-17 16:01:56 -04:00 committed by Eamon Walsh
parent 47bd311e3d
commit 9cee4ec5e6
14 changed files with 257 additions and 255 deletions

View File

@ -806,7 +806,7 @@ SecurityCheckDeviceAccess(CallbackListPtr *pcbl, pointer unused,
case X_SetModifierMapping: case X_SetModifierMapping:
SecurityAudit("client %d attempted request %d\n", SecurityAudit("client %d attempted request %d\n",
client->index, reqtype); client->index, reqtype);
rec->rval = FALSE; rec->status = BadAccess;
return; return;
default: default:
break; break;
@ -875,7 +875,7 @@ SecurityCheckDeviceAccess(CallbackListPtr *pcbl, pointer unused,
else else
SecurityAudit("client %d attempted to access device %d (%s)\n", SecurityAudit("client %d attempted to access device %d (%s)\n",
client->index, dev->id, devname); client->index, dev->id, devname);
rec->rval = FALSE; rec->status = BadAccess;
} }
return; return;
} /* SecurityCheckDeviceAccess */ } /* SecurityCheckDeviceAccess */
@ -1084,7 +1084,7 @@ SecurityCheckResourceIDAccess(CallbackListPtr *pcbl, pointer unused,
return; return;
deny: deny:
SecurityAuditResourceIDAccess(client, id); SecurityAuditResourceIDAccess(client, id);
rec->rval = FALSE; /* deny access */ rec->status = BadAccess; /* deny access */
} /* SecurityCheckResourceIDAccess */ } /* SecurityCheckResourceIDAccess */
@ -1176,7 +1176,7 @@ SecurityCheckDrawableAccess(CallbackListPtr *pcbl, pointer unused,
XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata; XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata;
if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
rec->rval = FALSE; rec->status = BadAccess;
} }
static void static void
@ -1192,7 +1192,7 @@ SecurityCheckMapAccess(CallbackListPtr *pcbl, pointer unused,
pWin->parent && pWin->parent->parent && pWin->parent && pWin->parent->parent &&
(TRUSTLEVEL(wClient(pWin->parent)) == XSecurityClientTrusted)) (TRUSTLEVEL(wClient(pWin->parent)) == XSecurityClientTrusted))
rec->rval = FALSE; rec->status = BadAccess;
} }
static void static void
@ -1202,7 +1202,7 @@ SecurityCheckBackgrndAccess(CallbackListPtr *pcbl, pointer unused,
XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata; XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
rec->rval = FALSE; rec->status = BadAccess;
} }
static void static void
@ -1214,7 +1214,7 @@ SecurityCheckExtAccess(CallbackListPtr *pcbl, pointer unused,
if ((TRUSTLEVEL(rec->client) != XSecurityClientTrusted) && if ((TRUSTLEVEL(rec->client) != XSecurityClientTrusted) &&
!EXTLEVEL(rec->ext)) !EXTLEVEL(rec->ext))
rec->rval = FALSE; rec->status = BadAccess;
} }
static void static void
@ -1225,7 +1225,7 @@ SecurityCheckHostlistAccess(CallbackListPtr *pcbl, pointer unused,
if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
{ {
rec->rval = FALSE; rec->status = BadAccess;
if (rec->access_mode == DixWriteAccess) if (rec->access_mode == DixWriteAccess)
SecurityAudit("client %d attempted to change host access\n", SecurityAudit("client %d attempted to change host access\n",
rec->client->index); rec->client->index);
@ -1255,14 +1255,14 @@ typedef struct _PropertyAccessRec {
#define SecurityAnyWindow 0 #define SecurityAnyWindow 0
#define SecurityRootWindow 1 #define SecurityRootWindow 1
#define SecurityWindowWithProperty 2 #define SecurityWindowWithProperty 2
char readAction; int readAction;
char writeAction; int writeAction;
char destroyAction; int destroyAction;
struct _PropertyAccessRec *next; struct _PropertyAccessRec *next;
} PropertyAccessRec, *PropertyAccessPtr; } PropertyAccessRec, *PropertyAccessPtr;
static PropertyAccessPtr PropertyAccessList = NULL; static PropertyAccessPtr PropertyAccessList = NULL;
static char SecurityDefaultAction = XaceErrorOperation; static int SecurityDefaultAction = BadAtom;
static char *SecurityPolicyFile = DEFAULTPOLICYFILE; static char *SecurityPolicyFile = DEFAULTPOLICYFILE;
static ATOM SecurityMaxPropertyName = 0; static ATOM SecurityMaxPropertyName = 0;
@ -1372,8 +1372,8 @@ SecurityParsePropertyAccessRule(
{ {
char *propname; char *propname;
char c; char c;
char action = SecurityDefaultAction; int action = SecurityDefaultAction;
char readAction, writeAction, destroyAction; int readAction, writeAction, destroyAction;
PropertyAccessPtr pacl, prev, cur; PropertyAccessPtr pacl, prev, cur;
char *mustHaveProperty = NULL; char *mustHaveProperty = NULL;
char *mustHaveValue = NULL; char *mustHaveValue = NULL;
@ -1418,9 +1418,9 @@ SecurityParsePropertyAccessRule(
{ {
switch (c) switch (c)
{ {
case 'i': action = XaceIgnoreOperation; break; case 'i': action = XaceIgnoreError; break;
case 'a': action = XaceAllowOperation; break; case 'a': action = Success; break;
case 'e': action = XaceErrorOperation; break; case 'e': action = BadAtom; break;
case 'r': readAction = action; break; case 'r': readAction = action; break;
case 'w': writeAction = action; break; case 'w': writeAction = action; break;
@ -1678,7 +1678,7 @@ SecurityCheckPropertyAccess(CallbackListPtr *pcbl, pointer unused,
ATOM propertyName = rec->pProp->propertyName; ATOM propertyName = rec->pProp->propertyName;
Mask access_mode = rec->access_mode; Mask access_mode = rec->access_mode;
PropertyAccessPtr pacl; PropertyAccessPtr pacl;
char action = SecurityDefaultAction; int action = SecurityDefaultAction;
/* if client trusted or window untrusted, allow operation */ /* if client trusted or window untrusted, allow operation */
@ -1757,7 +1757,7 @@ SecurityCheckPropertyAccess(CallbackListPtr *pcbl, pointer unused,
* If pacl doesn't apply, something above should have * If pacl doesn't apply, something above should have
* executed a continue, which will skip the follwing code. * executed a continue, which will skip the follwing code.
*/ */
action = XaceAllowOperation; action = Success;
if (access_mode & DixReadAccess) if (access_mode & DixReadAccess)
action = max(action, pacl->readAction); action = max(action, pacl->readAction);
if (access_mode & DixWriteAccess) if (access_mode & DixWriteAccess)
@ -1768,19 +1768,18 @@ SecurityCheckPropertyAccess(CallbackListPtr *pcbl, pointer unused,
} /* end for each pacl */ } /* end for each pacl */
} /* end if propertyName <= SecurityMaxPropertyName */ } /* end if propertyName <= SecurityMaxPropertyName */
if (XaceAllowOperation != action) if (action != Success)
{ /* audit the access violation */ { /* audit the access violation */
int cid = CLIENT_ID(pWin->drawable.id); int cid = CLIENT_ID(pWin->drawable.id);
int reqtype = ((xReq *)client->requestBuffer)->reqType; int reqtype = ((xReq *)client->requestBuffer)->reqType;
char *actionstr = (XaceIgnoreOperation == action) ? char *actionstr = (XaceIgnoreError == action) ? "ignored" : "error";
"ignored" : "error";
SecurityAudit("client %d attempted request %d with window 0x%x property %s (atom 0x%x) of client %d, %s\n", SecurityAudit("client %d attempted request %d with window 0x%x property %s (atom 0x%x) of client %d, %s\n",
client->index, reqtype, pWin->drawable.id, client->index, reqtype, pWin->drawable.id,
NameForAtom(propertyName), propertyName, cid, actionstr); NameForAtom(propertyName), propertyName, cid, actionstr);
} }
/* return codes increase with strictness */ /* return codes increase with strictness */
if (action > rec->rval) if (action != Success)
rec->rval = action; rec->status = action;
} /* SecurityCheckPropertyAccess */ } /* SecurityCheckPropertyAccess */

View File

@ -61,10 +61,10 @@ int XaceHook(int hook, ...)
case XACE_CORE_DISPATCH: { case XACE_CORE_DISPATCH: {
XaceCoreDispatchRec rec = { XaceCoreDispatchRec rec = {
va_arg(ap, ClientPtr), va_arg(ap, ClientPtr),
TRUE /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_RESOURCE_ACCESS: { case XACE_RESOURCE_ACCESS: {
@ -74,10 +74,10 @@ int XaceHook(int hook, ...)
va_arg(ap, RESTYPE), va_arg(ap, RESTYPE),
va_arg(ap, Mask), va_arg(ap, Mask),
va_arg(ap, pointer), va_arg(ap, pointer),
TRUE /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_DEVICE_ACCESS: { case XACE_DEVICE_ACCESS: {
@ -85,10 +85,10 @@ int XaceHook(int hook, ...)
va_arg(ap, ClientPtr), va_arg(ap, ClientPtr),
va_arg(ap, DeviceIntPtr), va_arg(ap, DeviceIntPtr),
va_arg(ap, Bool), va_arg(ap, Bool),
TRUE /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_PROPERTY_ACCESS: { case XACE_PROPERTY_ACCESS: {
@ -97,20 +97,20 @@ int XaceHook(int hook, ...)
va_arg(ap, WindowPtr), va_arg(ap, WindowPtr),
va_arg(ap, PropertyPtr), va_arg(ap, PropertyPtr),
va_arg(ap, Mask), va_arg(ap, Mask),
XaceAllowOperation /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_DRAWABLE_ACCESS: { case XACE_DRAWABLE_ACCESS: {
XaceDrawableAccessRec rec = { XaceDrawableAccessRec rec = {
va_arg(ap, ClientPtr), va_arg(ap, ClientPtr),
va_arg(ap, DrawablePtr), va_arg(ap, DrawablePtr),
TRUE /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_MAP_ACCESS: case XACE_MAP_ACCESS:
@ -118,10 +118,10 @@ int XaceHook(int hook, ...)
XaceMapAccessRec rec = { XaceMapAccessRec rec = {
va_arg(ap, ClientPtr), va_arg(ap, ClientPtr),
va_arg(ap, WindowPtr), va_arg(ap, WindowPtr),
TRUE /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_EXT_DISPATCH: case XACE_EXT_DISPATCH:
@ -129,20 +129,20 @@ int XaceHook(int hook, ...)
XaceExtAccessRec rec = { XaceExtAccessRec rec = {
va_arg(ap, ClientPtr), va_arg(ap, ClientPtr),
va_arg(ap, ExtensionEntry*), va_arg(ap, ExtensionEntry*),
TRUE /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_HOSTLIST_ACCESS: { case XACE_HOSTLIST_ACCESS: {
XaceHostlistAccessRec rec = { XaceHostlistAccessRec rec = {
va_arg(ap, ClientPtr), va_arg(ap, ClientPtr),
va_arg(ap, Mask), va_arg(ap, Mask),
TRUE /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_SELECTION_ACCESS: { case XACE_SELECTION_ACCESS: {
@ -150,20 +150,20 @@ int XaceHook(int hook, ...)
va_arg(ap, ClientPtr), va_arg(ap, ClientPtr),
va_arg(ap, Selection*), va_arg(ap, Selection*),
va_arg(ap, Mask), va_arg(ap, Mask),
TRUE /* default allow */ Success /* default allow */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_SITE_POLICY: { case XACE_SITE_POLICY: {
XaceSitePolicyRec rec = { XaceSitePolicyRec rec = {
va_arg(ap, char*), va_arg(ap, char*),
va_arg(ap, int), va_arg(ap, int),
FALSE /* default unrecognized */ BadValue /* default unrecognized */
}; };
calldata = &rec; calldata = &rec;
prv = &rec.rval; prv = &rec.status;
break; break;
} }
case XACE_DECLARE_EXT_SECURE: { case XACE_DECLARE_EXT_SECURE: {
@ -271,13 +271,14 @@ static int
XaceCatchDispatchProc(ClientPtr client) XaceCatchDispatchProc(ClientPtr client)
{ {
REQUEST(xReq); REQUEST(xReq);
int major = stuff->reqType; int rc, major = stuff->reqType;
if (!ProcVector[major]) if (!ProcVector[major])
return (BadRequest); return (BadRequest);
if (!XaceHook(XACE_CORE_DISPATCH, client)) rc = XaceHook(XACE_CORE_DISPATCH, client);
return (BadAccess); if (rc != Success)
return rc;
return client->swapped ? return client->swapped ?
(* SwappedProcVector[major])(client) : (* SwappedProcVector[major])(client) :
@ -294,7 +295,7 @@ XaceCatchExtProc(ClientPtr client)
if (!ext || !ProcVector[major]) if (!ext || !ProcVector[major])
return (BadRequest); return (BadRequest);
if (!XaceHook(XACE_EXT_DISPATCH, client, ext)) if (XaceHook(XACE_EXT_DISPATCH, client, ext) != Success)
return (BadRequest); /* pretend extension doesn't exist */ return (BadRequest); /* pretend extension doesn't exist */
return client->swapped ? return client->swapped ?

View File

@ -20,10 +20,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef _XACE_H #ifndef _XACE_H
#define _XACE_H #define _XACE_H
/* Hook return codes */ /* Special value used for ignore operation. This is a deprecated feature
#define XaceErrorOperation 0 * only for Security extension support. Do not use in new code.
#define XaceAllowOperation 1 */
#define XaceIgnoreOperation 2 #define XaceIgnoreError BadRequest
#ifdef XACE #ifdef XACE
@ -97,10 +97,10 @@ extern void XaceCensorImage(
/* Define calls away when XACE is not being built. */ /* Define calls away when XACE is not being built. */
#ifdef __GNUC__ #ifdef __GNUC__
#define XaceHook(args...) XaceAllowOperation #define XaceHook(args...) Success
#define XaceCensorImage(args...) { ; } #define XaceCensorImage(args...) { ; }
#else #else
#define XaceHook(...) XaceAllowOperation #define XaceHook(...) Success
#define XaceCensorImage(...) { ; } #define XaceCensorImage(...) { ; }
#endif #endif

View File

@ -33,7 +33,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* XACE_CORE_DISPATCH */ /* XACE_CORE_DISPATCH */
typedef struct { typedef struct {
ClientPtr client; ClientPtr client;
int rval; int status;
} XaceCoreDispatchRec; } XaceCoreDispatchRec;
/* XACE_RESOURCE_ACCESS */ /* XACE_RESOURCE_ACCESS */
@ -43,7 +43,7 @@ typedef struct {
RESTYPE rtype; RESTYPE rtype;
Mask access_mode; Mask access_mode;
pointer res; pointer res;
int rval; int status;
} XaceResourceAccessRec; } XaceResourceAccessRec;
/* XACE_DEVICE_ACCESS */ /* XACE_DEVICE_ACCESS */
@ -51,7 +51,7 @@ typedef struct {
ClientPtr client; ClientPtr client;
DeviceIntPtr dev; DeviceIntPtr dev;
Bool fromRequest; Bool fromRequest;
int rval; int status;
} XaceDeviceAccessRec; } XaceDeviceAccessRec;
/* XACE_PROPERTY_ACCESS */ /* XACE_PROPERTY_ACCESS */
@ -60,14 +60,14 @@ typedef struct {
WindowPtr pWin; WindowPtr pWin;
PropertyPtr pProp; PropertyPtr pProp;
Mask access_mode; Mask access_mode;
int rval; int status;
} XacePropertyAccessRec; } XacePropertyAccessRec;
/* XACE_DRAWABLE_ACCESS */ /* XACE_DRAWABLE_ACCESS */
typedef struct { typedef struct {
ClientPtr client; ClientPtr client;
DrawablePtr pDraw; DrawablePtr pDraw;
int rval; int status;
} XaceDrawableAccessRec; } XaceDrawableAccessRec;
/* XACE_MAP_ACCESS */ /* XACE_MAP_ACCESS */
@ -75,7 +75,7 @@ typedef struct {
typedef struct { typedef struct {
ClientPtr client; ClientPtr client;
WindowPtr pWin; WindowPtr pWin;
int rval; int status;
} XaceMapAccessRec; } XaceMapAccessRec;
/* XACE_EXT_DISPATCH */ /* XACE_EXT_DISPATCH */
@ -83,14 +83,14 @@ typedef struct {
typedef struct { typedef struct {
ClientPtr client; ClientPtr client;
ExtensionEntry *ext; ExtensionEntry *ext;
int rval; int status;
} XaceExtAccessRec; } XaceExtAccessRec;
/* XACE_HOSTLIST_ACCESS */ /* XACE_HOSTLIST_ACCESS */
typedef struct { typedef struct {
ClientPtr client; ClientPtr client;
Mask access_mode; Mask access_mode;
int rval; int status;
} XaceHostlistAccessRec; } XaceHostlistAccessRec;
/* XACE_SELECTION_ACCESS */ /* XACE_SELECTION_ACCESS */
@ -98,14 +98,14 @@ typedef struct {
ClientPtr client; ClientPtr client;
Selection *selection; Selection *selection;
Mask access_mode; Mask access_mode;
int rval; int status;
} XaceSelectionAccessRec; } XaceSelectionAccessRec;
/* XACE_SITE_POLICY */ /* XACE_SITE_POLICY */
typedef struct { typedef struct {
char *policyString; char *policyString;
int len; int len;
int rval; int status;
} XaceSitePolicyRec; } XaceSitePolicyRec;
/* XACE_DECLARE_EXT_SECURE */ /* XACE_DECLARE_EXT_SECURE */

View File

@ -193,7 +193,7 @@ SwapXID(ClientPtr client, XID id)
* class: Security class of the server object being accessed. * class: Security class of the server object being accessed.
* perm: Permissions required on the object. * perm: Permissions required on the object.
* *
* Returns: boolean TRUE=allowed, FALSE=denied. * Returns: X status code.
*/ */
static int static int
ServerPerm(ClientPtr client, ServerPerm(ClientPtr client,
@ -211,18 +211,19 @@ ServerPerm(ClientPtr client,
if (avc_has_perm(SID(client), RSID(serverClient,idx), class, if (avc_has_perm(SID(client), RSID(serverClient,idx), class,
perm, &AEREF(client), &auditdata) < 0) perm, &AEREF(client), &auditdata) < 0)
{ {
if (errno != EACCES) if (errno == EACCES)
return BadAccess;
ErrorF("ServerPerm: unexpected error %d\n", errno); ErrorF("ServerPerm: unexpected error %d\n", errno);
return FALSE; return BadValue;
} }
} }
else else
{ {
ErrorF("No client state in server-perm check!\n"); ErrorF("No client state in server-perm check!\n");
return TRUE; return Success;
} }
return TRUE; return Success;
} }
/* /*
@ -234,7 +235,7 @@ ServerPerm(ClientPtr client,
* class: Security class of the resource being accessed. * class: Security class of the resource being accessed.
* perm: Permissions required on the resource. * perm: Permissions required on the resource.
* *
* Returns: boolean TRUE=allowed, FALSE=denied. * Returns: X status code.
*/ */
static int static int
IDPerm(ClientPtr sclient, IDPerm(ClientPtr sclient,
@ -247,7 +248,7 @@ IDPerm(ClientPtr sclient,
XSELinuxAuditRec auditdata; XSELinuxAuditRec auditdata;
if (id == None) if (id == None)
return TRUE; return Success;
CheckXID(id); CheckXID(id);
tclient = clients[CLIENT_ID(id)]; tclient = clients[CLIENT_ID(id)];
@ -259,7 +260,7 @@ IDPerm(ClientPtr sclient,
*/ */
if (!tclient || !HAVESTATE(tclient) || !HAVESTATE(sclient)) if (!tclient || !HAVESTATE(tclient) || !HAVESTATE(sclient))
{ {
return TRUE; return Success;
} }
auditdata.client = sclient; auditdata.client = sclient;
@ -269,12 +270,13 @@ IDPerm(ClientPtr sclient,
if (avc_has_perm(SID(sclient), RSID(tclient,idx), class, if (avc_has_perm(SID(sclient), RSID(tclient,idx), class,
perm, &AEREF(sclient), &auditdata) < 0) perm, &AEREF(sclient), &auditdata) < 0)
{ {
if (errno != EACCES) if (errno == EACCES)
return BadAccess;
ErrorF("IDPerm: unexpected error %d\n", errno); ErrorF("IDPerm: unexpected error %d\n", errno);
return FALSE; return BadValue;
} }
return TRUE; return Success;
} }
/* /*
@ -501,8 +503,9 @@ FreeClientState(ClientPtr client)
#define REQUEST_SIZE_CHECK(client, req) \ #define REQUEST_SIZE_CHECK(client, req) \
(client->req_len >= (sizeof(req) >> 2)) (client->req_len >= (sizeof(req) >> 2))
#define IDPERM(client, req, field, class, perm) \ #define IDPERM(client, req, field, class, perm) \
(REQUEST_SIZE_CHECK(client,req) && \ (REQUEST_SIZE_CHECK(client,req) ? \
IDPerm(client, SwapXID(client,((req*)stuff)->field), class, perm)) IDPerm(client, SwapXID(client,((req*)stuff)->field), class, perm) : \
BadLength)
static int static int
CheckSendEventPerms(ClientPtr client) CheckSendEventPerms(ClientPtr client)
@ -513,7 +516,7 @@ CheckSendEventPerms(ClientPtr client)
/* might need type bounds checking here */ /* might need type bounds checking here */
if (!REQUEST_SIZE_CHECK(client, xSendEventReq)) if (!REQUEST_SIZE_CHECK(client, xSendEventReq))
return FALSE; return BadLength;
switch (stuff->event.u.u.type) { switch (stuff->event.u.u.type) {
case SelectionClear: case SelectionClear:
@ -574,11 +577,11 @@ static int
CheckConvertSelectionPerms(ClientPtr client) CheckConvertSelectionPerms(ClientPtr client)
{ {
register char n; register char n;
int rval = TRUE; int rval = Success;
REQUEST(xConvertSelectionReq); REQUEST(xConvertSelectionReq);
if (!REQUEST_SIZE_CHECK(client, xConvertSelectionReq)) if (!REQUEST_SIZE_CHECK(client, xConvertSelectionReq))
return FALSE; return BadLength;
if (client->swapped) if (client->swapped)
{ {
@ -591,24 +594,26 @@ CheckConvertSelectionPerms(ClientPtr client)
int i = 0; int i = 0;
while ((i < NumCurrentSelections) && while ((i < NumCurrentSelections) &&
CurrentSelections[i].selection != stuff->selection) i++; CurrentSelections[i].selection != stuff->selection) i++;
if (i < NumCurrentSelections) if (i < NumCurrentSelections) {
rval = rval && IDPerm(client, CurrentSelections[i].window, rval = IDPerm(client, CurrentSelections[i].window,
SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT);
}
rval = rval && IDPerm(client, stuff->requestor,
SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT); SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT);
if (rval != Success)
return rval; return rval;
}
}
return IDPerm(client, stuff->requestor,
SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT);
} }
static int static int
CheckSetSelectionOwnerPerms(ClientPtr client) CheckSetSelectionOwnerPerms(ClientPtr client)
{ {
register char n; register char n;
int rval = TRUE; int rval = Success;
REQUEST(xSetSelectionOwnerReq); REQUEST(xSetSelectionOwnerReq);
if (!REQUEST_SIZE_CHECK(client, xSetSelectionOwnerReq)) if (!REQUEST_SIZE_CHECK(client, xSetSelectionOwnerReq))
return FALSE; return BadLength;
if (client->swapped) if (client->swapped)
{ {
@ -621,13 +626,15 @@ CheckSetSelectionOwnerPerms(ClientPtr client)
int i = 0; int i = 0;
while ((i < NumCurrentSelections) && while ((i < NumCurrentSelections) &&
CurrentSelections[i].selection != stuff->selection) i++; CurrentSelections[i].selection != stuff->selection) i++;
if (i < NumCurrentSelections) if (i < NumCurrentSelections) {
rval = rval && IDPerm(client, CurrentSelections[i].window, rval = IDPerm(client, CurrentSelections[i].window,
SECCLASS_WINDOW, WINDOW__CHSELECTION);
}
rval = rval && IDPerm(client, stuff->window,
SECCLASS_WINDOW, WINDOW__CHSELECTION); SECCLASS_WINDOW, WINDOW__CHSELECTION);
if (rval != Success)
return rval; return rval;
}
}
return IDPerm(client, stuff->window,
SECCLASS_WINDOW, WINDOW__CHSELECTION);
} }
static void static void
@ -636,7 +643,7 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
XaceCoreDispatchRec *rec = (XaceCoreDispatchRec*)calldata; XaceCoreDispatchRec *rec = (XaceCoreDispatchRec*)calldata;
ClientPtr client = rec->client; ClientPtr client = rec->client;
REQUEST(xReq); REQUEST(xReq);
Bool rval; int rval = Success, rval2 = Success, rval3 = Success;
switch(stuff->reqType) { switch(stuff->reqType) {
/* Drawable class control requirements */ /* Drawable class control requirements */
@ -668,8 +675,8 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
case X_CopyArea: case X_CopyArea:
case X_CopyPlane: case X_CopyPlane:
rval = IDPERM(client, xCopyAreaReq, srcDrawable, rval = IDPERM(client, xCopyAreaReq, srcDrawable,
SECCLASS_DRAWABLE, DRAWABLE__COPY) SECCLASS_DRAWABLE, DRAWABLE__COPY);
&& IDPERM(client, xCopyAreaReq, dstDrawable, rval2 = IDPERM(client, xCopyAreaReq, dstDrawable,
SECCLASS_DRAWABLE, DRAWABLE__DRAW); SECCLASS_DRAWABLE, DRAWABLE__DRAW);
break; break;
case X_GetImage: case X_GetImage:
@ -712,11 +719,11 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
case X_CreateWindow: case X_CreateWindow:
rval = IDPERM(client, xCreateWindowReq, wid, rval = IDPERM(client, xCreateWindowReq, wid,
SECCLASS_WINDOW, SECCLASS_WINDOW,
WINDOW__CREATE | WINDOW__SETATTR | WINDOW__MOVE) WINDOW__CREATE | WINDOW__SETATTR | WINDOW__MOVE);
&& IDPERM(client, xCreateWindowReq, parent, rval2 = IDPERM(client, xCreateWindowReq, parent,
SECCLASS_WINDOW, SECCLASS_WINDOW,
WINDOW__CHSTACK | WINDOW__ADDCHILD) WINDOW__CHSTACK | WINDOW__ADDCHILD);
&& IDPERM(client, xCreateWindowReq, wid, rval3 = IDPERM(client, xCreateWindowReq, wid,
SECCLASS_DRAWABLE, DRAWABLE__CREATE); SECCLASS_DRAWABLE, DRAWABLE__CREATE);
break; break;
case X_DeleteProperty: case X_DeleteProperty:
@ -728,8 +735,8 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
case X_DestroySubwindows: case X_DestroySubwindows:
rval = IDPERM(client, xResourceReq, id, rval = IDPERM(client, xResourceReq, id,
SECCLASS_WINDOW, SECCLASS_WINDOW,
WINDOW__ENUMERATE | WINDOW__UNMAP | WINDOW__DESTROY) WINDOW__ENUMERATE | WINDOW__UNMAP | WINDOW__DESTROY);
&& IDPERM(client, xResourceReq, id, rval2 = IDPERM(client, xResourceReq, id,
SECCLASS_DRAWABLE, DRAWABLE__DESTROY); SECCLASS_DRAWABLE, DRAWABLE__DESTROY);
break; break;
case X_GetMotionEvents: case X_GetMotionEvents:
@ -768,8 +775,8 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
break; break;
case X_ReparentWindow: case X_ReparentWindow:
rval = IDPERM(client, xReparentWindowReq, window, rval = IDPERM(client, xReparentWindowReq, window,
SECCLASS_WINDOW, WINDOW__CHPARENT | WINDOW__MOVE) SECCLASS_WINDOW, WINDOW__CHPARENT | WINDOW__MOVE);
&& IDPERM(client, xReparentWindowReq, parent, rval2 = IDPERM(client, xReparentWindowReq, parent,
SECCLASS_WINDOW, WINDOW__CHSTACK | WINDOW__ADDCHILD); SECCLASS_WINDOW, WINDOW__CHSTACK | WINDOW__ADDCHILD);
break; break;
case X_SendEvent: case X_SendEvent:
@ -777,16 +784,16 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
break; break;
case X_SetInputFocus: case X_SetInputFocus:
rval = IDPERM(client, xSetInputFocusReq, focus, rval = IDPERM(client, xSetInputFocusReq, focus,
SECCLASS_WINDOW, WINDOW__SETFOCUS) SECCLASS_WINDOW, WINDOW__SETFOCUS);
&& ServerPerm(client, SECCLASS_XINPUT, XINPUT__SETFOCUS); rval2 = ServerPerm(client, SECCLASS_XINPUT, XINPUT__SETFOCUS);
break; break;
case X_SetSelectionOwner: case X_SetSelectionOwner:
rval = CheckSetSelectionOwnerPerms(client); rval = CheckSetSelectionOwnerPerms(client);
break; break;
case X_TranslateCoords: case X_TranslateCoords:
rval = IDPERM(client, xTranslateCoordsReq, srcWid, rval = IDPERM(client, xTranslateCoordsReq, srcWid,
SECCLASS_WINDOW, WINDOW__GETATTR) SECCLASS_WINDOW, WINDOW__GETATTR);
&& IDPERM(client, xTranslateCoordsReq, dstWid, rval2 = IDPERM(client, xTranslateCoordsReq, dstWid,
SECCLASS_WINDOW, WINDOW__GETATTR); SECCLASS_WINDOW, WINDOW__GETATTR);
break; break;
case X_UnmapWindow: case X_UnmapWindow:
@ -798,10 +805,10 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
break; break;
case X_WarpPointer: case X_WarpPointer:
rval = IDPERM(client, xWarpPointerReq, srcWid, rval = IDPERM(client, xWarpPointerReq, srcWid,
SECCLASS_WINDOW, WINDOW__GETATTR) SECCLASS_WINDOW, WINDOW__GETATTR);
&& IDPERM(client, xWarpPointerReq, dstWid, rval2 = IDPERM(client, xWarpPointerReq, dstWid,
SECCLASS_WINDOW, WINDOW__GETATTR) SECCLASS_WINDOW, WINDOW__GETATTR);
&& ServerPerm(client, SECCLASS_XINPUT, XINPUT__WARPPOINTER); rval3 = ServerPerm(client, SECCLASS_XINPUT, XINPUT__WARPPOINTER);
break; break;
/* Input class control requirements */ /* Input class control requirements */
@ -852,15 +859,15 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
break; break;
case X_CopyColormapAndFree: case X_CopyColormapAndFree:
rval = IDPERM(client, xCopyColormapAndFreeReq, mid, rval = IDPERM(client, xCopyColormapAndFreeReq, mid,
SECCLASS_COLORMAP, COLORMAP__CREATE) SECCLASS_COLORMAP, COLORMAP__CREATE);
&& IDPERM(client, xCopyColormapAndFreeReq, srcCmap, rval2 = IDPERM(client, xCopyColormapAndFreeReq, srcCmap,
SECCLASS_COLORMAP, SECCLASS_COLORMAP,
COLORMAP__READ | COLORMAP__FREE); COLORMAP__READ | COLORMAP__FREE);
break; break;
case X_CreateColormap: case X_CreateColormap:
rval = IDPERM(client, xCreateColormapReq, mid, rval = IDPERM(client, xCreateColormapReq, mid,
SECCLASS_COLORMAP, COLORMAP__CREATE) SECCLASS_COLORMAP, COLORMAP__CREATE);
&& IDPERM(client, xCreateColormapReq, window, rval2 = IDPERM(client, xCreateColormapReq, window,
SECCLASS_DRAWABLE, DRAWABLE__DRAW); SECCLASS_DRAWABLE, DRAWABLE__DRAW);
break; break;
case X_FreeColormap: case X_FreeColormap:
@ -873,8 +880,8 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
break; break;
case X_InstallColormap: case X_InstallColormap:
rval = IDPERM(client, xResourceReq, id, rval = IDPERM(client, xResourceReq, id,
SECCLASS_COLORMAP, COLORMAP__INSTALL) SECCLASS_COLORMAP, COLORMAP__INSTALL);
&& ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__INSTALL); rval2 = ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__INSTALL);
break; break;
case X_ListInstalledColormaps: case X_ListInstalledColormaps:
rval = ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__LIST); rval = ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__LIST);
@ -891,8 +898,8 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
break; break;
case X_UninstallColormap: case X_UninstallColormap:
rval = IDPERM(client, xResourceReq, id, rval = IDPERM(client, xResourceReq, id,
SECCLASS_COLORMAP, COLORMAP__UNINSTALL) SECCLASS_COLORMAP, COLORMAP__UNINSTALL);
&& ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__UNINSTALL); rval2 = ServerPerm(client, SECCLASS_COLORMAP, COLORMAP__UNINSTALL);
break; break;
/* Font class control requirements */ /* Font class control requirements */
@ -907,17 +914,17 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
SECCLASS_DRAWABLE, DRAWABLE__DRAW); SECCLASS_DRAWABLE, DRAWABLE__DRAW);
break; break;
case X_OpenFont: case X_OpenFont:
rval = ServerPerm(client, SECCLASS_FONT, FONT__LOAD) rval = ServerPerm(client, SECCLASS_FONT, FONT__LOAD);
&& IDPERM(client, xOpenFontReq, fid, rval2 = IDPERM(client, xOpenFontReq, fid,
SECCLASS_FONT, FONT__USE); SECCLASS_FONT, FONT__USE);
break; break;
case X_PolyText8: case X_PolyText8:
case X_PolyText16: case X_PolyText16:
/* Font accesses checked through the resource manager */ /* Font accesses checked through the resource manager */
rval = ServerPerm(client, SECCLASS_FONT, FONT__LOAD) rval = ServerPerm(client, SECCLASS_FONT, FONT__LOAD);
&& IDPERM(client, xPolyTextReq, gc, rval2 = IDPERM(client, xPolyTextReq, gc,
SECCLASS_GC, GC__SETATTR) SECCLASS_GC, GC__SETATTR);
&& IDPERM(client, xPolyTextReq, drawable, rval3 = IDPERM(client, xPolyTextReq, drawable,
SECCLASS_DRAWABLE, DRAWABLE__DRAW); SECCLASS_DRAWABLE, DRAWABLE__DRAW);
break; break;
@ -934,18 +941,18 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
/* Cursor class control requirements */ /* Cursor class control requirements */
case X_CreateCursor: case X_CreateCursor:
rval = IDPERM(client, xCreateCursorReq, cid, rval = IDPERM(client, xCreateCursorReq, cid,
SECCLASS_CURSOR, CURSOR__CREATE) SECCLASS_CURSOR, CURSOR__CREATE);
&& IDPERM(client, xCreateCursorReq, source, rval2 = IDPERM(client, xCreateCursorReq, source,
SECCLASS_DRAWABLE, DRAWABLE__DRAW) SECCLASS_DRAWABLE, DRAWABLE__DRAW);
&& IDPERM(client, xCreateCursorReq, mask, rval3 = IDPERM(client, xCreateCursorReq, mask,
SECCLASS_DRAWABLE, DRAWABLE__COPY); SECCLASS_DRAWABLE, DRAWABLE__COPY);
break; break;
case X_CreateGlyphCursor: case X_CreateGlyphCursor:
rval = IDPERM(client, xCreateGlyphCursorReq, cid, rval = IDPERM(client, xCreateGlyphCursorReq, cid,
SECCLASS_CURSOR, CURSOR__CREATEGLYPH) SECCLASS_CURSOR, CURSOR__CREATEGLYPH);
&& IDPERM(client, xCreateGlyphCursorReq, source, rval2 = IDPERM(client, xCreateGlyphCursorReq, source,
SECCLASS_FONT, FONT__USE) SECCLASS_FONT, FONT__USE);
&& IDPERM(client, xCreateGlyphCursorReq, mask, rval3 = IDPERM(client, xCreateGlyphCursorReq, mask,
SECCLASS_FONT, FONT__USE); SECCLASS_FONT, FONT__USE);
break; break;
case X_RecolorCursor: case X_RecolorCursor:
@ -970,8 +977,8 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
break; break;
case X_CopyGC: case X_CopyGC:
rval = IDPERM(client, xCopyGCReq, srcGC, rval = IDPERM(client, xCopyGCReq, srcGC,
SECCLASS_GC, GC__GETATTR) SECCLASS_GC, GC__GETATTR);
&& IDPERM(client, xCopyGCReq, dstGC, rval2 = IDPERM(client, xCopyGCReq, dstGC,
SECCLASS_GC, GC__SETATTR); SECCLASS_GC, GC__SETATTR);
break; break;
case X_FreeGC: case X_FreeGC:
@ -1009,11 +1016,14 @@ XSELinuxCoreDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
break; break;
default: default:
rval = TRUE;
break; break;
} }
if (!rval) if (rval != Success)
rec->rval = FALSE; rec->status = rval;
if (rval2 != Success)
rec->status = rval2;
if (rval != Success)
rec->status = rval3;
} }
static void static void
@ -1050,9 +1060,10 @@ XSELinuxExtDispatch(CallbackListPtr *pcbl, pointer unused, pointer calldata)
if (avc_has_perm(SID(client), extsid, SECCLASS_XEXTENSION, if (avc_has_perm(SID(client), extsid, SECCLASS_XEXTENSION,
perm, &AEREF(client), &auditdata) < 0) perm, &AEREF(client), &auditdata) < 0)
{ {
if (errno != EACCES) if (errno == EACCES)
rec->status = BadAccess;
ErrorF("ExtDispatch: unexpected error %d\n", errno); ErrorF("ExtDispatch: unexpected error %d\n", errno);
rec->rval = FALSE; rec->status = BadValue;
} }
} else } else
ErrorF("No client state in extension dispatcher!\n"); ErrorF("No client state in extension dispatcher!\n");
@ -1096,9 +1107,10 @@ XSELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
if (avc_has_perm(SID(client), propsid, SECCLASS_PROPERTY, if (avc_has_perm(SID(client), propsid, SECCLASS_PROPERTY,
perm, &AEREF(client), &auditdata) < 0) perm, &AEREF(client), &auditdata) < 0)
{ {
if (errno != EACCES) if (errno == EACCES)
rec->status = BadAccess;
ErrorF("Property: unexpected error %d\n", errno); ErrorF("Property: unexpected error %d\n", errno);
rec->rval = XaceIgnoreOperation; rec->status = BadValue;
} }
} else } else
ErrorF("No client state in property callback!\n"); ErrorF("No client state in property callback!\n");
@ -1114,7 +1126,7 @@ XSELinuxResLookup(CallbackListPtr *pcbl, pointer unused, pointer calldata)
ClientPtr client = rec->client; ClientPtr client = rec->client;
REQUEST(xReq); REQUEST(xReq);
access_vector_t perm = 0; access_vector_t perm = 0;
Bool rval = TRUE; int rval = Success;
/* serverClient requests OK */ /* serverClient requests OK */
if (client->index == 0) if (client->index == 0)
@ -1145,35 +1157,35 @@ XSELinuxResLookup(CallbackListPtr *pcbl, pointer unused, pointer calldata)
default: default:
break; break;
} }
if (!rval) if (rval != Success)
rec->rval = FALSE; rec->status = rval;
} /* XSELinuxResLookup */ } /* XSELinuxResLookup */
static void static void
XSELinuxMap(CallbackListPtr *pcbl, pointer unused, pointer calldata) XSELinuxMap(CallbackListPtr *pcbl, pointer unused, pointer calldata)
{ {
XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata; XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
if (!IDPerm(rec->client, rec->pWin->drawable.id, if (IDPerm(rec->client, rec->pWin->drawable.id,
SECCLASS_WINDOW, WINDOW__MAP)) SECCLASS_WINDOW, WINDOW__MAP) != Success)
rec->rval = FALSE; rec->status = BadAccess;
} /* XSELinuxMap */ } /* XSELinuxMap */
static void static void
XSELinuxBackgrnd(CallbackListPtr *pcbl, pointer unused, pointer calldata) XSELinuxBackgrnd(CallbackListPtr *pcbl, pointer unused, pointer calldata)
{ {
XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata; XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
if (!IDPerm(rec->client, rec->pWin->drawable.id, if (IDPerm(rec->client, rec->pWin->drawable.id,
SECCLASS_WINDOW, WINDOW__TRANSPARENT)) SECCLASS_WINDOW, WINDOW__TRANSPARENT) != Success)
rec->rval = FALSE; rec->status = BadAccess;
} /* XSELinuxBackgrnd */ } /* XSELinuxBackgrnd */
static void static void
XSELinuxDrawable(CallbackListPtr *pcbl, pointer unused, pointer calldata) XSELinuxDrawable(CallbackListPtr *pcbl, pointer unused, pointer calldata)
{ {
XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata; XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata;
if (!IDPerm(rec->client, rec->pDraw->id, if (IDPerm(rec->client, rec->pDraw->id,
SECCLASS_DRAWABLE, DRAWABLE__COPY)) SECCLASS_DRAWABLE, DRAWABLE__COPY) != Success)
rec->rval = FALSE; rec->status = BadAccess;
} /* XSELinuxDrawable */ } /* XSELinuxDrawable */
static void static void
@ -1183,8 +1195,8 @@ XSELinuxHostlist(CallbackListPtr *pcbl, pointer unused, pointer calldata)
access_vector_t perm = (rec->access_mode == DixReadAccess) ? access_vector_t perm = (rec->access_mode == DixReadAccess) ?
XSERVER__GETHOSTLIST : XSERVER__SETHOSTLIST; XSERVER__GETHOSTLIST : XSERVER__SETHOSTLIST;
if (!ServerPerm(rec->client, SECCLASS_XSERVER, perm)) if (ServerPerm(rec->client, SECCLASS_XSERVER, perm) != Success)
rec->rval = FALSE; rec->status = BadAccess;
} /* XSELinuxHostlist */ } /* XSELinuxHostlist */
/* Extension callbacks */ /* Extension callbacks */

View File

@ -1206,7 +1206,7 @@ DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
} }
} }
if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE)) if (XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE) != Success)
return BadAccess; return BadAccess;
/* None of the modifiers (old or new) may be down while we change /* None of the modifiers (old or new) may be down while we change
@ -1330,7 +1330,7 @@ ProcChangeKeyboardMapping(ClientPtr client)
for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) { if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE)) if (XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE) != Success)
return BadAccess; return BadAccess;
} }
} }
@ -1682,7 +1682,7 @@ ProcChangeKeyboardControl (ClientPtr client)
for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
if ((pDev->coreEvents || pDev == inputInfo.keyboard) && if ((pDev->coreEvents || pDev == inputInfo.keyboard) &&
pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE)) if (XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE) != Success)
return BadAccess; return BadAccess;
} }
} }
@ -1944,10 +1944,10 @@ ProcQueryKeymap(ClientPtr client)
rep.length = 2; rep.length = 2;
if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE)) if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
bzero((char *)&rep.map[0], 32);
else
for (i = 0; i<32; i++) for (i = 0; i<32; i++)
rep.map[i] = down[i]; rep.map[i] = down[i];
else
bzero((char *)&rep.map[0], 32);
WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
return Success; return Success;

View File

@ -1120,7 +1120,7 @@ ProcGetSelectionOwner(ClientPtr client)
reply.sequenceNumber = client->sequence; reply.sequenceNumber = client->sequence;
if (i < NumCurrentSelections && if (i < NumCurrentSelections &&
XaceHook(XACE_SELECTION_ACCESS, client, &CurrentSelections[i], XaceHook(XACE_SELECTION_ACCESS, client, &CurrentSelections[i],
DixReadAccess)) DixReadAccess) == Success)
reply.owner = CurrentSelections[i].destwindow; reply.owner = CurrentSelections[i].destwindow;
else else
reply.owner = None; reply.owner = None;
@ -1161,7 +1161,7 @@ ProcConvertSelection(ClientPtr client)
if ((i < NumCurrentSelections) && if ((i < NumCurrentSelections) &&
(CurrentSelections[i].window != None) && (CurrentSelections[i].window != None) &&
XaceHook(XACE_SELECTION_ACCESS, client, &CurrentSelections[i], XaceHook(XACE_SELECTION_ACCESS, client, &CurrentSelections[i],
DixReadAccess)) DixReadAccess) == Success)
{ {
event.u.u.type = SelectionRequest; event.u.u.type = SelectionRequest;
event.u.selectionRequest.time = stuff->time; event.u.selectionRequest.time = stuff->time;
@ -2276,7 +2276,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
} }
if (pDraw->type == DRAWABLE_WINDOW && if (pDraw->type == DRAWABLE_WINDOW &&
!XaceHook(XACE_DRAWABLE_ACCESS, client, pDraw)) XaceHook(XACE_DRAWABLE_ACCESS, client, pDraw) != Success)
{ {
pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw); pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
if (pVisibleRegion) if (pVisibleRegion)
@ -3343,8 +3343,9 @@ ProcListHosts(ClientPtr client)
REQUEST_SIZE_MATCH(xListHostsReq); REQUEST_SIZE_MATCH(xListHostsReq);
/* untrusted clients can't list hosts */ /* untrusted clients can't list hosts */
if (!XaceHook(XACE_HOSTLIST_ACCESS, client, DixReadAccess)) result = XaceHook(XACE_HOSTLIST_ACCESS, client, DixReadAccess);
return BadAccess; if (result != Success)
return result;
result = GetHosts(&pdata, &nHosts, &len, &reply.enabled); result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
if (result != Success) if (result != Success)

View File

@ -209,6 +209,8 @@ dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client,
{ {
DrawablePtr pTmp; DrawablePtr pTmp;
RESTYPE rtype; RESTYPE rtype;
int rc;
*pDraw = NULL; *pDraw = NULL;
client->errorValue = id; client->errorValue = id;
@ -220,8 +222,9 @@ dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client,
/* an access check is required for cached drawables */ /* an access check is required for cached drawables */
rtype = (type & M_WINDOW) ? RT_WINDOW : RT_PIXMAP; rtype = (type & M_WINDOW) ? RT_WINDOW : RT_PIXMAP;
if (!XaceHook(XACE_RESOURCE_ACCESS, client, id, rtype, access, pTmp)) rc = XaceHook(XACE_RESOURCE_ACCESS, client, id, rtype, access, pTmp);
return BadDrawable; if (rc != Success)
return rc;
} else } else
dixLookupResource((void **)&pTmp, id, RC_DRAWABLE, client, access); dixLookupResource((void **)&pTmp, id, RC_DRAWABLE, client, access);

View File

@ -2682,7 +2682,7 @@ CheckPassiveGrabsOnWindow(
(grab->confineTo->realized && (grab->confineTo->realized &&
BorderSizeNotEmpty(grab->confineTo)))) BorderSizeNotEmpty(grab->confineTo))))
{ {
if (!XaceHook(XACE_DEVICE_ACCESS, wClient(pWin), device, FALSE)) if (XaceHook(XACE_DEVICE_ACCESS, wClient(pWin), device, FALSE))
return FALSE; return FALSE;
#ifdef XKB #ifdef XKB
if (!noXkbExtension) { if (!noXkbExtension) {
@ -3529,7 +3529,7 @@ EnterLeaveEvent(
xKeymapEvent ke; xKeymapEvent ke;
ClientPtr client = grab ? rClient(grab) ClientPtr client = grab ? rClient(grab)
: clients[CLIENT_ID(pWin->drawable.id)]; : clients[CLIENT_ID(pWin->drawable.id)];
if (XaceHook(XACE_DEVICE_ACCESS, client, keybd, FALSE)) if (XaceHook(XACE_DEVICE_ACCESS, client, keybd, FALSE) == Success)
memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31); memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
else else
bzero((char *)&ke.map[0], 31); bzero((char *)&ke.map[0], 31);
@ -3636,7 +3636,7 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
{ {
xKeymapEvent ke; xKeymapEvent ke;
ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)]; ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
if (XaceHook(XACE_DEVICE_ACCESS, client, dev, FALSE)) if (XaceHook(XACE_DEVICE_ACCESS, client, dev, FALSE) == Success)
memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31); memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
else else
bzero((char *)&ke.map[0], 31); bzero((char *)&ke.map[0], 31);
@ -3924,7 +3924,7 @@ ProcSetInputFocus(client)
REQUEST_SIZE_MATCH(xSetInputFocusReq); REQUEST_SIZE_MATCH(xSetInputFocusReq);
if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE)) if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
return Success; return Success;
return SetInputFocus(client, inputInfo.keyboard, stuff->focus, return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
@ -4239,15 +4239,14 @@ ProcGrabKeyboard(ClientPtr client)
REQUEST_SIZE_MATCH(xGrabKeyboardReq); REQUEST_SIZE_MATCH(xGrabKeyboardReq);
if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE)) if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE)) {
result = Success;
rep.status = AlreadyGrabbed;
} else
result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode, result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
stuff->pointerMode, stuff->grabWindow, stuff->pointerMode, stuff->grabWindow,
stuff->ownerEvents, stuff->time, stuff->ownerEvents, stuff->time,
KeyPressMask | KeyReleaseMask, &rep.status); KeyPressMask | KeyReleaseMask, &rep.status);
else {
result = Success;
rep.status = AlreadyGrabbed;
}
if (result != Success) if (result != Success)
return result; return result;

View File

@ -319,7 +319,7 @@ ProcQueryExtension(ClientPtr client)
else else
{ {
i = FindExtension((char *)&stuff[1], stuff->nbytes); i = FindExtension((char *)&stuff[1], stuff->nbytes);
if (i < 0 || !XaceHook(XACE_EXT_ACCESS, client, extensions[i])) if (i < 0 || XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
reply.present = xFalse; reply.present = xFalse;
else else
{ {
@ -355,7 +355,7 @@ ProcListExtensions(ClientPtr client)
for (i=0; i<NumExtensions; i++) for (i=0; i<NumExtensions; i++)
{ {
/* call callbacks to find out whether to show extension */ /* call callbacks to find out whether to show extension */
if (!XaceHook(XACE_EXT_ACCESS, client, extensions[i])) if (XaceHook(XACE_EXT_ACCESS, client, extensions[i]) != Success)
continue; continue;
total_length += strlen(extensions[i]->name) + 1; total_length += strlen(extensions[i]->name) + 1;
@ -370,7 +370,7 @@ ProcListExtensions(ClientPtr client)
for (i=0; i<NumExtensions; i++) for (i=0; i<NumExtensions; i++)
{ {
int len; int len;
if (!XaceHook(XACE_EXT_ACCESS, client, extensions[i])) if (XaceHook(XACE_EXT_ACCESS, client, extensions[i]) != Success)
continue; continue;
*bufptr++ = len = strlen(extensions[i]->name); *bufptr++ = len = strlen(extensions[i]->name);

View File

@ -144,16 +144,12 @@ ProcRotateProperties(ClientPtr client)
DEALLOCATE_LOCAL(props); DEALLOCATE_LOCAL(props);
return BadMatch; return BadMatch;
} }
switch (XaceHook(XACE_PROPERTY_ACCESS, client, pWin, pProp, rc = XaceHook(XACE_PROPERTY_ACCESS, client, pWin, pProp,
DixReadAccess|DixWriteAccess)) DixReadAccess|DixWriteAccess);
{ if (rc != Success) {
case XaceErrorOperation:
DEALLOCATE_LOCAL(props); DEALLOCATE_LOCAL(props);
client->errorValue = atoms[i]; client->errorValue = atoms[i];
return BadAtom; return (rc == XaceIgnoreError) ? Success : rc;
case XaceIgnoreOperation:
DEALLOCATE_LOCAL(props);
return Success;
} }
props[i] = pProp; props[i] = pProp;
} }
@ -246,8 +242,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
{ {
PropertyPtr pProp; PropertyPtr pProp;
xEvent event; xEvent event;
int sizeInBytes; int sizeInBytes, totalSize, rc;
int totalSize;
pointer data; pointer data;
sizeInBytes = format>>3; sizeInBytes = format>>3;
@ -277,32 +272,24 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
memmove((char *)data, (char *)value, totalSize); memmove((char *)data, (char *)value, totalSize);
pProp->size = len; pProp->size = len;
pProp->devPrivates = NULL; pProp->devPrivates = NULL;
switch (XaceHook(XACE_PROPERTY_ACCESS, pClient, pWin, pProp, rc = XaceHook(XACE_PROPERTY_ACCESS, pClient, pWin, pProp,
DixCreateAccess)) DixCreateAccess);
{ if (rc != Success) {
case XaceErrorOperation:
xfree(data); xfree(data);
xfree(pProp); xfree(pProp);
pClient->errorValue = property; pClient->errorValue = property;
return BadAtom; return (rc == XaceIgnoreError) ? Success : rc;
case XaceIgnoreOperation:
xfree(data);
xfree(pProp);
return Success;
} }
pProp->next = pWin->optional->userProps; pProp->next = pWin->optional->userProps;
pWin->optional->userProps = pProp; pWin->optional->userProps = pProp;
} }
else else
{ {
switch (XaceHook(XACE_PROPERTY_ACCESS, pClient, pWin, pProp, rc = XaceHook(XACE_PROPERTY_ACCESS, pClient, pWin, pProp,
DixWriteAccess)) DixWriteAccess);
{ if (rc != Success) {
case XaceErrorOperation:
pClient->errorValue = property; pClient->errorValue = property;
return BadAtom; return (rc == XaceIgnoreError) ? Success : rc;
case XaceIgnoreOperation:
return Success;
} }
/* To append or prepend to a property the request format and type /* To append or prepend to a property the request format and type
must match those of the already defined property. The must match those of the already defined property. The
@ -471,7 +458,8 @@ int
ProcGetProperty(ClientPtr client) ProcGetProperty(ClientPtr client)
{ {
PropertyPtr pProp, prevProp; PropertyPtr pProp, prevProp;
unsigned long n, len, ind, rc; unsigned long n, len, ind;
int rc;
WindowPtr pWin; WindowPtr pWin;
xGetPropertyReply reply; xGetPropertyReply reply;
Mask access_mode = DixReadAccess; Mask access_mode = DixReadAccess;
@ -517,13 +505,12 @@ ProcGetProperty(ClientPtr client)
if (stuff->delete) if (stuff->delete)
access_mode |= DixDestroyAccess; access_mode |= DixDestroyAccess;
switch (XaceHook(XACE_PROPERTY_ACCESS, client, pWin, pProp, access_mode))
{ rc = XaceHook(XACE_PROPERTY_ACCESS, client, pWin, pProp, access_mode);
case XaceErrorOperation: if (rc != Success) {
client->errorValue = stuff->property; client->errorValue = stuff->property;
return BadAtom;; return (rc == XaceIgnoreError) ?
case XaceIgnoreOperation: NullPropertyReply(client, pProp->type, pProp->format, &reply) : rc;
return NullPropertyReply(client, pProp->type, pProp->format, &reply);
} }
/* If the request type and actual type don't match. Return the /* If the request type and actual type don't match. Return the
@ -669,14 +656,11 @@ ProcDeleteProperty(ClientPtr client)
return (BadAtom); return (BadAtom);
} }
switch (XaceHook(XACE_PROPERTY_ACCESS, client, pWin, result = XaceHook(XACE_PROPERTY_ACCESS, client, pWin,
FindProperty(pWin, stuff->property), DixDestroyAccess)) FindProperty(pWin, stuff->property), DixDestroyAccess);
{ if (result != Success) {
case XaceErrorOperation:
client->errorValue = stuff->property; client->errorValue = stuff->property;
return BadAtom;; return (result == XaceIgnoreError) ? Success : result;
case XaceIgnoreOperation:
return Success;
} }
result = DeleteProperty(pWin, stuff->property); result = DeleteProperty(pWin, stuff->property);

View File

@ -918,12 +918,16 @@ dixLookupResource(pointer *result, XID id, RESTYPE rtype,
(!istype && res->type & rtype))) (!istype && res->type & rtype)))
break; break;
} }
if (res) { if (!res)
if (client && !XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type, return BadValue;
mode, res->value))
return BadAccess; if (client) {
cid = XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type,
mode, res->value);
if (cid != Success)
return cid;
}
*result = res->value; *result = res->value;
return Success; return Success;
}
return BadValue;
} }

View File

@ -732,17 +732,16 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
/* security creation/labeling check /* security creation/labeling check
*/ */
if (!XaceHook(XACE_RESOURCE_ACCESS, client, *error = XaceHook(XACE_RESOURCE_ACCESS, client, wid, RT_WINDOW,
wid, RT_WINDOW, DixCreateAccess, pWin)) DixCreateAccess, pWin);
{ if (*error != Success) {
xfree(pWin); xfree(pWin);
*error = BadAccess;
return NullWindow; return NullWindow;
} }
/* can't let untrusted clients have background None windows; /* can't let untrusted clients have background None windows;
* they make it too easy to steal window contents * they make it too easy to steal window contents
*/ */
if (XaceHook(XACE_BACKGRND_ACCESS, client, pWin)) if (XaceHook(XACE_BACKGRND_ACCESS, client, pWin) == Success)
pWin->backgroundState = None; pWin->backgroundState = None;
else { else {
pWin->backgroundState = BackgroundPixel; pWin->backgroundState = BackgroundPixel;
@ -1052,7 +1051,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
if (pixID == None) if (pixID == None)
{ {
/* can't let untrusted clients have background None windows */ /* can't let untrusted clients have background None windows */
if (XaceHook(XACE_BACKGRND_ACCESS, client, pWin)) { if (XaceHook(XACE_BACKGRND_ACCESS, client, pWin) == Success) {
if (pWin->backgroundState == BackgroundPixmap) if (pWin->backgroundState == BackgroundPixmap)
(*pScreen->DestroyPixmap)(pWin->background.pixmap); (*pScreen->DestroyPixmap)(pWin->background.pixmap);
if (!pWin->parent) if (!pWin->parent)
@ -2773,7 +2772,7 @@ MapWindow(WindowPtr pWin, ClientPtr client)
return(Success); return(Success);
/* general check for permission to map window */ /* general check for permission to map window */
if (!XaceHook(XACE_MAP_ACCESS, client, pWin)) if (XaceHook(XACE_MAP_ACCESS, client, pWin) != Success)
return Success; return Success;
pScreen = pWin->drawable.pScreen; pScreen = pWin->drawable.pScreen;

View File

@ -1528,7 +1528,7 @@ AuthorizedClient(ClientPtr client)
return TRUE; return TRUE;
/* untrusted clients can't change host access */ /* untrusted clients can't change host access */
if (!XaceHook(XACE_HOSTLIST_ACCESS, client, DixWriteAccess)) if (XaceHook(XACE_HOSTLIST_ACCESS, client, DixWriteAccess) != Success)
return FALSE; return FALSE;
return LocalClient(client); return LocalClient(client);