Fixes: 15858 (podman system reset --force destroy machine)

Safe guards calls to os.RemoveAll in order to prevent calls from accidently
deleting the root file system in very strange edge cases. Did this by creating
GuardedRemoveAll and migrated machine os.RemoveAll calls to it.

Signed-off-by: Mike Perry <mike@bitbistro.org>
This commit is contained in:
Mike Perry 2022-09-21 21:41:44 -04:00
parent a77ac5be83
commit 0572e59725
5 changed files with 17 additions and 7 deletions

View File

@ -5,6 +5,7 @@ package machine
import ( import (
"errors" "errors"
"fmt"
"net" "net"
"net/url" "net/url"
"os" "os"
@ -237,6 +238,15 @@ func ConfDirPrefix() (string, error) {
return confDir, nil return confDir, nil
} }
// GuardedRemoveAll functions much like os.RemoveAll but
// will not delete certain catastrophic paths.
func GuardedRemoveAll(path string) error {
if path == "" || path == "/" {
return fmt.Errorf("refusing to recusively delete `%s`", path)
}
return os.RemoveAll(path)
}
// ResourceConfig describes physical attributes of the machine // ResourceConfig describes physical attributes of the machine
type ResourceConfig struct { type ResourceConfig struct {
// CPUs to be assigned to the VM // CPUs to be assigned to the VM

View File

@ -142,7 +142,7 @@ var _ = Describe("podman machine init", func() {
_, err = os.CreateTemp(tmpDir, "example") _, err = os.CreateTemp(tmpDir, "example")
Expect(err).To(BeNil()) Expect(err).To(BeNil())
mount := tmpDir + ":/testmountdir" mount := tmpDir + ":/testmountdir"
defer os.RemoveAll(tmpDir) defer func() { _ = machine.GuardedRemoveAll(tmpDir) }()
name := randomString() name := randomString()
i := new(initMachine) i := new(initMachine)

View File

@ -128,7 +128,7 @@ func teardown(origHomeDir string, testDir string, mb *machineTestBuilder) {
fmt.Printf("error occurred rm'ing machine: %q\n", err) fmt.Printf("error occurred rm'ing machine: %q\n", err)
} }
} }
if err := os.RemoveAll(testDir); err != nil { if err := machine.GuardedRemoveAll(testDir); err != nil {
Fail(fmt.Sprintf("failed to remove test dir: %q", err)) Fail(fmt.Sprintf("failed to remove test dir: %q", err))
} }
// this needs to be last in teardown // this needs to be last in teardown

View File

@ -1690,7 +1690,7 @@ func (p *Provider) RemoveAndCleanMachines() error {
} }
prevErr = err prevErr = err
} else { } else {
err := os.RemoveAll(dataDir) err := machine.GuardedRemoveAll(dataDir)
if err != nil { if err != nil {
if prevErr != nil { if prevErr != nil {
logrus.Error(prevErr) logrus.Error(prevErr)
@ -1707,7 +1707,7 @@ func (p *Provider) RemoveAndCleanMachines() error {
} }
prevErr = err prevErr = err
} else { } else {
err := os.RemoveAll(confDir) err := machine.GuardedRemoveAll(confDir)
if err != nil { if err != nil {
if prevErr != nil { if prevErr != nil {
logrus.Error(prevErr) logrus.Error(prevErr)

View File

@ -1339,7 +1339,7 @@ func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, fun
logrus.Error(err) logrus.Error(err)
} }
for _, f := range files { for _, f := range files {
if err := os.RemoveAll(f); err != nil { if err := machine.GuardedRemoveAll(f); err != nil {
logrus.Error(err) logrus.Error(err)
} }
} }
@ -1644,7 +1644,7 @@ func (p *Provider) RemoveAndCleanMachines() error {
} }
prevErr = err prevErr = err
} else { } else {
err := os.RemoveAll(dataDir) err := machine.GuardedRemoveAll(dataDir)
if err != nil { if err != nil {
if prevErr != nil { if prevErr != nil {
logrus.Error(prevErr) logrus.Error(prevErr)
@ -1661,7 +1661,7 @@ func (p *Provider) RemoveAndCleanMachines() error {
} }
prevErr = err prevErr = err
} else { } else {
err := os.RemoveAll(confDir) err := machine.GuardedRemoveAll(confDir)
if err != nil { if err != nil {
if prevErr != nil { if prevErr != nil {
logrus.Error(prevErr) logrus.Error(prevErr)