summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2009-06-26 16:51:22 -0400
committerEamon Walsh <ewalsh@tycho.nsa.gov>2009-06-26 17:52:51 -0400
commit31166c2ae0ce898c96995a8b16b58b127dc85a2f (patch)
tree93ce56f5825ae5ed2be86dd4d3f8afbb3de3faeb
parent51105de9b0d865c4b5e5a7d9ab23c89d808d1cfa (diff)
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>
-rw-r--r--dix/property.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/dix/property.c b/dix/property.c
index 0929dca17..9aaf248d3 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -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;