XACE: Add generic support for property and selection polyinstantiation.

This commit is contained in:
Eamon Walsh 2008-02-29 17:55:31 -05:00 committed by Eamon Walsh
parent 34bf308a9e
commit cc76ea6e3a
7 changed files with 36 additions and 31 deletions

View File

@ -910,7 +910,7 @@ SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
{ {
XacePropertyAccessRec *rec = calldata; XacePropertyAccessRec *rec = calldata;
SecurityStateRec *subj, *obj; SecurityStateRec *subj, *obj;
ATOM name = rec->pProp->propertyName; ATOM name = (*rec->ppProp)->propertyName;
Mask requested = rec->access_mode; Mask requested = rec->access_mode;
Mask allowed = SecurityResourceMask | DixReadAccess; Mask allowed = SecurityResourceMask | DixReadAccess;

View File

@ -56,16 +56,17 @@ int XaceHookDispatch(ClientPtr client, int major)
} }
int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin, int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin,
PropertyPtr pProp, Mask access_mode) PropertyPtr *ppProp, Mask access_mode)
{ {
XacePropertyAccessRec rec = { client, pWin, pProp, access_mode, Success }; XacePropertyAccessRec rec = { client, pWin, ppProp, access_mode, Success };
CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec); CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec);
return rec.status; return rec.status;
} }
int XaceHookSelectionAccess(ClientPtr client, Atom name, Mask access_mode) int XaceHookSelectionAccess(ClientPtr client,
Selection **ppSel, Mask access_mode)
{ {
XaceSelectionAccessRec rec = { client, name, access_mode, Success }; XaceSelectionAccessRec rec = { client, ppSel, access_mode, Success };
CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec); CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec);
return rec.status; return rec.status;
} }

View File

@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "region.h" #include "region.h"
#include "window.h" #include "window.h"
#include "property.h" #include "property.h"
#include "selection.h"
/* Default window background */ /* Default window background */
#define XaceBackgroundNoneState(w) ((w)->forcedBG ? BackgroundPixel : None) #define XaceBackgroundNoneState(w) ((w)->forcedBG ? BackgroundPixel : None)
@ -68,9 +69,9 @@ extern int XaceHook(
*/ */
extern int XaceHookDispatch(ClientPtr ptr, int major); extern int XaceHookDispatch(ClientPtr ptr, int major);
extern int XaceHookPropertyAccess(ClientPtr ptr, WindowPtr pWin, extern int XaceHookPropertyAccess(ClientPtr ptr, WindowPtr pWin,
PropertyPtr pProp, Mask access_mode); PropertyPtr *ppProp, Mask access_mode);
extern int XaceHookSelectionAccess(ClientPtr ptr, Atom name, extern int XaceHookSelectionAccess(ClientPtr ptr,
Mask access_mode); Selection **ppSel, Mask access_mode);
extern void XaceHookAuditEnd(ClientPtr ptr, int result); extern void XaceHookAuditEnd(ClientPtr ptr, int result);
/* Register a callback for a given hook. /* Register a callback for a given hook.

View File

@ -59,7 +59,7 @@ typedef struct {
typedef struct { typedef struct {
ClientPtr client; ClientPtr client;
WindowPtr pWin; WindowPtr pWin;
PropertyPtr pProp; PropertyPtr *ppProp;
Mask access_mode; Mask access_mode;
int status; int status;
} XacePropertyAccessRec; } XacePropertyAccessRec;
@ -110,7 +110,7 @@ typedef struct {
/* XACE_SELECTION_ACCESS */ /* XACE_SELECTION_ACCESS */
typedef struct { typedef struct {
ClientPtr client; ClientPtr client;
Atom name; Selection **ppSel;
Mask access_mode; Mask access_mode;
int status; int status;
} XaceSelectionAccessRec; } XaceSelectionAccessRec;

View File

@ -134,7 +134,7 @@ static struct security_class_mapping map[] = {
{ "x_gc", { "", "", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_gc", { "", "", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
{ "x_font", { "", "", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_glyph", "remove_glyph", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_font", { "", "", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_glyph", "remove_glyph", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
{ "x_colormap", { "read", "write", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_color", "remove_color", "", "", "", "", "", "", "install", "uninstall", "", "", "use", NULL }}, { "x_colormap", { "read", "write", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_color", "remove_color", "", "", "", "", "", "", "install", "uninstall", "", "", "use", NULL }},
{ "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", NULL }}, { "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "write", NULL }},
{ "x_selection", { "read", "", "", "", "getattr", "setattr", NULL }}, { "x_selection", { "read", "", "", "", "getattr", "setattr", NULL }},
{ "x_cursor", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_cursor", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
{ "x_client", { "", "", "destroy", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "manage", NULL }}, { "x_client", { "", "", "destroy", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "manage", NULL }},
@ -691,14 +691,15 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
SELinuxSubjectRec *subj; SELinuxSubjectRec *subj;
SELinuxObjectRec *obj; SELinuxObjectRec *obj;
SELinuxAuditRec auditdata = { .client = rec->client }; SELinuxAuditRec auditdata = { .client = rec->client };
PropertyPtr pProp = *rec->ppProp;
int rc; int rc;
subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
obj = dixLookupPrivate(&rec->pProp->devPrivates, objectKey); obj = dixLookupPrivate(&pProp->devPrivates, objectKey);
/* If this is a new object that needs labeling, do it now */ /* If this is a new object that needs labeling, do it now */
if (rec->access_mode & DixCreateAccess) { if (rec->access_mode & DixCreateAccess) {
const char *name = NameForAtom(rec->pProp->propertyName); const char *name = NameForAtom(pProp->propertyName);
security_context_t con; security_context_t con;
security_id_t sid; security_id_t sid;
@ -729,7 +730,7 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
} }
/* Perform the security check */ /* Perform the security check */
auditdata.property = rec->pProp->propertyName; auditdata.property = pProp->propertyName;
rc = SELinuxDoCheck(subj, obj, SECCLASS_X_PROPERTY, rec->access_mode, rc = SELinuxDoCheck(subj, obj, SECCLASS_X_PROPERTY, rec->access_mode,
&auditdata); &auditdata);
if (rc != Success) if (rc != Success)
@ -870,17 +871,21 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
SELinuxSubjectRec *subj; SELinuxSubjectRec *subj;
SELinuxObjectRec sel_sid; SELinuxObjectRec sel_sid;
SELinuxAuditRec auditdata = { .client = rec->client }; SELinuxAuditRec auditdata = { .client = rec->client };
Selection *pSel = *rec->ppSel;
int rc; int rc;
if (rec->access_mode & DixCreateAccess)
return; /* don't use create currently */
subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
rc = SELinuxSelectionToSID(rec->name, &sel_sid); rc = SELinuxSelectionToSID(pSel->selection, &sel_sid);
if (rc != Success) { if (rc != Success) {
rec->status = rc; rec->status = rc;
return; return;
} }
auditdata.selection = rec->name; auditdata.selection = pSel->selection;
rc = SELinuxDoCheck(subj, &sel_sid, SECCLASS_X_SELECTION, rec->access_mode, rc = SELinuxDoCheck(subj, &sel_sid, SECCLASS_X_SELECTION, rec->access_mode,
&auditdata); &auditdata);
if (rc != Success) if (rc != Success)
@ -1206,16 +1211,8 @@ ProcSELinuxGetPropertyContext(ClientPtr client)
if (rc != Success) if (rc != Success)
return rc; return rc;
pProp = wUserProps(pWin); rc = dixLookupProperty(&pProp, pWin, stuff->property, client,
while (pProp) { DixGetAttrAccess);
if (pProp->propertyName == stuff->property)
break;
pProp = pProp->next;
}
if (!pProp)
return BadValue;
rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess);
if (rc != Success) if (rc != Success)
return rc; return rc;

View File

@ -103,7 +103,7 @@ dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName,
break; break;
if (pProp) if (pProp)
rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode); rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode);
*result = pProp; *result = pProp;
return rc; return rc;
} }
@ -256,12 +256,14 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
PropertyPtr pProp; PropertyPtr pProp;
int sizeInBytes, totalSize, rc; int sizeInBytes, totalSize, rc;
pointer data; pointer data;
Mask access_mode;
sizeInBytes = format>>3; sizeInBytes = format>>3;
totalSize = len * sizeInBytes; totalSize = len * sizeInBytes;
access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess;
/* first see if property already exists */ /* first see if property already exists */
rc = dixLookupProperty(&pProp, pWin, property, pClient, DixWriteAccess); rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode);
if (rc == BadMatch) /* just add to list */ if (rc == BadMatch) /* just add to list */
{ {
@ -284,7 +286,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
memmove((char *)data, (char *)value, totalSize); memmove((char *)data, (char *)value, totalSize);
pProp->size = len; pProp->size = len;
pProp->devPrivates = NULL; pProp->devPrivates = NULL;
rc = XaceHookPropertyAccess(pClient, pWin, pProp, rc = XaceHookPropertyAccess(pClient, pWin, &pProp,
DixCreateAccess|DixWriteAccess); DixCreateAccess|DixWriteAccess);
if (rc != Success) { if (rc != Success) {
xfree(data); xfree(data);
@ -588,7 +590,7 @@ ProcListProperties(ClientPtr client)
temppAtoms = pAtoms; temppAtoms = pAtoms;
for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) {
realProp = pProp; realProp = pProp;
rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess); rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess);
if (rc == Success && realProp == pProp) { if (rc == Success && realProp == pProp) {
*temppAtoms++ = pProp->propertyName; *temppAtoms++ = pProp->propertyName;
numProps++; numProps++;

View File

@ -80,7 +80,7 @@ dixLookupSelection(Selection **result, Atom selectionName,
for (i = 0; i < NumCurrentSelections; i++) for (i = 0; i < NumCurrentSelections; i++)
if (CurrentSelections[i].selection == selectionName) { if (CurrentSelections[i].selection == selectionName) {
pSel = CurrentSelections + i; pSel = CurrentSelections + i;
rc = XaceHookSelectionAccess(client, selectionName, access_mode); rc = XaceHookSelectionAccess(client, &pSel, access_mode);
break; break;
} }
@ -206,6 +206,10 @@ ProcSetSelectionOwner(ClientPtr client)
pSel = CurrentSelections + NumCurrentSelections; pSel = CurrentSelections + NumCurrentSelections;
pSel->selection = stuff->selection; pSel->selection = stuff->selection;
pSel->devPrivates = NULL; pSel->devPrivates = NULL;
/* security creation/labeling check */
(void)XaceHookSelectionAccess(client, &pSel, DixCreateAccess);
pSel->next = NULL; pSel->next = NULL;
if (NumCurrentSelections > 0) if (NumCurrentSelections > 0)
CurrentSelections[NumCurrentSelections - 1].next = pSel; CurrentSelections[NumCurrentSelections - 1].next = pSel;