From 1bd51314ffbcb38a63e80ec14f648ae860ed4e23 Mon Sep 17 00:00:00 2001 From: lstocchi Date: Mon, 1 Dec 2025 16:49:51 +0100 Subject: [PATCH] prevent non hyper-v admin users to execute machine commands Update GetAll() and GetByVMType() to add a check to prevent non hyper-v admin users to interact with hyperv machines. Users can work with hyperv machines only with elevated rights or if members of the hyperv administrators group Signed-off-by: lstocchi --- pkg/machine/hyperv/hutil.go | 12 +++++++++--- pkg/machine/provider/platform_windows.go | 13 +++++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pkg/machine/hyperv/hutil.go b/pkg/machine/hyperv/hutil.go index 65c6d73c83..72cf15dc71 100644 --- a/pkg/machine/hyperv/hutil.go +++ b/pkg/machine/hyperv/hutil.go @@ -5,8 +5,9 @@ package hyperv import ( "errors" + "github.com/containers/podman/v6/pkg/machine/windows" "github.com/sirupsen/logrus" - "golang.org/x/sys/windows" + syswindows "golang.org/x/sys/windows" ) var ( @@ -17,7 +18,7 @@ var ( ) func HasHyperVAdminRights() bool { - sid, err := windows.CreateWellKnownSid(windows.WinBuiltinHyperVAdminsSid) + sid, err := syswindows.CreateWellKnownSid(syswindows.WinBuiltinHyperVAdminsSid) if err != nil { return false } @@ -27,7 +28,7 @@ func HasHyperVAdminRights() bool { // token of the calling thread. If the thread is not impersonating, // the function duplicates the thread's primary token to create an // impersonation token." - token := windows.Token(0) + token := syswindows.Token(0) member, err := token.IsMember(sid) if err != nil { logrus.Warnf("Token Membership Error: %s", err) @@ -36,3 +37,8 @@ func HasHyperVAdminRights() bool { return member } + +// HasHyperVPermissions checks if the user has either admin rights or Hyper-V admin rights. +func HasHyperVPermissions() bool { + return windows.HasAdminRights() || HasHyperVAdminRights() +} diff --git a/pkg/machine/provider/platform_windows.go b/pkg/machine/provider/platform_windows.go index d2e6522d15..50c5d4823d 100644 --- a/pkg/machine/provider/platform_windows.go +++ b/pkg/machine/provider/platform_windows.go @@ -39,6 +39,12 @@ func GetByVMType(resolvedVMType define.VMType) (vmconfigs.VMProvider, error) { case define.WSLVirt: return new(wsl.WSLStubber), nil case define.HyperVVirt: + // Check permissions before returning the Hyper-V provider. + // Working with Hyper-V requires users to be at least members of the Hyper-V admin group. + // Init and remove actions have custom use cases and they are checked on the stubber. + if !hyperv.HasHyperVPermissions() { + return nil, hyperv.ErrHypervUserNotInAdminGroup + } return new(hyperv.HyperVStubber), nil default: } @@ -46,10 +52,13 @@ func GetByVMType(resolvedVMType define.VMType) (vmconfigs.VMProvider, error) { } func GetAll() []vmconfigs.VMProvider { - return []vmconfigs.VMProvider{ + providers := []vmconfigs.VMProvider{ new(wsl.WSLStubber), - new(hyperv.HyperVStubber), } + if hyperv.HasHyperVPermissions() { + providers = append(providers, new(hyperv.HyperVStubber)) + } + return providers } // SupportedProviders returns the providers that are supported on the host operating system