Xen Security Advisory 468 v3 (CVE-2025-27462,CVE-2025-27463,CVE-2025-27464) - WinPVDrivers: Excessive permissions on user-exposed devices

Xen.org security team posted 1 patch 5 months ago
Failed in applying to current master (apply log)
src/xenbus/store.c | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
Xen Security Advisory 468 v3 (CVE-2025-27462,CVE-2025-27463,CVE-2025-27464) - WinPVDrivers: Excessive permissions on user-exposed devices
Posted by Xen.org security team 5 months ago
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

 Xen Security Advisory CVE-2025-27462,CVE-2025-27463,CVE-2025-27464 / XSA-468
                                   version 3

      WinPVDrivers: Excessive permissions on user-exposed devices

UPDATES IN VERSION 3
====================

Public release.

ISSUE DESCRIPTION
=================

The Windows PV drivers expose various facilities to userspace.  Several
of these have no security descriptor, and are therefore fully accessible
to unprivileged users.  These are:

  1. XenCons,  CVE-2025-27462
  2. XenIface, CVE-2025-27463
  3. XenBus,   CVE-2025-27464

IMPACT
======

Unprivileged users inside the guest can escalate privilege to that of
the guest kernel.

VULNERABLE SYSTEMS
==================

All Windows virtual machines running the Windows PV drivers are
vulnerable.

The xencons driver was first available in the 9.0.0 release, and is
vulnerable since its introduction.

The xeniface and xenbus drivers are vulnerable in all releases.

MITIGATION
==========

A PowerShell script to mitigate the issue in the XenIface driver has been
developed.  It is a single-shot script which can either scan for the
vulnerabilities, or fix them by inserting the relevant security descriptors
into the registry and the running device objects.  See the script for full
invocation information.

Because attaching PowerShell scripts to emails causes them to be
rejected by several major service providers, the script is instead
available from:

  https://paste.vates.tech/?415ce4adb9dde353#6REZBQosbawepd8RcCWrhZ5H3euYSNXGcfHr6hrwU2om
  password: 79322bc8-94fe-42f6-8b81-8373fa9458d0
  sha256: db45e6123312cf9a3a2136f903f82826556915b76b5149b00eeefbe0a2912107

It has only been lightly reviewed by the Xen Security Team.  Feedback
welcome.

CREDITS
=======

This issue was discovered by Tu Dinh of Vates

RESOLUTION
==========

Applying the attached paches resolves this issue.

xsa468/xenbus-01.patch             Windows xenbus
xsa468/xencons-0?.patch            Windows xencons
xsa468/xeniface-0?.patch           Windows xeniface

Note: xeniface-03 and 04 are not being treated as security issues, but
are included for downstreams wishing to include them in the same WHQL
testing run.

$ sha256sum xsa468*/*
3c4fbc0526c2a099e0866f9483c545605ab30c7bae8cfbfc7deea7f491b34ac3  xsa468/xenbus-01.patch
7336ce0fd1df73921ec4246bf71ccd8709a8fae20c056e7aba231f34ebccefc9  xsa468/xencons-01.patch
bbacf952c8f78ec6d0ea8ae25d6b1a5e4789c651bfbe6a357adbfc681c49809f  xsa468/xencons-02.patch
0e65525d0a89d693b0b62074e593be332a431cbe245aa8f7d94db4f93a0e7c78  xsa468/xeniface-01.patch
d9193ea2f120281b3ff0886f65ab87723520577826a347db539ef8904eaffa02  xsa468/xeniface-02.patch
f5a6da368cd0114e8d462d7959590e2abff0523574091427896d7092face0e6a  xsa468/xeniface-03.patch
01fadfd4906db35a14cba6d17cc2d28020f554564741c764db876dca43205ad3  xsa468/xeniface-04.patch
$

DEPLOYMENT DURING EMBARGO
=========================

Deployment of patches or mitigations is NOT permitted (except where
all the affected systems and VMs are administered and used only by
organisations which are members of the Xen Project Security Issues
Predisclosure List).  Specifically, deployment on public cloud systems
is NOT permitted.

This is because the fixes change in-guest behaviour.

Deployment is permitted only AFTER the embargo ends.


(Note: this during-embargo deployment notice is retained in
post-embargo publicly released Xen Project advisories, even though it
is then no longer applicable.  This is to enable the community to have
oversight of the Xen Project Security Team's decisionmaking.)

For more information about permissible uses of embargoed information,
consult the Xen Project community's agreed Security Policy:
  http://www.xenproject.org/security-policy.html
-----BEGIN PGP SIGNATURE-----

iQFABAEBCAAqFiEEI+MiLBRfRHX6gGCng/4UyVfoK9kFAmg1o+EMHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZB4IH+QGuIpu1qNVMNNL6rsWSHXJO764VIS8nn6sadMPI
heKoqWr9RMzPZsFDK5qWtckUR4Mfloj/3OD3VDb7a+qeeHFRHCvtpJ5L+q+JYAW6
5Fi5mGqNxTZWjCiwyKtKpJqRj7xSSb49TAi7BrshToV5jD66IyKUW44qFEeXPrs8
KTg2M3MhOO+OJrnHZHcKbhXd2IyhcYL96wg6KteVoQb35uyiDRpj1/mT4BQvp03n
3MJe3uQCavorEPiiWk+Zy/DXSBzFsGpsCSwGOYgjC7HZfWvtsmWeREQhai32LpBi
HW7yufiHwn/sC4hJT98CR1UvH/IJRbEG4kqVX4J6dxau9bw=
=QxLI
-----END PGP SIGNATURE-----
From fbe686c008d5c0373188b3738dfe3e75250d3cd7 Mon Sep 17 00:00:00 2001
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Date: Tue, 1 Apr 2025 10:36:12 +0000
Subject: Properly limit xenstore write lengths

Xenbus's write interface only checks write data sizes using asserts.
The size of overly-large writes (e.g. through Xeniface IOCTLs) is not
checked in release builds.

Verify write lengths using full checks instead of asserts to fix this
issue.

This is XSA-468 / CVE-2025-27464.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
Acked-by: Paul Durrant <paul@xen.org>
Reviewed-by: Owen Smith <owen.smith@cloud.com>
---
 src/xenbus/store.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/src/xenbus/store.c b/src/xenbus/store.c
index 02d3cc27b5cc..02cdd179ead1 100644
--- a/src/xenbus/store.c
+++ b/src/xenbus/store.c
@@ -32,6 +32,7 @@
 
 #include <ntddk.h>
 #include <ntstrsafe.h>
+#include <ntintsafe.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <xen.h>
@@ -210,6 +211,7 @@ StorePrepareRequest(
     Segment->Length = sizeof (struct xsd_sockmsg);
 
     va_start(Arguments, Type);
+    status = STATUS_UNSUCCESSFUL;
     for (;;) {
         PCHAR   Data;
         ULONG   Length;
@@ -222,14 +224,19 @@ StorePrepareRequest(
             break;
         }
 
+        if (Request->Count >= XENBUS_STORE_REQUEST_SEGMENT_COUNT)
+            goto fail2;
         Segment = &Request->Segment[Request->Count++];
-        ASSERT3U(Request->Count, <, XENBUS_STORE_REQUEST_SEGMENT_COUNT);
 
         Segment->Data = Data;
         Segment->Offset = 0;
         Segment->Length = Length;
 
-        Request->Header.len += Segment->Length;
+        if (!NT_SUCCESS(RtlULongAdd(Request->Header.len,
+                                    Segment->Length,
+                                    &Request->Header.len)) ||
+            Request->Header.len > XENSTORE_PAYLOAD_MAX)
+            goto fail3;
     }
     va_end(Arguments);
 
@@ -237,6 +244,10 @@ StorePrepareRequest(
 
     return STATUS_SUCCESS;
 
+fail3:
+fail2:
+    RtlZeroMemory(Request, sizeof (XENBUS_STORE_REQUEST));
+
 fail1:
     return status;
 }
@@ -1272,10 +1283,12 @@ StoreVPrintf(
         if (status != STATUS_BUFFER_OVERFLOW)
             goto fail2;
 
-        __StoreFree(Buffer);
+        status = STATUS_INVALID_BUFFER_SIZE;
         Length <<= 1;
+        if (Length > 1024)
+            goto fail3;
 
-        ASSERT3U(Length, <=, 1024);
+        __StoreFree(Buffer);
     }
 
     status = StoreWrite(Context,
@@ -1284,12 +1297,13 @@ StoreVPrintf(
                           Node,
                           Buffer);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail4;
 
     __StoreFree(Buffer);
 
     return STATUS_SUCCESS;
 
+fail4:
 fail3:
 fail2:
     __StoreFree(Buffer);
-- 
2.47.1

From 9f5f029544eb9384c106a6ccc6f2531c902125bb Mon Sep 17 00:00:00 2001
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Date: Wed, 5 Mar 2025 09:43:36 +0000
Subject: Restrict default access to Xencons PDO

Without assigning an explicit SDDL via IoCreateDeviceSecure, any user
can open the Xencons PDO via its default security descriptor.

This is part of XSA-468 / CVE-2025-27462.

Fixes: 28a08191188f ("Add boilerplate Pdo")
Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
Reviewed-By: Owen Smith <owen.smith@cloud.com>

diff --git a/src/xencons/console.c b/src/xencons/console.c
index 939d8c850e82..72421ce2a38d 100644
--- a/src/xencons/console.c
+++ b/src/xencons/console.c
@@ -36,6 +36,7 @@
 #include <wdmguid.h>
 #include <ntstrsafe.h>
 #include <stdlib.h>
+#include <wdmsec.h>
 
 #include <xencons_device.h>
 
@@ -287,6 +288,10 @@ __ConsoleDeviceControl(
     OutputBufferLength = StackLocation->Parameters.DeviceIoControl.OutputBufferLength;
     Buffer = Irp->AssociatedIrp.SystemBuffer;
 
+    status = WdmlibIoValidateDeviceIoControlAccess(Irp, FILE_READ_ACCESS);
+    if (status != STATUS_SUCCESS)
+        return status;
+
     switch (IoControlCode) {
     case IOCTL_XENCONS_GET_INSTANCE:
         Value = "0";
diff --git a/src/xencons/pdo.c b/src/xencons/pdo.c
index 68cccdefe3f7..8726f7da2e88 100644
--- a/src/xencons/pdo.c
+++ b/src/xencons/pdo.c
@@ -36,6 +36,7 @@
 #include <wdmguid.h>
 #include <ntstrsafe.h>
 #include <stdlib.h>
+#include <wdmsec.h>
 
 #include <suspend_interface.h>
 #include <xencons_device.h>
@@ -1915,13 +1916,15 @@ PdoCreate(
     NTSTATUS            status;
 
 #pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject'
-    status = IoCreateDevice(DriverGetDriverObject(),
-                            sizeof(XENCONS_DX),
-                            NULL,
-                            FILE_DEVICE_UNKNOWN,
-                            FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
-                            FALSE,
-                            &PhysicalDeviceObject);
+    status = IoCreateDeviceSecure(DriverGetDriverObject(),
+                                  sizeof(XENCONS_DX),
+                                  NULL,
+                                  FILE_DEVICE_UNKNOWN,
+                                  FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
+                                  FALSE,
+                                  &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
+                                  &GUID_XENCONS_DEVICE_CLASS,
+                                  &PhysicalDeviceObject);
     if (!NT_SUCCESS(status))
         goto fail1;
 
diff --git a/src/xencons/pdo.h b/src/xencons/pdo.h
index c53f361f2db6..52d78a57c1d1 100644
--- a/src/xencons/pdo.h
+++ b/src/xencons/pdo.h
@@ -37,6 +37,10 @@
 
 #include "driver.h"
 
+// {50006123-0940-4C78-A54B-A43DC83164EF}
+DEFINE_GUID(GUID_XENCONS_DEVICE_CLASS,
+    0x50006123, 0x940, 0x4c78, 0xa5, 0x4b, 0xa4, 0x3d, 0xc8, 0x31, 0x64, 0xef);
+
 extern VOID
 PdoSetDevicePnpState(
     IN  PXENCONS_PDO        Pdo,
From 0ad058645afc60aa2e76e39bfcc0cc223b93a019 Mon Sep 17 00:00:00 2001
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Date: Fri, 28 Mar 2025 22:58:50 +0000
Subject: Secure Xencons monitor named pipes

* Create monitor named pipes under the
  \\.\pipe\ProtectedPrefix\Administrators prefix to prevent unprivileged
  users from creating named pipe instances under the same path;
* Assign a restrictive security descriptor to monitor named pipes to
  prevent unprivileged users from reading console inputs;
* Set PIPE_REJECT_REMOTE_CLIENTS to prevent monitor named pipes from
  being exposed to the network.

This is part of XSA-468 / CVE-2025-27462.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
Reviewed-by: Owen Smith <owen.smith@cloud.com>
---
 src/monitor/monitor.c | 36 ++++++++++++++++++++++++++++--------
 src/tty/tty.c         |  2 +-
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 59e6ab6aee78..ec8a638638f8 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -40,6 +40,7 @@
 #include <cfgmgr32.h>
 #include <dbt.h>
 #include <setupapi.h>
+#include <sddl.h>
 #include <malloc.h>
 #include <assert.h>
 
@@ -93,7 +94,9 @@ typedef struct _MONITOR_CONNECTION {
 
 static MONITOR_CONTEXT MonitorContext;
 
-#define PIPE_BASE_NAME "\\\\.\\pipe\\xencons\\"
+#define PIPE_BASE_NAME "\\\\.\\pipe\\ProtectedPrefix\\Administrators\\xencons\\"
+// FILE_GENERIC_ALL for SYSTEM and Builtin\Administrators, nothing for the rest
+#define PIPE_SDDL "D:(A;;FA;;;SY)(A;;FA;;;BA)"
 
 #define MAXIMUM_BUFFER_SIZE 1024
 
@@ -436,6 +439,7 @@ ServerThread(
     DWORD               Object;
     PMONITOR_CONNECTION Connection;
     HRESULT             Error;
+    SECURITY_ATTRIBUTES SecurityAttributes;
 
     Log("====> %s", Console->DeviceName);
 
@@ -460,17 +464,26 @@ ServerThread(
 
     Log("%s", PipeName);
 
+    ZeroMemory(&SecurityAttributes, sizeof(SECURITY_ATTRIBUTES));
+    SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+    SecurityAttributes.bInheritHandle = FALSE;
+    if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(PIPE_SDDL,
+                                                              SDDL_REVISION_1,
+                                                              &SecurityAttributes.lpSecurityDescriptor,
+                                                              NULL))
+        goto fail3;
+
     for (;;) {
         Pipe = CreateNamedPipe(PipeName,
                                PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
-                               PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
+                               PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS,
                                PIPE_UNLIMITED_INSTANCES,
                                MAXIMUM_BUFFER_SIZE,
                                MAXIMUM_BUFFER_SIZE,
                                0,
-                               NULL);
+                               &SecurityAttributes);
         if (Pipe == INVALID_HANDLE_VALUE)
-            goto fail3;
+            goto fail4;
 
         (VOID) ConnectNamedPipe(Pipe,
                                 &Overlapped);
@@ -488,7 +501,7 @@ ServerThread(
 
         Connection = (PMONITOR_CONNECTION)malloc(sizeof(MONITOR_CONNECTION));
         if (Connection == NULL)
-            goto fail4;
+            goto fail5;
 
         __InitializeListHead(&Connection->ListEntry);
         Connection->Console = Console;
@@ -500,24 +513,31 @@ ServerThread(
                                           0,
                                           NULL);
         if (Connection->Thread == NULL)
-            goto fail5;
+            goto fail6;
     }
 
+    LocalFree(&SecurityAttributes.lpSecurityDescriptor);
+
     CloseHandle(Overlapped.hEvent);
 
     Log("<==== %s", Console->DeviceName);
 
     return 0;
 
+fail6:
+    Log("fail6");
+
+    free(Connection);
+
 fail5:
     Log("fail5");
 
-    free(Connection);
+    CloseHandle(Pipe);
 
 fail4:
     Log("fail4");
 
-    CloseHandle(Pipe);
+    LocalFree(&SecurityAttributes.lpSecurityDescriptor);
 
 fail3:
     Log("fail3");
diff --git a/src/tty/tty.c b/src/tty/tty.c
index c3b6f8e18345..08d372435772 100644
--- a/src/tty/tty.c
+++ b/src/tty/tty.c
@@ -44,7 +44,7 @@ typedef struct _TTY_STREAM {
     HANDLE  Write;
 } TTY_STREAM, *PTTY_STREAM;
 
-#define PIPE_NAME TEXT("\\\\.\\pipe\\xencons\\default")
+#define PIPE_NAME TEXT("\\\\.\\pipe\\ProtectedPrefix\\Administrators\\xencons\\default")
 #define MAXIMUM_BUFFER_SIZE 1024
 
 typedef struct _TTY_CONTEXT {
-- 
2.47.1

From 62e4dc40394964926f9133ae675efa0350af1e66 Mon Sep 17 00:00:00 2001
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Date: Wed, 5 Mar 2025 09:43:54 +0000
Subject: Restrict default access to Xeniface device

Without assigning an explicit SDDL via xeniface.inf, any user can open
the Xeniface FDO via its default security descriptor.

Additionally, validate user read+write access to the Xeniface FDO before
allowing IOCTLs to this interface.

This is part of XSA-468 / CVE-2025-27463.

Fixes: c649edc84f85 ("Initial commit of fully open xeniface code")
Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
Reviewed-By: Owen Smith <owen.smith@cloud.com>

diff --git a/src/xeniface.inf b/src/xeniface.inf
index fe5ea755e8f7..b5433920e987 100644
--- a/src/xeniface.inf
+++ b/src/xeniface.inf
@@ -72,6 +72,12 @@ xenagent_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,xena
 CopyFiles=XenIface_CopyFiles
 CopyFiles=XenAgent_CopyFiles
 
+[XenIface_Inst.HW]
+AddReg=XenIface_Inst.HW.AddReg
+
+[XenIface_Inst.HW.AddReg]
+HKR,,Security,,"D:P(A;;GA;;;SY)(A;;GA;;;BA)"  ; SDDL_DEVOBJ_SYS_ALL_ADM_ALL
+
 [Xeniface_Inst.Services]
 AddService = xeniface, 0x0002, XenIface_Service
 AddService = xenagent, 0x0800, XenAgent_Service,XenAgent_EventLog
diff --git a/src/xeniface/ioctls.c b/src/xeniface/ioctls.c
index 6282e77aba44..076750a65369 100644
--- a/src/xeniface/ioctls.c
+++ b/src/xeniface/ioctls.c
@@ -33,6 +33,7 @@
 
 #include <ntifs.h>
 #include <procgrp.h>
+#include <wdmsec.h>
 #include "driver.h"
 #include "ioctls.h"
 #include "xeniface_ioctls.h"
@@ -253,6 +254,10 @@ XenIfaceIoctl(
     if (Fdo->InterfacesAcquired == FALSE)
         goto done;
 
+    status = WdmlibIoValidateDeviceIoControlAccess(Irp, FILE_READ_ACCESS | FILE_WRITE_ACCESS);
+    if (status != STATUS_SUCCESS)
+        goto done;
+
     switch (ControlCode) {
         // store
     case IOCTL_XENIFACE_STORE_READ:
diff --git a/vs2019/xeniface/xeniface.vcxproj b/vs2019/xeniface/xeniface.vcxproj
index 1c5c15b4f9fe..9f8f766197e1 100644
--- a/vs2019/xeniface/xeniface.vcxproj
+++ b/vs2019/xeniface/xeniface.vcxproj
@@ -31,7 +31,7 @@
       <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\procgrp.lib;$(DDK_LIB_PATH)\wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
       <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
       <CETCompat>true</CETCompat>
diff --git a/vs2022/xeniface/xeniface.vcxproj b/vs2022/xeniface/xeniface.vcxproj
index 776e68e826a8..269ae3fd5f4a 100644
--- a/vs2022/xeniface/xeniface.vcxproj
+++ b/vs2022/xeniface/xeniface.vcxproj
@@ -31,7 +31,7 @@
       <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\procgrp.lib;$(DDK_LIB_PATH)\wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
       <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
       <CETCompat>true</CETCompat>
From a6df21c465012e6e1a7da4ac2be668a63fd50a07 Mon Sep 17 00:00:00 2001
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Date: Mon, 7 Apr 2025 09:34:46 +0000
Subject: Restrict access to Xeniface WMI classes

The default security descriptor provided to WMI GUIDs allows xenstore
access to LocalService and NetworkService accounts, which are supposed
to have minimum privileges on the local system.

Assign a security descriptor in xeniface.inf to restrict all WMI GUIDs.

This is part of XSA-468 / CVE-2025-27463.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
Reviewed-by: Owen Smith <owen.smith@cloud.com>
---
 src/xeniface.inf | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/xeniface.inf b/src/xeniface.inf
index b5433920e987..07e2a91efa38 100644
--- a/src/xeniface.inf
+++ b/src/xeniface.inf
@@ -72,6 +72,16 @@ xenagent_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,xena
 CopyFiles=XenIface_CopyFiles
 CopyFiles=XenAgent_CopyFiles
 
+[XenIface_Inst.WMI]
+WMIInterface={1D80EB99-A1D6-4492-B62F-8B4549FF0B5E},,XenIface_Inst.WMI.Security
+WMIInterface={12138A69-97B2-49DD-B9DE-54749AABC789},,XenIface_Inst.WMI.Security
+WMIInterface={AB8136BF-8EA7-420D-ADAD-89C83E587925},,XenIface_Inst.WMI.Security
+
+[XenIface_Inst.WMI.Security]
+; owned by BUILTIN\Administrators
+; grant GENERIC_ALL access to BUILTIN\Administrators and NT AUTHORITY\SYSTEM
+Security="O:BAG:BAD:(A;;GA;;;BA)(A;;GA;;;SY)"
+
 [XenIface_Inst.HW]
 AddReg=XenIface_Inst.HW.AddReg
 
-- 
2.47.1

From 13bd75331861e52d997aaa9f2ea454e0ef4141b5 Mon Sep 17 00:00:00 2001
From: Owen Smith <owen.smith@cloud.com>
Date: Thu, 3 Apr 2025 13:53:33 +0100
Subject: Dont reference In buffer after writing to Out buffer

In and Out both refer to the same I/O buffer, so referencing the In structure
after updating the value in the Out structure cal lead to the wrong results,
if the fields overlap.

Also reformats the function arguments and variable definitions.

Signed-off-by: Owen Smith <owen.smith@cloud.com>
Reviewed-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
Reviewed-by: Paul Durrant <paul@xen.org>
---
 src/xeniface/ioctl_evtchn.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/xeniface/ioctl_evtchn.c b/src/xeniface/ioctl_evtchn.c
index f5284858076e..6d6399650e54 100644
--- a/src/xeniface/ioctl_evtchn.c
+++ b/src/xeniface/ioctl_evtchn.c
@@ -210,9 +210,6 @@ IoctlEvtchnBindUnbound(
 
     ExInterlockedInsertTailList(&Fdo->EvtchnList, &Context->Entry, &Fdo->EvtchnLock);
 
-    Out->LocalPort = Context->LocalPort;
-    *Info = sizeof(XENIFACE_EVTCHN_BIND_UNBOUND_OUT);
-
     if (!In->Mask) {
         (VOID) XENBUS_EVTCHN(Unmask,
                              &Fdo->EvtchnInterface,
@@ -221,6 +218,9 @@ IoctlEvtchnBindUnbound(
                              TRUE);
     }
 
+    Out->LocalPort = Context->LocalPort;
+    *Info = sizeof(XENIFACE_EVTCHN_BIND_UNBOUND_OUT);
+
     Trace("< LocalPort %lu, Context %p\n", Context->LocalPort, Context);
     return STATUS_SUCCESS;
 
@@ -304,9 +304,6 @@ IoctlEvtchnBindInterdomain(
 
     ExInterlockedInsertTailList(&Fdo->EvtchnList, &Context->Entry, &Fdo->EvtchnLock);
 
-    Out->LocalPort = Context->LocalPort;
-    *Info = sizeof(XENIFACE_EVTCHN_BIND_INTERDOMAIN_OUT);
-
     if (!In->Mask) {
         (VOID) XENBUS_EVTCHN(Unmask,
                              &Fdo->EvtchnInterface,
@@ -315,6 +312,9 @@ IoctlEvtchnBindInterdomain(
                              TRUE);
     }
 
+    Out->LocalPort = Context->LocalPort;
+    *Info = sizeof(XENIFACE_EVTCHN_BIND_INTERDOMAIN_OUT);
+
     Trace("< LocalPort %lu, Context %p\n", Context->LocalPort, Context);
 
     return STATUS_SUCCESS;
-- 
2.47.1

From cd22cc5cb3e72e3634b719290015dc5fffe2b3ec Mon Sep 17 00:00:00 2001
From: Owen Smith <owen.smith@cloud.com>
Date: Thu, 3 Apr 2025 14:34:36 +0100
Subject: [PATCH 2/2] Fix leak in Permission list

Signed-off-by: Owen Smith <owen.smith@cloud.com>
Reviewed-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
Reviewed-by: Paul Durrant <paul@xen.org>
---
 src/xeniface/ioctl_store.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/xeniface/ioctl_store.c b/src/xeniface/ioctl_store.c
index 13527738dbb6..0fa850f2df83 100644
--- a/src/xeniface/ioctl_store.c
+++ b/src/xeniface/ioctl_store.c
@@ -435,6 +435,7 @@ IoctlStoreSetPermissions(
     if (!NT_SUCCESS(status))
         goto fail6;
 
+    __FreePermissions(Permissions);
     __FreeCapturedBuffer(Path);
     return status;
 
-- 
2.47.1