[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Add check for maximum xenstore key lengths



Check any xenstore path lengths before calling into xenstore, in order
to fail without passing control to xenstored, which should fail any request
with paths exceeding the defined maximum length.

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx>
---
 src/xenbus/store.c | 149 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 108 insertions(+), 41 deletions(-)

diff --git a/src/xenbus/store.c b/src/xenbus/store.c
index afb1954..0c00d23 100644
--- a/src/xenbus/store.c
+++ b/src/xenbus/store.c
@@ -1099,6 +1099,37 @@ RtlCaptureStackBackTrace(
     __out_opt   PULONG  BackTraceHash
     );
 
+static NTSTATUS
+StoreCheckPathLength(
+    _In_opt_ PSTR   Prefix,
+    _In_ PSTR       Node
+    )
+{
+    size_t          Length;
+    size_t          MaximumLength;
+
+    Length = Prefix == NULL ? 0 : strlen(Prefix);
+
+    if (Length == 0) {
+        // Prefix is NULL or empty
+        MaximumLength = Node[0] == '/' ?
+                            XENSTORE_ABS_PATH_MAX :
+                            XENSTORE_REL_PATH_MAX;
+
+        Length = strlen(Node) + 1;
+    } else {
+        MaximumLength = Prefix[0] == '/' ?
+                            XENSTORE_ABS_PATH_MAX :
+                            XENSTORE_REL_PATH_MAX;
+
+        Length += 1 + strlen(Node) + 1;
+    }
+
+    return Length > MaximumLength ?
+                STATUS_INVALID_BUFFER_SIZE :
+                STATUS_SUCCESS;
+}
+
 static NTSTATUS
 StoreRead(
     _In_ PINTERFACE                     Interface,
@@ -1116,6 +1147,10 @@ StoreRead(
     PXENBUS_STORE_BUFFER                Buffer;
     NTSTATUS                            status;
 
+    status = StoreCheckPathLength(Prefix, Node);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     (VOID) RtlCaptureStackBackTrace(1, 1, &Caller, NULL);
 
     RtlZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST));
@@ -1145,23 +1180,23 @@ StoreRead(
     KeReleaseSpinLock(&Context->Lock, Irql);
 
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail2;
 
     Response = StoreSubmitRequest(Context, &Request);
 
     status = STATUS_NO_MEMORY;
     if (Response == NULL)
-        goto fail2;
+        goto fail3;
 
     status = StoreCheckResponse(Response);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail4;
 
     Buffer = StoreCopyPayload(Context, Response, Caller);
 
     status = STATUS_NO_MEMORY;
     if (Buffer == NULL)
-        goto fail4;
+        goto fail5;
 
     StoreFreeResponse(Response);
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
@@ -1170,14 +1205,15 @@ StoreRead(
 
     return STATUS_SUCCESS;
 
+fail5:
 fail4:
-fail3:
     StoreFreeResponse(Response);
 
+fail3:
 fail2:
-fail1:
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
 
+fail1:
     return status;
 }
 
@@ -1245,9 +1281,9 @@ fail3:
     StoreFreeResponse(Response);
 
 fail2:
-fail1:
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
 
+fail1:
     return status;
 }
 
@@ -1326,6 +1362,10 @@ StorePrintf(
     va_list                             Arguments;
     NTSTATUS                            status;
 
+    status = StoreCheckPathLength(Prefix, Node);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     va_start(Arguments, Format);
     status = StoreVPrintf(Interface,
                             Transaction,
@@ -1336,6 +1376,9 @@ StorePrintf(
     va_end(Arguments);
 
     return status;
+
+fail1:
+    return status;
 }
 
 static NTSTATUS
@@ -1352,6 +1395,10 @@ StoreRemove(
     PXENBUS_STORE_RESPONSE              Response;
     NTSTATUS                            status;
 
+    status = StoreCheckPathLength(Prefix, Node);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     RtlZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST));
 
     KeAcquireSpinLock(&Context->Lock, &Irql);
@@ -1379,30 +1426,31 @@ StoreRemove(
     KeReleaseSpinLock(&Context->Lock, Irql);
 
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail2;
 
     Response = StoreSubmitRequest(Context, &Request);
 
     status = STATUS_NO_MEMORY;
     if (Response == NULL)
-        goto fail2;
+        goto fail3;
 
     status = StoreCheckResponse(Response);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail4;
 
     StoreFreeResponse(Response);
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
 
     return STATUS_SUCCESS;
 
-fail3:
+fail4:
     StoreFreeResponse(Response);
 
+fail3:
 fail2:
-fail1:
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
 
+fail1:
     return status;
 }
 
@@ -1423,6 +1471,10 @@ StoreDirectory(
     PXENBUS_STORE_BUFFER                Buffer;
     NTSTATUS                            status;
 
+    status = StoreCheckPathLength(Prefix, Node);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     (VOID) RtlCaptureStackBackTrace(1, 1, &Caller, NULL);
 
     RtlZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST));
@@ -1452,27 +1504,27 @@ StoreDirectory(
     KeReleaseSpinLock(&Context->Lock, Irql);
 
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail2;
 
     Response = StoreSubmitRequest(Context, &Request);
 
     status = STATUS_NO_MEMORY;
     if (Response == NULL)
-        goto fail2;
+        goto fail3;
 
     status = StoreCheckResponse(Response);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail4;
 
     Buffer = StoreCopyPayload(Context, Response, Caller);
 
     status = STATUS_NO_MEMORY;
     if (Buffer == NULL)
-        goto fail4;
+        goto fail5;
 
     status = STATUS_OBJECT_PATH_NOT_FOUND;
     if (Buffer->Length == 0)
-        goto fail5;
+        goto fail6;
 
     StoreFreeResponse(Response);
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
@@ -1481,17 +1533,18 @@ StoreDirectory(
 
     return STATUS_SUCCESS;
 
-fail5:
+fail6:
     StoreFreePayload(Context, Buffer);
 
+fail5:
 fail4:
-fail3:
     StoreFreeResponse(Response);
 
+fail3:
 fail2:
-fail1:
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
 
+fail1:
     return status;
 }
 
@@ -1672,11 +1725,15 @@ StoreWatchAdd(
     KIRQL                           Irql;
     NTSTATUS                        status;
 
+    status = StoreCheckPathLength(Prefix, Node);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     *Watch = __StoreAllocate(sizeof (XENBUS_STORE_WATCH));
 
     status = STATUS_NO_MEMORY;
     if (*Watch == NULL)
-        goto fail1;
+        goto fail2;
 
     (*Watch)->Magic = STORE_WATCH_MAGIC;
     (VOID) RtlCaptureStackBackTrace(1, 1, &(*Watch)->Caller, NULL);
@@ -1690,7 +1747,7 @@ StoreWatchAdd(
 
     status = STATUS_NO_MEMORY;
     if (Path == NULL)
-        goto fail2;
+        goto fail3;
 
     status = (Prefix == NULL) ?
              RtlStringCbPrintfA(Path, Length, "%s", Node) :
@@ -1736,24 +1793,24 @@ StoreWatchAdd(
 
     status = STATUS_NO_MEMORY;
     if (Response == NULL)
-        goto fail3;
+        goto fail4;
 
     status = StoreCheckResponse(Response);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail5;
 
     StoreFreeResponse(Response);
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
 
     return STATUS_SUCCESS;
 
-fail4:
-    Error("fail4\n");
+fail5:
+    Error("fail5\n");
 
     StoreFreeResponse(Response);
 
-fail3:
-    Error("fail3\n");
+fail4:
+    Error("fail4\n");
 
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
 
@@ -1770,8 +1827,8 @@ fail3:
 
     __StoreFree(Path);
 
-fail2:
-    Error("fail2\n");
+fail3:
+    Error("fail3\n");
 
     (*Watch)->Caller = NULL;
     (*Watch)->Magic = 0;
@@ -1779,6 +1836,9 @@ fail2:
     ASSERT(IsZeroMemory(*Watch, sizeof (XENBUS_STORE_WATCH)));
     __StoreFree(*Watch);
 
+fail2:
+    Error("fail2\n");
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -2057,11 +2117,15 @@ StorePermissionsSet(
     PSTR                                PermissionString;
     PSTR                                Segment;
 
+    status = StoreCheckPathLength(Prefix, Node);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     PermissionString = __StoreAllocate(XENSTORE_PAYLOAD_MAX);
 
     status = STATUS_NO_MEMORY;
     if (PermissionString == NULL)
-        goto fail1;
+        goto fail2;
 
     if (Prefix == NULL)
         Length = (ULONG)strlen(Node) + sizeof (CHAR);
@@ -2071,7 +2135,7 @@ StorePermissionsSet(
     Path = __StoreAllocate(Length);
 
     if (Path == NULL)
-        goto fail2;
+        goto fail3;
 
     status = (Prefix == NULL) ?
              RtlStringCbPrintfA(Path, Length, "%s", Node) :
@@ -2088,7 +2152,7 @@ StorePermissionsSet(
                                          Length,
                                          &Used);
         if (!NT_SUCCESS(status))
-            goto fail3;
+            goto fail4;
 
         Segment += Used;
         Length -= Used;
@@ -2108,17 +2172,17 @@ StorePermissionsSet(
     KeReleaseSpinLock(&Context->Lock, Irql);
 
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail5;
 
     Response = StoreSubmitRequest(Context, &Request);
 
     status = STATUS_NO_MEMORY;
     if (Response == NULL)
-        goto fail5;
+        goto fail6;
 
     status = StoreCheckResponse(Response);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail7;
 
     StoreFreeResponse(Response);
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
@@ -2128,9 +2192,12 @@ StorePermissionsSet(
 
     return STATUS_SUCCESS;
 
+fail7:
+    Error("fail7\n");
+    StoreFreeResponse(Response);
+
 fail6:
     Error("fail6\n");
-    StoreFreeResponse(Response);
 
 fail5:
     Error("fail5\n");
@@ -2138,17 +2205,17 @@ fail5:
 fail4:
     Error("fail4\n");
 
+    __StoreFree(Path);
+    ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
+
 fail3:
     Error("fail3\n");
 
-    __StoreFree(Path);
-    ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
+    __StoreFree(PermissionString);
 
 fail2:
     Error("fail2\n");
 
-    __StoreFree(PermissionString);
-
 fail1:
     Error("fail1 (%08x)\n", status);
 
-- 
2.50.1.windows.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.