[PATCH xserver] Don't count RetainPermanent clients twice in security.c

Peter Harris pharris at opentext.com
Mon Jul 15 16:44:45 PDT 2013


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.

Signed-off-by: Peter Harris <pharris at opentext.com>
---
 Xext/security.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Xext/security.c b/Xext/security.c
index 6cc9aa0..7bf6cc4 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);
         }
-- 
1.7.10.4



More information about the xorg-devel mailing list