summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2008-03-20 19:42:09 -0400
committerEamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil>2008-03-20 19:42:09 -0400
commite323bb426ce8a072d119cb2720b773241259c137 (patch)
tree5f2abc0f4e4e01d5ec1e6faf35f1b84b63fd4017
parentda973e962d09854b571320dee7dd9569060bc39e (diff)
XSELinux: Correctly handle some permission bits that are used more than once.
-rw-r--r--Xext/xselinux.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 18c652645..303589860 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -152,6 +152,12 @@ static struct security_class_mapping map[] = {
{ NULL }
};
+/* x_resource "read" bits from the list above */
+#define SELinuxReadMask (DixReadAccess|DixGetAttrAccess|DixListPropAccess| \
+ DixGetPropAccess|DixGetFocusAccess|DixListAccess| \
+ DixShowAccess|DixBlendAccess|DixReceiveAccess| \
+ DixUseAccess|DixDebugAccess)
+
/* forward declarations */
static void SELinuxScreen(CallbackListPtr *, pointer, pointer);
@@ -853,6 +859,7 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
SELinuxObjectRec *obj, *data;
Selection *pSel = *rec->ppSel;
Atom name = pSel->selection;
+ Mask access_mode = rec->access_mode;
SELinuxAuditRec auditdata = { .client = rec->client, .selection = name };
security_id_t tsid;
int rc;
@@ -861,11 +868,12 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
obj = dixLookupPrivate(&pSel->devPrivates, objectKey);
/* If this is a new object that needs labeling, do it now */
- if (rec->access_mode & DixCreateAccess) {
+ if (access_mode & DixCreateAccess) {
sidput(obj->sid);
rc = SELinuxSelectionToSID(name, subj, &obj->sid, &obj->poly);
if (rc != Success)
obj->sid = unlabeled_sid;
+ access_mode = DixSetAttrAccess;
}
/* If this is a polyinstantiated object, find the right instance */
else if (obj->poly) {
@@ -890,13 +898,13 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
}
/* Perform the security check */
- rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SELECTION, rec->access_mode,
+ rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SELECTION, access_mode,
&auditdata);
if (rc != Success)
rec->status = rc;
/* Label the content (advisory only) */
- if (rec->access_mode & DixSetAttrAccess) {
+ if (access_mode & DixSetAttrAccess) {
data = dixLookupPrivate(&pSel->devPrivates, dataKey);
sidput(data->sid);
if (subj->sel_create_sid)
@@ -976,6 +984,7 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
SELinuxSubjectRec *subj;
SELinuxObjectRec *obj;
SELinuxAuditRec auditdata = { .client = rec->client };
+ Mask access_mode = rec->access_mode;
PrivateRec **privatePtr;
security_class_t class;
int rc, offset;
@@ -997,7 +1006,7 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
}
/* If this is a new object that needs labeling, do it now */
- if (rec->access_mode & DixCreateAccess && offset >= 0) {
+ if (access_mode & DixCreateAccess && offset >= 0) {
rc = SELinuxLabelResource(rec, subj, obj, class);
if (rc != Success) {
rec->status = rc;
@@ -1005,10 +1014,16 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
}
}
+ /* Collapse generic resource permissions down to read/write */
+ if (class == SECCLASS_X_RESOURCE) {
+ access_mode = !!(rec->access_mode & SELinuxReadMask); /* rd */
+ access_mode |= !!(rec->access_mode & ~SELinuxReadMask) << 1; /* wr */
+ }
+
/* Perform the security check */
auditdata.restype = rec->rtype;
auditdata.id = rec->id;
- rc = SELinuxDoCheck(subj, obj, class, rec->access_mode, &auditdata);
+ rc = SELinuxDoCheck(subj, obj, class, access_mode, &auditdata);
if (rc != Success)
rec->status = rc;
}