github.com/opencontainers/runtime-tools@v0.9.0/generate/seccomp/parse_action.go (about) 1 package seccomp 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 rspec "github.com/opencontainers/runtime-spec/specs-go" 9 ) 10 11 // SyscallOpts contain options for parsing syscall rules 12 type SyscallOpts struct { 13 Action string 14 Syscall string 15 Index string 16 Value string 17 ValueTwo string 18 Operator string 19 } 20 21 // ParseSyscallFlag takes a SyscallOpts struct and the seccomp configuration 22 // and sets the new syscall rule accordingly 23 func ParseSyscallFlag(args SyscallOpts, config *rspec.LinuxSeccomp) error { 24 var arguments []string 25 if args.Index != "" && args.Value != "" && args.ValueTwo != "" && args.Operator != "" { 26 arguments = []string{args.Action, args.Syscall, args.Index, args.Value, 27 args.ValueTwo, args.Operator} 28 } else { 29 arguments = []string{args.Action, args.Syscall} 30 } 31 32 action, _ := parseAction(arguments[0]) 33 if action == config.DefaultAction && args.argsAreEmpty() { 34 // default already set, no need to make changes 35 return nil 36 } 37 38 var newSyscall rspec.LinuxSyscall 39 numOfArgs := len(arguments) 40 if numOfArgs == 6 || numOfArgs == 2 { 41 argStruct, err := parseArguments(arguments[1:]) 42 if err != nil { 43 return err 44 } 45 newSyscall = newSyscallStruct(arguments[1], action, argStruct) 46 } else { 47 return fmt.Errorf("incorrect number of arguments to ParseSyscall: %d", numOfArgs) 48 } 49 50 descison, err := decideCourseOfAction(&newSyscall, config.Syscalls) 51 if err != nil { 52 return err 53 } 54 delimDescison := strings.Split(descison, ":") 55 56 if delimDescison[0] == seccompAppend { 57 config.Syscalls = append(config.Syscalls, newSyscall) 58 } 59 60 if delimDescison[0] == seccompOverwrite { 61 indexForOverwrite, err := strconv.ParseInt(delimDescison[1], 10, 32) 62 if err != nil { 63 return err 64 } 65 config.Syscalls[indexForOverwrite] = newSyscall 66 } 67 68 return nil 69 } 70 71 var actions = map[string]rspec.LinuxSeccompAction{ 72 "allow": rspec.ActAllow, 73 "errno": rspec.ActErrno, 74 "kill": rspec.ActKill, 75 "trace": rspec.ActTrace, 76 "trap": rspec.ActTrap, 77 } 78 79 // Take passed action, return the SCMP_ACT_<ACTION> version of it 80 func parseAction(action string) (rspec.LinuxSeccompAction, error) { 81 a, ok := actions[action] 82 if !ok { 83 return "", fmt.Errorf("unrecognized action: %s", action) 84 } 85 return a, nil 86 } 87 88 // ParseDefaultAction sets the default action of the seccomp configuration 89 // and then removes any rules that were already specified with this action 90 func ParseDefaultAction(action string, config *rspec.LinuxSeccomp) error { 91 if action == "" { 92 return nil 93 } 94 95 defaultAction, err := parseAction(action) 96 if err != nil { 97 return err 98 } 99 config.DefaultAction = defaultAction 100 err = RemoveAllMatchingRules(config, defaultAction) 101 if err != nil { 102 return err 103 } 104 return nil 105 } 106 107 // ParseDefaultActionForce simply sets the default action of the seccomp configuration 108 func ParseDefaultActionForce(action string, config *rspec.LinuxSeccomp) error { 109 if action == "" { 110 return nil 111 } 112 113 defaultAction, err := parseAction(action) 114 if err != nil { 115 return err 116 } 117 config.DefaultAction = defaultAction 118 return nil 119 } 120 121 func newSyscallStruct(name string, action rspec.LinuxSeccompAction, args []rspec.LinuxSeccompArg) rspec.LinuxSyscall { 122 syscallStruct := rspec.LinuxSyscall{ 123 Names: []string{name}, 124 Action: action, 125 Args: args, 126 } 127 return syscallStruct 128 } 129 130 func (s SyscallOpts) argsAreEmpty() bool { 131 return (s.Index == "" && 132 s.Value == "" && 133 s.ValueTwo == "" && 134 s.Operator == "") 135 }