Skip to content

Commit

Permalink
apparmor: Implement ApplyProfileThread()
Browse files Browse the repository at this point in the history
We need to implement ApplyProfileThread() to apply a profile
via /proc/self-thread/attr/exec rather than /proc/self/attr/exec
otherwise we get (~50%) failures trying to write the profile
to /proc/self/attr/exec. When using self-thread we get 100% success.

Signed-off-by: Stefan Berger <[email protected]>
  • Loading branch information
stefanberger committed Jan 6, 2020
1 parent 794d9fa commit 506d9ac
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
24 changes: 19 additions & 5 deletions libcontainer/apparmor/apparmor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ func IsEnabled() bool {
return false
}

func setProcAttr(attr, value string) error {
func setProcAttr(attr, value string, useThread bool) error {
// Under AppArmor you can only change your own attr, so use /proc/self/
// instead of /proc/<tid>/ like libapparmor does
path := fmt.Sprintf("/proc/self/attr/%s", attr)
var path string
if useThread {
path = fmt.Sprintf("/proc/thread-self/attr/%s", attr)
} else {
path = fmt.Sprintf("/proc/self/attr/%s", attr)
}

f, err := os.OpenFile(path, os.O_WRONLY, 0)
if err != nil {
Expand All @@ -41,20 +46,29 @@ func setProcAttr(attr, value string) error {
}

// changeOnExec reimplements aa_change_onexec from libapparmor in Go
func changeOnExec(name string) error {
func changeOnExec(name string, useThread bool) error {
value := "exec " + name
if err := setProcAttr("exec", value); err != nil {
if err := setProcAttr("exec", value, useThread); err != nil {
return fmt.Errorf("apparmor failed to apply profile: %s", err)
}
return nil
}

// ApplyProfileThread will apply the profile with the specified name to the process
// after the next exec using /proc/self-thread rather than /proc/self
func ApplyProfileThread(name string) error {
if name == "" {
return nil
}
return changeOnExec(name, true)
}

// 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
}

return changeOnExec(name)
return changeOnExec(name, false)
}
7 changes: 7 additions & 0 deletions libcontainer/apparmor/apparmor_disabled.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ func IsEnabled() bool {
return false
}

func ApplyProfileThread(name string) error {
if name != "" {
return ErrApparmorNotEnabled
}
return nil
}

func ApplyProfile(name string) error {
if name != "" {
return ErrApparmorNotEnabled
Expand Down

0 comments on commit 506d9ac

Please sign in to comment.