[GDI32][NTGDI] Avoid integer overflow (follow-up of #1492) (#1495)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Thu, 11 Apr 2019 08:57:57 +0000 (17:57 +0900)
committerGitHub <noreply@github.com>
Thu, 11 Apr 2019 08:57:57 +0000 (17:57 +0900)
Follow up of #1492. CORE-15755
- Use RtlULongMult function to check integer overflows.

win32ss/gdi/gdi32/include/precomp.h
win32ss/gdi/gdi32/objects/font.c
win32ss/gdi/ntgdi/freetype.c

index 5f8614b..3d4b823 100644 (file)
@@ -58,5 +58,6 @@
 #include <ntgdibad.h>
 
 #include <undocgdi.h>
+#include <ntintsafe.h>
 
 #endif /* _GDI32_PCH_ */
index e20c070..1b6cfa7 100644 (file)
@@ -295,7 +295,9 @@ IntEnumFontFamilies(HDC Dc, const LOGFONTW *LogFont, PVOID EnumProc, LPARAM lPar
     ENUMLOGFONTEXA EnumLogFontExA;
     NEWTEXTMETRICEXA NewTextMetricExA;
     LOGFONTW lfW;
-    LONG DataSize, InfoCount;
+    LONG InfoCount;
+    ULONG DataSize;
+    NTSTATUS Status;
 
     DataSize = INITIAL_FAMILY_COUNT * sizeof(FONTFAMILYINFO);
     Info = RtlAllocateHeap(GetProcessHeap(), 0, DataSize);
@@ -330,7 +332,13 @@ IntEnumFontFamilies(HDC Dc, const LOGFONTW *LogFont, PVOID EnumProc, LPARAM lPar
     if (INITIAL_FAMILY_COUNT < InfoCount)
     {
         RtlFreeHeap(GetProcessHeap(), 0, Info);
-        DataSize = InfoCount * sizeof(FONTFAMILYINFO);
+
+        Status = RtlULongMult(InfoCount, sizeof(FONTFAMILYINFO), &DataSize);
+        if (!NT_SUCCESS(Status) || DataSize > LONG_MAX)
+        {
+            DPRINT1("Overflowed.\n");
+            return 1;
+        }
         Info = RtlAllocateHeap(GetProcessHeap(), 0, DataSize);
         if (Info == NULL)
         {
index 298c1fa..2f699cd 100644 (file)
@@ -5456,7 +5456,8 @@ NtGdiGetFontFamilyInfo(HDC Dc,
     NTSTATUS Status;
     LOGFONTW LogFont;
     PFONTFAMILYINFO Info;
-    LONG GotCount, AvailCount, DataSize, SafeInfoCount;
+    LONG GotCount, AvailCount, SafeInfoCount;
+    ULONG DataSize;
 
     if (UnsafeLogFont == NULL || UnsafeInfo == NULL || UnsafeInfoCount == NULL)
     {
@@ -5490,9 +5491,10 @@ NtGdiGetFontFamilyInfo(HDC Dc,
     }
 
     /* Allocate space for a safe copy */
-    DataSize = SafeInfoCount * sizeof(FONTFAMILYINFO);
-    if (DataSize <= 0)
+    Status = RtlULongMult(SafeInfoCount, sizeof(FONTFAMILYINFO), &DataSize);
+    if (!NT_SUCCESS(Status) || (ULONG)DataSize > LONG_MAX)
     {
+        DPRINT1("Overflowed.\n");
         EngSetLastError(ERROR_INVALID_PARAMETER);
         return -1;
     }
@@ -5511,9 +5513,10 @@ NtGdiGetFontFamilyInfo(HDC Dc,
     /* Return data to caller */
     if (GotCount > 0)
     {
-        DataSize = GotCount * sizeof(FONTFAMILYINFO);
-        if (DataSize <= 0)
+        Status = RtlULongMult(GotCount, sizeof(FONTFAMILYINFO), &DataSize);
+        if (!NT_SUCCESS(Status) || DataSize > LONG_MAX)
         {
+            DPRINT1("Overflowed.\n");
             ExFreePoolWithTag(Info, GDITAG_TEXT);
             EngSetLastError(ERROR_INVALID_PARAMETER);
             return -1;