summaryrefslogtreecommitdiff
path: root/Xext
diff options
context:
space:
mode:
Diffstat (limited to 'Xext')
-rw-r--r--Xext/security.c42
-rw-r--r--Xext/xselinux.c72
2 files changed, 73 insertions, 41 deletions
diff --git a/Xext/security.c b/Xext/security.c
index c9077c87e..7962fdb37 100644
--- a/Xext/security.c
+++ b/Xext/security.c
@@ -61,10 +61,10 @@ typedef struct {
} SecurityStateRec;
/* Extensions that untrusted clients shouldn't have access to */
-static char *SecurityUntrustedExtensions[] = {
- "RandR",
- "SECURITY",
- "XFree86-DGA",
+static char *SecurityTrustedExtensions[] = {
+ "XC-MISC",
+ "BIG-REQUESTS",
+ "XpExtension",
NULL
};
@@ -74,6 +74,7 @@ static char *SecurityUntrustedExtensions[] = {
static const Mask SecurityResourceMask =
DixGetAttrAccess | DixReceiveAccess | DixListPropAccess |
DixGetPropAccess | DixListAccess;
+static const Mask SecurityWindowExtraMask = DixRemoveAccess;
static const Mask SecurityRootWindowExtraMask =
DixReceiveAccess | DixSendAccess | DixAddAccess | DixRemoveAccess;
static const Mask SecurityDeviceMask =
@@ -817,6 +818,10 @@ SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
if (subj->haveState && subj->trustLevel != XSecurityClientTrusted)
((WindowPtr)rec->res)->forcedBG = TRUE;
+ /* additional permissions for specific resource types */
+ if (rec->rtype == RT_WINDOW)
+ allowed |= SecurityWindowExtraMask;
+
/* special checks for server-owned resources */
if (cid == 0) {
if (rec->rtype & RC_DRAWABLE)
@@ -852,16 +857,18 @@ SecurityExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
- if (subj->haveState && subj->trustLevel != XSecurityClientTrusted)
- while (SecurityUntrustedExtensions[i])
- if (!strcmp(SecurityUntrustedExtensions[i++], rec->ext->name)) {
- SecurityAudit("Security: denied client %d access to extension "
- "%s on request %s\n",
- rec->client->index, rec->ext->name,
- SecurityLookupRequestName(rec->client));
- rec->status = BadAccess;
- return;
- }
+ if (subj->haveState && subj->trustLevel == XSecurityClientTrusted)
+ return;
+
+ while (SecurityTrustedExtensions[i])
+ if (!strcmp(SecurityTrustedExtensions[i++], rec->ext->name))
+ return;
+
+ SecurityAudit("Security: denied client %d access to extension "
+ "%s on request %s\n",
+ rec->client->index, rec->ext->name,
+ SecurityLookupRequestName(rec->client));
+ rec->status = BadAccess;
}
static void
@@ -946,9 +953,10 @@ SecuritySend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
SecurityAudit("Security: denied client %d from sending event "
"of type %s to window 0x%x of client %d\n",
- rec->client->index, rec->pWin->drawable.id,
- wClient(rec->pWin)->index,
- LookupEventName(rec->events[i].u.u.type));
+ rec->client->index,
+ LookupEventName(rec->events[i].u.u.type),
+ rec->pWin->drawable.id,
+ wClient(rec->pWin)->index);
rec->status = BadAccess;
return;
}
diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 4a1fe004b..2c7262140 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -1258,6 +1258,17 @@ typedef struct {
CARD32 id;
} SELinuxListItemRec;
+static security_context_t
+SELinuxCopyContext(char *ptr, unsigned len)
+{
+ security_context_t copy = xalloc(len + 1);
+ if (!copy)
+ return NULL;
+ strncpy(copy, ptr, len);
+ copy[len] = '\0';
+ return copy;
+}
+
static int
ProcSELinuxQueryVersion(ClientPtr client)
{
@@ -1315,29 +1326,34 @@ ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
{
PrivateRec **privPtr = &client->devPrivates;
security_id_t *pSid;
- security_context_t ctx;
+ security_context_t ctx = NULL;
char *ptr;
+ int rc;
REQUEST(SELinuxSetCreateContextReq);
REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len);
- ctx = (char *)(stuff + 1);
- if (stuff->context_len > 0 && ctx[stuff->context_len - 1])
- return BadLength;
+ if (stuff->context_len > 0) {
+ ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len);
+ if (!ctx)
+ return BadAlloc;
+ }
if (offset == CTX_DEV) {
/* Device create context currently requires manage permission */
- int rc = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess);
+ rc = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess);
if (rc != Success)
- return rc;
+ goto out;
privPtr = &serverClient->devPrivates;
}
else if (offset == USE_SEL) {
/* Selection use context currently requires no selections owned */
Selection *pSel;
for (pSel = CurrentSelections; pSel; pSel = pSel->next)
- if (pSel->client == client)
- return BadMatch;
+ if (pSel->client == client) {
+ rc = BadMatch;
+ goto out;
+ }
}
ptr = dixLookupPrivate(privPtr, subjectKey);
@@ -1345,13 +1361,15 @@ ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
sidput(*pSid);
*pSid = NULL;
+ rc = Success;
if (stuff->context_len > 0) {
- if (security_check_context_raw(ctx) < 0)
- return BadValue;
- if (avc_context_to_sid_raw(ctx, pSid) < 0)
- return BadValue;
+ if (security_check_context_raw(ctx) < 0 ||
+ avc_context_to_sid_raw(ctx, pSid) < 0)
+ rc = BadValue;
}
- return Success;
+out:
+ xfree(ctx);
+ return rc;
}
static int
@@ -1384,18 +1402,21 @@ ProcSELinuxSetDeviceContext(ClientPtr client)
REQUEST(SELinuxSetContextReq);
REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len);
- ctx = (char *)(stuff + 1);
- if (stuff->context_len < 1 || ctx[stuff->context_len - 1])
+ if (stuff->context_len < 1)
return BadLength;
+ ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len);
+ if (!ctx)
+ return BadAlloc;
rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess);
if (rc != Success)
- return rc;
+ goto out;
- if (security_check_context_raw(ctx) < 0)
- return BadValue;
- if (avc_context_to_sid_raw(ctx, &sid) < 0)
- return BadValue;
+ if (security_check_context_raw(ctx) < 0 ||
+ avc_context_to_sid_raw(ctx, &sid) < 0) {
+ rc = BadValue;
+ goto out;
+ }
subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
sidput(subj->sid);
@@ -1404,7 +1425,10 @@ ProcSELinuxSetDeviceContext(ClientPtr client)
sidput(obj->sid);
sidget(obj->sid = sid);
- return Success;
+ rc = Success;
+out:
+ xfree(ctx);
+ return rc;
}
static int
@@ -1543,7 +1567,7 @@ SELinuxSendItemsToClient(ClientPtr client, SELinuxListItemRec *items,
CARD32 *buf;
buf = xcalloc(size, sizeof(CARD32));
- if (!buf) {
+ if (size && !buf) {
rc = BadAlloc;
goto out;
}
@@ -1615,7 +1639,7 @@ ProcSELinuxListProperties(ClientPtr client)
for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
count++;
items = xcalloc(count, sizeof(SELinuxListItemRec));
- if (!items)
+ if (count && !items)
return BadAlloc;
/* Fill in the items and calculate size */
@@ -1649,7 +1673,7 @@ ProcSELinuxListSelections(ClientPtr client)
for (pSel = CurrentSelections; pSel; pSel = pSel->next)
count++;
items = xcalloc(count, sizeof(SELinuxListItemRec));
- if (!items)
+ if (count && !items)
return BadAlloc;
/* Fill in the items and calculate size */