summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2013-03-09 14:40:33 -0800
committerAlan Coopersmith <alan.coopersmith@oracle.com>2013-05-02 22:48:06 -0700
commitdfe6e1f3b8ede3d0bab7a5fa57f73513a09ec649 (patch)
tree1e769bacd3f4f6399c4791adc07cf79ceca151a1
parent6ecd96e8be3c33e2ffad6631cea4aa0a030d93c2 (diff)
downloadxorg-lib-libXext-dfe6e1f3b8ede3d0bab7a5fa57f73513a09ec649.tar.gz
integer overflow in XSyncListSystemCounters() [CVE-2013-1982 6/6]
If the number of counters or amount of data reported by the server is large enough that it overflows when multiplied by the size of the appropriate struct, then memory corruption can occur when more bytes are read from the X server than the size of the buffers we allocated to hold them. V2: Make sure we don't walk past the end of the reply when converting data from wire format to the structures returned to the caller. Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r--src/XSync.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/src/XSync.c b/src/XSync.c
index 3ca1308..ce4ab44 100644
--- a/src/XSync.c
+++ b/src/XSync.c
@@ -59,6 +59,7 @@ PERFORMANCE OF THIS SOFTWARE.
#include <X11/extensions/extutil.h>
#include <X11/extensions/sync.h>
#include <X11/extensions/syncproto.h>
+#include <limits.h>
#include "eat.h"
static XExtensionInfo _sync_info_data;
@@ -352,19 +353,28 @@ XSyncListSystemCounters(Display *dpy, int *n_counters_return)
if (rep.nCounters > 0)
{
xSyncSystemCounter *pWireSysCounter, *pNextWireSysCounter;
+ xSyncSystemCounter *pLastWireSysCounter;
XSyncCounter counter;
- int replylen;
+ unsigned int replylen;
int i;
- list = Xmalloc(rep.nCounters * sizeof(XSyncSystemCounter));
- replylen = rep.length << 2;
- pWireSysCounter = Xmalloc ((unsigned) replylen + sizeof(XSyncCounter));
- /* +1 to leave room for last counter read-ahead */
+ if (rep.nCounters < (INT_MAX / sizeof(XSyncSystemCounter)))
+ list = Xmalloc(rep.nCounters * sizeof(XSyncSystemCounter));
+ if (rep.length < (INT_MAX >> 2)) {
+ replylen = rep.length << 2;
+ pWireSysCounter = Xmalloc (replylen + sizeof(XSyncCounter));
+ /* +1 to leave room for last counter read-ahead */
+ pLastWireSysCounter = (xSyncSystemCounter *)
+ ((char *)pWireSysCounter) + replylen;
+ } else {
+ replylen = 0;
+ pWireSysCounter = NULL;
+ }
if ((!list) || (!pWireSysCounter))
{
- if (list) Xfree((char *) list);
- if (pWireSysCounter) Xfree((char *) pWireSysCounter);
+ Xfree(list);
+ Xfree(pWireSysCounter);
_XEatDataWords(dpy, rep.length);
list = NULL;
goto bail;
@@ -388,6 +398,14 @@ XSyncListSystemCounters(Display *dpy, int *n_counters_return)
pNextWireSysCounter = (xSyncSystemCounter *)
(((char *)pWireSysCounter) + ((SIZEOF(xSyncSystemCounter) +
pWireSysCounter->name_length + 3) & ~3));
+ /* Make sure we haven't gone too far */
+ if (pNextWireSysCounter > pLastWireSysCounter) {
+ Xfree(list);
+ Xfree(pWireSysCounter);
+ list = NULL;
+ goto bail;
+ }
+
counter = pNextWireSysCounter->counter;
list[i].name = ((char *)pWireSysCounter) +