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 */
|
/* This is what we store as client security state */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int haveState;
|
unsigned int haveState :1;
|
||||||
unsigned int trustLevel;
|
unsigned int live :1;
|
||||||
|
unsigned int trustLevel :2;
|
||||||
XID authId;
|
XID authId;
|
||||||
} SecurityStateRec;
|
} SecurityStateRec;
|
||||||
|
|
||||||
|
@ -141,6 +142,7 @@ SecurityLabelInitial(void)
|
||||||
state = dixLookupPrivate(&serverClient->devPrivates, stateKey);
|
state = dixLookupPrivate(&serverClient->devPrivates, stateKey);
|
||||||
state->trustLevel = XSecurityClientTrusted;
|
state->trustLevel = XSecurityClientTrusted;
|
||||||
state->haveState = TRUE;
|
state->haveState = TRUE;
|
||||||
|
state->live = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -953,6 +955,7 @@ SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
|
||||||
state->trustLevel = XSecurityClientTrusted;
|
state->trustLevel = XSecurityClientTrusted;
|
||||||
state->authId = None;
|
state->authId = None;
|
||||||
state->haveState = TRUE;
|
state->haveState = TRUE;
|
||||||
|
state->live = FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ClientStateRunning:
|
case ClientStateRunning:
|
||||||
|
@ -963,6 +966,7 @@ SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
|
||||||
if (rc == Success) {
|
if (rc == Success) {
|
||||||
/* it is a generated authorization */
|
/* it is a generated authorization */
|
||||||
pAuth->refcnt++;
|
pAuth->refcnt++;
|
||||||
|
state->live = TRUE;
|
||||||
if (pAuth->refcnt == 1 && pAuth->timer)
|
if (pAuth->refcnt == 1 && pAuth->timer)
|
||||||
TimerCancel(pAuth->timer);
|
TimerCancel(pAuth->timer);
|
||||||
|
|
||||||
|
@ -975,9 +979,10 @@ SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
|
||||||
rc = dixLookupResourceByType((pointer *) &pAuth, state->authId,
|
rc = dixLookupResourceByType((pointer *) &pAuth, state->authId,
|
||||||
SecurityAuthorizationResType, serverClient,
|
SecurityAuthorizationResType, serverClient,
|
||||||
DixGetAttrAccess);
|
DixGetAttrAccess);
|
||||||
if (rc == Success) {
|
if (rc == Success && state->live) {
|
||||||
/* it is a generated authorization */
|
/* it is a generated authorization */
|
||||||
pAuth->refcnt--;
|
pAuth->refcnt--;
|
||||||
|
state->live = FALSE;
|
||||||
if (pAuth->refcnt == 0)
|
if (pAuth->refcnt == 0)
|
||||||
SecurityStartAuthorizationTimer(pAuth);
|
SecurityStartAuthorizationTimer(pAuth);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue