mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
runc features: add seccomp filter flags
Amend runc features to print seccomp flags. Two set of flags are added: * known flags are those that this version of runc is aware of; * supported flags are those that can be set; normally, this is the same set as known flags, but due to older version of kernel and/or libseccomp, some known flags might be unsupported. This commit also consolidates three different switch statements dealing with flags into one, in func setFlag. A note is added to this function telling what else to look for when adding new flags. Unfortunately, it also adds a list of known flags, that should be kept in sync with the switch statement. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
@@ -87,27 +87,10 @@ func InitSeccomp(config *configs.Seccomp) (int, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Add extra flags
|
||||
// Add extra flags.
|
||||
for _, flag := range config.Flags {
|
||||
switch flag {
|
||||
case "SECCOMP_FILTER_FLAG_TSYNC":
|
||||
// libseccomp-golang always use filterAttrTsync when
|
||||
// possible so all goroutines will receive the same
|
||||
// rules, so there is nothing to do. It does not make
|
||||
// sense to apply the seccomp filter on only one
|
||||
// thread; other threads will be terminated after exec
|
||||
// anyway.
|
||||
case specs.LinuxSeccompFlagLog:
|
||||
if err := filter.SetLogBit(true); err != nil {
|
||||
return -1, fmt.Errorf("error adding log flag to seccomp filter: %w", err)
|
||||
}
|
||||
case specs.LinuxSeccompFlagSpecAllow:
|
||||
if err := filter.SetSSB(true); err != nil {
|
||||
return -1, fmt.Errorf("error adding SSB flag to seccomp filter: %w", err)
|
||||
}
|
||||
// NOTE when adding more flags, make sure to also modify filterFlags in patchbpf.
|
||||
default:
|
||||
return -1, fmt.Errorf("seccomp flags %q not yet supported by runc", flag)
|
||||
if err := setFlag(filter, flag); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +132,67 @@ func InitSeccomp(config *configs.Seccomp) (int, error) {
|
||||
return seccompFd, nil
|
||||
}
|
||||
|
||||
type unknownFlagError struct {
|
||||
flag specs.LinuxSeccompFlag
|
||||
}
|
||||
|
||||
func (e *unknownFlagError) Error() string {
|
||||
return "seccomp flag " + string(e.flag) + " is not known to runc"
|
||||
}
|
||||
|
||||
func setFlag(filter *libseccomp.ScmpFilter, flag specs.LinuxSeccompFlag) error {
|
||||
switch flag {
|
||||
case flagTsync:
|
||||
// libseccomp-golang always use filterAttrTsync when
|
||||
// possible so all goroutines will receive the same
|
||||
// rules, so there is nothing to do. It does not make
|
||||
// sense to apply the seccomp filter on only one
|
||||
// thread; other threads will be terminated after exec
|
||||
// anyway.
|
||||
return nil
|
||||
case specs.LinuxSeccompFlagLog:
|
||||
if err := filter.SetLogBit(true); err != nil {
|
||||
return fmt.Errorf("error adding log flag to seccomp filter: %w", err)
|
||||
}
|
||||
return nil
|
||||
case specs.LinuxSeccompFlagSpecAllow:
|
||||
if err := filter.SetSSB(true); err != nil {
|
||||
return fmt.Errorf("error adding SSB flag to seccomp filter: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// NOTE when adding more flags above, do not forget to also:
|
||||
// - add new flags to `flags` slice in config.go;
|
||||
// - add new flags to tests/integration/seccomp.bats flags test;
|
||||
// - modify func filterFlags in patchbpf/ accordingly.
|
||||
|
||||
return &unknownFlagError{flag: flag}
|
||||
}
|
||||
|
||||
// FlagSupported checks if the flag is known to runc and supported by
|
||||
// currently used libseccomp and kernel (i.e. it can be set).
|
||||
func FlagSupported(flag specs.LinuxSeccompFlag) error {
|
||||
filter := &libseccomp.ScmpFilter{}
|
||||
err := setFlag(filter, flag)
|
||||
|
||||
// For flags we don't know, setFlag returns unknownFlagError.
|
||||
var uf *unknownFlagError
|
||||
if errors.As(err, &uf) {
|
||||
return err
|
||||
}
|
||||
// For flags that are known to runc and libseccomp-golang but can not
|
||||
// be applied because either libseccomp or the kernel is too old,
|
||||
// seccomp.VersionError is returned.
|
||||
var verErr *libseccomp.VersionError
|
||||
if errors.As(err, &verErr) {
|
||||
// Not supported by libseccomp or the kernel.
|
||||
return err
|
||||
}
|
||||
|
||||
// All other flags are known and supported.
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert Libcontainer Action to Libseccomp ScmpAction
|
||||
func getAction(act configs.Action, errnoRet *uint) (libseccomp.ScmpAction, error) {
|
||||
switch act {
|
||||
|
||||
Reference in New Issue
Block a user