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;
|
CARD32 id;
|
||||||
} SELinuxListItemRec;
|
} 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
|
static int
|
||||||
ProcSELinuxQueryVersion(ClientPtr client)
|
ProcSELinuxQueryVersion(ClientPtr client)
|
||||||
{
|
{
|
||||||
|
@ -1315,29 +1326,34 @@ ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
|
||||||
{
|
{
|
||||||
PrivateRec **privPtr = &client->devPrivates;
|
PrivateRec **privPtr = &client->devPrivates;
|
||||||
security_id_t *pSid;
|
security_id_t *pSid;
|
||||||
security_context_t ctx;
|
security_context_t ctx = NULL;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
int rc;
|
||||||
|
|
||||||
REQUEST(SELinuxSetCreateContextReq);
|
REQUEST(SELinuxSetCreateContextReq);
|
||||||
REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len);
|
REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len);
|
||||||
|
|
||||||
ctx = (char *)(stuff + 1);
|
if (stuff->context_len > 0) {
|
||||||
if (stuff->context_len > 0 && ctx[stuff->context_len - 1])
|
ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len);
|
||||||
return BadLength;
|
if (!ctx)
|
||||||
|
return BadAlloc;
|
||||||
|
}
|
||||||
|
|
||||||
if (offset == CTX_DEV) {
|
if (offset == CTX_DEV) {
|
||||||
/* Device create context currently requires manage permission */
|
/* 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)
|
if (rc != Success)
|
||||||
return rc;
|
goto out;
|
||||||
privPtr = &serverClient->devPrivates;
|
privPtr = &serverClient->devPrivates;
|
||||||
}
|
}
|
||||||
else if (offset == USE_SEL) {
|
else if (offset == USE_SEL) {
|
||||||
/* Selection use context currently requires no selections owned */
|
/* Selection use context currently requires no selections owned */
|
||||||
Selection *pSel;
|
Selection *pSel;
|
||||||
for (pSel = CurrentSelections; pSel; pSel = pSel->next)
|
for (pSel = CurrentSelections; pSel; pSel = pSel->next)
|
||||||
if (pSel->client == client)
|
if (pSel->client == client) {
|
||||||
return BadMatch;
|
rc = BadMatch;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = dixLookupPrivate(privPtr, subjectKey);
|
ptr = dixLookupPrivate(privPtr, subjectKey);
|
||||||
|
@ -1345,13 +1361,15 @@ ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
|
||||||
sidput(*pSid);
|
sidput(*pSid);
|
||||||
*pSid = NULL;
|
*pSid = NULL;
|
||||||
|
|
||||||
|
rc = Success;
|
||||||
if (stuff->context_len > 0) {
|
if (stuff->context_len > 0) {
|
||||||
if (security_check_context_raw(ctx) < 0)
|
if (security_check_context_raw(ctx) < 0 ||
|
||||||
return BadValue;
|
avc_context_to_sid_raw(ctx, pSid) < 0)
|
||||||
if (avc_context_to_sid_raw(ctx, pSid) < 0)
|
rc = BadValue;
|
||||||
return BadValue;
|
|
||||||
}
|
}
|
||||||
return Success;
|
out:
|
||||||
|
xfree(ctx);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1384,18 +1402,21 @@ ProcSELinuxSetDeviceContext(ClientPtr client)
|
||||||
REQUEST(SELinuxSetContextReq);
|
REQUEST(SELinuxSetContextReq);
|
||||||
REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len);
|
REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len);
|
||||||
|
|
||||||
ctx = (char *)(stuff + 1);
|
if (stuff->context_len < 1)
|
||||||
if (stuff->context_len < 1 || ctx[stuff->context_len - 1])
|
|
||||||
return BadLength;
|
return BadLength;
|
||||||
|
ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len);
|
||||||
|
if (!ctx)
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess);
|
rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess);
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return rc;
|
goto out;
|
||||||
|
|
||||||
if (security_check_context_raw(ctx) < 0)
|
if (security_check_context_raw(ctx) < 0 ||
|
||||||
return BadValue;
|
avc_context_to_sid_raw(ctx, &sid) < 0) {
|
||||||
if (avc_context_to_sid_raw(ctx, &sid) < 0)
|
rc = BadValue;
|
||||||
return BadValue;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
|
subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
|
||||||
sidput(subj->sid);
|
sidput(subj->sid);
|
||||||
|
@ -1404,7 +1425,10 @@ ProcSELinuxSetDeviceContext(ClientPtr client)
|
||||||
sidput(obj->sid);
|
sidput(obj->sid);
|
||||||
sidget(obj->sid = sid);
|
sidget(obj->sid = sid);
|
||||||
|
|
||||||
return Success;
|
rc = Success;
|
||||||
|
out:
|
||||||
|
xfree(ctx);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Reference in New Issue
Block a user