security: Don't count RetainPermanent clients twice
If a RetainPermanent client is subsequently killed by a KillClient request, the reference count is decremented twice. This can cause the server to prematurely kill other clients using the same Authorization. Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Peter Harris <pharris@opentext.com>
This commit is contained in:
		
							parent
							
								
									20c2a3bcb1
								
							
						
					
					
						commit
						132507eba9
					
				| 
						 | 
				
			
			@ -57,8 +57,9 @@ static DevPrivateKeyRec stateKeyRec;
 | 
			
		|||
 | 
			
		||||
/* This is what we store as client security state */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    int haveState;
 | 
			
		||||
    unsigned int trustLevel;
 | 
			
		||||
    unsigned int haveState  :1;
 | 
			
		||||
    unsigned int live       :1;
 | 
			
		||||
    unsigned int trustLevel :2;
 | 
			
		||||
    XID authId;
 | 
			
		||||
} SecurityStateRec;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,6 +142,7 @@ SecurityLabelInitial(void)
 | 
			
		|||
    state = dixLookupPrivate(&serverClient->devPrivates, stateKey);
 | 
			
		||||
    state->trustLevel = XSecurityClientTrusted;
 | 
			
		||||
    state->haveState = TRUE;
 | 
			
		||||
    state->live = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -953,6 +955,7 @@ SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 | 
			
		|||
        state->trustLevel = XSecurityClientTrusted;
 | 
			
		||||
        state->authId = None;
 | 
			
		||||
        state->haveState = TRUE;
 | 
			
		||||
        state->live = FALSE;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case ClientStateRunning:
 | 
			
		||||
| 
						 | 
				
			
			@ -963,6 +966,7 @@ SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 | 
			
		|||
        if (rc == Success) {
 | 
			
		||||
            /* it is a generated authorization */
 | 
			
		||||
            pAuth->refcnt++;
 | 
			
		||||
            state->live = TRUE;
 | 
			
		||||
            if (pAuth->refcnt == 1 && pAuth->timer)
 | 
			
		||||
                TimerCancel(pAuth->timer);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -975,9 +979,10 @@ SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 | 
			
		|||
        rc = dixLookupResourceByType((pointer *) &pAuth, state->authId,
 | 
			
		||||
                                     SecurityAuthorizationResType, serverClient,
 | 
			
		||||
                                     DixGetAttrAccess);
 | 
			
		||||
        if (rc == Success) {
 | 
			
		||||
        if (rc == Success && state->live) {
 | 
			
		||||
            /* it is a generated authorization */
 | 
			
		||||
            pAuth->refcnt--;
 | 
			
		||||
            state->live = FALSE;
 | 
			
		||||
            if (pAuth->refcnt == 0)
 | 
			
		||||
                SecurityStartAuthorizationTimer(pAuth);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue