Skip to content

Commit

Permalink
i/builtin: check mount flags for conflicts
Browse files Browse the repository at this point in the history
The mount-control interface used to allow requesting contradicting mount
options, such as nodev and dev and would silently pass this down to
apparmor_parser. The parser would detect this and cause the failure of the
security setup.

With this code we now detect this much earlier, at interface validation stage.

Fixes: https://warthogs.atlassian.net/browse/SNAPDENG-32984

Signed-off-by: Zygmunt Krynicki <[email protected]>
  • Loading branch information
zyga committed Dec 11, 2024
1 parent f76bf55 commit c789f68
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
9 changes: 9 additions & 0 deletions interfaces/builtin/mount_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/snapcore/snapd/interfaces"
"github.com/snapcore/snapd/interfaces/apparmor"
"github.com/snapcore/snapd/interfaces/utils"
"github.com/snapcore/snapd/osutil/mount/libmount"
apparmor_sandbox "github.com/snapcore/snapd/sandbox/apparmor"
"github.com/snapcore/snapd/snap"
"github.com/snapcore/snapd/strutil"
Expand Down Expand Up @@ -482,8 +483,11 @@ func validateMountOptions(mountInfo *MountInfo) error {
} else {
types = defaultFSTypes
}

var optsToCheck []string // Kernel options to check for consistency.
for _, o := range mountInfo.options {
if strutil.ListContains(allowedKernelMountOptions, o) {
optsToCheck = append(optsToCheck, o)
continue
}
optionName := strings.SplitAfter(o, "=")[0] // for options with arguments, validate only option
Expand All @@ -495,6 +499,11 @@ func validateMountOptions(mountInfo *MountInfo) error {
}
return fmt.Errorf(`mount-control option unrecognized or forbidden: %q`, o)
}

if err := libmount.ValidateMountOptions(optsToCheck...); err != nil {
return fmt.Errorf("mount-control options are inconsistent: %w", err)
}

return nil
}

Expand Down
14 changes: 14 additions & 0 deletions interfaces/builtin/mount_control_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,20 @@ func (s *MountControlInterfaceSuite) TestMountDevicePathWithCommas(c *C) {
c.Check(err, IsNil)
}

func (s *MountControlInterfaceSuite) TestConflictingMountOptions(c *C) {
plugYaml := `
mount:
- persistent: true
what: /dev/foo
where: /mnt/foo
options: [rw, ro]
`
snapYaml := fmt.Sprintf(mountControlYaml, plugYaml)
plug, _ := MockConnectedPlug(c, snapYaml, nil, "mntctl")
err := interfaces.BeforeConnectPlug(s.iface, plug)
c.Check(err, ErrorMatches, "mount-control options are inconsistent: option ro conflicts with rw")
}

func (s *MountControlInterfaceSuite) TestMountOptionsAreValid(c *C) {
// All the options we claim to support are also allowed by the validator.
for _, opt := range builtin.AllowedKernelMountOptions() {
Expand Down

0 comments on commit c789f68

Please sign in to comment.