[ros-diffs] [weiden] 30455: Dereference callproc handles without a system call

weiden at svn.reactos.org weiden at svn.reactos.org
Thu Nov 15 06:42:44 CET 2007


Author: weiden
Date: Thu Nov 15 08:42:44 2007
New Revision: 30455

URL: http://svn.reactos.org/svn/reactos?rev=30455&view=rev
Log:
Dereference callproc handles without a system call

Modified:
    trunk/reactos/dll/win32/user32/include/user32.h
    trunk/reactos/dll/win32/user32/include/user32p.h
    trunk/reactos/dll/win32/user32/misc/dllmain.c
    trunk/reactos/dll/win32/user32/misc/misc.c
    trunk/reactos/dll/win32/user32/windows/message.c
    trunk/reactos/subsystems/win32/win32k/include/object.h
    trunk/reactos/subsystems/win32/win32k/ntuser/object.c

Modified: trunk/reactos/dll/win32/user32/include/user32.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/user32.h?rev=30455&r1=30454&r2=30455&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32.h (original)
+++ trunk/reactos/dll/win32/user32/include/user32.h Thu Nov 15 08:42:44 2007
@@ -45,8 +45,9 @@
 BOOL FASTCALL IsMetaFile(HDC);
 
 extern PW32PROCESSINFO g_pi;
+extern PW32PROCESSINFO g_kpi;
 
-static PVOID __inline
+static __inline PVOID
 SharedPtrToUser(PVOID Ptr)
 {
     ASSERT(Ptr != NULL);
@@ -55,7 +56,7 @@
     return (PVOID)((ULONG_PTR)Ptr - g_pi->UserHeapDelta);
 }
 
-static PVOID __inline
+static __inline PVOID
 DesktopPtrToUser(PVOID Ptr)
 {
     PW32THREADINFO ti = GetW32ThreadInfo();
@@ -65,3 +66,13 @@
     return (PVOID)((ULONG_PTR)Ptr - ti->DesktopHeapDelta);
 }
 
+static __inline PVOID
+SharedPtrToKernel(PVOID Ptr)
+{
+    ASSERT(Ptr != NULL);
+    ASSERT(g_pi != NULL);
+    ASSERT(g_pi->UserHeapDelta != 0);
+    return (PVOID)((ULONG_PTR)Ptr + g_pi->UserHeapDelta);
+}
+
+PCALLPROC FASTCALL ValidateCallProc(HANDLE hCallProc);

Modified: trunk/reactos/dll/win32/user32/include/user32p.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/user32p.h?rev=30455&r1=30454&r2=30455&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32p.h (original)
+++ trunk/reactos/dll/win32/user32/include/user32p.h Thu Nov 15 08:42:44 2007
@@ -200,7 +200,12 @@
 typedef struct _USER_HANDLE_ENTRY
 {
     void          *ptr;          /* pointer to object */
-    PW32THREADINFO pti;          // pointer to Win32ThreadInfo
+    union
+    {
+        PVOID pi;
+        PW32THREADINFO pti;          // pointer to Win32ThreadInfo
+        PW32PROCESSINFO ppi;         // pointer to W32ProcessInfo
+    };
     unsigned short type;         /* object type (0 if free) */
     unsigned short generation;   /* generation counter */
 } USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
@@ -214,6 +219,7 @@
 } USER_HANDLE_TABLE, * PUSER_HANDLE_TABLE;
 
 extern PUSER_HANDLE_TABLE gHandleTable;
+extern PUSER_HANDLE_ENTRY gHandleEntries;
 
 PUSER_HANDLE_ENTRY FASTCALL GetUser32Handle(HANDLE);
 PVOID FASTCALL ValidateHandle(HANDLE, UINT);

Modified: trunk/reactos/dll/win32/user32/misc/dllmain.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/dllmain.c?rev=30455&r1=30454&r2=30455&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/misc/dllmain.c (original)
+++ trunk/reactos/dll/win32/user32/misc/dllmain.c Thu Nov 15 08:42:44 2007
@@ -5,7 +5,9 @@
 static ULONG User32TlsIndex;
 HINSTANCE User32Instance;
 PUSER_HANDLE_TABLE gHandleTable = NULL;
-PW32PROCESSINFO g_pi = NULL;
+PUSER_HANDLE_ENTRY gHandleEntries = NULL;
+PW32PROCESSINFO g_pi = NULL; /* User Mode Pointer */
+PW32PROCESSINFO g_kpi = NULL; /* Kernel Mode Pointer */
 
 PW32PROCESSINFO
 GetW32ProcessInfo(VOID);
@@ -56,7 +58,9 @@
       (PVOID)User32CallHookProcFromKernel;
 
    g_pi = GetW32ProcessInfo();
+   g_kpi = SharedPtrToKernel(g_pi);
    gHandleTable = SharedPtrToUser(g_pi->UserHandleTable);
+   gHandleEntries = SharedPtrToUser(gHandleTable->handles);
 
    /* Allocate an index for user32 thread local data. */
    User32TlsIndex = TlsAlloc();

Modified: trunk/reactos/dll/win32/user32/misc/misc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/misc.c?rev=30455&r1=30454&r2=30455&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/misc/misc.c (original)
+++ trunk/reactos/dll/win32/user32/misc/misc.c Thu Nov 15 08:42:44 2007
@@ -314,23 +314,23 @@
 FASTCALL
 GetUser32Handle(HANDLE handle)
 {
-  PUSER_HANDLE_TABLE ht = gHandleTable;
-  USHORT generation;
-
-  TRACE("Main Handle Table %x\n", ht);
-
-  INT Index = (((UINT)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
-
-  if (Index < 0 || Index >= ht->nb_handles) return NULL;
-
-  if (!ht->handles[Index].type) return NULL;
-
-  generation = (UINT)handle >> 16;
-
-  if (generation == ht->handles[Index].generation || !generation || generation == 0xffff)
-     return &ht->handles[Index];
-
-  return NULL;
+    INT Index;
+    USHORT generation;
+
+    Index = (((UINT)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
+
+    if (Index < 0 || Index >= gHandleTable->nb_handles)
+        return NULL;
+
+    if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
+        return NULL;
+
+    generation = (UINT)handle >> 16;
+
+    if (generation == gHandleEntries[Index].generation || !generation || generation == 0xffff)
+        return &gHandleEntries[Index];
+
+    return NULL;
 }
 
 /*
@@ -345,8 +345,8 @@
     TRUE, /* VALIDATE_TYPE_MWPOS */
     TRUE, /* VALIDATE_TYPE_HOOK */
     FALSE, /* (not used) */
-    FALSE, /* VALIDATE_TYPE_CALLPROC */
-    FALSE, /* VALIDATE_TYPE_ACCEL */
+    TRUE, /* VALIDATE_TYPE_CALLPROC */
+    TRUE, /* VALIDATE_TYPE_ACCEL */
     FALSE, /* (not used) */
     FALSE, /* (not used) */
     FALSE, /* (not used) */
@@ -361,6 +361,7 @@
 ValidateHandle(HANDLE handle, UINT uType)
 {
   PVOID ret;
+  PUSER_HANDLE_ENTRY pEntry;
   PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
 
   ASSERT(uType <= VALIDATE_TYPE_MONITOR);
@@ -372,13 +373,13 @@
      if (handle == ClientInfo->hWND) return ClientInfo->pvWND;
   }
 
-  PUSER_HANDLE_ENTRY pEntry = GetUser32Handle(handle);
+  pEntry = GetUser32Handle(handle);
 
   if (pEntry && uType == 0)
       uType = pEntry->type;
 
 // Must have an entry and must be the same type!
-  if ( (!pEntry) || (pEntry->type != uType) )
+  if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
   {
      switch ( uType )
      {  // Test (with wine too) confirms these results!
@@ -406,8 +407,6 @@
     }
     return NULL;
   }
-
-  if (!(NtUserValidateHandleSecure(handle, FALSE))) return NULL;
 
   if (g_ObjectHeapTypeShared[uType])
     ret = SharedPtrToUser(pEntry->ptr);
@@ -427,3 +426,17 @@
 
   return ret;
 }
+
+//
+// Validate callproc handle and return the pointer to the object.
+//
+PCALLPROC
+FASTCALL
+ValidateCallProc(HANDLE hCallProc)
+{
+    PCALLPROC CallProc = ValidateHandle(hCallProc, VALIDATE_TYPE_CALLPROC);
+    if (CallProc != NULL && CallProc->pi == g_kpi)
+        return CallProc;
+
+    return NULL;
+}

Modified: trunk/reactos/dll/win32/user32/windows/message.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/message.c?rev=30455&r1=30454&r2=30455&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/message.c (original)
+++ trunk/reactos/dll/win32/user32/windows/message.c Thu Nov 15 08:42:44 2007
@@ -1233,27 +1233,29 @@
 		WPARAM wParam,
 		LPARAM lParam)
 {
-  WNDPROC_INFO wpInfo;
-
-  if (lpPrevWndFunc == NULL)
-    {
-      WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
-      return 0;
-    }
-
-  if (!IsCallProcHandle(lpPrevWndFunc))
-    return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
-  else
-    {
-       if (NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
-                                      &wpInfo))
-         return IntCallWindowProcA(!wpInfo.IsUnicode, wpInfo.WindowProc,
-                                  hWnd, Msg, wParam, lParam);
-       else
-       {
-         WARN("CallWindowProcA: can not dereference WndProcHandle\n");
-         return 0;
-       }
+    PCALLPROC CallProc;
+
+    if (lpPrevWndFunc == NULL)
+    {
+        WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
+        return 0;
+    }
+
+    if (!IsCallProcHandle(lpPrevWndFunc))
+        return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
+    else
+    {
+        CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
+        if (CallProc != NULL)
+        {
+            return IntCallWindowProcA(!CallProc->Unicode, CallProc->WndProc,
+                                      hWnd, Msg, wParam, lParam);
+        }
+        else
+        {
+            WARN("CallWindowProcA: can not dereference WndProcHandle\n");
+            return 0;
+        }
     }
 }
 
@@ -1268,29 +1270,31 @@
 		WPARAM wParam,
 		LPARAM lParam)
 {
-  WNDPROC_INFO wpInfo;
-
-  /* FIXME - can the first parameter be NULL? */
-  if (lpPrevWndFunc == NULL)
-    {
-      WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
-      return 0;
-    }
-
-  if (!IsCallProcHandle(lpPrevWndFunc))
-    return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
-  else
-  {
-    if (NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
-                                      &wpInfo))
-      return IntCallWindowProcW(!wpInfo.IsUnicode, wpInfo.WindowProc,
-                                hWnd, Msg, wParam, lParam);
-       else
-       {
-         WARN("CallWindowProcW: can not dereference WndProcHandle\n");
-         return 0;
-       }
-  }
+    PCALLPROC CallProc;
+
+    /* FIXME - can the first parameter be NULL? */
+    if (lpPrevWndFunc == NULL)
+    {
+        WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
+        return 0;
+    }
+
+    if (!IsCallProcHandle(lpPrevWndFunc))
+        return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
+    else
+    {
+        CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
+        if (CallProc != NULL)
+        {
+            return IntCallWindowProcW(!CallProc->Unicode, CallProc->WndProc,
+                                      hWnd, Msg, wParam, lParam);
+        }
+        else
+        {
+            WARN("CallWindowProcW: can not dereference WndProcHandle\n");
+            return 0;
+        }
+    }
 }
 
 

Modified: trunk/reactos/subsystems/win32/win32k/include/object.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/object.h?rev=30455&r1=30454&r2=30455&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/object.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/object.h Thu Nov 15 08:42:44 2007
@@ -20,7 +20,12 @@
 typedef struct _USER_HANDLE_ENTRY
 {
     void          *ptr;          /* pointer to object */
-    PW32THREADINFO pti;          // pointer to Win32ThreadInfo
+    union
+    {
+        PVOID pi;
+        PW32THREADINFO pti;          // pointer to Win32ThreadInfo
+        PW32PROCESSINFO ppi;         // pointer to W32ProcessInfo
+    };
     unsigned short type;         /* object type (0 if free) */
     unsigned short generation;   /* generation counter */
 } USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/object.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/object.c?rev=30455&r1=30454&r2=30455&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/object.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/object.c Thu Nov 15 08:42:44 2007
@@ -108,12 +108,43 @@
    ret = entry->ptr;
    entry->ptr  = ht->freelist;
    entry->type = 0;
-   entry->pti = 0;
+   entry->pi = NULL;
    ht->freelist  = entry;
 
    usedHandles--;
 
    return ret;
+}
+
+static __inline PVOID
+UserHandleOwnerByType(USER_OBJECT_TYPE type)
+{
+    PVOID pi;
+
+    switch (type)
+    {
+        case otWindow:
+            pi = GetW32ThreadInfo();
+            break;
+
+        case otMenu:
+        case otCursorIcon:
+        case otHook:
+        case otCallProc:
+        case otAccel:
+            pi = GetW32ProcessInfo();
+            break;
+
+        case otMonitor:
+            pi = NULL; /* System */
+            break;
+
+        default:
+            pi = NULL;
+            break;
+    }
+
+    return pi;
 }
 
 /* allocate a user handle for a given object */
@@ -124,8 +155,7 @@
       return 0;
    entry->ptr  = object;
    entry->type = type;
-   entry->pti = GetW32ThreadInfo();
-   if (entry->pti->pi->UserHandleTable == NULL) GetW32ProcessInfo();
+   entry->pi = UserHandleOwnerByType(type);
    if (++entry->generation >= 0xffff)
       entry->generation = 1;
    return entry_to_handle(ht, entry );




More information about the Ros-diffs mailing list