Skip to content

Commit

Permalink
gadget/install: support for no{exec,dev,suid} mount flags
Browse files Browse the repository at this point in the history
  • Loading branch information
Meulengracht committed Nov 19, 2024
1 parent 0543dff commit eb3064d
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 13 deletions.
25 changes: 22 additions & 3 deletions gadget/install/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,35 @@ func makeFilesystem(params mkfsParams) error {
return udevTrigger(params.Device)
}

type mntfsParams struct {
NoExec bool
NoDev bool
NoSuid bool
}

func (p *mntfsParams) flags() uintptr {
var flags uintptr
if p.NoDev {
flags |= syscall.MS_NODEV
}
if p.NoExec {
flags |= syscall.MS_NOEXEC
}
if p.NoSuid {
flags |= syscall.MS_NOSUID
}
return flags
}

// mountFilesystem mounts the filesystem on a given device with
// filesystem type fs under the provided mount point directory.
func mountFilesystem(fsDevice, fs, mountpoint string) error {
func mountFilesystem(fsDevice, fs, mountpoint string, params mntfsParams) error {
if err := os.MkdirAll(mountpoint, 0755); err != nil {
return fmt.Errorf("cannot create mountpoint: %v", err)
}
if err := sysMount(fsDevice, mountpoint, fs, 0, ""); err != nil {
if err := sysMount(fsDevice, mountpoint, fs, params.flags(), ""); err != nil {
return fmt.Errorf("cannot mount filesystem %q at %q: %v", fsDevice, mountpoint, err)
}

return nil
}

Expand Down
55 changes: 48 additions & 7 deletions gadget/install/content_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ type contentTestSuite struct {

gadgetRoot string

mockMountPoint string
mockMountCalls []struct{ source, target, fstype string }
mockMountPoint string
mockMountCalls []struct {
source, target, fstype string
flags uintptr
}
mockUnmountCalls []string

mockMountErr error
Expand All @@ -76,7 +79,10 @@ func (s *contentTestSuite) SetUpTest(c *C) {
s.mockMountPoint = c.MkDir()

restore := install.MockSysMount(func(source, target, fstype string, flags uintptr, data string) error {
s.mockMountCalls = append(s.mockMountCalls, struct{ source, target, fstype string }{source, target, fstype})
s.mockMountCalls = append(s.mockMountCalls, struct {
source, target, fstype string
flags uintptr
}{source, target, fstype, flags})
return s.mockMountErr
})
s.AddCleanup(restore)
Expand Down Expand Up @@ -498,17 +504,52 @@ func (s *contentTestSuite) TestMountFilesystem(c *C) {
defer dirs.SetRootDir("")

// mount a filesystem...
err := install.MountFilesystem("/dev/node2", "vfat", filepath.Join(boot.InitramfsRunMntDir, "ubuntu-seed"))
err := install.MountFilesystem("/dev/node2", "vfat", filepath.Join(boot.InitramfsRunMntDir, "ubuntu-seed"), install.MntfsParams{})
c.Assert(err, IsNil)

// ...and check if it was mounted at the right mount point
c.Check(s.mockMountCalls, HasLen, 1)
c.Check(s.mockMountCalls, DeepEquals, []struct{ source, target, fstype string }{
{"/dev/node2", boot.InitramfsUbuntuSeedDir, "vfat"},
c.Check(s.mockMountCalls, DeepEquals, []struct {
source, target, fstype string
flags uintptr
}{
{"/dev/node2", boot.InitramfsUbuntuSeedDir, "vfat", 0},
})

// try again with mocked error
s.mockMountErr = fmt.Errorf("mock mount error")
err = install.MountFilesystem("/dev/node2", "vfat", filepath.Join(boot.InitramfsRunMntDir, "ubuntu-seed"))
err = install.MountFilesystem("/dev/node2", "vfat", filepath.Join(boot.InitramfsRunMntDir, "ubuntu-seed"), install.MntfsParams{})
c.Assert(err, ErrorMatches, `cannot mount filesystem "/dev/node2" at ".*/run/mnt/ubuntu-seed": mock mount error`)
}

func (s *contentTestSuite) TestMountFilesystemOptions(c *C) {
dirs.SetRootDir(c.MkDir())
defer dirs.SetRootDir("")

tests := []struct {
params install.MntfsParams
expectedFlags uintptr
}{
{install.MntfsParams{}, 0},
{install.MntfsParams{NoExec: true}, syscall.MS_NOEXEC},
{install.MntfsParams{NoDev: true}, syscall.MS_NODEV},
{install.MntfsParams{NoSuid: true}, syscall.MS_NOSUID},
}

for _, t := range tests {
// reset calls
s.mockMountCalls = nil

err := install.MountFilesystem("/dev/node2", "vfat", filepath.Join(boot.InitramfsRunMntDir, "ubuntu-seed"), t.params)
c.Assert(err, IsNil)

// .. verify flags
c.Check(s.mockMountCalls, HasLen, 1)
c.Check(s.mockMountCalls, DeepEquals, []struct {
source, target, fstype string
flags uintptr
}{
{"/dev/node2", boot.InitramfsUbuntuSeedDir, "vfat", t.expectedFlags},
})
}
}
1 change: 1 addition & 0 deletions gadget/install/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
)

type MkfsParams = mkfsParams
type MntfsParams = mntfsParams

var (
MakeFilesystem = makeFilesystem
Expand Down
6 changes: 3 additions & 3 deletions gadget/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ func Run(model gadget.Model, gadgetRoot string, kernelSnapInfo *KernelSnapInfo,
if options.Mount && vs.Label != "" && vs.HasFilesystem() {
// fs is taken from gadget, as on disk one might be displayed as
// crypto_LUKS, which is not useful for formatting.
if err := mountFilesystem(fsDevice, vs.LinuxFilesystem(), getMntPointForPart(vs)); err != nil {
if err := mountFilesystem(fsDevice, vs.LinuxFilesystem(), getMntPointForPart(vs), mntfsParams{}); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -592,7 +592,7 @@ func MountVolumes(onVolumes map[string]*gadget.Volume, encSetupData *EncryptionS
// Device might have been encrypted
device := deviceForMaybeEncryptedVolume(&part, encSetupData)

if err := mountFilesystem(device, part.LinuxFilesystem(), mntPt); err != nil {
if err := mountFilesystem(device, part.LinuxFilesystem(), mntPt, mntfsParams{}); err != nil {
defer unmount()
return "", nil, fmt.Errorf("cannot mount %q at %q: %v", device, mntPt, err)
}
Expand Down Expand Up @@ -788,7 +788,7 @@ func FactoryReset(model gadget.Model, gadgetRoot string, kernelSnapInfo *KernelS
if options.Mount && vs.Label != "" && vs.HasFilesystem() {
// fs is taken from gadget, as on disk one might be displayed as
// crypto_LUKS, which is not useful for formatting.
if err := mountFilesystem(fsDevice, vs.LinuxFilesystem(), getMntPointForPart(vs)); err != nil {
if err := mountFilesystem(fsDevice, vs.LinuxFilesystem(), getMntPointForPart(vs), mntfsParams{}); err != nil {
return nil, err
}
}
Expand Down

0 comments on commit eb3064d

Please sign in to comment.