6c9628cdb1
* Rename 'vendor/src' -> 'vendor' * Ignore vendor/ instead of vendor/src/ for lint * Rename 'cmd/client' -> 'cmd/ocic' to make it 'go install'able * Rename 'cmd/server' -> 'cmd/ocid' to make it 'go install'able * Update Makefile to build and install from GOPATH * Update tests to locate ocid/ocic in GOPATH/bin * Search for binaries in GOPATH/bin instead of PATH * Install tools using `go get -u`, so they are updated on each run Signed-off-by: Jonathan Yu <jawnsy@redhat.com>
140 lines
4 KiB
Go
140 lines
4 KiB
Go
package seccomp
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strconv"
|
|
"strings"
|
|
|
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
|
)
|
|
|
|
// Determine if a new syscall rule should be appended, overwrite an existing rule
|
|
// or if no action should be taken at all
|
|
func decideCourseOfAction(newSyscall *rspec.Syscall, syscalls []rspec.Syscall) (string, error) {
|
|
ruleForSyscallAlreadyExists := false
|
|
|
|
var sliceOfDeterminedActions []string
|
|
for i, syscall := range syscalls {
|
|
if syscall.Name == newSyscall.Name {
|
|
ruleForSyscallAlreadyExists = true
|
|
|
|
if identical(newSyscall, &syscall) {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, nothing)
|
|
}
|
|
|
|
if sameAction(newSyscall, &syscall) {
|
|
if bothHaveArgs(newSyscall, &syscall) {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend)
|
|
}
|
|
if onlyOneHasArgs(newSyscall, &syscall) {
|
|
if firstParamOnlyHasArgs(newSyscall, &syscall) {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i))
|
|
} else {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, nothing)
|
|
}
|
|
}
|
|
}
|
|
|
|
if !sameAction(newSyscall, &syscall) {
|
|
if bothHaveArgs(newSyscall, &syscall) {
|
|
if sameArgs(newSyscall, &syscall) {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i))
|
|
}
|
|
if !sameArgs(newSyscall, &syscall) {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend)
|
|
}
|
|
}
|
|
if onlyOneHasArgs(newSyscall, &syscall) {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend)
|
|
}
|
|
if neitherHasArgs(newSyscall, &syscall) {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if !ruleForSyscallAlreadyExists {
|
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend)
|
|
}
|
|
|
|
// Nothing has highest priority
|
|
for _, determinedAction := range sliceOfDeterminedActions {
|
|
if determinedAction == nothing {
|
|
return determinedAction, nil
|
|
}
|
|
}
|
|
|
|
// Overwrite has second highest priority
|
|
for _, determinedAction := range sliceOfDeterminedActions {
|
|
if strings.Contains(determinedAction, seccompOverwrite) {
|
|
return determinedAction, nil
|
|
}
|
|
}
|
|
|
|
// Append has the lowest priority
|
|
for _, determinedAction := range sliceOfDeterminedActions {
|
|
if determinedAction == seccompAppend {
|
|
return determinedAction, nil
|
|
}
|
|
}
|
|
|
|
return "", fmt.Errorf("Trouble determining action: %s", sliceOfDeterminedActions)
|
|
}
|
|
|
|
func hasArguments(config *rspec.Syscall) bool {
|
|
nilSyscall := new(rspec.Syscall)
|
|
return !sameArgs(nilSyscall, config)
|
|
}
|
|
|
|
func identical(config1, config2 *rspec.Syscall) bool {
|
|
return reflect.DeepEqual(config1, config2)
|
|
}
|
|
|
|
func identicalExceptAction(config1, config2 *rspec.Syscall) bool {
|
|
samename := sameName(config1, config2)
|
|
sameAction := sameAction(config1, config2)
|
|
sameArgs := sameArgs(config1, config2)
|
|
|
|
return samename && !sameAction && sameArgs
|
|
}
|
|
|
|
func identicalExceptArgs(config1, config2 *rspec.Syscall) bool {
|
|
samename := sameName(config1, config2)
|
|
sameAction := sameAction(config1, config2)
|
|
sameArgs := sameArgs(config1, config2)
|
|
|
|
return samename && sameAction && !sameArgs
|
|
}
|
|
|
|
func sameName(config1, config2 *rspec.Syscall) bool {
|
|
return config1.Name == config2.Name
|
|
}
|
|
|
|
func sameAction(config1, config2 *rspec.Syscall) bool {
|
|
return config1.Action == config2.Action
|
|
}
|
|
|
|
func sameArgs(config1, config2 *rspec.Syscall) bool {
|
|
return reflect.DeepEqual(config1.Args, config2.Args)
|
|
}
|
|
|
|
func bothHaveArgs(config1, config2 *rspec.Syscall) bool {
|
|
return hasArguments(config1) && hasArguments(config2)
|
|
}
|
|
|
|
func onlyOneHasArgs(config1, config2 *rspec.Syscall) bool {
|
|
conf1 := hasArguments(config1)
|
|
conf2 := hasArguments(config2)
|
|
|
|
return (conf1 && !conf2) || (!conf1 && conf2)
|
|
}
|
|
|
|
func neitherHasArgs(config1, config2 *rspec.Syscall) bool {
|
|
return !hasArguments(config1) && !hasArguments(config2)
|
|
}
|
|
|
|
func firstParamOnlyHasArgs(config1, config2 *rspec.Syscall) bool {
|
|
return !hasArguments(config1) && hasArguments(config2)
|
|
}
|