Skip to content

Commit

Permalink
Error when machine memory exceeds system memory
Browse files Browse the repository at this point in the history
Close loophole that would allow you to assign more memory than the
system has to a podman machine

Fixes: #18206

Signed-off-by: Brent Baude <bbaude@redhat.com>
  • Loading branch information
baude committed Jun 28, 2024
1 parent c86386e commit 786ea01
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
21 changes: 21 additions & 0 deletions cmd/podman/machine/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import (
"os"

"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/strongunits"
"github.com/containers/podman/v5/cmd/podman/registry"
ldefine "github.com/containers/podman/v5/libpod/define"
"github.com/containers/podman/v5/libpod/events"
"github.com/containers/podman/v5/pkg/machine"
"github.com/containers/podman/v5/pkg/machine/define"
"github.com/containers/podman/v5/pkg/machine/shim"
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
"github.com/shirou/gopsutil/v3/mem"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -196,6 +198,12 @@ func initMachine(cmd *cobra.Command, args []string) error {
initOpts.UserModeNetworking = &initOptionalFlags.UserModeNetworking
}

if cmd.Flags().Changed("memory") {
if err := checkMaxMemory(strongunits.MiB(initOpts.Memory)); err != nil {
return err
}
}

// TODO need to work this back in
// if finished, err := vm.Init(initOpts); err != nil || !finished {
// // Finished = true, err = nil - Success! Log a message with further instructions
Expand Down Expand Up @@ -226,3 +234,16 @@ func initMachine(cmd *cobra.Command, args []string) error {
fmt.Printf("To start your machine run:\n\n\tpodman machine start%s\n\n", extra)
return err
}

// checkMaxMemory gets the total system memory and compares it to the variable. if the variable
// is larger than the total memory, it returns an error
func checkMaxMemory(newMem strongunits.MiB) error {
memStat, err := mem.VirtualMemory()
if err != nil {
return err
}
if total := strongunits.B(memStat.Total); strongunits.B(memStat.Total) < newMem.ToBytes() {
return fmt.Errorf("requested amount of memory (%d MB) greater than total system memory (%d MB)", newMem, total)
}
return nil
}
3 changes: 3 additions & 0 deletions cmd/podman/machine/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ func setMachine(cmd *cobra.Command, args []string) error {
}
if cmd.Flags().Changed("memory") {
newMemory := strongunits.MiB(setFlags.Memory)
if err := checkMaxMemory(newMemory); err != nil {
return err
}
setOpts.Memory = &newMemory
}
if cmd.Flags().Changed("disk-size") {
Expand Down
14 changes: 13 additions & 1 deletion pkg/machine/e2e/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import (
"strings"
"time"

"github.com/containers/common/pkg/strongunits"
"github.com/containers/podman/v5/pkg/machine/define"
"github.com/containers/podman/v5/utils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
"github.com/shirou/gopsutil/v3/mem"
"github.com/sirupsen/logrus"
)

Expand All @@ -35,7 +37,7 @@ var _ = Describe("podman machine init", func() {
cpus = 1
}

It("bad init name", func() {
It("bad init", func() {
i := initMachine{}
reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
session, err := mb.setName(reallyLongName).setCmd(&i).run()
Expand Down Expand Up @@ -77,6 +79,16 @@ var _ = Describe("podman machine init", func() {
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(125))
Expect(session.errorToString()).To(ContainSubstring(`invalid username "-/a": names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*: invalid argument`))

// this comes in bytes
memStat, err := mem.VirtualMemory()
Expect(err).ToNot(HaveOccurred())
total := strongunits.ToMib(strongunits.B(memStat.Total)) + 1024

badMem := initMachine{}
badMemSession, err := mb.setCmd(badMem.withMemory(uint(total))).run()
Expect(err).ToNot(HaveOccurred())
Expect(badMemSession).To(Exit(125))
})

It("simple init", func() {
Expand Down
5 changes: 5 additions & 0 deletions pkg/machine/e2e/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ var _ = Describe("podman machine set", func() {
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))

setMem := setMachine{}
SetMemSession, err := mb.setName(name).setCmd(setMem.withMemory(524288)).run()
Expect(err).ToNot(HaveOccurred())
Expect(SetMemSession).To(Exit(125))

set := setMachine{}
setSession, err := mb.setName(name).setCmd(set.withCPUs(2).withDiskSize(102).withMemory(4096)).run()
Expect(err).ToNot(HaveOccurred())
Expand Down

0 comments on commit 786ea01

Please sign in to comment.