|
[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 |