[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 2/3] Add support for changing key permissions to the STORE interface
STORE interface now includes a function to change key permissions. This allows granting key access to other, non-privileged domains. Signed-off-by: Rafal Wojdyla <omeg@xxxxxxxxxxxxxxxxxxxxxx> --- include/store_interface.h | 68 ++++++++++++++++- src/xenbus/store.c | 185 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 248 insertions(+), 5 deletions(-) diff --git a/include/store_interface.h b/include/store_interface.h index 5bcbba3..6775b27 100644 --- a/include/store_interface.h +++ b/include/store_interface.h @@ -50,6 +50,23 @@ typedef struct _XENBUS_STORE_TRANSACTION XENBUS_STORE_TRANSACTION, *PXENBUS_S */ typedef struct _XENBUS_STORE_WATCH XENBUS_STORE_WATCH, *PXENBUS_STORE_WATCH; +/*! \typedef XENBUS_STORE_PERMISSION_MASK + \brief Bitmask of XenStore key permissions +*/ +typedef enum _XENBUS_STORE_PERMISSION_MASK { + XENBUS_STORE_PERM_NONE = 0, + XENBUS_STORE_PERM_READ = 1, + XENBUS_STORE_PERM_WRITE = 2, +} XENBUS_STORE_PERMISSION_MASK; + +/*! \typedef XENBUS_STORE_PERMISSION + \brief XenStore key permissions entry for a single domain +*/ +typedef struct _XENBUS_STORE_PERMISSION { + USHORT Domain; + XENBUS_STORE_PERMISSION_MASK Mask; +} XENBUS_STORE_PERMISSION, *PXENBUS_STORE_PERMISSION; + /*! \typedef XENBUS_STORE_ACQUIRE \brief Acquire a reference to the STORE interface @@ -247,10 +264,36 @@ typedef VOID IN PINTERFACE Interface ); +/*! \typedef XENBUS_STORE_PERMISSIONS_SET + \brief Set permissions for a XenStore key + + \param Interface The interface header + \param Transaction The transaction handle (NULL if this is not + part of a transaction) + \param Prefix An optional prefix for the \a Node + \param Node The concatenation of the \a Prefix and this value specifies + the XenStore key to set permissions of + \param Permissions An array of permissions to set + \param NumberPermissions Number of elements in the \a Permissions array +*/ +typedef NTSTATUS +(*XENBUS_STORE_PERMISSIONS_SET)( + IN PINTERFACE Interface, + IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, + IN PCHAR Prefix OPTIONAL, + IN PCHAR Node, + IN PXENBUS_STORE_PERMISSION Permissions, + IN ULONG NumberPermissions + ); + // {86824C3B-D34E-4753-B281-2F1E3AD214D7} DEFINE_GUID(GUID_XENBUS_STORE_INTERFACE, 0x86824c3b, 0xd34e, 0x4753, 0xb2, 0x81, 0x2f, 0x1e, 0x3a, 0xd2, 0x14, 0xd7); +/*! \struct _XENBUS_STORE_INTERFACE_V1 + \brief STORE interface version 1 + \ingroup interfaces +*/ struct _XENBUS_STORE_INTERFACE_V1 { INTERFACE Interface; XENBUS_STORE_ACQUIRE StoreAcquire; @@ -267,11 +310,28 @@ struct _XENBUS_STORE_INTERFACE_V1 { XENBUS_STORE_POLL StorePoll; }; -/*! \struct _XENBUS_STORE_INTERFACE_V1 - \brief STORE interface version 1 +/*! \struct _XENBUS_STORE_INTERFACE_V2 + \brief STORE interface version 2 \ingroup interfaces */ -typedef struct _XENBUS_STORE_INTERFACE_V1 XENBUS_STORE_INTERFACE, *PXENBUS_STORE_INTERFACE; +struct _XENBUS_STORE_INTERFACE_V2 { + INTERFACE Interface; + XENBUS_STORE_ACQUIRE StoreAcquire; + XENBUS_STORE_RELEASE StoreRelease; + XENBUS_STORE_FREE StoreFree; + XENBUS_STORE_READ StoreRead; + XENBUS_STORE_PRINTF StorePrintf; + XENBUS_STORE_REMOVE StoreRemove; + XENBUS_STORE_DIRECTORY StoreDirectory; + XENBUS_STORE_TRANSACTION_START StoreTransactionStart; + XENBUS_STORE_TRANSACTION_END StoreTransactionEnd; + XENBUS_STORE_WATCH_ADD StoreWatchAdd; + XENBUS_STORE_WATCH_REMOVE StoreWatchRemove; + XENBUS_STORE_POLL StorePoll; + XENBUS_STORE_PERMISSIONS_SET StorePermissionsSet; +}; + +typedef struct _XENBUS_STORE_INTERFACE_V2 XENBUS_STORE_INTERFACE, *PXENBUS_STORE_INTERFACE; /*! \def XENBUS_STORE \brief Macro at assist in method invocation @@ -282,7 +342,7 @@ typedef struct _XENBUS_STORE_INTERFACE_V1 XENBUS_STORE_INTERFACE, *PXENBUS_STORE #endif // _WINDLL #define XENBUS_STORE_INTERFACE_VERSION_MIN 1 -#define XENBUS_STORE_INTERFACE_VERSION_MAX 1 +#define XENBUS_STORE_INTERFACE_VERSION_MAX 2 #endif // _XENBUS_STORE_INTERFACE_H diff --git a/src/xenbus/store.c b/src/xenbus/store.c index c54b0f0..cf5ac79 100644 --- a/src/xenbus/store.c +++ b/src/xenbus/store.c @@ -442,7 +442,6 @@ StoreIgnoreHeaderType( case XS_RELEASE: case XS_GET_DOMAIN_PATH: case XS_MKDIR: - case XS_SET_PERMS: case XS_IS_DOMAIN_INTRODUCED: case XS_RESUME: case XS_SET_TARGET: @@ -470,6 +469,7 @@ StoreVerifyHeader( Header->type != XS_TRANSACTION_END && Header->type != XS_WRITE && Header->type != XS_RM && + Header->type != XS_SET_PERMS && Header->type != XS_WATCH_EVENT && Header->type != XS_ERROR && !StoreIgnoreHeaderType(Header->type)) { @@ -1816,6 +1816,155 @@ StorePoll( KeReleaseSpinLockFromDpcLevel(&Context->Lock); } +static NTSTATUS +StorePermissionToString( + IN PXENBUS_STORE_PERMISSION Permission, + OUT PCHAR Buffer, + IN ULONG BufferSize, + OUT PULONG UsedSize + ) +{ + size_t Remaining; + NTSTATUS status = STATUS_INVALID_PARAMETER; + + ASSERT(BufferSize > 1); + + switch (Permission->Mask) { + case XENBUS_STORE_PERM_NONE: + *Buffer = 'n'; + break; + case XENBUS_STORE_PERM_READ: + *Buffer = 'r'; + break; + case XENBUS_STORE_PERM_WRITE: + *Buffer = 'w'; + break; + case XENBUS_STORE_PERM_READ | XENBUS_STORE_PERM_WRITE: + *Buffer = 'b'; + break; + default: + goto fail1; + } + + status = RtlStringCbPrintfExA(Buffer + 1, BufferSize - 1, NULL, &Remaining, 0, "%u", Permission->Domain); + if (!NT_SUCCESS(status)) + goto fail2; + + *UsedSize = BufferSize - (ULONG)Remaining + 1; + return STATUS_SUCCESS; + +fail2: + Error("fail2\n"); + +fail1: + Error("fail1 (%08x)\n", status); + return status; +} + +static NTSTATUS +StorePermissionsSet( + IN PINTERFACE Interface, + IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, + IN PCHAR Prefix OPTIONAL, + IN PCHAR Node, + IN PXENBUS_STORE_PERMISSION Permissions, + IN ULONG NumberPermissions + ) +{ + PXENBUS_STORE_CONTEXT Context = Interface->Context; + XENBUS_STORE_REQUEST Request; + PXENBUS_STORE_RESPONSE Response; + NTSTATUS status; + ULONG Index, Length, Used; + PCHAR Path = NULL; + PCHAR PermissionString, Segment; + + status = STATUS_NO_MEMORY; + PermissionString = __StoreAllocate(XENSTORE_PAYLOAD_MAX); + if (PermissionString == NULL) + goto fail1; + + if (Prefix == NULL) + Length = (ULONG)strlen(Node) + sizeof(CHAR); + else + Length = (ULONG)strlen(Prefix) + 1 + (ULONG)strlen(Node) + sizeof(CHAR); + + Path = __StoreAllocate(Length); + + if (Path == NULL) + goto fail2; + + status = (Prefix == NULL) ? + RtlStringCbPrintfA(Path, Length, "%s", Node) : + RtlStringCbPrintfA(Path, Length, "%s/%s", Prefix, Node); + ASSERT(NT_SUCCESS(status)); + + RtlZeroMemory(&Request, sizeof(XENBUS_STORE_REQUEST)); + + for (Index = 0, Segment = PermissionString, Length = XENSTORE_PAYLOAD_MAX; + Index < NumberPermissions; + Index++) { + status = StorePermissionToString(&Permissions[Index], Segment, Length, &Used); + if (!NT_SUCCESS(status)) + goto fail3; + + Segment += Used; + Length -= Used; + } + + status = StorePrepareRequest(Context, + &Request, + Transaction, + XS_SET_PERMS, + Path, strlen(Path), + "", 1, + PermissionString, XENSTORE_PAYLOAD_MAX - Length, + NULL, 0); + + if (!NT_SUCCESS(status)) + goto fail4; + + status = STATUS_NO_MEMORY; + Response = StoreSubmitRequest(Context, &Request); + if (Response == NULL) + goto fail5; + + status = StoreCheckResponse(Response); + if (!NT_SUCCESS(status)) + goto fail6; + + StoreFreeResponse(Response); + ASSERT(IsZeroMemory(&Request, sizeof(XENBUS_STORE_REQUEST))); + + __StoreFree(Path); + __StoreFree(PermissionString); + + return STATUS_SUCCESS; + +fail6: + Error("fail6\n"); + StoreFreeResponse(Response); + +fail5: + Error("fail5\n"); + +fail4: + Error("fail4\n"); + +fail3: + Error("fail3\n"); + __StoreFree(Path); + ASSERT(IsZeroMemory(&Request, sizeof(XENBUS_STORE_REQUEST))); + +fail2: + Error("fail2\n"); + __StoreFree(PermissionString); + +fail1: + Error("fail1 (%08x)\n", status); + return status; +} + static _Function_class_(KSERVICE_ROUTINE) _IRQL_requires_(HIGH_LEVEL) @@ -2327,6 +2476,23 @@ static struct _XENBUS_STORE_INTERFACE_V1 StoreInterfaceVersion1 = { StorePoll }; +static struct _XENBUS_STORE_INTERFACE_V2 StoreInterfaceVersion2 = { + { sizeof(struct _XENBUS_STORE_INTERFACE_V2), 2, NULL, NULL, NULL }, + StoreAcquire, + StoreRelease, + StoreFree, + StoreRead, + StorePrintf, + StoreRemove, + StoreDirectory, + StoreTransactionStart, + StoreTransactionEnd, + StoreWatchAdd, + StoreWatchRemove, + StorePoll, + StorePermissionsSet +}; + NTSTATUS StoreInitialize( IN PXENBUS_FDO Fdo, @@ -2426,6 +2592,23 @@ StoreGetInterface( status = STATUS_SUCCESS; break; } + case 2: { + struct _XENBUS_STORE_INTERFACE_V2 *StoreInterface; + + StoreInterface = (struct _XENBUS_STORE_INTERFACE_V2 *)Interface; + + status = STATUS_BUFFER_OVERFLOW; + if (Size < sizeof(struct _XENBUS_STORE_INTERFACE_V2)) + break; + + *StoreInterface = StoreInterfaceVersion2; + + ASSERT3U(Interface->Version, == , Version); + Interface->Context = Context; + + status = STATUS_SUCCESS; + break; + } default: status = STATUS_NOT_SUPPORTED; break; -- 1.8.1.msysgit.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |