xace: add a new hook for checking property content after it has been set.

Allows security modules to enforce what property contents can be set by
clients.  Uses the new DixPostAccess bit to distinguish between the
existing call made during the lookup (with the old property data) and
this new call.  Note that this only applies to writes, prepends, or
appends to existing properties; for new properties the existing
DixCreateAccess hook call may be used since it includes the new data.

Refer to the XACE-Spec document in xorg-docs, section "Property Access."

Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
This commit is contained in:
Eamon Walsh 2009-06-26 16:51:22 -04:00
parent 51105de9b0
commit 31166c2ae0

View File

@ -253,6 +253,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
pointer value, Bool sendevent)
{
PropertyPtr pProp;
PropertyRec savedProp;
int sizeInBytes, totalSize, rc;
pointer data;
Mask access_mode;
@ -307,15 +308,16 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
return(BadMatch);
if ((pProp->type != type) && (mode != PropModeReplace))
return(BadMatch);
/* save the old values for later */
savedProp = *pProp;
if (mode == PropModeReplace)
{
if (totalSize != pProp->size * (pProp->format >> 3))
{
data = (pointer)xrealloc(pProp->data, totalSize);
if (!data && len)
return(BadAlloc);
pProp->data = data;
}
data = xalloc(totalSize);
if (!data && len)
return(BadAlloc);
pProp->data = data;
if (len)
memmove((char *)pProp->data, (char *)value, totalSize);
pProp->size = len;
@ -328,10 +330,10 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
}
else if (mode == PropModeAppend)
{
data = (pointer)xrealloc(pProp->data,
sizeInBytes * (len + pProp->size));
data = xalloc((pProp->size + len) * sizeInBytes);
if (!data)
return(BadAlloc);
memcpy(data, pProp->data, pProp->size * sizeInBytes);
pProp->data = data;
memmove(&((char *)data)[pProp->size * sizeInBytes],
(char *)value,
@ -346,10 +348,20 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
memmove(&((char *)data)[totalSize], (char *)pProp->data,
(int)(pProp->size * sizeInBytes));
memmove((char *)data, (char *)value, totalSize);
xfree(pProp->data);
pProp->data = data;
pProp->size += len;
}
/* Allow security modules to check the new content */
access_mode |= DixPostAccess;
rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode);
if (rc == Success)
xfree(savedProp.data);
else {
xfree(pProp->data);
*pProp = savedProp;
return rc;
}
}
else
return rc;