xselinux: Don't require incoming context strings to be null-terminated.
This commit is contained in:
parent
df27b870a8
commit
e8b324102f
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user