Skip to content

Commit

Permalink
sandbox/apparmor: support bundled 3.0 or 4.0 (preferred) abi
Browse files Browse the repository at this point in the history
Mirror the logic used in apparmor-from-the-host to apparmor-from-snapd-snap.
This mainly fixes tests that repackage old snapd snap without touching
apparmor, but in general seems like the right thing to do.

The logic is such, that abi 4 is preferred.

Signed-off-by: Zygmunt Krynicki <[email protected]>
  • Loading branch information
zyga committed Jul 10, 2024
1 parent 700f794 commit c5df0af
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 7 deletions.
30 changes: 24 additions & 6 deletions sandbox/apparmor/apparmor.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,16 +782,34 @@ func AppArmorParser() (cmd *exec.Cmd, internal bool, err error) {
if path, err := snapdtool.InternalToolPath("apparmor_parser"); err == nil {
if osutil.IsExecutable(path) && snapdAppArmorSupportsReexec() && !systemAppArmorLoadsSnapPolicy() {
prefix := strings.TrimSuffix(path, "apparmor_parser")
// when using the internal apparmor_parser also use
// its own configuration and includes etc plus
// also ensure we use the 4.0 feature ABI to get
// the widest array of policy features across the
// widest array of kernel versions
snapdAbi30File := filepath.Join(prefix, "/apparmor.d/abi/3.0")
snapdAbi40File := filepath.Join(prefix, "/apparmor.d/abi/4.0")

// When using the internal apparmor_parser also use its own
// configuration and includes etc plus also ensure we use the 4.0
// feature ABI to get the widest array of policy features across
// the widest array of kernel versions.
//
// In case snapd is injectd into snapd with older apparmor, use

This comment has been minimized.

Copy link
@ernestl

ernestl Jul 11, 2024

Collaborator

injected

This comment has been minimized.

Copy link
@ernestl

ernestl Jul 11, 2024

Collaborator

In case snapd <?> is injected into snapd snap

This comment has been minimized.

Copy link
@zyga

zyga Jul 11, 2024

Author Contributor

Thanks, I'll fix this.

// that instead so that things don't generally fail.
abiFile := ""
fi40, err40 := os.Lstat(snapdAbi40File)
fi30, err30 := os.Lstat(snapdAbi30File)
switch {
case err40 == nil && !fi40.IsDir():
abiFile = snapdAbi40File
case err30 == nil && !fi30.IsDir():
abiFile = snapdAbi30File
default:
return nil, false, fmt.Errorf("internal snapd apparmor_parser but no abi files")
}

args := []string{
"--config-file", filepath.Join(prefix, "/apparmor/parser.conf"),
"--base", filepath.Join(prefix, "/apparmor.d"),
"--policy-features", filepath.Join(prefix, "/apparmor.d/abi/4.0"),
"--policy-features", abiFile,
}

return exec.Command(path, args...), true, nil
}
}
Expand Down
40 changes: 39 additions & 1 deletion sandbox/apparmor/apparmor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,16 @@ func (*apparmorSuite) TestAppArmorParser(c *C) {
c.Check(err, Equals, nil)
}

func (*apparmorSuite) TestAppArmorInternalAppArmorParser(c *C) {
func (*apparmorSuite) TestAppArmorInternalAppArmorParserAbi3(c *C) {
fakeroot := c.MkDir()
dirs.SetRootDir(fakeroot)

d := filepath.Join(dirs.SnapMountDir, "/snapd/42", "/usr/lib/snapd")
c.Assert(os.MkdirAll(d, 0755), IsNil)
p := filepath.Join(d, "apparmor_parser")
c.Assert(os.WriteFile(p, nil, 0755), IsNil)
c.Assert(os.MkdirAll(filepath.Join(d, "apparmor.d/abi"), 755), IsNil)
c.Assert(os.WriteFile(filepath.Join(d, "apparmor.d/abi/3.0"), nil, 0644), IsNil)
restore := snapdtool.MockOsReadlink(func(path string) (string, error) {
c.Assert(path, Equals, "/proc/self/exe")
return filepath.Join(d, "snapd"), nil
Expand All @@ -98,6 +100,38 @@ func (*apparmorSuite) TestAppArmorInternalAppArmorParser(c *C) {
p,
"--config-file", filepath.Join(d, "/apparmor/parser.conf"),
"--base", filepath.Join(d, "/apparmor.d"),
"--policy-features", filepath.Join(d, "/apparmor.d/abi/3.0"),
})
c.Check(internal, Equals, true)
}

func (*apparmorSuite) TestAppArmorInternalAppArmorParserAbi4(c *C) {
fakeroot := c.MkDir()
dirs.SetRootDir(fakeroot)

d := filepath.Join(dirs.SnapMountDir, "/snapd/42", "/usr/lib/snapd")
c.Assert(os.MkdirAll(d, 0755), IsNil)
p := filepath.Join(d, "apparmor_parser")
c.Assert(os.WriteFile(p, nil, 0755), IsNil)
c.Assert(os.MkdirAll(filepath.Join(d, "apparmor.d/abi"), 755), IsNil)
c.Assert(os.WriteFile(filepath.Join(d, "apparmor.d/abi/3.0"), nil, 0644), IsNil)
c.Assert(os.WriteFile(filepath.Join(d, "apparmor.d/abi/4.0"), nil, 0644), IsNil)
restore := snapdtool.MockOsReadlink(func(path string) (string, error) {
c.Assert(path, Equals, "/proc/self/exe")
return filepath.Join(d, "snapd"), nil
})
defer restore()
restore = apparmor.MockSnapdAppArmorSupportsReexec(func() bool { return true })
defer restore()

cmd, internal, err := apparmor.AppArmorParser()
c.Check(err, IsNil)
c.Check(cmd.Path, Equals, p)
c.Check(cmd.Args, DeepEquals, []string{
p,
"--config-file", filepath.Join(d, "/apparmor/parser.conf"),
"--base", filepath.Join(d, "/apparmor.d"),
// 4.0 was preferred.
"--policy-features", filepath.Join(d, "/apparmor.d/abi/4.0"),
})
c.Check(internal, Equals, true)
Expand Down Expand Up @@ -439,6 +473,8 @@ func (s *parserFeatureTestSuite) TestInternalParser(c *C) {
c.Assert(err, IsNil)
err = os.WriteFile(filepath.Join(libSnapdDir, "apparmor_parser"), nil, 0755)
c.Assert(err, IsNil)
c.Assert(os.MkdirAll(filepath.Join(d, "apparmor.d/abi"), 755), IsNil)
c.Assert(os.WriteFile(filepath.Join(d, "apparmor.d/abi/4.0"), nil, 0644), IsNil)

// Pretend that we are running snapd from that snap location.
restore := snapdtool.MockOsReadlink(func(path string) (string, error) {
Expand Down Expand Up @@ -690,6 +726,8 @@ func (s *apparmorSuite) TestSetupConfCacheDirsWithInternalApparmor(c *C) {
c.Assert(os.MkdirAll(d, 0755), IsNil)
p := filepath.Join(d, "apparmor_parser")
c.Assert(os.WriteFile(p, nil, 0755), IsNil)
c.Assert(os.MkdirAll(filepath.Join(d, "apparmor.d/abi"), 755), IsNil)
c.Assert(os.WriteFile(filepath.Join(d, "apparmor.d/abi/4.0"), nil, 0644), IsNil)
restore := snapdtool.MockOsReadlink(func(path string) (string, error) {
c.Assert(path, Equals, "/proc/self/exe")
return filepath.Join(d, "snapd"), nil
Expand Down

0 comments on commit c5df0af

Please sign in to comment.