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