mirror of
https://github.com/containers/podman.git
synced 2025-11-13 01:29:06 +08:00
198 lines
5.8 KiB
Go
198 lines
5.8 KiB
Go
// NOTE: this package has originally been copied from
|
|
// github.com/opencontainers/runc and modified to work for other use cases
|
|
|
|
package seccomp
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/opencontainers/runtime-spec/specs-go"
|
|
)
|
|
|
|
var (
|
|
goArchToSeccompArchMap = map[string]Arch{
|
|
"386": ArchX86,
|
|
"amd64": ArchX86_64,
|
|
"amd64p32": ArchX32,
|
|
"arm": ArchARM,
|
|
"arm64": ArchAARCH64,
|
|
"mips": ArchMIPS,
|
|
"mips64": ArchMIPS64,
|
|
"mips64le": ArchMIPSEL64,
|
|
"mips64p32": ArchMIPS64N32,
|
|
"mips64p32le": ArchMIPSEL64N32,
|
|
"mipsle": ArchMIPSEL,
|
|
"ppc": ArchPPC,
|
|
"ppc64": ArchPPC64,
|
|
"ppc64le": ArchPPC64LE,
|
|
"s390": ArchS390,
|
|
"s390x": ArchS390X,
|
|
}
|
|
specArchToLibseccompArchMap = map[specs.Arch]string{
|
|
specs.ArchX86: "x86",
|
|
specs.ArchX86_64: "amd64",
|
|
specs.ArchX32: "x32",
|
|
specs.ArchARM: "arm",
|
|
specs.ArchAARCH64: "arm64",
|
|
specs.ArchMIPS: "mips",
|
|
specs.ArchMIPS64: "mips64",
|
|
specs.ArchMIPS64N32: "mips64n32",
|
|
specs.ArchMIPSEL: "mipsel",
|
|
specs.ArchMIPSEL64: "mipsel64",
|
|
specs.ArchMIPSEL64N32: "mipsel64n32",
|
|
specs.ArchPPC: "ppc",
|
|
specs.ArchPPC64: "ppc64",
|
|
specs.ArchPPC64LE: "ppc64le",
|
|
specs.ArchS390: "s390",
|
|
specs.ArchS390X: "s390x",
|
|
}
|
|
specArchToSeccompArchMap = map[specs.Arch]Arch{
|
|
specs.ArchX86: ArchX86,
|
|
specs.ArchX86_64: ArchX86_64,
|
|
specs.ArchX32: ArchX32,
|
|
specs.ArchARM: ArchARM,
|
|
specs.ArchAARCH64: ArchAARCH64,
|
|
specs.ArchMIPS: ArchMIPS,
|
|
specs.ArchMIPS64: ArchMIPS64,
|
|
specs.ArchMIPS64N32: ArchMIPS64N32,
|
|
specs.ArchMIPSEL: ArchMIPSEL,
|
|
specs.ArchMIPSEL64: ArchMIPSEL64,
|
|
specs.ArchMIPSEL64N32: ArchMIPSEL64N32,
|
|
specs.ArchPPC: ArchPPC,
|
|
specs.ArchPPC64: ArchPPC64,
|
|
specs.ArchPPC64LE: ArchPPC64LE,
|
|
specs.ArchS390: ArchS390,
|
|
specs.ArchS390X: ArchS390X,
|
|
}
|
|
specActionToSeccompActionMap = map[specs.LinuxSeccompAction]Action{
|
|
specs.ActKill: ActKill,
|
|
// TODO: wait for this PR to get merged:
|
|
// https://github.com/opencontainers/runtime-spec/pull/1064
|
|
// specs.ActKillProcess ActKillProcess,
|
|
// specs.ActKillThread ActKillThread,
|
|
specs.ActErrno: ActErrno,
|
|
specs.ActTrap: ActTrap,
|
|
specs.ActAllow: ActAllow,
|
|
specs.ActTrace: ActTrace,
|
|
specs.ActLog: ActLog,
|
|
specs.ActNotify: ActNotify,
|
|
}
|
|
specOperatorToSeccompOperatorMap = map[specs.LinuxSeccompOperator]Operator{
|
|
specs.OpNotEqual: OpNotEqual,
|
|
specs.OpLessThan: OpLessThan,
|
|
specs.OpLessEqual: OpLessEqual,
|
|
specs.OpEqualTo: OpEqualTo,
|
|
specs.OpGreaterEqual: OpGreaterEqual,
|
|
specs.OpGreaterThan: OpGreaterThan,
|
|
specs.OpMaskedEqual: OpMaskedEqual,
|
|
}
|
|
)
|
|
|
|
// GoArchToSeccompArch converts a runtime.GOARCH to a seccomp `Arch`. The
|
|
// function returns an error if the architecture conversion is not supported.
|
|
func GoArchToSeccompArch(goArch string) (Arch, error) {
|
|
arch, ok := goArchToSeccompArchMap[goArch]
|
|
if !ok {
|
|
return "", fmt.Errorf("unsupported go arch provided: %s", goArch)
|
|
}
|
|
return arch, nil
|
|
}
|
|
|
|
// specToSeccomp converts a `LinuxSeccomp` spec into a `Seccomp` struct.
|
|
func specToSeccomp(spec *specs.LinuxSeccomp) (*Seccomp, error) {
|
|
res := &Seccomp{
|
|
Syscalls: []*Syscall{},
|
|
}
|
|
|
|
for _, arch := range spec.Architectures {
|
|
newArch, err := specArchToSeccompArch(arch)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("convert spec arch: %w", err)
|
|
}
|
|
res.Architectures = append(res.Architectures, newArch)
|
|
}
|
|
|
|
// Convert default action
|
|
newDefaultAction, err := specActionToSeccompAction(spec.DefaultAction)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("convert default action: %w", err)
|
|
}
|
|
res.DefaultAction = newDefaultAction
|
|
res.DefaultErrnoRet = spec.DefaultErrnoRet
|
|
|
|
// Loop through all syscall blocks and convert them to the internal format
|
|
for _, call := range spec.Syscalls {
|
|
newAction, err := specActionToSeccompAction(call.Action)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("convert action: %w", err)
|
|
}
|
|
|
|
for _, name := range call.Names {
|
|
newCall := Syscall{
|
|
Name: name,
|
|
Action: newAction,
|
|
ErrnoRet: call.ErrnoRet,
|
|
Args: []*Arg{},
|
|
}
|
|
|
|
// Loop through all the arguments of the syscall and convert them
|
|
for _, arg := range call.Args {
|
|
newOp, err := specOperatorToSeccompOperator(arg.Op)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("convert operator: %w", err)
|
|
}
|
|
|
|
newArg := Arg{
|
|
Index: arg.Index,
|
|
Value: arg.Value,
|
|
ValueTwo: arg.ValueTwo,
|
|
Op: newOp,
|
|
}
|
|
|
|
newCall.Args = append(newCall.Args, &newArg)
|
|
}
|
|
res.Syscalls = append(res.Syscalls, &newCall)
|
|
}
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// specArchToLibseccompArch converts a spec arch into a libseccomp one.
|
|
func specArchToLibseccompArch(arch specs.Arch) (string, error) {
|
|
if res, ok := specArchToLibseccompArchMap[arch]; ok {
|
|
return res, nil
|
|
}
|
|
return "", fmt.Errorf(
|
|
"architecture %q is not valid for libseccomp", arch,
|
|
)
|
|
}
|
|
|
|
// specArchToSeccompArch converts a spec arch into an internal one.
|
|
func specArchToSeccompArch(arch specs.Arch) (Arch, error) {
|
|
if res, ok := specArchToSeccompArchMap[arch]; ok {
|
|
return res, nil
|
|
}
|
|
return "", fmt.Errorf("architecture %q is not valid", arch)
|
|
}
|
|
|
|
// specActionToSeccompAction converts a spec action into a seccomp one.
|
|
func specActionToSeccompAction(action specs.LinuxSeccompAction) (Action, error) {
|
|
if res, ok := specActionToSeccompActionMap[action]; ok {
|
|
return res, nil
|
|
}
|
|
return "", fmt.Errorf(
|
|
"spec action %q is not valid internal action", action,
|
|
)
|
|
}
|
|
|
|
// specOperatorToSeccompOperator converts a spec operator into a seccomp one.
|
|
func specOperatorToSeccompOperator(operator specs.LinuxSeccompOperator) (Operator, error) {
|
|
if op, ok := specOperatorToSeccompOperatorMap[operator]; ok {
|
|
return op, nil
|
|
}
|
|
return "", fmt.Errorf(
|
|
"spec operator %q is not a valid internal operator", operator,
|
|
)
|
|
}
|