[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] Add check for maximum xenstore key lengths
On 22/08/2025 16:40, Owen Smith wrote: > 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> Reviewed-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx> > --- > 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); > Ngoc Tu Dinh | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |