diff -up xorg-server-1.1.1/Xext/EVI.c.jx xorg-server-1.1.1/Xext/EVI.c --- xorg-server-1.1.1/Xext/EVI.c.jx 2006-07-05 14:31:36.000000000 -0400 +++ xorg-server-1.1.1/Xext/EVI.c 2007-12-11 13:26:28.000000000 -0500 @@ -89,10 +89,22 @@ ProcEVIGetVisualInfo(ClientPtr client) { REQUEST(xEVIGetVisualInfoReq); xEVIGetVisualInfoReply rep; - int n, n_conflict, n_info, sz_info, sz_conflict; + int i, n, n_conflict, n_info, sz_info, sz_conflict; VisualID32 *conflict; + unsigned int total_visuals = 0; xExtendedVisualInfo *eviInfo; int status; + + /* + * do this first, otherwise REQUEST_FIXED_SIZE can overflow. we assume + * here that you don't have more than 2^32 visuals over all your screens; + * this seems like a safe assumption. + */ + for (i = 0; i < screenInfo.numScreens; i++) { + total_visuals += screenInfo.screens[i]->numVisuals; + if (stuff->n_visual > total_visuals) + return BadValue; + REQUEST_FIXED_SIZE(xEVIGetVisualInfoReq, stuff->n_visual * sz_VisualID32); status = eviPriv->getVisualInfo((VisualID32 *)&stuff[1], (int)stuff->n_visual, &eviInfo, &n_info, &conflict, &n_conflict); diff -up xorg-server-1.1.1/Xext/sampleEVI.c.jx xorg-server-1.1.1/Xext/sampleEVI.c --- xorg-server-1.1.1/Xext/sampleEVI.c.jx 2006-07-05 14:31:36.000000000 -0400 +++ xorg-server-1.1.1/Xext/sampleEVI.c 2007-12-11 13:38:08.000000000 -0500 @@ -49,19 +49,31 @@ static int sampleGetVisualInfo( xExtendedVisualInfo *evi; int max_visuals = 0, max_sz_conflict, sz_conflict = 0; register int visualI, scrI, sz_evi = 0, conflictI, n_conflict; - *evi_rn = evi = (xExtendedVisualInfo *)xalloc(max_sz_evi); - if (!*evi_rn) - return BadAlloc; + + if (max_sz_evi < n_visual || max_sz_evi < screenInfo.numScreens) + return BadAlloc; + for (scrI = 0; scrI < screenInfo.numScreens; scrI++) { if (screenInfo.screens[scrI]->numVisuals > max_visuals) max_visuals = screenInfo.screens[scrI]->numVisuals; } + max_sz_conflict = n_visual * sz_VisualID32 * screenInfo.numScreens * max_visuals; + if (max_sz_conflict < n_visual + || max_sz_conflict < screenInfo.numScreens + || max_sz_conflict < max_visuals) + return BadAlloc; + + *evi_rn = evi = (xExtendedVisualInfo *)xalloc(max_sz_evi); + if (!*evi_rn) + return BadAlloc; + temp_conflict = (VisualID32 *)xalloc(max_sz_conflict); if (!temp_conflict) { xfree(*evi_rn); return BadAlloc; } + for (scrI = 0; scrI < screenInfo.numScreens; scrI++) { for (visualI = 0; visualI < n_visual; visualI++) { evi[sz_evi].core_visual_id = visual[visualI];