Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
4.8 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. tls.c
  5. Abstract:
  6. This module implements verification functions for TLS (thread
  7. local storage) interfaces.
  8. Author:
  9. Silviu Calinoiu (SilviuC) 3-Jul-2001
  10. Revision History:
  11. 3-Jul-2001 (SilviuC): initial version.
  12. --*/
  13. #include "pch.h"
  14. #include "verifier.h"
  15. #include "support.h"
  16. #include "logging.h"
  17. //
  18. // TLS (thread local storage) checks.
  19. //
  20. // If more than 2**16 indeces are requested the functions will start
  21. // to fail TLS index allocations.
  22. //
  23. // N.B. The MSDN documentation volunteered a limit of 1088 for a TLS
  24. // index. This is an internal implementation detail that should never
  25. // made it to outside world. Because of it some application that
  26. // actually checks for the index to be lower than this will get confused
  27. // by the values coming from verifier because they are guaranteed to be
  28. // bigger than that.
  29. //
  30. #define TLS_MAXIMUM_INDEX 0xFFFF
  31. #define TLS_MAGIC_PATTERN 0xABBA
  32. //
  33. // The break for invalid TLS indexes can be disabled using this value.
  34. //
  35. BOOL AVrfpBreakForInvalidTlsValue = TRUE;
  36. DWORD
  37. ScrambleTlsIndex (
  38. DWORD Index
  39. )
  40. {
  41. return (Index << 16) | TLS_MAGIC_PATTERN;
  42. }
  43. DWORD
  44. UnscrambleTlsIndex (
  45. DWORD Index
  46. )
  47. {
  48. return (Index >> 16);
  49. }
  50. BOOL
  51. CheckTlsIndex (
  52. DWORD Index
  53. )
  54. {
  55. DWORD Tid;
  56. BOOL TlsIndexValid;
  57. TlsIndexValid = TRUE;
  58. if (AVrfpBreakForInvalidTlsValue != FALSE) {
  59. Tid = HandleToUlong(NtCurrentTeb()->ClientId.UniqueThread);
  60. //
  61. // Check the TLS index value.
  62. //
  63. if ((Index & 0xFFFF) != TLS_MAGIC_PATTERN) {
  64. VERIFIER_STOP (APPLICATION_VERIFIER_INVALID_TLS_VALUE | APPLICATION_VERIFIER_CONTINUABLE_BREAK,
  65. "Invalid TLS index used in current stack (use kb).",
  66. Index, "Invalid TLS index",
  67. TLS_MAGIC_PATTERN, "Expected lower part of the index",
  68. 0, NULL, 0, NULL);
  69. TlsIndexValid = FALSE;
  70. }
  71. }
  72. return TlsIndexValid;
  73. }
  74. //WINBASEAPI
  75. DWORD
  76. WINAPI
  77. AVrfpTlsAlloc(
  78. VOID
  79. )
  80. {
  81. typedef DWORD (WINAPI * FUNCTION_TYPE) (VOID);
  82. FUNCTION_TYPE Function;
  83. DWORD Index;
  84. Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
  85. AVRF_INDEX_KERNEL32_TLSALLOC);
  86. Index = (*Function)();
  87. //
  88. // If we get a TLS index bigger than maximum possible index
  89. // return failure.
  90. //
  91. if (Index > TLS_MAXIMUM_INDEX) {
  92. return TLS_OUT_OF_INDEXES;
  93. }
  94. if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_TLS_CHECKS) != 0) {
  95. //
  96. // Scramble the TLS index and return it.
  97. //
  98. Index = ScrambleTlsIndex (Index);
  99. }
  100. return Index;
  101. }
  102. //WINBASEAPI
  103. BOOL
  104. WINAPI
  105. AVrfpTlsFree(
  106. IN DWORD dwTlsIndex
  107. )
  108. {
  109. typedef BOOL (WINAPI * FUNCTION_TYPE) (DWORD);
  110. FUNCTION_TYPE Function;
  111. BOOL Result;
  112. Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
  113. AVRF_INDEX_KERNEL32_TLSFREE);
  114. if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_TLS_CHECKS) != 0) {
  115. Result = CheckTlsIndex (dwTlsIndex);
  116. if (Result == FALSE) {
  117. return FALSE;
  118. }
  119. dwTlsIndex = UnscrambleTlsIndex (dwTlsIndex);
  120. }
  121. return (*Function)(dwTlsIndex);
  122. }
  123. //WINBASEAPI
  124. LPVOID
  125. WINAPI
  126. AVrfpTlsGetValue(
  127. IN DWORD dwTlsIndex
  128. )
  129. {
  130. typedef LPVOID (WINAPI * FUNCTION_TYPE) (DWORD);
  131. FUNCTION_TYPE Function;
  132. LPVOID Value;
  133. BOOL Result;
  134. Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
  135. AVRF_INDEX_KERNEL32_TLSGETVALUE);
  136. if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_TLS_CHECKS) != 0) {
  137. Result = CheckTlsIndex (dwTlsIndex);
  138. if (Result == FALSE) {
  139. return NULL;
  140. }
  141. dwTlsIndex = UnscrambleTlsIndex (dwTlsIndex);
  142. }
  143. Value = (*Function)(dwTlsIndex);
  144. return Value;
  145. }
  146. //WINBASEAPI
  147. BOOL
  148. WINAPI
  149. AVrfpTlsSetValue(
  150. IN DWORD dwTlsIndex,
  151. IN LPVOID lpTlsValue
  152. )
  153. {
  154. typedef BOOL (WINAPI * FUNCTION_TYPE) (DWORD, LPVOID);
  155. FUNCTION_TYPE Function;
  156. BOOL Result;
  157. Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
  158. AVRF_INDEX_KERNEL32_TLSSETVALUE);
  159. if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_TLS_CHECKS) != 0) {
  160. Result = CheckTlsIndex (dwTlsIndex);
  161. if (Result == FALSE) {
  162. return FALSE;
  163. }
  164. dwTlsIndex = UnscrambleTlsIndex (dwTlsIndex);
  165. }
  166. return (*Function)(dwTlsIndex, lpTlsValue);
  167. }