diff options
author | Valentin Rothberg <rothberg@redhat.com> | 2019-01-09 14:54:58 +0100 |
---|---|---|
committer | Valentin Rothberg <rothberg@redhat.com> | 2019-01-09 22:18:11 +0100 |
commit | edb285d17675061832aceaf72021b87aba149438 (patch) | |
tree | 332f020dfc754a2a2ecaa80bd2891392c81305f1 /libpod | |
parent | c37f73159609b203545ca6fe54c86b9deacfca21 (diff) | |
download | podman-edb285d17675061832aceaf72021b87aba149438.tar.gz podman-edb285d17675061832aceaf72021b87aba149438.tar.bz2 podman-edb285d17675061832aceaf72021b87aba149438.zip |
apparmor: apply default profile at container initialization
Apply the default AppArmor profile at container initialization to cover
all possible code paths (i.e., podman-{start,run}) before executing the
runtime. This allows moving most of the logic into pkg/apparmor.
Also make the loading and application of the default AppArmor profile
versio-indepenent by checking for the `libpod-default-` prefix and
over-writing the profile in the run-time spec if needed.
The intitial run-time spec of the container differs a bit from the
applied one when having started the container, which results in
displaying a potentially outdated AppArmor profile when inspecting
a container. To fix that, load the container config from the file
system if present and use it to display the data.
Fixes: #2107
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container.go | 26 | ||||
-rw-r--r-- | libpod/container_inspect.go | 5 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 8 |
3 files changed, 38 insertions, 1 deletions
diff --git a/libpod/container.go b/libpod/container.go index d0eb6a992..026eb1c4f 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -1,7 +1,9 @@ package libpod import ( + "encoding/json" "fmt" + "io/ioutil" "net" "os" "path/filepath" @@ -407,6 +409,30 @@ func (c *Container) Spec() *spec.Spec { return returnSpec } +// specFromState returns the unmarshalled json config of the container. If the +// config does not exist (e.g., because the container was never started) return +// the spec from the config. +func (c *Container) specFromState() (*spec.Spec, error) { + spec := c.config.Spec + + if f, err := os.Open(c.state.ConfigPath); err == nil { + content, err := ioutil.ReadAll(f) + if err != nil { + return nil, errors.Wrapf(err, "error reading container config") + } + if err := json.Unmarshal([]byte(content), &spec); err != nil { + return nil, errors.Wrapf(err, "error unmarshalling container config") + } + } else { + // ignore when the file does not exist + if !os.IsNotExist(err) { + return nil, errors.Wrapf(err, "error opening container config") + } + } + + return spec, nil +} + // ID returns the container's ID func (c *Container) ID() string { return c.config.ID diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 06a0c9f32..e2730c282 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -12,7 +12,10 @@ import ( func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data) (*inspect.ContainerInspectData, error) { config := c.config runtimeInfo := c.state - spec := c.config.Spec + spec, err := c.specFromState() + if err != nil { + return nil, err + } // Process is allowed to be nil in the spec args := []string{} diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 582a4c3e7..2f03d45ea 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -20,6 +20,7 @@ import ( cnitypes "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/plugins/pkg/ns" crioAnnotations "github.com/containers/libpod/pkg/annotations" + "github.com/containers/libpod/pkg/apparmor" "github.com/containers/libpod/pkg/criu" "github.com/containers/libpod/pkg/lookup" "github.com/containers/libpod/pkg/resolvconf" @@ -185,6 +186,13 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } + // Apply AppArmor checks and load the default profile if needed. + updatedProfile, err := apparmor.CheckProfileAndLoadDefault(c.config.Spec.Process.ApparmorProfile) + if err != nil { + return nil, err + } + g.SetProcessApparmorProfile(updatedProfile) + if err := c.makeBindMounts(); err != nil { return nil, err } |