diff options
author | Keith Packard <keithp@keithp.com> | 2016-06-07 16:31:14 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2016-07-05 01:36:23 +0200 |
commit | 8ce22de4deb3b6cc7b1d3bfc9498d1747b8f033c (patch) | |
tree | e43840e60a8715347e92e5f94f44da3b12376ed0 | |
parent | ee090f9785571343235d5ebda070bca37ab600cb (diff) |
security: Start hacking on security extensionsecure-x
Provide three levels, trusted, normal and untrusted. Assign them based
on UID.
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | Xext/security.c | 99 | ||||
-rw-r--r-- | include/dixaccess.h | 1 |
2 files changed, 90 insertions, 10 deletions
diff --git a/Xext/security.c b/Xext/security.c index 8cb3a2c73..c7977cf60 100644 --- a/Xext/security.c +++ b/Xext/security.c @@ -64,18 +64,72 @@ typedef struct { } SecurityStateRec; /* The only extensions that untrusted clients have access to */ -static const char *SecurityTrustedExtensions[] = { +static const char *SecurityNormalExtensions[] = { + "BIG-REQUESTS", + "DAMAGE", + "DOUBLE-BUFFER", + "DPMS", + "DRI2", + "DRI3", + "GLX", + "Generic Event Extension", + "MIT-SCREEN-SAVER", + "MIT-SHM", + "Present", + "RANDR", + "RENDER", + "SGI-GLX", + "SHAPE", + "SYNC", + "X-Resource", + "XC-MISC", + "XFIXES", + "XINERAMA", + "XInputExtension", + "XKEYBOARD", + "XVideo", "XC-MISC", + NULL +}; + +static const char *SecurityUntrustedExtensions[] = { "BIG-REQUESTS", + "DAMAGE", + "DOUBLE-BUFFER", + "DRI3", + "GLX", + "Generic Event Extension", + "MIT-SHM", + "Present", + "RANDR", + "RENDER", + "SGI-GLX", + "SHAPE", + "SYNC", + "X-Resource", + "XC-MISC", + "XFIXES", + "XINERAMA", + "XInputExtension", + "XKEYBOARD", + "XVideo", + "XC-MISC", NULL }; /* * Access modes that untrusted clients are allowed on trusted objects. */ -static const Mask SecurityResourceMask = - DixGetAttrAccess | DixReceiveAccess | DixListPropAccess | - DixGetPropAccess | DixListAccess; +static const Mask SecurityResourceMask[] = { + [XSecurityClientTrusted] = ~0, + [XSecurityClientNormal] = ~0, + [XSecurityClientUntrusted] = (DixGetAttrAccess | + DixReceiveAccess | + DixListPropAccess | + DixGetPropAccess | + DixListAccess) +}; + static const Mask SecurityWindowExtraMask = DixRemoveAccess; static const Mask SecurityRootWindowExtraMask = DixReceiveAccess | DixSendAccess | DixAddAccess | DixRemoveAccess; @@ -438,6 +492,7 @@ ProcSecurityGenerateAuthorization(ClientPtr client) if (stuff->valueMask & XSecurityTrustLevel) { trustLevel = *values++; if (trustLevel != XSecurityClientTrusted && + trustLevel != XSecurityClientNormal && trustLevel != XSecurityClientUntrusted) { client->errorValue = trustLevel; return BadValue; @@ -742,13 +797,15 @@ SecurityResource(CallbackListPtr *pcbl, void *unused, void *calldata) SecurityStateRec *subj, *obj; int cid = CLIENT_ID(rec->id); Mask requested = rec->access_mode; - Mask allowed = SecurityResourceMask; + Mask allowed; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); + allowed = SecurityResourceMask[subj->trustLevel]; + /* disable background None for untrusted windows */ if ((requested & DixCreateAccess) && (rec->rtype == RT_WINDOW)) - if (subj->haveState && subj->trustLevel != XSecurityClientTrusted) + if (subj->haveState && !(allowed & DixBGNoneAccess)) ((WindowPtr) rec->res)->forcedBG = TRUE; /* additional permissions for specific resource types */ @@ -788,6 +845,7 @@ SecurityExtension(CallbackListPtr *pcbl, void *unused, void *calldata) { XaceExtAccessRec *rec = calldata; SecurityStateRec *subj; + const char **extensions = NULL; int i = 0; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); @@ -795,8 +853,17 @@ SecurityExtension(CallbackListPtr *pcbl, void *unused, void *calldata) if (subj->haveState && subj->trustLevel == XSecurityClientTrusted) return; - while (SecurityTrustedExtensions[i]) - if (!strcmp(SecurityTrustedExtensions[i++], rec->ext->name)) + switch (subj->trustLevel) { + case XSecurityClientNormal: + extensions = SecurityNormalExtensions; + break; + case XSecurityClientUntrusted: + extensions = SecurityUntrustedExtensions; + break; + } + + while (extensions[i]) + if (!strcmp(extensions[i++], rec->ext->name)) return; SecurityAudit("Security: denied client %d access to extension " @@ -851,11 +918,13 @@ SecurityProperty(CallbackListPtr *pcbl, void *unused, void *calldata) SecurityStateRec *subj, *obj; ATOM name = (*rec->ppProp)->propertyName; Mask requested = rec->access_mode; - Mask allowed = SecurityResourceMask | DixReadAccess; + Mask allowed; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey); + allowed = SecurityResourceMask[subj->trustLevel] | DixReadAccess; + if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { SecurityAudit("Security: denied client %d access to property %s " "(atom 0x%x) window 0x%lx of client %d on request %s\n", @@ -946,12 +1015,22 @@ SecurityClientState(CallbackListPtr *pcbl, void *unused, void *calldata) SecurityStateRec *state; SecurityAuthorizationPtr pAuth; int rc; + LocalClientCredRec *lcc; state = dixLookupPrivate(&pci->client->devPrivates, stateKey); switch (pci->client->clientState) { case ClientStateInitial: - state->trustLevel = XSecurityClientTrusted; + state->trustLevel = XSecurityClientUntrusted; + if (GetLocalClientCreds(pci->client, &lcc) != -1) { + if (lcc->fieldsSet & LCC_UID_SET) { + if (lcc->euid == 0) + state->trustLevel = XSecurityClientTrusted; + else if (lcc->euid != 65534) + state->trustLevel = XSecurityClientNormal; + } + FreeLocalClientCreds(lcc); + } state->authId = None; state->haveState = TRUE; state->live = FALSE; diff --git a/include/dixaccess.h b/include/dixaccess.h index 784c83c64..98f57d110 100644 --- a/include/dixaccess.h +++ b/include/dixaccess.h @@ -50,5 +50,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DixDebugAccess (1<<26) /* debug object */ #define DixBellAccess (1<<27) /* audible sound */ #define DixPostAccess (1<<28) /* post or follow-up call */ +#define DixBGNoneAccess (1<<29) /* create bg none windows */ #endif /* DIX_ACCESS_H */ |