[UMPNPMGR] Validate device instance IDs before use
authorEric Kohl <eric.kohl@reactos.org>
Sat, 9 Nov 2019 17:48:10 +0000 (18:48 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 9 Nov 2019 17:48:10 +0000 (18:48 +0100)
base/services/umpnpmgr/rpcserver.c

index 70f7760..e8a4890 100644 (file)
@@ -226,6 +226,72 @@ GetDeviceStatus(
 }
 
 
+static
+BOOL
+IsValidDeviceInstanceID(
+    _In_ PWSTR pszDeviceInstanceID)
+{
+    INT nPartLength[3] = {0, 0, 0};
+    INT nLength = 0, nParts = 0;
+    PWCHAR p;
+
+    DPRINT("IsValidDeviceInstanceID(%S)\n",
+           pszDeviceInstanceID);
+
+    if (pszDeviceInstanceID == NULL)
+    {
+        DPRINT("Device instance ID is NULL!\n");
+        return FALSE;
+    }
+
+    p = pszDeviceInstanceID;
+    while (*p != UNICODE_NULL)
+    {
+        if (*p == L'\\')
+        {
+            nParts++;
+            if (nParts >= 3)
+            {
+                DPRINT("Too many separators: %d\n", nParts);
+                return FALSE;
+            }
+        }
+        else
+        {
+            nPartLength[nParts]++;
+        }
+
+        nLength++;
+        if (nLength >= MAX_DEVICE_ID_LEN)
+        {
+            DPRINT("Too long: %d\n", nLength);
+            return FALSE;
+        }
+
+        p++;
+    }
+
+    if (nParts != 2)
+    {
+        DPRINT("Invalid number of separtors: %d\n", nParts);
+        return FALSE;
+    }
+
+    if ((nPartLength[0] == 0) ||
+        (nPartLength[1] == 0) ||
+        (nPartLength[2] == 0))
+    {
+        DPRINT("Invalid part lengths: %d %d %d\n",
+               nPartLength[0], nPartLength[1], nPartLength[2]);
+        return FALSE;
+    }
+
+    DPRINT("Valid device instance ID!\n");
+
+    return TRUE;
+}
+
+
 /* PUBLIC FUNCTIONS **********************************************************/
 
 /* Function 0 */
@@ -361,6 +427,9 @@ PNP_ValidateDeviceInstance(
     DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
            pDeviceID, ulFlags);
 
+    if (!IsValidDeviceInstanceID(pDeviceID))
+        return CR_INVALID_DEVINST;
+
     if (RegOpenKeyExW(hEnumKey,
                       pDeviceID,
                       0,
@@ -441,6 +510,9 @@ PNP_GetRelatedDeviceInstance(
     DPRINT("  Relationship %ld\n", ulRelationship);
     DPRINT("  DeviceId %S\n", pDeviceID);
 
+    if (!IsValidDeviceInstanceID(pDeviceID))
+        return CR_INVALID_DEVINST;
+
     RtlInitUnicodeString(&PlugPlayData.TargetDeviceInstance,
                          pDeviceID);
 
@@ -1349,6 +1421,9 @@ PNP_GetDepth(
 
     DPRINT("PNP_GetDepth() called\n");
 
+    if (!IsValidDeviceInstanceID(pszDeviceID))
+        return CR_INVALID_DEVINST;
+
     RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
                          pszDeviceID);
 
@@ -1406,7 +1481,12 @@ PNP_GetDeviceRegProp(
         goto done;
     }
 
-    /* FIXME: Check pDeviceID */
+    /* Check pDeviceID */
+    if (!IsValidDeviceInstanceID(pDeviceID))
+    {
+        ret = CR_INVALID_DEVINST;
+        goto done;
+    }
 
     if (*pulLength < *pulTransferLen)
         *pulLength = *pulTransferLen;
@@ -1653,6 +1733,9 @@ PNP_SetDeviceRegProp(
     DPRINT("DataType: %lu\n", ulDataType);
     DPRINT("Length: %lu\n", ulLength);
 
+    if (!IsValidDeviceInstanceID(pDeviceId))
+        return CR_INVALID_DEVINST;
+
     switch (ulProperty)
     {
         case CM_DRP_DEVICEDESC:
@@ -1790,6 +1873,9 @@ PNP_GetClassInstance(
     DPRINT("PNP_GetClassInstance(%p %S %p %lu)\n",
            hBinding, pDeviceId, pszClassInstance, ulLength);
 
+    if (!IsValidDeviceInstanceID(pDeviceId))
+        return CR_INVALID_DEVINST;
+
     ulTransferLength = ulLength;
     ret = PNP_GetDeviceRegProp(hBinding,
                                pDeviceId,
@@ -2091,6 +2177,9 @@ PNP_GetInterfaceDeviceList(
 
     UNREFERENCED_PARAMETER(hBinding);
 
+    if (!IsValidDeviceInstanceID(pszDeviceID))
+        return CR_INVALID_DEVINST;
+
     RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
                          pszDeviceID);
 
@@ -2134,6 +2223,9 @@ PNP_GetInterfaceDeviceListSize(
 
     DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
 
+    if (!IsValidDeviceInstanceID(pszDeviceID))
+        return CR_INVALID_DEVINST;
+
     RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
                          pszDeviceID);
 
@@ -2729,6 +2821,9 @@ PNP_GetDeviceStatus(
     DPRINT("PNP_GetDeviceStatus(%p %S %p %p)\n",
            hBinding, pDeviceID, pulStatus, pulProblem, ulFlags);
 
+    if (!IsValidDeviceInstanceID(pDeviceID))
+        return CR_INVALID_DEVINST;
+
     return GetDeviceStatus(pDeviceID, pulStatus, pulProblem);
 }
 
@@ -2961,6 +3056,9 @@ PNP_QueryRemove(
     if (ulFlags & ~CM_REMOVE_BITS)
         return CR_INVALID_FLAG;
 
+    if (!IsValidDeviceInstanceID(pszDeviceID))
+        return CR_INVALID_DEVINST;
+
     if (pVetoType != NULL)
         *pVetoType = PNP_VetoTypeUnknown;
 
@@ -3006,6 +3104,9 @@ PNP_RequestDeviceEject(
     if (ulFlags != 0)
         return CR_INVALID_FLAG;
 
+    if (!IsValidDeviceInstanceID(pszDeviceID))
+        return CR_INVALID_DEVINST;
+
     if (pVetoType != NULL)
         *pVetoType = PNP_VetoTypeUnknown;
 
@@ -3140,6 +3241,9 @@ PNP_HwProfFlags(
 
     DPRINT("PNP_HwProfFlags() called\n");
 
+    if (!IsValidDeviceInstanceID(pDeviceID))
+        return CR_INVALID_DEVINST;
+
     if (ulConfig == 0)
     {
         wcscpy(szKeyName,
@@ -3748,6 +3852,9 @@ PNP_GetCustomDevProp(
         goto done;
     }
 
+    if (!IsValidDeviceInstanceID(pDeviceID))
+        return CR_INVALID_DEVINST;
+
     if (*pulLength < *pulTransferLen)
         *pulLength = *pulTransferLen;