diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2013-03-09 14:40:33 -0800 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2013-04-26 17:32:34 -0700 |
commit | 67ecdcf7e29de9fa78b421122620525ed2c7db88 (patch) | |
tree | ffb91f5de73a7937d33fe243dfdca704bcbce4af | |
parent | 96d1da55a08c4cd52b763cb07bdce5cdcbec4da8 (diff) |
integer overflow in XeviGetVisualInfo() [CVE-2013-1982 4/6]
If the number of visuals or conflicts 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 buffer we allocated to hold them.
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r-- | src/XEVI.c | 25 |
1 files changed, 18 insertions, 7 deletions
@@ -30,6 +30,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> #include <X11/Xutil.h> +#include <limits.h> #include "eat.h" static XExtensionInfo *xevi_info;/* needs to move to globals.c */ @@ -165,13 +166,20 @@ Status XeviGetVisualInfo( return BadAccess; } Xfree(temp_visual); - sz_info = rep.n_info * sizeof(ExtendedVisualInfo); - sz_xInfo = rep.n_info * sz_xExtendedVisualInfo; - sz_conflict = rep.n_conflicts * sizeof(VisualID); - sz_xConflict = rep.n_conflicts * sz_VisualID32; - infoPtr = *evi_return = (ExtendedVisualInfo *)Xmalloc(sz_info + sz_conflict); - xInfoPtr = temp_xInfo = (xExtendedVisualInfo *)Xmalloc(sz_xInfo); - xConflictPtr = temp_conflict = (VisualID32 *)Xmalloc(sz_xConflict); + if ((rep.n_info < 65536) && (rep.n_conflicts < 65536)) { + sz_info = rep.n_info * sizeof(ExtendedVisualInfo); + sz_xInfo = rep.n_info * sz_xExtendedVisualInfo; + sz_conflict = rep.n_conflicts * sizeof(VisualID); + sz_xConflict = rep.n_conflicts * sz_VisualID32; + *evi_return = Xmalloc(sz_info + sz_conflict); + temp_xInfo = Xmalloc(sz_xInfo); + temp_conflict = Xmalloc(sz_xConflict); + } else { + sz_xInfo = sz_xConflict = 0; + *evi_return = NULL; + temp_xInfo = NULL; + temp_conflict = NULL; + } if (!*evi_return || !temp_xInfo || !temp_conflict) { _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); @@ -188,6 +196,9 @@ Status XeviGetVisualInfo( _XRead(dpy, (char *)temp_conflict, sz_xConflict); UnlockDisplay(dpy); SyncHandle(); + infoPtr = *evi_return; + xInfoPtr = temp_xInfo; + xConflictPtr = temp_conflict; n_data = rep.n_info; conflict = (VisualID *)(infoPtr + n_data); while (n_data-- > 0) { |