[CMLIB]: Implement CmpFreeSecurityDescriptor. See r70609.
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 10 Feb 2016 22:28:12 +0000 (22:28 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 10 Feb 2016 22:28:12 +0000 (22:28 +0000)
CORE-10793 CORE-10796

svn path=/trunk/; revision=70707

reactos/lib/cmlib/CMakeLists.txt
reactos/lib/cmlib/cmkeydel.c
reactos/lib/cmlib/cmlib.h
reactos/lib/cmlib/cmse.c [new file with mode: 0644]

index 8805324..258fba9 100644 (file)
@@ -8,6 +8,7 @@ list(APPEND SOURCE
     cmindex.c
     cmkeydel.c
     cmname.c
+    cmse.c
     cmvalue.c
     hivebin.c
     hivecell.c
index 626f234..ff017b2 100644 (file)
@@ -220,8 +220,8 @@ CmpFreeKeyByCell(IN PHHIVE Hive,
             HvFreeCell(Hive, CellData->ValueList.List);
         }
 
-        /* FIXME: This leaks the security desriptor! */
-        DPRINT("Potentially leaking key security descriptor. Please call CmpFreeSecurityDescriptor\n");
+        /* Free the key security descriptor */
+        CmpFreeSecurityDescriptor(Hive, Cell);
     }
 
     /* Free the key body itself, and then return our status */
index 2ec6eaa..64861c5 100644 (file)
@@ -676,7 +676,21 @@ NTAPI
 CmpFreeKeyByCell(
     IN PHHIVE Hive,
     IN HCELL_INDEX Cell,
-    IN BOOLEAN Unlink    
+    IN BOOLEAN Unlink
+);
+
+VOID
+NTAPI
+CmpRemoveSecurityCellList(
+    IN PHHIVE Hive,
+    IN HCELL_INDEX SecurityCell
+);
+
+VOID
+NTAPI
+CmpFreeSecurityDescriptor(
+    IN PHHIVE Hive,
+    IN HCELL_INDEX Cell
 );
 
 /******************************************************************************/
diff --git a/reactos/lib/cmlib/cmse.c b/reactos/lib/cmlib/cmse.c
new file mode 100644 (file)
index 0000000..ce4cbdb
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            lib/cmlib/cmse.c
+ * PURPOSE:         Configuration Manager Library - Security Subsystem Interface
+ * PROGRAMMERS:     Hermes Belusca-Maito (hermes.belusca@sfr.fr)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "cmlib.h"
+#define NDEBUG
+#include "debug.h"
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+CmpRemoveSecurityCellList(IN PHHIVE Hive,
+                          IN HCELL_INDEX SecurityCell)
+{
+    PCM_KEY_SECURITY SecurityData, FlinkCell, BlinkCell;
+
+    PAGED_CODE();
+
+    // ASSERT( (((PCMHIVE)Hive)->HiveSecurityLockOwner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive() == TRUE) );
+
+    SecurityData = HvGetCell(Hive, SecurityCell);
+    if (!SecurityData) return;
+
+    FlinkCell = HvGetCell(Hive, SecurityData->Flink);
+    if (!FlinkCell)
+    {
+        HvReleaseCell(Hive, SecurityCell);
+        return;
+    }
+
+    BlinkCell = HvGetCell(Hive, SecurityData->Blink);
+    if (!BlinkCell)
+    {
+        HvReleaseCell(Hive, SecurityData->Flink);
+        HvReleaseCell(Hive, SecurityCell);
+        return;
+    }
+
+    /* Sanity checks */
+    ASSERT(FlinkCell->Blink == SecurityCell);
+    ASSERT(BlinkCell->Flink == SecurityCell);
+
+    /* Unlink the security block and free it */
+    FlinkCell->Blink = SecurityData->Blink;
+    BlinkCell->Flink = SecurityData->Flink;
+#ifdef USE_CM_CACHE
+    CmpRemoveFromSecurityCache(Hive, SecurityCell);
+#endif
+
+    /* Release the cells */
+    HvReleaseCell(Hive, SecurityData->Blink);
+    HvReleaseCell(Hive, SecurityData->Flink);
+    HvReleaseCell(Hive, SecurityCell);
+}
+
+VOID
+NTAPI
+CmpFreeSecurityDescriptor(IN PHHIVE Hive,
+                          IN HCELL_INDEX Cell)
+{
+    PCM_KEY_NODE CellData;
+    PCM_KEY_SECURITY SecurityData;
+
+    PAGED_CODE();
+
+    // ASSERT( (((PCMHIVE)Hive)->HiveSecurityLockOwner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive() == TRUE) );
+
+    CellData = HvGetCell(Hive, Cell);
+    if (!CellData) return;
+
+    ASSERT(CellData->Signature == CM_KEY_NODE_SIGNATURE);
+
+    // FIXME: ReactOS-specific: check whether this key has a security block.
+    // On Windows there is no such check, all keys seem to have a valid
+    // security block.
+    // If we remove this check on ReactOS (and continue running) then we get
+    // a BSOD at the end...
+    if (CellData->Security == HCELL_NIL)
+    {
+        DPRINT1("Cell 0x%08x (data 0x%p) has no security block!\n", Cell, CellData);
+        HvReleaseCell(Hive, Cell);
+        return;
+    }
+
+    SecurityData = HvGetCell(Hive, CellData->Security);
+    if (!SecurityData)
+    {
+        HvReleaseCell(Hive, Cell);
+        return;
+    }
+
+    ASSERT(SecurityData->Signature == CM_KEY_SECURITY_SIGNATURE);
+
+    if (SecurityData->ReferenceCount > 1)
+    {
+        SecurityData->ReferenceCount--;
+    }
+    else // if (SecurityData->ReferenceCount <= 1)
+    {
+        CmpRemoveSecurityCellList(Hive, CellData->Security);
+        HvFreeCell(Hive, CellData->Security);
+    }
+
+    CellData->Security = HCELL_NIL;
+    HvReleaseCell(Hive, CellData->Security);
+    HvReleaseCell(Hive, Cell);
+}