diff options
author | Valentin Rothberg <vrothberg@suse.com> | 2018-07-09 08:50:52 +0200 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-07-11 16:36:24 +0000 |
commit | 06ab343bd7c113fe761631142dde4829e8aa4d40 (patch) | |
tree | 0f38b5dd752683d59f9cfe335b748bf759a76a9c /pkg/apparmor/aaparser.go | |
parent | 84cfdb20617ac7a5a1138375599e28cdad26b824 (diff) | |
download | podman-06ab343bd7c113fe761631142dde4829e8aa4d40.tar.gz podman-06ab343bd7c113fe761631142dde4829e8aa4d40.tar.bz2 podman-06ab343bd7c113fe761631142dde4829e8aa4d40.zip |
podman/libpod: add default AppArmor profile
Make users of libpod more secure by adding the libpod/apparmor package
to load a pre-defined AppArmor profile. Large chunks of libpod/apparmor
come from github.com/moby/moby.
Also check if a specified AppArmor profile is actually loaded and throw
an error if necessary.
The default profile is loaded only on Linux builds with the `apparmor`
buildtag enabled.
Signed-off-by: Valentin Rothberg <vrothberg@suse.com>
Closes: #1063
Approved by: rhatdan
Diffstat (limited to 'pkg/apparmor/aaparser.go')
-rw-r--r-- | pkg/apparmor/aaparser.go | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/pkg/apparmor/aaparser.go b/pkg/apparmor/aaparser.go new file mode 100644 index 000000000..cec9c4885 --- /dev/null +++ b/pkg/apparmor/aaparser.go @@ -0,0 +1,90 @@ +// +build linux,apparmor + +package apparmor + +import ( + "fmt" + "os/exec" + "strconv" + "strings" +) + +const ( + binary = "apparmor_parser" +) + +// getVersion returns the major and minor version of apparmor_parser. +func getVersion() (int, error) { + output, err := cmd("", "--version") + if err != nil { + return -1, err + } + + return parseVersion(output) +} + +// loadProfile runs `apparmor_parser -Kr` on a specified apparmor profile to +// replace the profile. The `-K` is necessary to make sure that apparmor_parser +// doesn't try to write to a read-only filesystem. +func loadProfile(profilePath string) error { + _, err := cmd("", "-Kr", profilePath) + return err +} + +// cmd runs `apparmor_parser` with the passed arguments. +func cmd(dir string, arg ...string) (string, error) { + c := exec.Command(binary, arg...) + c.Dir = dir + + output, err := c.CombinedOutput() + if err != nil { + return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), output, err) + } + + return string(output), nil +} + +// parseVersion takes the output from `apparmor_parser --version` and returns +// a representation of the {major, minor, patch} version as a single number of +// the form MMmmPPP {major, minor, patch}. +func parseVersion(output string) (int, error) { + // output is in the form of the following: + // AppArmor parser version 2.9.1 + // Copyright (C) 1999-2008 Novell Inc. + // Copyright 2009-2012 Canonical Ltd. + + lines := strings.SplitN(output, "\n", 2) + words := strings.Split(lines[0], " ") + version := words[len(words)-1] + + // split by major minor version + v := strings.Split(version, ".") + if len(v) == 0 || len(v) > 3 { + return -1, fmt.Errorf("parsing version failed for output: `%s`", output) + } + + // Default the versions to 0. + var majorVersion, minorVersion, patchLevel int + + majorVersion, err := strconv.Atoi(v[0]) + if err != nil { + return -1, err + } + + if len(v) > 1 { + minorVersion, err = strconv.Atoi(v[1]) + if err != nil { + return -1, err + } + } + if len(v) > 2 { + patchLevel, err = strconv.Atoi(v[2]) + if err != nil { + return -1, err + } + } + + // major*10^5 + minor*10^3 + patch*10^0 + numericVersion := majorVersion*1e5 + minorVersion*1e3 + patchLevel + return numericVersion, nil +} |