mirror of
https://github.com/containers/podman.git
synced 2025-11-16 11:07:44 +08:00
Switch to containers/common for seccomp
The seccomp/containers-golang library is not maintained any more and we should stick to containers/common. Signed-off-by: Sascha Grunert <sgrunert@suse.com>
This commit is contained in:
47
vendor/github.com/containers/common/pkg/apparmor/apparmor_linux.go
generated
vendored
47
vendor/github.com/containers/common/pkg/apparmor/apparmor_linux.go
generated
vendored
@@ -13,6 +13,7 @@ import (
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/containers/common/pkg/apparmor/internal/supported"
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
runcaa "github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
"github.com/pkg/errors"
|
||||
@@ -22,12 +23,11 @@ import (
|
||||
// profileDirectory is the file store for apparmor profiles and macros.
|
||||
var profileDirectory = "/etc/apparmor.d"
|
||||
|
||||
// IsEnabled returns true if AppArmor is enabled on the host.
|
||||
// IsEnabled returns true if AppArmor is enabled on the host. It also checks
|
||||
// for the existence of the `apparmor_parser` binary, which will be required to
|
||||
// apply profiles.
|
||||
func IsEnabled() bool {
|
||||
if unshare.IsRootless() {
|
||||
return false
|
||||
}
|
||||
return runcaa.IsEnabled()
|
||||
return supported.NewAppArmorVerifier().IsSupported() == nil
|
||||
}
|
||||
|
||||
// profileData holds information about the given profile for generation.
|
||||
@@ -43,7 +43,7 @@ type profileData struct {
|
||||
}
|
||||
|
||||
// generateDefault creates an apparmor profile from ProfileData.
|
||||
func (p *profileData) generateDefault(out io.Writer) error {
|
||||
func (p *profileData) generateDefault(apparmorParserPath string, out io.Writer) error {
|
||||
compiled, err := template.New("apparmor_profile").Parse(defaultProfileTemplate)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "create AppArmor profile from template")
|
||||
@@ -59,7 +59,7 @@ func (p *profileData) generateDefault(out io.Writer) error {
|
||||
p.InnerImports = append(p.InnerImports, "#include <abstractions/base>")
|
||||
}
|
||||
|
||||
ver, err := getAAParserVersion()
|
||||
ver, err := getAAParserVersion(apparmorParserPath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get AppArmor version")
|
||||
}
|
||||
@@ -85,18 +85,23 @@ func InstallDefault(name string) error {
|
||||
Name: name,
|
||||
}
|
||||
|
||||
cmd := exec.Command("apparmor_parser", "-Kr")
|
||||
apparmorParserPath, err := supported.NewAppArmorVerifier().FindAppArmorParserBinary()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "find `apparmor_parser` binary")
|
||||
}
|
||||
|
||||
cmd := exec.Command(apparmorParserPath, "-Kr")
|
||||
pipe, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "execute apparmor_parser")
|
||||
return errors.Wrapf(err, "execute %s", apparmorParserPath)
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
if pipeErr := pipe.Close(); pipeErr != nil {
|
||||
logrus.Errorf("unable to close AppArmor pipe: %q", pipeErr)
|
||||
}
|
||||
return errors.Wrap(err, "start apparmor_parser command")
|
||||
return errors.Wrapf(err, "start %s command", apparmorParserPath)
|
||||
}
|
||||
if err := p.generateDefault(pipe); err != nil {
|
||||
if err := p.generateDefault(apparmorParserPath, pipe); err != nil {
|
||||
if pipeErr := pipe.Close(); pipeErr != nil {
|
||||
logrus.Errorf("unable to close AppArmor pipe: %q", pipeErr)
|
||||
}
|
||||
@@ -118,11 +123,17 @@ func InstallDefault(name string) error {
|
||||
// generation fails.
|
||||
func DefaultContent(name string) ([]byte, error) {
|
||||
p := profileData{Name: name}
|
||||
var bytes bytes.Buffer
|
||||
if err := p.generateDefault(&bytes); err != nil {
|
||||
buffer := &bytes.Buffer{}
|
||||
|
||||
apparmorParserPath, err := supported.NewAppArmorVerifier().FindAppArmorParserBinary()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "find `apparmor_parser` binary")
|
||||
}
|
||||
|
||||
if err := p.generateDefault(apparmorParserPath, buffer); err != nil {
|
||||
return nil, errors.Wrap(err, "generate default AppAmor profile")
|
||||
}
|
||||
return bytes.Bytes(), nil
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
// IsLoaded checks if a profile with the given name has been loaded into the
|
||||
@@ -159,8 +170,8 @@ func IsLoaded(name string) (bool, error) {
|
||||
}
|
||||
|
||||
// execAAParser runs `apparmor_parser` with the passed arguments.
|
||||
func execAAParser(dir string, args ...string) (string, error) {
|
||||
c := exec.Command("apparmor_parser", args...)
|
||||
func execAAParser(apparmorParserPath, dir string, args ...string) (string, error) {
|
||||
c := exec.Command(apparmorParserPath, args...)
|
||||
c.Dir = dir
|
||||
|
||||
output, err := c.Output()
|
||||
@@ -172,8 +183,8 @@ func execAAParser(dir string, args ...string) (string, error) {
|
||||
}
|
||||
|
||||
// getAAParserVersion returns the major and minor version of apparmor_parser.
|
||||
func getAAParserVersion() (int, error) {
|
||||
output, err := execAAParser("", "--version")
|
||||
func getAAParserVersion(apparmorParserPath string) (int, error) {
|
||||
output, err := execAAParser(apparmorParserPath, "", "--version")
|
||||
if err != nil {
|
||||
return -1, errors.Wrap(err, "execute apparmor_parser")
|
||||
}
|
||||
|
||||
113
vendor/github.com/containers/common/pkg/apparmor/internal/supported/supported.go
generated
vendored
Normal file
113
vendor/github.com/containers/common/pkg/apparmor/internal/supported/supported.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
package supported
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
runcaa "github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
|
||||
|
||||
// ApparmorVerifier is the global struct for verifying if AppAmor is available
|
||||
// on the system.
|
||||
type ApparmorVerifier struct {
|
||||
impl verifierImpl
|
||||
parserBinaryPath string
|
||||
}
|
||||
|
||||
var (
|
||||
singleton *ApparmorVerifier
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
// NewAppArmorVerifier can be used to retrieve a new ApparmorVerifier instance.
|
||||
func NewAppArmorVerifier() *ApparmorVerifier {
|
||||
once.Do(func() {
|
||||
singleton = &ApparmorVerifier{impl: &defaultVerifier{}}
|
||||
})
|
||||
return singleton
|
||||
}
|
||||
|
||||
// IsSupported returns nil if AppAmor is supported by the host system.
|
||||
// The method will error if:
|
||||
// - the process runs in rootless mode
|
||||
// - AppArmor is disabled by the host system
|
||||
// - the `apparmor_parser` binary is not discoverable
|
||||
func (a *ApparmorVerifier) IsSupported() error {
|
||||
if a.impl.UnshareIsRootless() {
|
||||
return errors.New("AppAmor is not supported on rootless containers")
|
||||
}
|
||||
if !a.impl.RuncIsEnabled() {
|
||||
return errors.New("AppArmor not supported by the host system")
|
||||
}
|
||||
|
||||
_, err := a.FindAppArmorParserBinary()
|
||||
return err
|
||||
}
|
||||
|
||||
// FindAppArmorParserBinary returns the `apparmor_parser` binary either from
|
||||
// `/sbin` or from `$PATH`. It returns an error if the binary could not be
|
||||
// found.
|
||||
func (a *ApparmorVerifier) FindAppArmorParserBinary() (string, error) {
|
||||
// Use the memoized path if available
|
||||
if a.parserBinaryPath != "" {
|
||||
logrus.Debugf("Using %s binary", a.parserBinaryPath)
|
||||
return a.parserBinaryPath, nil
|
||||
}
|
||||
|
||||
const (
|
||||
binary = "apparmor_parser"
|
||||
sbin = "/sbin"
|
||||
)
|
||||
|
||||
// `/sbin` is not always in `$PATH`, so we check it explicitly
|
||||
sbinBinaryPath := filepath.Join(sbin, binary)
|
||||
if _, err := a.impl.OsStat(sbinBinaryPath); err == nil {
|
||||
logrus.Debugf("Found %s binary in %s", binary, sbinBinaryPath)
|
||||
a.parserBinaryPath = sbinBinaryPath
|
||||
return sbinBinaryPath, nil
|
||||
}
|
||||
|
||||
// Fallback to checking $PATH
|
||||
if path, err := a.impl.ExecLookPath(binary); err == nil {
|
||||
logrus.Debugf("Found %s binary in %s", binary, path)
|
||||
a.parserBinaryPath = path
|
||||
return path, nil
|
||||
}
|
||||
|
||||
return "", errors.Errorf(
|
||||
"%s binary neither found in %s nor $PATH", binary, sbin,
|
||||
)
|
||||
}
|
||||
|
||||
//counterfeiter:generate . verifierImpl
|
||||
type verifierImpl interface {
|
||||
UnshareIsRootless() bool
|
||||
RuncIsEnabled() bool
|
||||
OsStat(name string) (os.FileInfo, error)
|
||||
ExecLookPath(file string) (string, error)
|
||||
}
|
||||
|
||||
type defaultVerifier struct{}
|
||||
|
||||
func (d *defaultVerifier) UnshareIsRootless() bool {
|
||||
return unshare.IsRootless()
|
||||
}
|
||||
|
||||
func (d *defaultVerifier) RuncIsEnabled() bool {
|
||||
return runcaa.IsEnabled()
|
||||
}
|
||||
|
||||
func (d *defaultVerifier) OsStat(name string) (os.FileInfo, error) {
|
||||
return os.Stat(name)
|
||||
}
|
||||
|
||||
func (d *defaultVerifier) ExecLookPath(file string) (string, error) {
|
||||
return exec.LookPath(file)
|
||||
}
|
||||
Reference in New Issue
Block a user