Author: khornicek
Date: Fri Oct 31 15:57:09 2014
New Revision: 65150

URL: http://svn.reactos.org/svn/reactos?rev=65150&view=rev
Log:
[WIN32K]
- don't access user mode buffers directly in the Freetype code

Modified:
    trunk/reactos/win32ss/gdi/ntgdi/freetype.c

Modified: trunk/reactos/win32ss/gdi/ntgdi/freetype.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/freetype.c?rev=65150&r1=65149&r2=65150&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/freetype.c  [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/freetype.c  [iso-8859-1] Fri Oct 31 
15:57:09 2014
@@ -3365,7 +3365,7 @@
     BrushOrigin.x = 0;
     BrushOrigin.y = 0;
 
-    psurf = dc->dclevel.pSurface ;
+    psurf = dc->dclevel.pSurface;
 
     if(!psurf) 
         psurf = psurfDefaultBitmap;
@@ -3921,7 +3921,7 @@
     IN HDC hDC,
     IN UINT FirstChar,
     IN ULONG Count,
-    IN OPTIONAL PWCHAR pwch,
+    IN OPTIONAL PWCHAR UnSafepwch,
     IN FLONG fl,
     OUT PVOID Buffer)
 {
@@ -3937,14 +3937,29 @@
     HFONT hFont = 0;
     NTSTATUS Status = STATUS_SUCCESS;
     PMATRIX pmxWorldToDevice;
-
-    if (pwch)
-    {
+    PWCHAR Safepwch = NULL;
+
+    if (!Buffer)
+    {
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (UnSafepwch)
+    {
+        UINT pwchSize = Count * sizeof(WCHAR);
+        Safepwch = ExAllocatePoolWithTag(PagedPool, pwchSize, GDITAG_TEXT);
+
+        if(!Safepwch)
+        {
+            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return FALSE;
+        }
+
         _SEH2_TRY
         {
-            ProbeForRead(pwch,
-            sizeof(PWSTR),
-            1);
+            ProbeForRead(UnSafepwch, pwchSize, 1);
+            RtlCopyMemory(Safepwch, UnSafepwch, pwchSize);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
@@ -3952,15 +3967,13 @@
         }
         _SEH2_END;
     }
+
     if (!NT_SUCCESS(Status))
     {
+        if(Safepwch)
+            ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
+
         EngSetLastError(Status);
-        return FALSE;
-    }
-
-    if (!Buffer)
-    {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
@@ -3969,6 +3982,10 @@
     if (!fl) SafeBuffF = (LPABCFLOAT) SafeBuff;
     if (SafeBuff == NULL)
     {
+
+        if(Safepwch)
+            ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
+
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return FALSE;
     }
@@ -3977,6 +3994,10 @@
     if (dc == NULL)
     {
         ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
+
+        if(Safepwch)
+            ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
+
         EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
     }
@@ -3991,6 +4012,10 @@
     if (TextObj == NULL)
     {
         ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
+
+        if(Safepwch)
+            ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
+
         EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
     }
@@ -4014,6 +4039,10 @@
         {
             DPRINT1("WARNING: Could not find desired charmap!\n");
             ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
+
+            if(Safepwch)
+                ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
+
             EngSetLastError(ERROR_INVALID_HANDLE);
             return FALSE;
         }
@@ -4035,12 +4064,12 @@
     {
         int adv, lsb, bbx, left, right;
 
-        if (pwch)
+        if (Safepwch)
         {
             if (fl & GCABCW_INDICES)
-                glyph_index = pwch[i - FirstChar];
+                glyph_index = Safepwch[i - FirstChar];
             else
-                glyph_index = FT_Get_Char_Index(face, pwch[i - FirstChar]);
+                glyph_index = FT_Get_Char_Index(face, Safepwch[i - FirstChar]);
         }
         else
         {
@@ -4079,13 +4108,18 @@
     IntUnLockFreeType;
     TEXTOBJ_UnlockText(TextObj);
     Status = MmCopyToCaller(Buffer, SafeBuff, BufferSize);
+
+    ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
+
+    if(Safepwch)
+        ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
+
     if (! NT_SUCCESS(Status))
     {
         SetLastNtError(Status);
-        ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
         return FALSE;
     }
-    ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
+
     DPRINT("NtGdiGetCharABCWidths Worked!\n");
     return TRUE;
 }
@@ -4099,7 +4133,7 @@
     IN HDC hDC,
     IN UINT FirstChar,
     IN UINT Count,
-    IN OPTIONAL PWCHAR pwc,
+    IN OPTIONAL PWCHAR UnSafepwc,
     IN FLONG fl,
     OUT PVOID Buffer)
 {
@@ -4115,14 +4149,22 @@
     UINT i, glyph_index, BufferSize;
     HFONT hFont = 0;
     PMATRIX pmxWorldToDevice;
-
-    if (pwc)
-    {
+    PWCHAR Safepwc = NULL;
+
+    if (UnSafepwc)
+    {
+        UINT pwcSize = Count * sizeof(WCHAR);
+        Safepwc = ExAllocatePoolWithTag(PagedPool, pwcSize, GDITAG_TEXT);
+
+        if(!Safepwc)
+        {
+            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return FALSE;
+        }
         _SEH2_TRY
         {
-            ProbeForRead(pwc,
-            sizeof(PWSTR),
-            1);
+            ProbeForRead(UnSafepwc, pwcSize, 1);
+            RtlCopyMemory(Safepwc, UnSafepwc, pwcSize);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
@@ -4130,6 +4172,7 @@
         }
         _SEH2_END;
     }
+
     if (!NT_SUCCESS(Status))
     {
         EngSetLastError(Status);
@@ -4141,6 +4184,9 @@
     if (!fl) SafeBuffF = (PFLOAT) SafeBuff;
     if (SafeBuff == NULL)
     {
+        if(Safepwc)
+            ExFreePoolWithTag(Safepwc, GDITAG_TEXT);
+
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return FALSE;
     }
@@ -4148,6 +4194,9 @@
     dc = DC_LockDc(hDC);
     if (dc == NULL)
     {
+        if(Safepwc)
+            ExFreePoolWithTag(Safepwc, GDITAG_TEXT);
+
         ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
         EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
@@ -4161,6 +4210,9 @@
 
     if (TextObj == NULL)
     {
+        if(Safepwc)
+            ExFreePoolWithTag(Safepwc, GDITAG_TEXT);
+
         ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
         EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
@@ -4184,7 +4236,11 @@
         if (!found)
         {
             DPRINT1("WARNING: Could not find desired charmap!\n");
-            ExFreePool(SafeBuff);
+
+            if(Safepwc)
+                ExFreePoolWithTag(Safepwc, GDITAG_TEXT);
+
+            ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
             EngSetLastError(ERROR_INVALID_HANDLE);
             return FALSE;
         }
@@ -4204,12 +4260,12 @@
 
     for (i = FirstChar; i < FirstChar+Count; i++)
     {
-        if (pwc)
+        if (Safepwc)
         {
             if (fl & GCW_INDICES)
-                glyph_index = pwc[i - FirstChar];
+                glyph_index = Safepwc[i - FirstChar];
             else
-                glyph_index = FT_Get_Char_Index(face, pwc[i - FirstChar]);
+                glyph_index = FT_Get_Char_Index(face, Safepwc[i - FirstChar]);
         }
         else
         {
@@ -4227,6 +4283,10 @@
     IntUnLockFreeType;
     TEXTOBJ_UnlockText(TextObj);
     MmCopyToCaller(Buffer, SafeBuff, BufferSize);
+
+    if(Safepwc)
+        ExFreePoolWithTag(Safepwc, GDITAG_TEXT);
+
     ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
     return TRUE;
 }
@@ -4347,7 +4407,8 @@
     FT_Face face;
     WCHAR DefChar = 0xffff;
     PWSTR Buffer = NULL;
-    ULONG Size;
+    ULONG Size, pwcSize;
+    PWSTR Safepwc = NULL;
 
     if ((!UnSafepwc) && (!UnSafepgi)) return cwc;
 
@@ -4392,11 +4453,19 @@
         ExFreePoolWithTag(potm, GDITAG_TEXT);
     }
 
+    pwcSize = cwc * sizeof(WCHAR);
+    Safepwc = ExAllocatePoolWithTag(PagedPool, pwcSize, GDITAG_TEXT);
+
+    if (!Safepwc)
+    {
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return GDI_ERROR;
+    }
+
     _SEH2_TRY
     {
-        ProbeForRead(UnSafepwc,
-        sizeof(PWSTR),
-        1);
+        ProbeForRead(UnSafepwc, pwcSize, 1);
+        RtlCopyMemory(Safepwc, UnSafepwc, pwcSize);
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -4417,7 +4486,7 @@
 
     for (i = 0; i < cwc; i++)
     {
-        Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]); // FIXME: Unsafe!
+        Buffer[i] = FT_Get_Char_Index(face, Safepwc[i]);
         if (Buffer[i] == 0)
         {
             Buffer[i] = DefChar;
@@ -4428,12 +4497,8 @@
 
     _SEH2_TRY
     {
-        ProbeForWrite(UnSafepgi,
-        sizeof(WORD),
-        1);
-        RtlCopyMemory(UnSafepgi,
-                      Buffer,
-                      cwc*sizeof(WORD));
+        ProbeForWrite(UnSafepgi, cwc * sizeof(WORD), 1);
+        RtlCopyMemory(UnSafepgi, Buffer, cwc * sizeof(WORD));
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -4443,6 +4508,7 @@
 
 ErrorRet:
     ExFreePoolWithTag(Buffer, GDITAG_TEXT);
+    ExFreePoolWithTag(Safepwc, GDITAG_TEXT);
     if (NT_SUCCESS(Status)) return cwc;
     EngSetLastError(Status);
     return GDI_ERROR;


Reply via email to