From db093f621f4e6d40feafbe6d7b89a9bee6f6ff85 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 11 Dec 2017 11:19:13 +0100 Subject: [PATCH] libcontainer: remove dependency on libapparmor libapparmor is integrated in libcontainer using cgo but is only used to call a single function: aa_change_onexec. It turns out this function is simple enough (writing a string to a file in /proc//attr/...) to be re-implemented locally in libcontainer in plain Go. This allows to drop the dependency on libapparmor and the corresponding cgo integration. Fixes #1674 Signed-off-by: Tobias Klauser --- .travis.yml | 2 +- README.md | 2 +- libcontainer/apparmor/apparmor.go | 37 ++++++++++++++++++++++--------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index e320c0a8..e06d77dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ env: before_install: - echo "deb http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list - sudo apt-get -qq update - - sudo apt-get install -y libapparmor-dev libseccomp-dev/trusty-backports + - sudo apt-get install -y libseccomp-dev/trusty-backports - go get -u github.com/golang/lint/golint - go get -u github.com/vbatts/git-validation - env | grep TRAVIS_ diff --git a/README.md b/README.md index eabfb982..3ca7a1a2 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ make BUILDTAGS='seccomp apparmor' |-----------|------------------------------------|-------------| | seccomp | Syscall filtering | libseccomp | | selinux | selinux process and mount labeling | | -| apparmor | apparmor profile support | libapparmor | +| apparmor | apparmor profile support | | | ambient | ambient capability support | kernel 4.3 | diff --git a/libcontainer/apparmor/apparmor.go b/libcontainer/apparmor/apparmor.go index 82ed1a68..7fff0627 100644 --- a/libcontainer/apparmor/apparmor.go +++ b/libcontainer/apparmor/apparmor.go @@ -2,15 +2,10 @@ package apparmor -// #cgo LDFLAGS: -lapparmor -// #include -// #include -import "C" import ( "fmt" "io/ioutil" "os" - "unsafe" ) // IsEnabled returns true if apparmor is enabled for the host. @@ -24,16 +19,36 @@ func IsEnabled() bool { return false } +func setprocattr(attr, value string) error { + // Under AppArmor you can only change your own attr, so use /proc/self/ + // instead of /proc// like libapparmor does + path := fmt.Sprintf("/proc/self/attr/%s", attr) + + f, err := os.OpenFile(path, os.O_WRONLY, 0) + if err != nil { + return err + } + defer f.Close() + + _, err = fmt.Fprintf(f, "%s", value) + return err +} + +// changeOnExec reimplements aa_change_onexec from libapparmor in Go +func changeOnExec(name string) error { + value := "exec " + name + if err := setprocattr("exec", value); err != nil { + return fmt.Errorf("apparmor failed to apply profile: %s", err) + } + return nil +} + // ApplyProfile will apply the profile with the specified name to the process after // the next exec. func ApplyProfile(name string) error { if name == "" { return nil } - cName := C.CString(name) - defer C.free(unsafe.Pointer(cName)) - if _, err := C.aa_change_onexec(cName); err != nil { - return fmt.Errorf("apparmor failed to apply profile: %s", err) - } - return nil + + return changeOnExec(name) }