Uploaded image for project: 'Core ReactOS'
  1. Core ReactOS
  2. CORE-14270

Syscalls must not return values smaller than 32 bit




      The syscall interface is aware of the number of parameters a function receives, and copies them to kernel space as necessary. It is not aware of each function's return type, though, and always returns the contents of the EAX register (or equivalent on other architectures) to user mode. If the prototype of a syscall function (Nt*/Zw*) specifies a return type smaller than 32 bits, the compiler may leave the unused high-order bits untouched. This may leak privileged kernel information to user mode, and must thus be avoided.
      NB: returning 32 bit values on x64 is less of (not?) a problem because setting the EAX register will automatically zero out the top 32 bits of RAX. Not sure about ARM64/IA64
      See: http://j00ru.vexillium.org/?p=762

      Fix approach:

      • Create a simple test for each function that calls it with a prototype that returns a 32 bit value and show that the upper bits are always 0 on Windows
      • Change the function prototype to an equivalent 32 bit type

      Incomplete list of functions known to be problematic (please add if you find more):
      NtUserDestroyAcceleratorTable (BOOLEAN)
      NtUserDestroyWindow (BOOLEAN)
      NtUserGetAsyncKeyState (SHORT)
      NtUserGetKeyState (SHORT)
      NtUserGetTitleBarInfo (BOOLEAN)
      NtUserNotifyWinEvent (VOID)
      NtUserRegisterClassExWOW (RTL_ATOM)
      NtUserSetClassWord (WORD)
      NtUserSetWindowWord (WORD)

      Note that BOOL is a 32 bit type and thus okay, while BOOLEAN is 8 bit and problematic in this context. Also note that returning VOID is equally as problematic as a small type – the full 32 bits would be leaked in this case.




            Pwn_Solo Pwn_Solo
            ThFabba ThFabba
            3 Vote for this issue
            3 Start watching this issue