Connect Seccomp configuration in Spec to configuration in Libcontainer

Signed-off-by: Matthew Heon <mheon@redhat.com>
This commit is contained in:
Matthew Heon 2015-08-24 14:30:45 -04:00 committed by Matthew Heon
parent 7291a52148
commit 2ee6d1e8b6
2 changed files with 119 additions and 0 deletions

View File

@ -0,0 +1,53 @@
package seccomp
import (
"fmt"
"github.com/opencontainers/runc/libcontainer/configs"
)
// ConvertStringToOperator converts a string into a Seccomp comparison operator.
// Comparison operators use the names they are assigned by Libseccomp's header.
// Attempting to convert a string that is not a valid operator results in an
// error.
func ConvertStringToOperator(in string) (configs.Operator, error) {
switch in {
case "SCMP_CMP_NE":
return configs.NotEqualTo, nil
case "SCMP_CMP_LT":
return configs.LessThan, nil
case "SCMP_CMP_LE":
return configs.LessThanOrEqualTo, nil
case "SCMP_CMP_EQ":
return configs.EqualTo, nil
case "SCMP_CMP_GE":
return configs.GreaterThan, nil
case "SCMP_CMP_GT":
return configs.GreaterThanOrEqualTo, nil
case "SCMP_CMP_MASKED_EQ":
return configs.MaskEqualTo, nil
default:
return 0, fmt.Errorf("string %s is not a valid operator for seccomp", in)
}
}
// ConvertStringToAction converts a string into a Seccomp rule match action.
// Actions use the named they are assigned in Libseccomp's header, though some
// (notable, SCMP_ACT_TRACE) are not available in this implementation and will
// return errors.
// Attempting to convert a string that is not a valid action results in an
// error.
func ConvertStringToAction(in string) (configs.Action, error) {
switch in {
case "SCMP_ACT_KILL":
return configs.Kill, nil
case "SCMP_ACT_ERRNO":
return configs.Errno, nil
case "SCMP_ACT_TRAP":
return configs.Trap, nil
case "SCMP_ACT_ALLOW":
return configs.Allow, nil
default:
return 0, fmt.Errorf("string %s is not a valid action for seccomp", in)
}
}

66
spec.go
View File

@ -15,6 +15,7 @@ import (
"github.com/codegangsta/cli"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/seccomp"
"github.com/opencontainers/specs"
)
@ -180,6 +181,10 @@ var specCommand = cli.Command{
Swappiness: -1,
},
},
Seccomp: specs.Seccomp{
DefaultAction: "SCMP_ACT_ALLOW",
Syscalls: []*specs.Syscall{},
},
},
}
data, err := json.MarshalIndent(&spec, "", "\t")
@ -282,6 +287,11 @@ func createLibcontainerConfig(cgroupName string, spec *specs.LinuxSpec) (*config
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
}
}
seccomp, err := setupSeccomp(&spec.Linux.Seccomp)
if err != nil {
return nil, err
}
config.Seccomp = seccomp
config.Sysctl = spec.Linux.Sysctl
config.ProcessLabel = spec.Linux.SelinuxProcessLabel
config.AppArmorProfile = spec.Linux.ApparmorProfile
@ -470,3 +480,59 @@ func parseMountOptions(options string) (int, string) {
}
return flag, strings.Join(data, ",")
}
func setupSeccomp(config *specs.Seccomp) (*configs.Seccomp, error) {
if config == nil {
return nil, nil
}
// No default action specified, no syscalls listed, assume seccomp disabled
if config.DefaultAction == "" && len(config.Syscalls) == 0 {
return nil, nil
}
newConfig := new(configs.Seccomp)
newConfig.Syscalls = []*configs.Syscall{}
// Convert default action from string representation
newDefaultAction, err := seccomp.ConvertStringToAction(string(config.DefaultAction))
if err != nil {
return nil, err
}
newConfig.DefaultAction = newDefaultAction
// Loop through all syscall blocks and convert them to libcontainer format
for _, call := range config.Syscalls {
newAction, err := seccomp.ConvertStringToAction(string(call.Action))
if err != nil {
return nil, err
}
newCall := configs.Syscall{
Name: call.Name,
Action: newAction,
Args: []*configs.Arg{},
}
// Loop through all the arguments of the syscall and convert them
for _, arg := range call.Args {
newOp, err := seccomp.ConvertStringToOperator(string(arg.Op))
if err != nil {
return nil, err
}
newArg := configs.Arg{
Index: arg.Index,
Value: arg.Value,
ValueTwo: arg.ValueTwo,
Op: newOp,
}
newCall.Args = append(newCall.Args, &newArg)
}
newConfig.Syscalls = append(newConfig.Syscalls, &newCall)
}
return newConfig, nil
}