def parse_action(self, tokens): if not tokens: self._parser_state.error('missing action') action_token = tokens.pop(0) if action_token.type == 'ACTION': if action_token.value == 'allow': return bpf.Allow() if action_token.value == 'kill': return self._kill_action if action_token.value == 'kill-process': return bpf.KillProcess() if action_token.value == 'kill-thread': return bpf.KillThread() if action_token.value == 'trap': return bpf.Trap() if action_token.value == 'trace': return bpf.Trace() if action_token.value == 'log': return bpf.Log() elif action_token.type == 'NUMERIC_CONSTANT': constant = self._parse_single_constant(action_token) if constant == 1: return bpf.Allow() elif action_token.type == 'RETURN': if not tokens: self._parser_state.error('missing return value') return bpf.ReturnErrno(self._parse_single_constant(tokens.pop(0))) return self._parser_state.error('invalid action', token=action_token)
def test_parse_filter(self): """Accept valid filters.""" self.assertEqual( self.parser.parse_filter(self._tokenize('arg0 == 0')), [ parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('kill-process')), [ parser.Filter(None, bpf.KillProcess()), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('kill-thread')), [ parser.Filter(None, bpf.KillThread()), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('trap')), [ parser.Filter(None, bpf.Trap()), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('return ENOSYS')), [ parser.Filter(None, bpf.ReturnErrno(self.arch.constants['ENOSYS'])), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('trace')), [ parser.Filter(None, bpf.Trace()), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('user-notify')), [ parser.Filter(None, bpf.UserNotify()), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('log')), [ parser.Filter(None, bpf.Log()), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('allow')), [ parser.Filter(None, bpf.Allow()), ]) self.assertEqual( self.parser.parse_filter(self._tokenize('1')), [ parser.Filter(None, bpf.Allow()), ]) self.assertEqual( self.parser.parse_filter( self._tokenize( '{ arg0 == 0, arg0 == 1; return ENOSYS, trap }')), [ parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()), parser.Filter([[parser.Atom(0, '==', 1)]], bpf.ReturnErrno(self.arch.constants['ENOSYS'])), parser.Filter(None, bpf.Trap()), ])
def parse_action(self, tokens): if not tokens: self._parser_state.error('missing action') action_token = tokens.pop(0) # denylist policies must specify a return for every line. if self._denylist: if action_token.type != 'RETURN': self._parser_state.error('invalid denylist policy') if action_token.type == 'ACTION': if action_token.value == 'allow': return bpf.Allow() if action_token.value == 'kill': return self._kill_action if action_token.value == 'kill-process': return bpf.KillProcess() if action_token.value == 'kill-thread': return bpf.KillThread() if action_token.value == 'trap': return bpf.Trap() if action_token.value == 'trace': return bpf.Trace() if action_token.value == 'user-notify': return bpf.UserNotify() if action_token.value == 'log': return bpf.Log() elif action_token.type == 'NUMERIC_CONSTANT': constant = self._parse_single_constant(action_token) if constant == 1: return bpf.Allow() elif action_token.type == 'RETURN': if not tokens: self._parser_state.error('missing return value') if self._ret_log: tokens.pop(0) return bpf.Log() else: return bpf.ReturnErrno( self._parse_single_constant(tokens.pop(0))) return self._parser_state.error('invalid action', token=action_token)