diff --git a/Xext/security.c b/Xext/security.c index af8d205..3aa5286 100644 --- a/Xext/security.c +++ b/Xext/security.c @@ -810,12 +810,24 @@ SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceResourceAccessRec *rec = calldata; SecurityStateRec *subj, *obj; - int cid = CLIENT_ID(rec->id); + int offset, cid = CLIENT_ID(rec->id); Mask requested = rec->access_mode; Mask allowed = SecurityResourceMask; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&clients[cid]->devPrivates, stateKey); + + /* Determine if the resource object has a devPrivates field */ + offset = dixLookupPrivateOffset(rec->rtype); + if (offset < 0) + /* No: use the trustLevel of the owning client */ + obj = dixLookupPrivate(&clients[cid]->devPrivates, stateKey); + else + /* Yes: use the trustLevel from the resource object itself */ + obj = dixLookupPrivate(DEVPRIV_AT(rec->res, offset), stateKey); + + /* If this is a new object with devPrivates, copy the owner's info */ + if ((requested & DixCreateAccess) && offset >= 0) + memcpy(obj, subj, sizeof(SecurityStateRec)); /* disable background None for untrusted windows */ if ((requested & DixCreateAccess) && (rec->rtype == RT_WINDOW))