Vendor in containers/common v0.40.0

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2021-06-16 05:57:09 -04:00
parent 725b5001a1
commit b6662eed3f
135 changed files with 5564 additions and 389 deletions

View File

@ -23,6 +23,10 @@ type ImportOptions struct {
CommitMessage string
// Tag the imported image with this value.
Tag string
// Overwrite OS of imported image.
OS string
// Overwrite Arch of imported image.
Arch string
}
// Import imports a custom tarball at the specified path. Returns the name of
@ -48,8 +52,10 @@ func (r *Runtime) Import(ctx context.Context, path string, options *ImportOption
}
config := v1.Image{
Config: ic,
History: hist,
Config: ic,
History: hist,
OS: options.OS,
Architecture: options.Arch,
}
u, err := url.ParseRequestURI(path)

View File

@ -351,7 +351,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
// attempt pulling that instead of doing the full short-name dance.
localImage, resolvedImageName, err = r.LookupImage(imageName, nil)
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
return nil, errors.Wrap(err, "error looking up local image")
logrus.Errorf("Looking up %s in local storage: %v", imageName, err)
}
if pullPolicy == config.PullPolicyNever {

View File

@ -132,13 +132,21 @@ func (r *Runtime) storageToImage(storageImage *storage.Image, ref types.ImageRef
}
// Exists returns true if the specicifed image exists in the local containers
// storage.
// storage. Note that it may return false if an image corrupted.
func (r *Runtime) Exists(name string) (bool, error) {
image, _, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true})
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
return false, err
}
return image != nil, nil
if image == nil {
return false, nil
}
// Inspect the image to make sure if it's corrupted or not.
if _, err := image.Inspect(context.Background(), false); err != nil {
logrus.Errorf("Image %s exists in local storage but may be corrupted: %v", name, err)
return false, nil
}
return true, nil
}
// LookupImageOptions allow for customizing local image lookups.

View File

@ -134,9 +134,13 @@ func Login(ctx context.Context, systemContext *types.SystemContext, opts *LoginO
if err = docker.CheckAuth(ctx, systemContext, username, password, server); err == nil {
// Write the new credentials to the authfile
if err := config.SetAuthentication(systemContext, server, username, password); err != nil {
desc, err := config.SetCredentials(systemContext, server, username, password)
if err != nil {
return err
}
if opts.Verbose {
fmt.Fprintln(opts.Stdout, "Used: ", desc)
}
}
if err == nil {
fmt.Fprintln(opts.Stdout, "Login Succeeded!")

View File

@ -20,6 +20,7 @@ type LoginOptions struct {
Username string
StdinPassword bool
GetLoginSet bool
Verbose bool // set to true for verbose output
// Options caller can set
Stdin io.Reader // set to os.Stdin
Stdout io.Writer // set to os.Stdout
@ -47,6 +48,7 @@ func GetLoginFlags(flags *LoginOptions) *pflag.FlagSet {
fs.StringVarP(&flags.Username, "username", "u", "", "Username for registry")
fs.BoolVar(&flags.StdinPassword, "password-stdin", false, "Take the password from stdin")
fs.BoolVar(&flags.GetLoginSet, "get-login", false, "Return the current login user for the registry")
fs.BoolVarP(&flags.Verbose, "verbose", "v", false, "Write more detailed information to stdout")
return &fs
}

View File

@ -5,6 +5,7 @@ import (
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
"sync"
@ -23,7 +24,7 @@ const (
_configPath = "containers/containers.conf"
// DefaultContainersConfig holds the default containers config path
DefaultContainersConfig = "/usr/share/" + _configPath
// OverrideContainersConfig holds the default config paths overridden by the root user
// OverrideContainersConfig holds the default config path overridden by the root user
OverrideContainersConfig = "/etc/" + _configPath
// UserOverrideContainersConfig holds the containers config path overridden by the rootless user
UserOverrideContainersConfig = ".config/" + _configPath
@ -55,6 +56,8 @@ type Config struct {
Engine EngineConfig `toml:"engine"`
// Network section defines the configuration of CNI Plugins
Network NetworkConfig `toml:"network"`
// Secret section defines configurations for the secret management
Secrets SecretConfig `toml:"secrets"`
}
// ContainersConfig represents the "containers" TOML config table
@ -137,6 +140,11 @@ type ContainersConfig struct {
// Negative values indicate that the log file won't be truncated.
LogSizeMax int64 `toml:"log_size_max,omitempty"`
// Specifies default format tag for container log messages.
// This is useful for creating a specific tag for container log messages.
// Containers logs default to truncated container ID as a tag.
LogTag string `toml:"log_tag,omitempty"`
// NetNS indicates how to create a network namespace for the container
NetNS string `toml:"netns,omitempty"`
@ -440,6 +448,17 @@ type NetworkConfig struct {
NetworkConfigDir string `toml:"network_config_dir,omitempty"`
}
// SecretConfig represents the "secret" TOML config table
type SecretConfig struct {
// Driver specifies the secret driver to use.
// Current valid value:
// * file
// * pass
Driver string `toml:"driver,omitempty"`
// Opts contains driver specific options
Opts map[string]string `toml:"opts,omitempty"`
}
// Destination represents destination for remote service
type Destination struct {
// URI, required. Example: ssh://root@example.com:22/run/podman/podman.sock
@ -513,10 +532,49 @@ func readConfigFromFile(path string, config *Config) error {
return nil
}
// addConfigs will search one level in the config dirPath for config files
// If the dirPath does not exist, addConfigs will return nil
func addConfigs(dirPath string, configs []string) ([]string, error) {
newConfigs := []string{}
err := filepath.Walk(dirPath,
// WalkFunc to read additional configs
func(path string, info os.FileInfo, err error) error {
switch {
case err != nil:
// return error (could be a permission problem)
return err
case info == nil:
// this should only happen when err != nil but let's be sure
return nil
case info.IsDir():
if path != dirPath {
// make sure to not recurse into sub-directories
return filepath.SkipDir
}
// ignore directories
return nil
default:
// only add *.conf files
if strings.HasSuffix(path, ".conf") {
newConfigs = append(newConfigs, path)
}
return nil
}
},
)
if os.IsNotExist(err) {
err = nil
}
sort.Strings(newConfigs)
return append(configs, newConfigs...), err
}
// Returns the list of configuration files, if they exist in order of hierarchy.
// The files are read in order and each new file can/will override previous
// file settings.
func systemConfigs() ([]string, error) {
var err error
configs := []string{}
path := os.Getenv("CONTAINERS_CONF")
if path != "" {
@ -531,7 +589,12 @@ func systemConfigs() ([]string, error) {
if _, err := os.Stat(OverrideContainersConfig); err == nil {
configs = append(configs, OverrideContainersConfig)
}
path, err := ifRootlessConfigPath()
configs, err = addConfigs(OverrideContainersConfig+".d", configs)
if err != nil {
return nil, err
}
path, err = ifRootlessConfigPath()
if err != nil {
return nil, err
}
@ -539,6 +602,10 @@ func systemConfigs() ([]string, error) {
if _, err := os.Stat(path); err == nil {
configs = append(configs, path)
}
configs, err = addConfigs(path+".d", configs)
if err != nil {
return nil, err
}
}
return configs, nil
}

View File

@ -16,30 +16,16 @@
[containers]
# List of devices. Specified as
# "<device-on-host>:<device-on-container>:<permissions>", for example:
# "/dev/sdc:/dev/xvdc:rwm".
# If it is empty or commented out, only the default devices will be used
# List of annotation. Specified as
# "key = value"
# If it is empty or commented out, no annotations will be added
#
# devices = []
# List of volumes. Specified as
# "<directory-on-host>:<directory-in-container>:<options>", for example:
# "/db:/var/lib/db:ro".
# If it is empty or commented out, no volumes will be added
#
# volumes = []
# annotations = []
# Used to change the name of the default AppArmor profile of container engine.
#
# apparmor_profile = "container-default"
# List of annotation. Specified as
# "key=value"
# If it is empty or commented out, no annotations will be added
#
# annotations = []
# Default way to to create a cgroup namespace for the container
# Options are:
# `private` Create private Cgroup Namespace for the container.
@ -93,6 +79,13 @@ default_sysctls = [
# "nofile=1280:2560",
# ]
# List of devices. Specified as
# "<device-on-host>:<device-on-container>:<permissions>", for example:
# "/dev/sdc:/dev/xvdc:rwm".
# If it is empty or commented out, only the default devices will be used
#
# devices = []
# List of default DNS options to be added to /etc/resolv.conf inside of the container.
#
# dns_options = []
@ -166,6 +159,12 @@ default_sysctls = [
#
# log_size_max = -1
# Specifies default format tag for container log messages.
# This is useful for creating a specific tag for container log messages.
# Containers logs default to truncated container ID as a tag.
#
# log_tag = ""
# Default way to to create a Network namespace for the container
# Options are:
# `private` Create private Network Namespace for the container.
@ -179,10 +178,6 @@ default_sysctls = [
#
# no_hosts = false
# Maximum number of processes allowed in a container.
#
# pids_limit = 2048
# Default way to to create a PID namespace for the container
# Options are:
# `private` Create private PID Namespace for the container.
@ -190,6 +185,13 @@ default_sysctls = [
#
# pidns = "private"
# Maximum number of processes allowed in a container.
#
# pids_limit = 2048
# Indicates the networking to be used for rootless containers
# rootless_networking = "slirp4netns"
# Path to the seccomp.json profile which is used as the default seccomp profile
# for the runtime.
#
@ -209,14 +211,7 @@ default_sysctls = [
# Set umask inside the container
#
# umask="0022"
# Default way to to create a UTS namespace for the container
# Options are:
# `private` Create private UTS Namespace for the container.
# `host` Share host UTS Namespace with the container.
#
# utsns = "private"
# umask = "0022"
# Default way to to create a User namespace for the container
# Options are:
@ -229,7 +224,21 @@ default_sysctls = [
# UIDs are allocated from the "container" UIDs listed in
# /etc/subuid & /etc/subgid
#
# userns_size=65536
# userns_size = 65536
# Default way to to create a UTS namespace for the container
# Options are:
# `private` Create private UTS Namespace for the container.
# `host` Share host UTS Namespace with the container.
#
# utsns = "private"
# List of volumes. Specified as
# "<directory-on-host>:<directory-in-container>:<options>", for example:
# "/db:/var/lib/db:ro".
# If it is empty or commented out, no volumes will be added
#
# volumes = []
# The network table contains settings pertaining to the management of
# CNI plugins.
@ -254,14 +263,8 @@ default_sysctls = [
# network_config_dir = "/etc/cni/net.d/"
[engine]
# Maximum number of image layers to be copied (pulled/pushed) simultaneously.
# Not setting this field, or setting it to zero, will fall back to containers/image defaults.
# image_parallel_copies=0
# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
# container images. By default image pulled and pushed match the format of the
# source image. Building/committing defaults to OCI.
# image_default_format = ""
# Index to the active service
# active_service = production
# Cgroup management implementation used for the runtime.
# Valid options "systemd" or "cgroupfs"
@ -319,10 +322,19 @@ default_sysctls = [
# "/usr/share/containers/oci/hooks.d",
# ]
# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
# container images. By default image pulled and pushed match the format of the
# source image. Building/committing defaults to OCI.
# image_default_format = ""
# Default transport method for pulling and pushing for images
#
# image_default_transport = "docker://"
# Maximum number of image layers to be copied (pulled/pushed) simultaneously.
# Not setting this field, or setting it to zero, will fall back to containers/image defaults.
# image_parallel_copies = 0
# Default command to run the infra container
#
# infra_command = "/pause"
@ -345,7 +357,7 @@ default_sysctls = [
# Indicates if Podman is running inside a VM via Podman Machine.
# Podman uses this value to do extra setup around networking from the
# container inside the VM to to host.
# machine_enabled=false
# machine_enabled = false
# MultiImageArchive - if true, the container engine allows for storing archives
# (e.g., of the docker-archive transport) with multiple images. By default,
@ -364,12 +376,12 @@ default_sysctls = [
# Path to the slirp4netns binary
#
# network_cmd_path=""
# network_cmd_path = ""
# Default options to pass to the slirp4netns binary.
# For example "allow_host_loopback=true"
#
# network_cmd_options=[]
# network_cmd_options = []
# Whether to use chroot instead of pivot_root in the runtime
#
@ -389,8 +401,22 @@ default_sysctls = [
# `podman --remote=true` for access to the remote Podman service.
# remote = false
# Indicates the networking to be used for rootless containers
# rootless_networking="slirp4netns"
# Default OCI runtime
#
# runtime = "crun"
# List of the OCI runtimes that support --format=json. When json is supported
# engine will use it for reporting nicer errors.
#
# runtime_supports_json = ["crun", "runc", "kata", "runsc"]
# List of the OCI runtimes that supports running containers with KVM Separation.
#
# runtime_supports_kvm = ["kata"]
# List of the OCI runtimes that supports running containers without cgroups.
#
# runtime_supports_nocgroups = ["crun"]
# Directory for persistent engine files (database, etc)
# By default, this will be configured relative to where the containers/storage
@ -399,6 +425,22 @@ default_sysctls = [
#
# static_dir = "/var/lib/containers/storage/libpod"
# Number of seconds to wait for container to exit before sending kill signal.
# stop_timeout = 10
# map of service destinations
# [service_destinations]
# [service_destinations.production]
# URI to access the Podman service
# Examples:
# rootless "unix://run/user/$UID/podman/podman.sock" (Default)
# rootfull "unix://run/podman/podman.sock (Default)
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
# uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock"
# Path to file containing ssh identity key
# identity = "~/.ssh/id_rsa"
# Directory for temporary files. Must be tmpfs (wiped after reboot)
#
# tmp_dir = "/run/libpod"
@ -410,42 +452,6 @@ default_sysctls = [
#
# volume_path = "/var/lib/containers/storage/volumes"
# Default OCI runtime
#
# runtime = "crun"
# List of the OCI runtimes that support --format=json. When json is supported
# engine will use it for reporting nicer errors.
#
# runtime_supports_json = ["crun", "runc", "kata", "runsc"]
# List of the OCI runtimes that supports running containers without cgroups.
#
# runtime_supports_nocgroups = ["crun"]
# List of the OCI runtimes that supports running containers with KVM Separation.
#
# runtime_supports_kvm = ["kata"]
# Number of seconds to wait for container to exit before sending kill signal.
# stop_timeout = 10
# Index to the active service
# active_service = production
# map of service destinations
# [service_destinations]
# [service_destinations.production]
# URI to access the Podman service
# Examples:
# rootless "unix://run/user/$UID/podman/podman.sock" (Default)
# rootfull "unix://run/podman/podman.sock (Default)
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
# uri="ssh://user@production.example.com/run/user/1001/podman/podman.sock"
# Path to file containing ssh identity key
# identity = "~/.ssh/id_rsa"
# Paths to look for a valid OCI runtime (crun, runc, kata, runsc, etc)
[engine.runtimes]
# crun = [
@ -458,16 +464,6 @@ default_sysctls = [
# "/run/current-system/sw/bin/crun",
# ]
# runc = [
# "/usr/bin/runc",
# "/usr/sbin/runc",
# "/usr/local/bin/runc",
# "/usr/local/sbin/runc",
# "/sbin/runc",
# "/bin/runc",
# "/usr/lib/cri-o-runc/sbin/runc",
# ]
# kata = [
# "/usr/bin/kata-runtime",
# "/usr/sbin/kata-runtime",
@ -479,6 +475,16 @@ default_sysctls = [
# "/usr/bin/kata-fc",
# ]
# runc = [
# "/usr/bin/runc",
# "/usr/sbin/runc",
# "/usr/local/bin/runc",
# "/usr/local/sbin/runc",
# "/sbin/runc",
# "/bin/runc",
# "/usr/lib/cri-o-runc/sbin/runc",
# ]
# runsc = [
# "/usr/bin/runsc",
# "/usr/sbin/runsc",
@ -497,3 +503,9 @@ default_sysctls = [
# TOML does not provide a way to end a table other than a further table being
# defined, so every key hereafter will be part of [volume_plugins] and not the
# main config.
[secret]
# driver = "file"
[secret.opts]
# root = "/example/directory"

View File

@ -144,8 +144,6 @@ func DefaultConfig() (*Config, error) {
return nil, err
}
netns := "bridge"
cniConfig := _cniConfigDir
defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath
@ -161,7 +159,6 @@ func DefaultConfig() (*Config, error) {
defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath
}
}
netns = "slirp4netns"
cniConfig = filepath.Join(configHome, _cniConfigDirRootless)
}
@ -197,12 +194,10 @@ func DefaultConfig() (*Config, error) {
IPCNS: "private",
LogDriver: defaultLogDriver(),
LogSizeMax: DefaultLogSizeMax,
NetNS: netns,
NoHosts: false,
PidsLimit: DefaultPidsLimit,
PidNS: "private",
RootlessNetworking: DefaultRootlessNetwork,
SeccompProfile: SeccompDefaultPath,
ShmSize: DefaultShmSize,
TZ: "",
Umask: "0022",
@ -216,10 +211,19 @@ func DefaultConfig() (*Config, error) {
NetworkConfigDir: cniConfig,
CNIPluginDirs: cniBinDir,
},
Engine: *defaultEngineConfig,
Engine: *defaultEngineConfig,
Secrets: defaultSecretConfig(),
}, nil
}
// defaultSecretConfig returns the default secret configuration.
// Please note that the default is choosing the "file" driver.
func defaultSecretConfig() SecretConfig {
return SecretConfig{
Driver: "file",
}
}
// defaultConfigFromMemory returns a default engine configuration. Note that the
// config is different for root and rootless. It also parses the storage.conf.
func defaultConfigFromMemory() (*EngineConfig, error) {

View File

@ -130,7 +130,7 @@ func NewTemplate(name string) *Template {
func (t *Template) Parse(text string) (*Template, error) {
if strings.HasPrefix(text, "table ") {
t.isTable = true
text = "{{range .}}" + NormalizeFormat(text) + "{{end}}"
text = "{{range .}}" + NormalizeFormat(text) + "{{end -}}"
} else {
text = NormalizeFormat(text)
}
@ -157,12 +157,12 @@ func (t *Template) IsTable() bool {
return t.isTable
}
var rangeRegex = regexp.MustCompile(`{{\s*range\s*\.\s*}}.*{{\s*end\s*}}`)
var rangeRegex = regexp.MustCompile(`{{\s*range\s*\.\s*}}.*{{\s*end\s*-?\s*}}`)
// EnforceRange ensures that the format string contains a range
func EnforceRange(format string) string {
if !rangeRegex.MatchString(format) {
return "{{range .}}" + format + "{{end}}"
return "{{range .}}" + format + "{{end -}}"
}
return format
}

View File

@ -118,6 +118,7 @@ func specToSeccomp(spec *specs.LinuxSeccomp) (*Seccomp, error) {
return nil, errors.Wrap(err, "convert default action")
}
res.DefaultAction = newDefaultAction
res.DefaultErrnoRet = spec.DefaultErrnoRet
// Loop through all syscall blocks and convert them to the internal format
for _, call := range spec.Syscalls {

View File

@ -44,8 +44,54 @@ func arches() []Architecture {
// DefaultProfile defines the allowlist for the default seccomp profile.
func DefaultProfile() *Seccomp {
einval := uint(unix.EINVAL)
enosys := uint(unix.ENOSYS)
eperm := uint(unix.EPERM)
syscalls := []*Syscall{
{
Names: []string{
"bdflush",
"clone3",
"io_pgetevents",
"io_uring_enter",
"io_uring_register",
"io_uring_setup",
"kexec_file_load",
"kexec_load",
"membarrier",
"migrate_pages",
"move_pages",
"nfsservctl",
"nice",
"oldfstat",
"oldlstat",
"oldolduname",
"oldstat",
"olduname",
"pciconfig_iobase",
"pciconfig_read",
"pciconfig_write",
"pkey_alloc",
"pkey_free",
"pkey_mprotect",
"rseq",
"sgetmask",
"ssetmask",
"swapcontext",
"swapoff",
"swapon",
"sysfs",
"uselib",
"userfaultfd",
"ustat",
"vm86",
"vm86old",
"vmsplice",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
},
{
Names: []string{
"_llseek",
@ -128,6 +174,7 @@ func DefaultProfile() *Seccomp {
"ftruncate",
"ftruncate64",
"futex",
"futex_time64",
"futimesat",
"get_robust_list",
"get_thread_area",
@ -212,7 +259,9 @@ func DefaultProfile() *Seccomp {
"mq_notify",
"mq_open",
"mq_timedreceive",
"mq_timedreceive_time64",
"mq_timedsend",
"mq_timedsend_time64",
"mq_unlink",
"mremap",
"msgctl",
@ -252,6 +301,7 @@ func DefaultProfile() *Seccomp {
"pwritev2",
"read",
"readahead",
"readdir",
"readlink",
"readlinkat",
"readv",
@ -259,6 +309,7 @@ func DefaultProfile() *Seccomp {
"recv",
"recvfrom",
"recvmmsg",
"recvmmsg_time64",
"recvmsg",
"remap_file_pages",
"removexattr",
@ -274,6 +325,7 @@ func DefaultProfile() *Seccomp {
"rt_sigreturn",
"rt_sigsuspend",
"rt_sigtimedwait",
"rt_sigtimedwait_time64",
"rt_tgsigqueueinfo",
"sched_get_priority_max",
"sched_get_priority_min",
@ -282,6 +334,7 @@ func DefaultProfile() *Seccomp {
"sched_getparam",
"sched_getscheduler",
"sched_rr_get_interval",
"sched_rr_get_interval_time64",
"sched_setaffinity",
"sched_setattr",
"sched_setparam",
@ -293,6 +346,7 @@ func DefaultProfile() *Seccomp {
"semget",
"semop",
"semtimedop",
"semtimedop_time64",
"send",
"sendfile",
"sendfile64",
@ -361,6 +415,7 @@ func DefaultProfile() *Seccomp {
"timer_gettime",
"timer_gettime64",
"timer_settime",
"timer_settime64",
"timerfd_create",
"timerfd_gettime",
"timerfd_gettime64",
@ -514,6 +569,17 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_DAC_READ_SEARCH"},
},
},
{
Names: []string{
"open_by_handle_at",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_DAC_READ_SEARCH"},
},
},
{
Names: []string{
"bpf",
@ -531,6 +597,24 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_ADMIN"},
},
},
{
Names: []string{
"bpf",
"fanotify_init",
"lookup_dcookie",
"perf_event_open",
"quotactl",
"setdomainname",
"sethostname",
"setns",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_ADMIN"},
},
},
{
Names: []string{
"chroot",
@ -541,6 +625,17 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_CHROOT"},
},
},
{
Names: []string{
"chroot",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_CHROOT"},
},
},
{
Names: []string{
"delete_module",
@ -554,6 +649,20 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_MODULE"},
},
},
{
Names: []string{
"delete_module",
"init_module",
"finit_module",
"query_module",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_MODULE"},
},
},
{
Names: []string{
"get_mempolicy",
@ -566,6 +675,19 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_NICE"},
},
},
{
Names: []string{
"get_mempolicy",
"mbind",
"set_mempolicy",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_NICE"},
},
},
{
Names: []string{
"acct",
@ -576,6 +698,17 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_PACCT"},
},
},
{
Names: []string{
"acct",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_PACCT"},
},
},
{
Names: []string{
"kcmp",
@ -590,6 +723,21 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_PTRACE"},
},
},
{
Names: []string{
"kcmp",
"process_madvise",
"process_vm_readv",
"process_vm_writev",
"ptrace",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_PTRACE"},
},
},
{
Names: []string{
"iopl",
@ -601,6 +749,18 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_RAWIO"},
},
},
{
Names: []string{
"iopl",
"ioperm",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_RAWIO"},
},
},
{
Names: []string{
"settimeofday",
@ -614,6 +774,20 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_TIME"},
},
},
{
Names: []string{
"settimeofday",
"stime",
"clock_settime",
"clock_settime64",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_TIME"},
},
},
{
Names: []string{
"vhangup",
@ -624,6 +798,17 @@ func DefaultProfile() *Seccomp {
Caps: []string{"CAP_SYS_TTY_CONFIG"},
},
},
{
Names: []string{
"vhangup",
},
Action: ActErrno,
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Caps: []string{"CAP_SYS_TTY_CONFIG"},
},
},
{
Names: []string{
"socket",
@ -706,8 +891,9 @@ func DefaultProfile() *Seccomp {
}
return &Seccomp{
DefaultAction: ActErrno,
ArchMap: arches(),
Syscalls: syscalls,
DefaultAction: ActErrno,
DefaultErrnoRet: &enosys,
ArchMap: arches(),
Syscalls: syscalls,
}
}

View File

@ -41,7 +41,7 @@ func BuildFilter(spec *specs.LinuxSeccomp) (*libseccomp.ScmpFilter, error) {
return nil, errors.Wrap(err, "convert spec to seccomp profile")
}
defaultAction, err := toAction(profile.DefaultAction, nil)
defaultAction, err := toAction(profile.DefaultAction, profile.DefaultErrnoRet)
if err != nil {
return nil, errors.Wrapf(err, "convert default action %s", profile.DefaultAction)
}

View File

@ -1,5 +1,6 @@
{
"defaultAction": "SCMP_ACT_ERRNO",
"defaultErrnoRet": 38,
"archMap": [
{
"architecture": "SCMP_ARCH_X86_64",
@ -50,6 +51,53 @@
}
],
"syscalls": [
{
"names": [
"bdflush",
"clone3",
"io_pgetevents",
"io_uring_enter",
"io_uring_register",
"io_uring_setup",
"kexec_file_load",
"kexec_load",
"membarrier",
"migrate_pages",
"move_pages",
"nfsservctl",
"nice",
"oldfstat",
"oldlstat",
"oldolduname",
"oldstat",
"olduname",
"pciconfig_iobase",
"pciconfig_read",
"pciconfig_write",
"pkey_alloc",
"pkey_free",
"pkey_mprotect",
"rseq",
"sgetmask",
"ssetmask",
"swapcontext",
"swapoff",
"swapon",
"sysfs",
"uselib",
"userfaultfd",
"ustat",
"vm86",
"vm86old",
"vmsplice"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {},
"errnoRet": 1
},
{
"names": [
"_llseek",
@ -132,6 +180,7 @@
"ftruncate",
"ftruncate64",
"futex",
"futex_time64",
"futimesat",
"get_robust_list",
"get_thread_area",
@ -216,7 +265,9 @@
"mq_notify",
"mq_open",
"mq_timedreceive",
"mq_timedreceive_time64",
"mq_timedsend",
"mq_timedsend_time64",
"mq_unlink",
"mremap",
"msgctl",
@ -256,6 +307,7 @@
"pwritev2",
"read",
"readahead",
"readdir",
"readlink",
"readlinkat",
"readv",
@ -263,6 +315,7 @@
"recv",
"recvfrom",
"recvmmsg",
"recvmmsg_time64",
"recvmsg",
"remap_file_pages",
"removexattr",
@ -278,6 +331,7 @@
"rt_sigreturn",
"rt_sigsuspend",
"rt_sigtimedwait",
"rt_sigtimedwait_time64",
"rt_tgsigqueueinfo",
"sched_get_priority_max",
"sched_get_priority_min",
@ -286,6 +340,7 @@
"sched_getparam",
"sched_getscheduler",
"sched_rr_get_interval",
"sched_rr_get_interval_time64",
"sched_setaffinity",
"sched_setattr",
"sched_setparam",
@ -297,6 +352,7 @@
"semget",
"semop",
"semtimedop",
"semtimedop_time64",
"send",
"sendfile",
"sendfile64",
@ -365,6 +421,7 @@
"timer_gettime",
"timer_gettime64",
"timer_settime",
"timer_settime64",
"timerfd_create",
"timerfd_gettime",
"timerfd_gettime64",
@ -580,6 +637,21 @@
},
"excludes": {}
},
{
"names": [
"open_by_handle_at"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_DAC_READ_SEARCH"
]
},
"errnoRet": 1
},
{
"names": [
"bpf",
@ -601,6 +673,28 @@
},
"excludes": {}
},
{
"names": [
"bpf",
"fanotify_init",
"lookup_dcookie",
"perf_event_open",
"quotactl",
"setdomainname",
"sethostname",
"setns"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_ADMIN"
]
},
"errnoRet": 1
},
{
"names": [
"chroot"
@ -615,6 +709,21 @@
},
"excludes": {}
},
{
"names": [
"chroot"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_CHROOT"
]
},
"errnoRet": 1
},
{
"names": [
"delete_module",
@ -632,6 +741,24 @@
},
"excludes": {}
},
{
"names": [
"delete_module",
"init_module",
"finit_module",
"query_module"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_MODULE"
]
},
"errnoRet": 1
},
{
"names": [
"get_mempolicy",
@ -648,6 +775,23 @@
},
"excludes": {}
},
{
"names": [
"get_mempolicy",
"mbind",
"set_mempolicy"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_NICE"
]
},
"errnoRet": 1
},
{
"names": [
"acct"
@ -662,6 +806,21 @@
},
"excludes": {}
},
{
"names": [
"acct"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_PACCT"
]
},
"errnoRet": 1
},
{
"names": [
"kcmp",
@ -680,6 +839,25 @@
},
"excludes": {}
},
{
"names": [
"kcmp",
"process_madvise",
"process_vm_readv",
"process_vm_writev",
"ptrace"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_PTRACE"
]
},
"errnoRet": 1
},
{
"names": [
"iopl",
@ -695,6 +873,22 @@
},
"excludes": {}
},
{
"names": [
"iopl",
"ioperm"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_RAWIO"
]
},
"errnoRet": 1
},
{
"names": [
"settimeofday",
@ -712,6 +906,24 @@
},
"excludes": {}
},
{
"names": [
"settimeofday",
"stime",
"clock_settime",
"clock_settime64"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_TIME"
]
},
"errnoRet": 1
},
{
"names": [
"vhangup"
@ -726,6 +938,21 @@
},
"excludes": {}
},
{
"names": [
"vhangup"
],
"action": "SCMP_ACT_ERRNO",
"args": [],
"comment": "",
"includes": {},
"excludes": {
"caps": [
"CAP_SYS_TTY_CONFIG"
]
},
"errnoRet": 1
},
{
"names": [
"socket"

View File

@ -111,6 +111,7 @@ func setupSeccomp(config *Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, error)
}
newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction)
newConfig.DefaultErrnoRet = config.DefaultErrnoRet
Loop:
// Loop through all syscall blocks and convert them to libcontainer format after filtering them

View File

@ -6,7 +6,8 @@ package seccomp
// Seccomp represents the config for a seccomp profile for syscall restriction.
type Seccomp struct {
DefaultAction Action `json:"defaultAction"`
DefaultAction Action `json:"defaultAction"`
DefaultErrnoRet *uint `json:"defaultErrnoRet"`
// Architectures is kept to maintain backward compatibility with the old
// seccomp profile.
Architectures []Arch `json:"architectures,omitempty"`

View File

@ -0,0 +1,176 @@
package passdriver
import (
"bytes"
"context"
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
"github.com/pkg/errors"
)
var (
// errNoSecretData indicates that there is not data associated with an id
errNoSecretData = errors.New("no secret data with ID")
// errNoSecretData indicates that there is secret data already associated with an id
errSecretIDExists = errors.New("secret data with ID already exists")
// errInvalidKey indicates that something about your key is wrong
errInvalidKey = errors.New("invalid key")
)
type driverConfig struct {
// Root contains the root directory where the secrets are stored
Root string
// KeyID contains the key id that will be used for encryption (i.e. user@domain.tld)
KeyID string
}
func (cfg *driverConfig) ParseOpts(opts map[string]string) {
if val, ok := opts["root"]; ok {
cfg.Root = val
cfg.findGpgID() // try to find a .gpg-id in the parent directories of Root
}
if val, ok := opts["key"]; ok {
cfg.KeyID = val
}
}
func defaultDriverConfig() *driverConfig {
cfg := &driverConfig{}
if home, err := os.UserHomeDir(); err == nil {
defaultLocations := []string{
filepath.Join(home, ".password-store"),
filepath.Join(home, ".local/share/gopass/stores/root"),
}
for _, path := range defaultLocations {
if stat, err := os.Stat(path); err != nil || !stat.IsDir() {
continue
}
cfg.Root = path
bs, err := ioutil.ReadFile(filepath.Join(path, ".gpg-id"))
if err != nil {
continue
}
cfg.KeyID = string(bytes.Trim(bs, "\r\n"))
break
}
}
return cfg
}
func (cfg *driverConfig) findGpgID() {
path := cfg.Root
for len(path) > 1 {
if _, err := os.Stat(filepath.Join(path, ".gpg-id")); err == nil {
bs, err := ioutil.ReadFile(filepath.Join(path, ".gpg-id"))
if err != nil {
continue
}
cfg.KeyID = string(bytes.Trim(bs, "\r\n"))
break
}
path = filepath.Dir(path)
}
}
// Driver is the passdriver object
type Driver struct {
driverConfig
}
// NewDriver creates a new secret driver.
func NewDriver(opts map[string]string) (*Driver, error) {
cfg := defaultDriverConfig()
cfg.ParseOpts(opts)
driver := &Driver{
driverConfig: *cfg,
}
return driver, nil
}
// List returns all secret IDs
func (d *Driver) List() (secrets []string, err error) {
files, err := ioutil.ReadDir(d.Root)
if err != nil {
return nil, errors.Wrap(err, "failed to read secret directory")
}
for _, f := range files {
fileName := f.Name()
withoutSuffix := fileName[:len(fileName)-len(".gpg")]
secrets = append(secrets, withoutSuffix)
}
sort.Strings(secrets)
return secrets, nil
}
// Lookup returns the bytes associated with a secret ID
func (d *Driver) Lookup(id string) ([]byte, error) {
out := &bytes.Buffer{}
key, err := d.getPath(id)
if err != nil {
return nil, err
}
if err := d.gpg(context.TODO(), nil, out, "--decrypt", key); err != nil {
return nil, errors.Wrapf(errNoSecretData, id)
}
if out.Len() == 0 {
return nil, errors.Wrapf(errNoSecretData, id)
}
return out.Bytes(), nil
}
// Store saves the bytes associated with an ID. An error is returned if the ID already exists
func (d *Driver) Store(id string, data []byte) error {
if _, err := d.Lookup(id); err == nil {
return errors.Wrap(errSecretIDExists, id)
}
in := bytes.NewReader(data)
key, err := d.getPath(id)
if err != nil {
return err
}
return d.gpg(context.TODO(), in, nil, "--encrypt", "-r", d.KeyID, "-o", key)
}
// Delete removes the secret associated with the specified ID. An error is returned if no matching secret is found.
func (d *Driver) Delete(id string) error {
key, err := d.getPath(id)
if err != nil {
return err
}
if err := os.Remove(key); err != nil {
return errors.Wrap(errNoSecretData, id)
}
return nil
}
func (d *Driver) gpg(ctx context.Context, in io.Reader, out io.Writer, args ...string) error {
cmd := exec.CommandContext(ctx, "gpg", args...)
cmd.Env = os.Environ()
cmd.Stdin = in
cmd.Stdout = out
cmd.Stderr = ioutil.Discard
return cmd.Run()
}
func (d *Driver) getPath(id string) (string, error) {
path, err := filepath.Abs(filepath.Join(d.Root, id))
if err != nil {
return "", errInvalidKey
}
if !strings.HasPrefix(path, d.Root) {
return "", errInvalidKey
}
return path + ".gpg", nil
}

View File

@ -8,6 +8,7 @@ import (
"time"
"github.com/containers/common/pkg/secrets/filedriver"
"github.com/containers/common/pkg/secrets/passdriver"
"github.com/containers/storage/pkg/lockfile"
"github.com/containers/storage/pkg/stringid"
"github.com/pkg/errors"
@ -271,12 +272,15 @@ func validateSecretName(name string) error {
// getDriver creates a new driver.
func getDriver(name string, opts map[string]string) (SecretsDriver, error) {
if name == "file" {
switch name {
case "file":
if path, ok := opts["path"]; ok {
return filedriver.NewDriver(path)
} else {
return nil, errors.Wrap(errInvalidDriverOpt, "need path for filedriver")
}
case "pass":
return passdriver.NewDriver(opts)
}
return nil, errInvalidDriver
}

View File

@ -1,4 +1,4 @@
package version
// Version is the version of the build.
const Version = "0.39.1-dev"
const Version = "0.40.0"