...

Source file src/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go

Documentation: github.com/opencontainers/runc/libcontainer/apparmor

     1  package apparmor
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"sync"
     8  
     9  	"github.com/opencontainers/runc/libcontainer/utils"
    10  )
    11  
    12  var (
    13  	appArmorEnabled bool
    14  	checkAppArmor   sync.Once
    15  )
    16  
    17  // isEnabled returns true if apparmor is enabled for the host.
    18  func isEnabled() bool {
    19  	checkAppArmor.Do(func() {
    20  		if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil {
    21  			buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled")
    22  			appArmorEnabled = err == nil && len(buf) > 1 && buf[0] == 'Y'
    23  		}
    24  	})
    25  	return appArmorEnabled
    26  }
    27  
    28  func setProcAttr(attr, value string) error {
    29  	// Under AppArmor you can only change your own attr, so use /proc/self/
    30  	// instead of /proc/<tid>/ like libapparmor does
    31  	attrPath := "/proc/self/attr/apparmor/" + attr
    32  	if _, err := os.Stat(attrPath); errors.Is(err, os.ErrNotExist) {
    33  		// fall back to the old convention
    34  		attrPath = "/proc/self/attr/" + attr
    35  	}
    36  
    37  	f, err := os.OpenFile(attrPath, os.O_WRONLY, 0)
    38  	if err != nil {
    39  		return err
    40  	}
    41  	defer f.Close()
    42  
    43  	if err := utils.EnsureProcHandle(f); err != nil {
    44  		return err
    45  	}
    46  
    47  	_, err = f.WriteString(value)
    48  	return err
    49  }
    50  
    51  // changeOnExec reimplements aa_change_onexec from libapparmor in Go
    52  func changeOnExec(name string) error {
    53  	if err := setProcAttr("exec", "exec "+name); err != nil {
    54  		return fmt.Errorf("apparmor failed to apply profile: %w", err)
    55  	}
    56  	return nil
    57  }
    58  
    59  // applyProfile will apply the profile with the specified name to the process after
    60  // the next exec. It is only supported on Linux and produces an error on other
    61  // platforms.
    62  func applyProfile(name string) error {
    63  	if name == "" {
    64  		return nil
    65  	}
    66  
    67  	return changeOnExec(name)
    68  }
    69  

View as plain text