Source code of Windows XP (NT5)
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.

249 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. cmchek2.c
  5. Abstract:
  6. This module implements consistency checking for the registry.
  7. Author:
  8. Bryan M. Willman (bryanwi) 27-Jan-92
  9. Environment:
  10. Revision History:
  11. --*/
  12. #include "cmp.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(PAGE,CmpValidateHiveSecurityDescriptors)
  15. #endif
  16. extern ULONG CmpUsedStorage;
  17. #ifdef HIVE_SECURITY_STATS
  18. ULONG
  19. CmpCheckForSecurityDuplicates(
  20. IN OUT PCMHIVE CmHive
  21. );
  22. #endif
  23. BOOLEAN
  24. CmpValidateHiveSecurityDescriptors(
  25. IN PHHIVE Hive,
  26. OUT PBOOLEAN ResetSD
  27. )
  28. /*++
  29. Routine Description:
  30. Walks the list of security descriptors present in the hive and passes
  31. each security descriptor to RtlValidSecurityDescriptor.
  32. Only applies to descriptors in Stable store. Those in Volatile store
  33. cannot have come from disk and therefore do not need this treatment
  34. anyway.
  35. Arguments:
  36. Hive - Supplies pointer to the hive control structure
  37. Return Value:
  38. TRUE - All security descriptors are valid
  39. FALSE - At least one security descriptor is invalid
  40. --*/
  41. {
  42. PCM_KEY_NODE RootNode;
  43. PCM_KEY_SECURITY SecurityCell;
  44. HCELL_INDEX ListAnchor;
  45. HCELL_INDEX NextCell;
  46. HCELL_INDEX LastCell;
  47. BOOLEAN BuildSecurityCache;
  48. #ifdef HIVE_SECURITY_STATS
  49. UNICODE_STRING HiveName;
  50. ULONG NoOfCells = 0;
  51. ULONG SmallestSize = 0;
  52. ULONG BiggestSize = 0;
  53. ULONG TotalSecuritySize = 0;
  54. RtlInitUnicodeString(&HiveName, (PCWSTR)Hive->BaseBlock->FileName);
  55. #ifndef _CM_LDR_
  56. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"Security stats for hive (%lx) (%.*S):\n",Hive,HiveName.Length / sizeof(WCHAR),HiveName.Buffer);
  57. #endif //_CM_LDR_
  58. #endif
  59. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC,"CmpValidateHiveSecurityDescriptor: Hive = %p\n",(ULONG_PTR)Hive));
  60. ASSERT( Hive->ReleaseCellRoutine == NULL );
  61. *ResetSD = FALSE;
  62. if( ((PCMHIVE)Hive)->SecurityCount == 0 ) {
  63. BuildSecurityCache = TRUE;
  64. } else {
  65. BuildSecurityCache = FALSE;
  66. }
  67. if (!HvIsCellAllocated(Hive,Hive->BaseBlock->RootCell)) {
  68. //
  69. // root cell HCELL_INDEX is bogus
  70. //
  71. return(FALSE);
  72. }
  73. RootNode = (PCM_KEY_NODE) HvGetCell(Hive, Hive->BaseBlock->RootCell);
  74. if( RootNode == NULL ) {
  75. //
  76. // we couldn't map a view for the bin containing this cell
  77. //
  78. return FALSE;
  79. }
  80. if( FALSE ) {
  81. YankSD:
  82. if( CmDoSelfHeal() ) {
  83. //
  84. // reset all security for the entire hive to the root security. There is no reliable way to
  85. // patch the security list
  86. //
  87. SecurityCell = (PCM_KEY_SECURITY) HvGetCell(Hive, RootNode->Security);
  88. if( SecurityCell == NULL ) {
  89. return FALSE;
  90. }
  91. if( HvMarkCellDirty(Hive, RootNode->Security) ) {
  92. SecurityCell->Flink = SecurityCell->Blink = RootNode->Security;
  93. } else {
  94. return FALSE;
  95. }
  96. //
  97. // destroy existing cache and set up an empty one
  98. //
  99. CmpDestroySecurityCache((PCMHIVE)Hive);
  100. CmpInitSecurityCache((PCMHIVE)Hive);
  101. CmMarkSelfHeal(Hive);
  102. *ResetSD = TRUE;
  103. } else {
  104. return FALSE;
  105. }
  106. }
  107. LastCell = 0;
  108. ListAnchor = NextCell = RootNode->Security;
  109. do {
  110. if (!HvIsCellAllocated(Hive, NextCell)) {
  111. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC,"CM: CmpValidateHiveSecurityDescriptors\n"));
  112. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC," NextCell: %08lx is invalid HCELL_INDEX\n",NextCell));
  113. goto YankSD;
  114. }
  115. SecurityCell = (PCM_KEY_SECURITY) HvGetCell(Hive, NextCell);
  116. if( SecurityCell == NULL ) {
  117. //
  118. // we couldn't map a view for the bin containing this cell
  119. //
  120. return FALSE;
  121. }
  122. #ifdef HIVE_SECURITY_STATS
  123. NoOfCells++;
  124. if( (SmallestSize == 0) || ((SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor)) < SmallestSize) ) {
  125. SmallestSize = SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor);
  126. }
  127. if( (BiggestSize == 0) || ((SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor)) > BiggestSize) ) {
  128. BiggestSize = SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor);
  129. }
  130. TotalSecuritySize += (SecurityCell->DescriptorLength + FIELD_OFFSET(CM_KEY_SECURITY, Descriptor));
  131. #endif
  132. if (NextCell != ListAnchor) {
  133. //
  134. // Check to make sure that our Blink points to where we just
  135. // came from.
  136. //
  137. if (SecurityCell->Blink != LastCell) {
  138. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC," Invalid Blink (%08lx) on security cell %08lx\n",SecurityCell->Blink, NextCell));
  139. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC," should point to %08lx\n", LastCell));
  140. return(FALSE);
  141. }
  142. }
  143. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_SEC,"CmpValidSD: SD shared by %d nodes\n",SecurityCell->ReferenceCount));
  144. if (!SeValidSecurityDescriptor(SecurityCell->DescriptorLength, &SecurityCell->Descriptor)) {
  145. #if DBG
  146. CmpDumpSecurityDescriptor(&SecurityCell->Descriptor,"INVALID DESCRIPTOR");
  147. #endif
  148. goto YankSD;
  149. }
  150. //
  151. // cache this security cell; now that we know it is valid
  152. //
  153. if( BuildSecurityCache == TRUE ) {
  154. if( !NT_SUCCESS(CmpAddSecurityCellToCache ( (PCMHIVE)Hive,NextCell,TRUE) ) ) {
  155. return FALSE;
  156. }
  157. } else {
  158. //
  159. // just check this cell is there
  160. //
  161. ULONG Index;
  162. if( CmpFindSecurityCellCacheIndex ((PCMHIVE)Hive,NextCell,&Index) == FALSE ) {
  163. //
  164. // bad things happened; maybe an error in our caching code?
  165. //
  166. return FALSE;
  167. }
  168. }
  169. LastCell = NextCell;
  170. NextCell = SecurityCell->Flink;
  171. } while ( NextCell != ListAnchor );
  172. #ifdef HIVE_SECURITY_STATS
  173. #ifndef _CM_LDR_
  174. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t NumberOfCells \t = %20lu (%8lx) \n",NoOfCells,NoOfCells);
  175. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t SmallestCellSize \t = %20lu (%8lx) \n",SmallestSize,SmallestSize);
  176. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t BiggestCellSize \t = %20lu (%8lx) \n",BiggestSize,BiggestSize);
  177. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t TotalSecuritySize\t = %20lu (%8lx) \n",TotalSecuritySize,TotalSecuritySize);
  178. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\t HiveLength \t = %20lu (%8lx) \n",Hive->BaseBlock->Length,Hive->BaseBlock->Length);
  179. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"\n");
  180. #endif //_CM_LDR_
  181. #endif
  182. if( BuildSecurityCache == TRUE ) {
  183. //
  184. // adjust the size of the cache in case we allocated too much
  185. //
  186. CmpAdjustSecurityCacheSize ( (PCMHIVE)Hive );
  187. #ifdef HIVE_SECURITY_STATS
  188. {
  189. ULONG Duplicates;
  190. Duplicates = CmpCheckForSecurityDuplicates((PCMHIVE)Hive);
  191. if( Duplicates ) {
  192. #ifndef _CM_LDR_
  193. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_TRACE_LEVEL,"Hive %p %lu security cells duplicated !!!\n",Hive,Duplicates);
  194. #endif //_CM_LDR_
  195. }
  196. }
  197. #endif
  198. }
  199. return(TRUE);
  200. }