1
0
mirror of https://github.com/containers/podman.git synced 2026-02-05 06:45:31 +01:00

Merge pull request #27885 from lstocchi/i27615

Prevent starting and stopping legacy hyperv machines when not elevated
This commit is contained in:
Mario Loriedo
2026-01-13 14:38:07 +01:00
committed by GitHub
3 changed files with 48 additions and 2 deletions

View File

@@ -5,13 +5,37 @@ import (
"fmt"
"io/fs"
"strconv"
"time"
"github.com/containers/podman/v6/pkg/machine/define"
)
const (
pidFileWaitTimeout = 2 * time.Second
pidFileCheckInterval = 50 * time.Millisecond
)
func readPIDFileWithRetry(f define.VMFile) ([]byte, error) {
deadline := time.Now().Add(pidFileWaitTimeout)
for time.Now().Before(deadline) {
gvPid, err := f.Read()
if err == nil {
return gvPid, nil
}
if !errors.Is(err, fs.ErrNotExist) {
return nil, err
}
time.Sleep(pidFileCheckInterval)
}
// Final attempt after timeout
return f.Read()
}
// CleanupGVProxy reads the --pid-file for gvproxy attempts to stop it
func CleanupGVProxy(f define.VMFile) error {
gvPid, err := f.Read()
gvPid, err := readPIDFileWithRetry(f)
if err != nil {
// The file will also be removed by gvproxy when it exits so
// we need to account for the race and can just ignore it here.

View File

@@ -15,6 +15,7 @@ var (
ErrHypervRegistryInitRequiresElevation = errors.New("the first time Podman initializes a Hyper-V machine, it requires admin rights. Please run Podman as an administrator")
ErrHypervRegistryRemoveRequiresElevation = errors.New("removing this Hyper-V machine requires admin rights to clean up the Windows Registry. Please run Podman as an administrator")
ErrHypervRegistryUpdateRequiresElevation = errors.New("this machine's configuration requires additional Hyper-V networking (hvsock) entries in the Windows Registry. Please run Podman as an administrator")
ErrHypervLegacyMachineRequiresElevation = errors.New("starting or stopping Hyper-V machines created with Podman 5.x or earlier requires admin rights. Please run Podman as an administrator")
)
func HasHyperVAdminRights() bool {

View File

@@ -265,6 +265,21 @@ func (h HyperVStubber) canRemove(mc *vmconfigs.MachineConfig) error {
return ErrHypervRegistryRemoveRequiresElevation
}
// canStartOrStop checks if the machine can be started or stopped.
// Legacy machines require admin rights to start or stop.
func (h HyperVStubber) canStartOrStop(mc *vmconfigs.MachineConfig) error {
if windows.HasAdminRights() {
return nil
}
// if machine is legacy (machineName field), require admin rights to start or stop
if isLegacyMachine(mc) {
return ErrHypervLegacyMachineRequiresElevation
}
return nil
}
// countMachinesWithToolname counts only machines that have a toolname field with value "podman".
func (h HyperVStubber) countMachinesWithToolname() (int, error) {
dirs, err := env.GetMachineDirs(h.VMType())
@@ -345,7 +360,9 @@ func (h HyperVStubber) StartNetworking(mc *vmconfigs.MachineConfig, cmd *gvproxy
}
func (h HyperVStubber) StartVM(mc *vmconfigs.MachineConfig) (func() error, func() error, error) {
var err error
if err := h.canStartOrStop(mc); err != nil {
return nil, nil, err
}
_, vm, err := GetVMFromMC(mc)
if err != nil {
@@ -412,6 +429,10 @@ func (h HyperVStubber) State(mc *vmconfigs.MachineConfig, _ bool) (define.Status
}
func (h HyperVStubber) StopVM(mc *vmconfigs.MachineConfig, hardStop bool) error {
if err := h.canStartOrStop(mc); err != nil {
return err
}
vmm := hypervctl.NewVirtualMachineManager()
vm, err := vmm.GetMachine(mc.Name)
if err != nil {