summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-06-07 16:31:14 -0700
committerKeith Packard <keithp@keithp.com>2016-07-05 01:36:23 +0200
commit8ce22de4deb3b6cc7b1d3bfc9498d1747b8f033c (patch)
treee43840e60a8715347e92e5f94f44da3b12376ed0
parentee090f9785571343235d5ebda070bca37ab600cb (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.c99
-rw-r--r--include/dixaccess.h1
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 */