summaryrefslogtreecommitdiff
path: root/Xext
diff options
context:
space:
mode:
authorPeter Harris <pharris@opentext.com>2013-07-15 19:44:45 -0400
committerAdam Jackson <ajax@redhat.com>2013-09-10 13:26:25 -0400
commit132507eba93e4dfd466d5c30c9b818cdc6f8536e (patch)
treeab63f28f009c1272a9aa84f05b2074d2d3af9a7b /Xext
parent20c2a3bcb11b5baf564e2c73a477ba23f5ae2b10 (diff)
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>
Diffstat (limited to 'Xext')
-rw-r--r--Xext/security.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/Xext/security.c b/Xext/security.c
index 6cc9aa044..7bf6cc4b0 100644
--- a/Xext/security.c
+++ b/Xext/security.c
@@ -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);
}