- Patch by Dan Kegel: Fix minor read buffer overrun in CombineRgn. http://bugs.winehq.org/show_bug.cgi?id=20851
- When locking and unlocking regions, use probe to check attribute space first before read or write access.

svn path=/trunk/; revision=44902
This commit is contained in:
James Tabor 2010-01-03 00:05:15 +00:00
parent 241aaf9d5b
commit 1f8e0c8569
2 changed files with 27 additions and 12 deletions

View file

@ -750,7 +750,12 @@ GreDeleteObject(HGDIOBJ hObject)
{ {
return TRUE; return TRUE;
} }
if (pAttr) FreeObjectAttr(pAttr); if (pAttr)
{
KeEnterCriticalRegion();
FreeObjectAttr(pAttr);
KeLeaveCriticalRegion();
}
break; break;
case GDI_OBJECT_TYPE_DC: case GDI_OBJECT_TYPE_DC:

View file

@ -1650,7 +1650,8 @@ REGION_SubtractO(
pNextRect++; pNextRect++;
} }
r1++; r1++;
left = r1->left; if (r1 != r1End)
left = r1->left;
} }
} }
@ -2062,9 +2063,11 @@ REGION_AllocRgnWithHandle(INT nReg)
} }
} }
KeEnterCriticalRegion();
Index = GDI_HANDLE_GET_INDEX(hReg); Index = GDI_HANDLE_GET_INDEX(hReg);
Entry = &GdiHandleTable->Entries[Index]; Entry = &GdiHandleTable->Entries[Index];
Entry->UserData = AllocateObjectAttr(); Entry->UserData = AllocateObjectAttr();
KeLeaveCriticalRegion();
EMPTY_REGION(pReg); EMPTY_REGION(pReg);
pReg->rdh.dwSize = sizeof(RGNDATAHEADER); pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
@ -2081,22 +2084,26 @@ RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
INT Index; INT Index;
PGDI_TABLE_ENTRY Entry; PGDI_TABLE_ENTRY Entry;
PROSRGNDATA pRgn; PROSRGNDATA pRgn;
PRGN_ATTR pRgn_Attr; PRGN_ATTR pRgn_Attr;
pRgn = REGION_LockRgn(hRgn); pRgn = REGION_LockRgn(hRgn);
if (pRgn) if (pRgn)
{ {
KeEnterCriticalRegion();
Index = GDI_HANDLE_GET_INDEX(hRgn); Index = GDI_HANDLE_GET_INDEX(hRgn);
Entry = &GdiHandleTable->Entries[Index]; Entry = &GdiHandleTable->Entries[Index];
pRgn_Attr = Entry->UserData; pRgn_Attr = Entry->UserData;
KeLeaveCriticalRegion();
if (pRgn_Attr) if (pRgn_Attr)
{ {
_SEH2_TRY _SEH2_TRY
{ {
if ( pRgn_Attr->AttrFlags & (ATTR_RGN_VALID|ATTR_RGN_DIRTY) ) ProbeForWrite(pRgn_Attr, sizeof(RGN_ATTR), 1);
if ( !(pRgn_Attr->AttrFlags & ATTR_CACHED) &&
pRgn_Attr->AttrFlags & (ATTR_RGN_VALID|ATTR_RGN_DIRTY) )
{ {
switch (pRgn_Attr->Flags) switch (pRgn_Attr->Flags)
{ {
@ -2142,15 +2149,18 @@ RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
if (pRgn) if (pRgn)
{ {
KeEnterCriticalRegion();
Index = GDI_HANDLE_GET_INDEX(pRgn->BaseObject.hHmgr); Index = GDI_HANDLE_GET_INDEX(pRgn->BaseObject.hHmgr);
Entry = &GdiHandleTable->Entries[Index]; Entry = &GdiHandleTable->Entries[Index];
pRgn_Attr = Entry->UserData; pRgn_Attr = Entry->UserData;
KeLeaveCriticalRegion();
_SEH2_TRY if ( pRgn_Attr )
{ {
if ( pRgn_Attr ) _SEH2_TRY
{ {
ProbeForWrite(pRgn_Attr, sizeof(RGN_ATTR), 1);
if ( pRgn_Attr->AttrFlags & ATTR_RGN_VALID ) if ( pRgn_Attr->AttrFlags & ATTR_RGN_VALID )
{ {
pRgn_Attr->Flags = REGION_Complexity( pRgn ); pRgn_Attr->Flags = REGION_Complexity( pRgn );
@ -2160,11 +2170,11 @@ RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
pRgn_Attr->Rect.bottom = pRgn->rdh.rcBound.bottom; pRgn_Attr->Rect.bottom = pRgn->rdh.rcBound.bottom;
} }
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
} }
REGION_UnlockRgn(pRgn); REGION_UnlockRgn(pRgn);
} }