[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [win-pv-devel] [PATCH 2/3] Add support for changing key permissions to the STORE interface



> -----Original Message-----
> From: win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx [mailto:win-pv-devel-
> bounces@xxxxxxxxxxxxxxxxxxxx] On Behalf Of Rafal Wojdyla
> Sent: 11 September 2015 13:31
> To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> Subject: [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>

Again a few stylistic issues and again I'll fix them.

Acked-by: Paul Durrant <paul.durrant@xxxxxxxxxx>

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

_______________________________________________
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®.