[Win32k]
authorJames Tabor <james.tabor@reactos.org>
Sun, 3 Jan 2010 00:05:15 +0000 (00:05 +0000)
committerJames Tabor <james.tabor@reactos.org>
Sun, 3 Jan 2010 00:05:15 +0000 (00:05 +0000)
- 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

reactos/subsystems/win32/win32k/objects/gdiobj.c
reactos/subsystems/win32/win32k/objects/region.c

index 262c353..3b6aeae 100644 (file)
@@ -750,7 +750,12 @@ GreDeleteObject(HGDIOBJ hObject)
              {
                 return TRUE;
              }
-             if (pAttr) FreeObjectAttr(pAttr);
+             if (pAttr)
+             {
+                KeEnterCriticalRegion();
+                FreeObjectAttr(pAttr);
+                KeLeaveCriticalRegion();
+             }
              break;
 
           case GDI_OBJECT_TYPE_DC:
index 5b43eab..22ab61f 100644 (file)
@@ -1650,7 +1650,8 @@ REGION_SubtractO(
                 pNextRect++;
             }
             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);
     Entry = &GdiHandleTable->Entries[Index];
     Entry->UserData = AllocateObjectAttr();
+    KeLeaveCriticalRegion();
 
     EMPTY_REGION(pReg);
     pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
@@ -2081,22 +2084,26 @@ RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
   INT Index;
   PGDI_TABLE_ENTRY Entry;
   PROSRGNDATA pRgn;
-  PRGN_ATTR pRgn_Attr;
+  PRGN_ATTR pRgn_Attr;  
 
   pRgn = REGION_LockRgn(hRgn);
 
   if (pRgn)
   {
+     KeEnterCriticalRegion();
      Index = GDI_HANDLE_GET_INDEX(hRgn);
      Entry = &GdiHandleTable->Entries[Index];
-
      pRgn_Attr = Entry->UserData;
+     KeLeaveCriticalRegion();
 
      if (pRgn_Attr)
      {
         _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)
               {
@@ -2142,15 +2149,18 @@ RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
 
   if (pRgn)
   {
+     KeEnterCriticalRegion();
      Index = GDI_HANDLE_GET_INDEX(pRgn->BaseObject.hHmgr);
      Entry = &GdiHandleTable->Entries[Index];
-
      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 )
            {
               pRgn_Attr->Flags = REGION_Complexity( pRgn );
@@ -2160,11 +2170,11 @@ RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
               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);
 }