From 31166c2ae0ce898c96995a8b16b58b127dc85a2f Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Fri, 26 Jun 2009 16:51:22 -0400 Subject: [PATCH] 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 --- dix/property.c | 32 ++++++++++++++++++++++---------- 1 file 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;