apparmor: do not save profile to /etc/apparmor.d
Writing the profile to /etc/apparmor.d, while also manually loading it into the kernel results in quite a bit of confusion. In addition, it means that people using apparmor but have /etc mounted read-only cannot use apparmor at all on a Docker host. Fix this by writing the profile to a temporary directory and deleting it after it's been inserted. Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
parent
6fafd07282
commit
2f7596aaef
2 changed files with 12 additions and 13 deletions
|
@ -23,10 +23,10 @@ func GetVersion() (int, error) {
|
||||||
return parseVersion(output)
|
return parseVersion(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadProfile runs `apparmor_parser -r -W` on a specified apparmor profile to
|
// LoadProfile runs `apparmor_parser -r` on a specified apparmor profile to
|
||||||
// replace and write it to disk.
|
// replace the profile.
|
||||||
func LoadProfile(profilePath string) error {
|
func LoadProfile(profilePath string) error {
|
||||||
_, err := cmd(filepath.Dir(profilePath), "-r", "-W", filepath.Base(profilePath))
|
_, err := cmd("-r", filepath.Dir(profilePath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ package apparmor
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -16,8 +17,6 @@ import (
|
||||||
var (
|
var (
|
||||||
// profileDirectory is the file store for apparmor profiles and macros.
|
// profileDirectory is the file store for apparmor profiles and macros.
|
||||||
profileDirectory = "/etc/apparmor.d"
|
profileDirectory = "/etc/apparmor.d"
|
||||||
// defaultProfilePath is the default path for the apparmor profile to be saved.
|
|
||||||
defaultProfilePath = path.Join(profileDirectory, "docker")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// profileData holds information about the given profile for generation.
|
// profileData holds information about the given profile for generation.
|
||||||
|
@ -70,26 +69,26 @@ func macroExists(m string) bool {
|
||||||
// InstallDefault generates a default profile and installs it in the
|
// InstallDefault generates a default profile and installs it in the
|
||||||
// ProfileDirectory with `apparmor_parser`.
|
// ProfileDirectory with `apparmor_parser`.
|
||||||
func InstallDefault(name string) error {
|
func InstallDefault(name string) error {
|
||||||
// Make sure the path where they want to save the profile exists
|
|
||||||
if err := os.MkdirAll(profileDirectory, 0755); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
p := profileData{
|
p := profileData{
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.OpenFile(defaultProfilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
// Install to a temporary directory.
|
||||||
|
f, err := ioutil.TempFile("", name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
profilePath := f.Name()
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
defer os.Remove(profilePath)
|
||||||
|
|
||||||
if err := p.generateDefault(f); err != nil {
|
if err := p.generateDefault(f); err != nil {
|
||||||
f.Close()
|
f.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f.Close()
|
|
||||||
|
|
||||||
if err := aaparser.LoadProfile(defaultProfilePath); err != nil {
|
if err := aaparser.LoadProfile(profilePath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue