diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2009-04-08 15:10:16 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2009-04-08 16:05:11 -0400 |
commit | feb01d7d6e98fa77f9069b08aaa9727368ef3aaf (patch) | |
tree | 921770231070e609ba09b7769f4eca5c21f75d64 | |
parent | b7dc7374bbcb708eee6eec26ff141619f914d8eb (diff) |
xselinux: Don't require incoming context strings to be null-terminated.
(cherry picked from commit e8b324102f6e21ae2b8292a6f50d016dd6254dd6)
-rw-r--r-- | Xext/xselinux.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 226a4b418..a175c2caf 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -1261,6 +1261,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) { @@ -1318,29 +1329,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); @@ -1348,13 +1364,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 @@ -1387,18 +1405,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); @@ -1407,7 +1428,10 @@ ProcSELinuxSetDeviceContext(ClientPtr client) sidput(obj->sid); sidget(obj->sid = sid); - return Success; + rc = Success; +out: + xfree(ctx); + return rc; } static int |