sandbox/cgroup: ignore matching pids from snaps inside containers

Signed-off-by: Miguel Pires <miguel.pires@canonical.com>
This commit is contained in:
Miguel Pires
2022-07-15 17:09:10 +01:00
parent 7f63a940dc
commit cbfbd06629
2 changed files with 45 additions and 16 deletions

View File

@@ -88,6 +88,24 @@ func PidsOfSnap(snapInstanceName string) (map[string][]int, error) {
// pidsByTag maps security tag to a list of pids.
pidsByTag := make(map[string][]int)
ver, err := Version()
if err != nil {
return nil, err
}
var cgroupPathToScan string
if ver == V2 {
// In v2 mode scan all of /sys/fs/cgroup as there is no specialization
// anymore (each directory represents a hierarchy with equal
// capabilities and old split into controllers is gone).
cgroupPathToScan = filepath.Join(rootPath, cgroupMountPoint)
} else {
// In v1 mode scan just /sys/fs/cgroup/systemd as that is sufficient
// for finding snap-specific cgroup names. Systemd uses this for
// tracking and scopes and services are represented there.
cgroupPathToScan = filepath.Join(rootPath, cgroupMountPoint, "systemd")
}
// Walk the cgroup tree and look for "cgroup.procs" files. Having found one
// we try to derive the snap security tag from it. If successful and the
// tag matches the snap we are interested in, we harvest the snapshot of
@@ -100,6 +118,14 @@ func PidsOfSnap(snapInstanceName string) (map[string][]int, error) {
// that error quickly.
return err
}
// ignore snaps inside containers
for _, slice := range []string{"lxc.payload", "machine.slice", "docker"} {
if strings.HasPrefix(path, filepath.Join(cgroupPathToScan, slice)) {
return filepath.SkipDir
}
}
if fileInfo.IsDir() {
// We don't care about directories.
return nil
@@ -133,22 +159,6 @@ func PidsOfSnap(snapInstanceName string) (map[string][]int, error) {
return filepath.SkipDir
}
var cgroupPathToScan string
ver, err := Version()
if err != nil {
return nil, err
}
if ver == V2 {
// In v2 mode scan all of /sys/fs/cgroup as there is no specialization
// anymore (each directory represents a hierarchy with equal
// capabilities and old split into controllers is gone).
cgroupPathToScan = filepath.Join(rootPath, cgroupMountPoint)
} else {
// In v1 mode scan just /sys/fs/cgroup/systemd as that is sufficient
// for finding snap-specific cgroup names. Systemd uses this for
// tracking and scopes and services are represented there.
cgroupPathToScan = filepath.Join(rootPath, cgroupMountPoint, "systemd")
}
// NOTE: Walk is internally performed in lexical order so the output is
// deterministic and we don't need to sort the returned aggregated PIDs.
if err := filepath.Walk(cgroupPathToScan, walkFunc); err != nil {

View File

@@ -224,3 +224,22 @@ func (s *scanningSuite) TestPidsOfSnapUnrelated(c *C) {
}, comment)
}
}
func (s *scanningSuite) TestContainerPidsAreIgnored(c *C) {
for _, ver := range []int{cgroup.V2, cgroup.V1} {
comment := Commentf("cgroup version %v", ver)
restore := cgroup.MockVersion(ver, nil)
defer restore()
s.writePids(c, "user.slice/user-1000.slice/user@1000.service/snap.foo.bar.scope", []int{1})
s.writePids(c, "system.slice/snap.foo.bar.service", []int{2})
s.writePids(c, "lxc.payload.my-container/system.slice/snap.foo.bar.service", []int{3})
s.writePids(c, "machine.slice/snap.foo.bar.service", []int{4})
s.writePids(c, "docker/snap.foo.bar.service", []int{5})
pids, err := cgroup.PidsOfSnap("foo")
c.Assert(err, IsNil, comment)
c.Check(pids, HasLen, 1, comment)
c.Check(pids["snap.foo.bar"], testutil.DeepUnsortedMatches, []int{1, 2}, comment)
}
}