[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 | 163 +++++++++++++++++++++++++++++++++------------
 1 file changed, 122 insertions(+), 41 deletions(-)

diff --git a/src/xenbus/store.c b/src/xenbus/store.c
index afb1954..27e0706 100644
--- a/src/xenbus/store.c
+++ b/src/xenbus/store.c
@@ -1099,6 +1099,51 @@ RtlCaptureStackBackTrace(
     __out_opt   PULONG  BackTraceHash
     );
 
+static NTSTATUS
+StoreCheckPathLength(
+    _In_opt_ PSTR   Prefix,
+    _In_ PSTR       Node
+    )
+{
+    size_t          MaximumLength;
+    size_t          Length;
+
+    if (Prefix != NULL) {
+        MaximumLength = (Prefix[0] == '/' || Prefix[0] == '\0') ?
+                    XENSTORE_ABS_PATH_MAX :
+                    XENSTORE_REL_PATH_MAX;
+
+        Length = strlen(Prefix);
+        if (Length > MaximumLength)
+            goto fail1;
+        MaximumLength -= Length;
+
+        if (MaximumLength < 1)
+            goto fail2;
+        MaximumLength -= 1;
+    } else {
+        MaximumLength = Node[0] == '/' ?
+                            XENSTORE_ABS_PATH_MAX :
+                            XENSTORE_REL_PATH_MAX;
+    }
+
+    Length = strlen(Node);
+    if (Length > MaximumLength)
+        goto fail3;
+    MaximumLength -= Length;
+
+    if (MaximumLength < 1)
+        goto fail4;
+
+    return STATUS_SUCCESS;
+
+fail4:
+fail3:
+fail2:
+fail1:
+    return STATUS_INVALID_BUFFER_SIZE;
+}
+
 static NTSTATUS
 StoreRead(
     _In_ PINTERFACE                     Interface,
@@ -1116,6 +1161,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 +1194,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 +1219,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 +1295,9 @@ fail3:
     StoreFreeResponse(Response);
 
 fail2:
-fail1:
     ASSERT(IsZeroMemory(&Request, sizeof (XENBUS_STORE_REQUEST)));
 
+fail1:
     return status;
 }
 
@@ -1326,6 +1376,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 +1390,9 @@ StorePrintf(
     va_end(Arguments);
 
     return status;
+
+fail1:
+    return status;
 }
 
 static NTSTATUS
@@ -1352,6 +1409,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 +1440,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 +1485,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 +1518,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 +1547,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 +1739,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 +1761,7 @@ StoreWatchAdd(
 
     status = STATUS_NO_MEMORY;
     if (Path == NULL)
-        goto fail2;
+        goto fail3;
 
     status = (Prefix == NULL) ?
              RtlStringCbPrintfA(Path, Length, "%s", Node) :
@@ -1736,24 +1807,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 +1841,8 @@ fail3:
 
     __StoreFree(Path);
 
-fail2:
-    Error("fail2\n");
+fail3:
+    Error("fail3\n");
 
     (*Watch)->Caller = NULL;
     (*Watch)->Magic = 0;
@@ -1779,6 +1850,9 @@ fail2:
     ASSERT(IsZeroMemory(*Watch, sizeof (XENBUS_STORE_WATCH)));
     __StoreFree(*Watch);
 
+fail2:
+    Error("fail2\n");
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -2057,11 +2131,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 +2149,7 @@ StorePermissionsSet(
     Path = __StoreAllocate(Length);
 
     if (Path == NULL)
-        goto fail2;
+        goto fail3;
 
     status = (Prefix == NULL) ?
              RtlStringCbPrintfA(Path, Length, "%s", Node) :
@@ -2088,7 +2166,7 @@ StorePermissionsSet(
                                          Length,
                                          &Used);
         if (!NT_SUCCESS(status))
-            goto fail3;
+            goto fail4;
 
         Segment += Used;
         Length -= Used;
@@ -2108,17 +2186,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 +2206,12 @@ StorePermissionsSet(
 
     return STATUS_SUCCESS;
 
+fail7:
+    Error("fail7\n");
+    StoreFreeResponse(Response);
+
 fail6:
     Error("fail6\n");
-    StoreFreeResponse(Response);
 
 fail5:
     Error("fail5\n");
@@ -2138,17 +2219,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®.