[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


 


Rackspace

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