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…
==============================================================================
--- 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;