XACE: Add generic support for property and selection polyinstantiation.
This commit is contained in:
parent
34bf308a9e
commit
cc76ea6e3a
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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++;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue