Skip to content

Commit d6bdced

Browse files
committed
wip
1 parent 7d57166 commit d6bdced

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2653
-99
lines changed

internal/bootstrap/bootstrap.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/rabbitstack/fibratus/pkg/handle"
3131
"github.com/rabbitstack/fibratus/pkg/kcap"
3232
"github.com/rabbitstack/fibratus/pkg/ps"
33+
"github.com/rabbitstack/fibratus/pkg/rules"
3334
"github.com/rabbitstack/fibratus/pkg/symbolize"
3435
"github.com/rabbitstack/fibratus/pkg/sys"
3536
"github.com/rabbitstack/fibratus/pkg/util/multierror"
@@ -52,7 +53,7 @@ type App struct {
5253
config *config.Config
5354
evs *EventSourceControl
5455
symbolizer *symbolize.Symbolizer
55-
rules *filter.Rules
56+
engine *rules.Engine
5657
hsnap handle.Snapshotter
5758
psnap ps.Snapshotter
5859
filament filament.Filament
@@ -134,34 +135,34 @@ func NewApp(cfg *config.Config, options ...Option) (*App, error) {
134135
hsnap := handle.NewSnapshotter(cfg, opts.handleSnapshotFn)
135136
psnap := ps.NewSnapshotter(hsnap, cfg)
136137

137-
var (
138-
rules *filter.Rules
139-
res *config.RulesCompileResult
140-
)
138+
var engine *rules.Engine
139+
var rs *config.RulesCompileResult
140+
141141
if cfg.Filters.Rules.Enabled && !cfg.ForwardMode && !cfg.IsCaptureSet() {
142-
rules = filter.NewRules(psnap, cfg)
142+
engine = rules.NewEngine(psnap, cfg)
143143
var err error
144-
res, err = rules.Compile()
144+
rs, err = engine.Compile()
145145
if err != nil {
146146
return nil, err
147147
}
148-
if res != nil {
149-
log.Infof("rules compile summary: %s", res)
148+
if rs != nil {
149+
log.Infof("rules compile summary: %s", rs)
150150
}
151151
} else {
152152
log.Info("rule engine is disabled")
153153
}
154154

155-
evs := NewEventSourceControl(psnap, hsnap, cfg, res)
155+
evs := NewEventSourceControl(psnap, hsnap, cfg, rs)
156156

157157
app := &App{
158158
config: cfg,
159159
evs: evs,
160-
rules: rules,
160+
engine: engine,
161161
hsnap: hsnap,
162162
psnap: psnap,
163163
signals: sigs,
164164
}
165+
165166
return app, nil
166167
}
167168

@@ -234,8 +235,8 @@ func (f *App) Run(args []string) error {
234235
f.evs.RegisterEventListener(f.symbolizer)
235236
}
236237
// register rule engine
237-
if f.rules != nil {
238-
f.evs.RegisterEventListener(f.rules)
238+
if f.engine != nil {
239+
f.evs.RegisterEventListener(f.engine)
239240
}
240241
// register YARA scanner
241242
if cfg.Yara.Enabled {

pkg/filter/_fixtures/sequence_rule_bound_fields.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

pkg/filter/_fixtures/sequence_rule_bound_fields_with_functions.yml

Lines changed: 0 additions & 26 deletions
This file was deleted.

pkg/filter/filter.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ type Filter interface {
5353
// RunSequence runs a filter with sequence expressions. Sequence rules depend
5454
// on the state machine transitions and partial matches to decide whether the
5555
// rule is fired.
56-
RunSequence(evt *kevent.Kevent, seqID uint16, partials map[uint16][]*kevent.Kevent, rawMatch bool) bool
56+
RunSequence(evt *kevent.Kevent, seqID int, partials map[int][]*kevent.Kevent, rawMatch bool) bool
5757
// GetStringFields returns field names mapped to their string values.
5858
GetStringFields() map[fields.Field][]string
5959
// GetFields returns all fields used in the filter expression.
@@ -87,7 +87,7 @@ type filter struct {
8787
segments []fields.Segment
8888
boundFields []*ql.BoundFieldLiteral
8989
// seqBoundFields contains per-sequence bound fields resolved from bound field literals
90-
seqBoundFields map[uint16][]BoundField
90+
seqBoundFields map[int][]BoundField
9191
// stringFields contains filter field names mapped to their string values
9292
stringFields map[fields.Field][]string
9393
hasFunctions bool
@@ -182,22 +182,22 @@ func (f *filter) Compile() error {
182182
return f.checkBoundRefs()
183183
}
184184

185-
func (f *filter) Run(kevt *kevent.Kevent) bool {
185+
func (f *filter) Run(e *kevent.Kevent) bool {
186186
if f.expr == nil {
187187
return false
188188
}
189-
return ql.Eval(f.expr, f.mapValuer(kevt), f.hasFunctions)
189+
return ql.Eval(f.expr, f.mapValuer(e), f.hasFunctions)
190190
}
191191

192-
func (f *filter) RunSequence(kevt *kevent.Kevent, seqID uint16, partials map[uint16][]*kevent.Kevent, rawMatch bool) bool {
192+
func (f *filter) RunSequence(e *kevent.Kevent, seqID int, partials map[int][]*kevent.Kevent, rawMatch bool) bool {
193193
if f.seq == nil {
194194
return false
195195
}
196-
nseqs := uint16(len(f.seq.Expressions))
196+
nseqs := len(f.seq.Expressions)
197197
if seqID > nseqs-1 {
198198
return false
199199
}
200-
valuer := f.mapValuer(kevt)
200+
valuer := f.mapValuer(e)
201201
expr := f.seq.Expressions[seqID]
202202

203203
if rawMatch {
@@ -213,12 +213,12 @@ func (f *filter) RunSequence(kevt *kevent.Kevent, seqID uint16, partials map[uin
213213
// aliases
214214
p := make(map[string][]*kevent.Kevent)
215215
nslots := len(partials[seqID])
216-
for i := uint16(0); i < seqID; i++ {
216+
for i := 0; i < seqID; i++ {
217217
alias := f.seq.Expressions[i].Alias
218218
if alias == "" {
219219
continue
220220
}
221-
p[alias] = partials[i+1]
221+
p[alias] = partials[i]
222222
if len(p[alias]) > nslots {
223223
nslots = len(p[alias])
224224
}
@@ -292,8 +292,8 @@ func (f *filter) RunSequence(kevt *kevent.Kevent, seqID uint16, partials map[uin
292292
match = ql.Eval(expr.Expr, valuer, f.hasFunctions)
293293
if match {
294294
// compute sequence key hash to tie the events
295-
evt.AddMeta(kevent.RuleSequenceByKey, hashers.FnvUint64(hash))
296-
kevt.AddMeta(kevent.RuleSequenceByKey, hashers.FnvUint64(hash))
295+
evt.AddMeta(kevent.RuleSequenceLink, hashers.FnvUint64(hash))
296+
e.AddMeta(kevent.RuleSequenceLink, hashers.FnvUint64(hash))
297297
break
298298
}
299299
}
@@ -308,9 +308,9 @@ func (f *filter) RunSequence(kevt *kevent.Kevent, seqID uint16, partials map[uin
308308
joins := make([]bool, seqID)
309309
joinID := valuer[by.Value]
310310
outer:
311-
for i := uint16(0); i < seqID; i++ {
312-
for _, p := range partials[i+1] {
313-
if compareSeqJoin(joinID, p.SequenceBy()) {
311+
for i := 0; i < seqID; i++ {
312+
for _, p := range partials[i] {
313+
if CompareSeqLink(joinID, p.SequenceLink()) {
314314
joins[i] = true
315315
continue outer
316316
}
@@ -323,7 +323,7 @@ func (f *filter) RunSequence(kevt *kevent.Kevent, seqID uint16, partials map[uin
323323

324324
if match && by != nil {
325325
if v := valuer[by.Value]; v != nil {
326-
kevt.AddMeta(kevent.RuleSequenceByKey, v)
326+
e.AddMeta(kevent.RuleSequenceLink, v)
327327
}
328328
}
329329
}
@@ -456,7 +456,7 @@ func (f *filter) addSegment(segment *ql.BoundSegmentLiteral) {
456456
// addSeqBoundFields receives the sequence id and the list of bound field literals
457457
// and populates the list of bound fields containing the field structure convenient
458458
// for accessors.
459-
func (f *filter) addSeqBoundFields(seqID uint16, fields []*ql.BoundFieldLiteral) []BoundField {
459+
func (f *filter) addSeqBoundFields(seqID int, fields []*ql.BoundFieldLiteral) []BoundField {
460460
flds := make([]BoundField, 0, len(fields))
461461
for _, field := range fields {
462462
flds = append(flds,
@@ -497,9 +497,9 @@ func (f *filter) checkBoundRefs() error {
497497
return nil
498498
}
499499

500-
// compareSeqJoin returns true if both values
500+
// CompareSeqLink returns true if both values
501501
// representing the sequence joins are equal.
502-
func compareSeqJoin(s1, s2 any) bool {
502+
func CompareSeqLink(s1, s2 any) bool {
503503
if s1 == nil || s2 == nil {
504504
return false
505505
}

pkg/filter/filter_windows.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func New(expr string, config *config.Config, options ...Option) Filter {
9999
segments: make([]fields.Segment, 0),
100100
stringFields: make(map[fields.Field][]string),
101101
boundFields: make([]*ql.BoundFieldLiteral, 0),
102-
seqBoundFields: make(map[uint16][]BoundField),
102+
seqBoundFields: make(map[int][]BoundField),
103103
}
104104
}
105105

@@ -129,7 +129,7 @@ func NewFromCLIWithAllAccessors(args []string) (Filter, error) {
129129
segments: make([]fields.Segment, 0),
130130
stringFields: make(map[fields.Field][]string),
131131
boundFields: make([]*ql.BoundFieldLiteral, 0),
132-
seqBoundFields: make(map[uint16][]BoundField),
132+
seqBoundFields: make(map[int][]BoundField),
133133
}
134134
if err := filter.Compile(); err != nil {
135135
return nil, fmt.Errorf("bad filter:\n %v", err)

pkg/filter/rules.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ const (
4747
)
4848

4949
var (
50-
filterMatches = expvar.NewMap("filter.matches")
51-
filtersCount = expvar.NewInt("filter.filters.count")
50+
filterMatches = expvar.NewMap("filter.matches1")
51+
filtersCount = expvar.NewInt("filter.filters.count1")
5252

53-
matchTransitionErrors = expvar.NewInt("sequence.match.transition.errors")
54-
partialsPerSequence = expvar.NewMap("sequence.partials.count")
55-
partialExpirations = expvar.NewMap("sequence.partial.expirations")
56-
partialBreaches = expvar.NewMap("sequence.partial.breaches")
53+
matchTransitionErrors = expvar.NewInt("sequence.match.transition.errors1")
54+
partialsPerSequence = expvar.NewMap("sequence.partials.count1")
55+
partialExpirations = expvar.NewMap("sequence.partial.expirations1")
56+
partialBreaches = expvar.NewMap("sequence.partial.breaches1")
5757

5858
ErrInvalidFilter = func(rule string, err error) error {
5959
return fmt.Errorf("syntax error in rule %q: \n%v", rule, err)
@@ -283,8 +283,8 @@ func (s *sequenceState) addPartial(rule string, kevt *kevent.Kevent, outOfOrder
283283
}
284284
}
285285
if outOfOrder {
286-
kevt.AddMeta(kevent.RuleExpressionKey, rule)
287-
kevt.AddMeta(kevent.RuleSequenceOutOfOrderKey, true)
286+
kevt.AddMeta(kevent.RuleSequenceID, rule)
287+
kevt.AddMeta(kevent.RuleSequenceOOOKey, true)
288288
}
289289
log.Debugf("adding partial to slot [%d] for rule %q: %s", i, rule, kevt)
290290
partialsPerSequence.Add(s.name, 1)
@@ -464,7 +464,7 @@ func (f compiledFilter) run(kevt *kevent.Kevent, i int, rawMatch, lock bool) boo
464464
f.ss.mu.RLock()
465465
defer f.ss.mu.RUnlock()
466466
}
467-
return f.filter.RunSequence(kevt, uint16(i), f.ss.partials, rawMatch)
467+
return f.filter.RunSequence(kevt, i, nil, rawMatch)
468468
}
469469
return f.filter.Run(kevt)
470470
}
@@ -790,7 +790,7 @@ func (r *Rules) runSequence(kevt *kevent.Kevent, f *compiledFilter) bool {
790790
for i := uint16(1); i < nseqs+1; i++ {
791791
for _, outer := range f.ss.partials[i] {
792792
for _, inner := range f.ss.partials[i+1] {
793-
if compareSeqJoin(outer.SequenceBy(), inner.SequenceBy()) {
793+
if CompareSeqLink(outer.SequenceLink(), inner.SequenceLink()) {
794794
setMatch(i, outer)
795795
setMatch(i+1, inner)
796796
}
@@ -806,19 +806,19 @@ func (r *Rules) matchUnorderedPartials(f *compiledFilter) {
806806
defer f.ss.mu.Unlock()
807807
for n, partials := range f.ss.partials {
808808
for _, partial := range partials {
809-
if !partial.ContainsMeta(kevent.RuleSequenceOutOfOrderKey) {
809+
if !partial.ContainsMeta(kevent.RuleSequenceOOOKey) {
810810
continue
811811
}
812812
matches := f.run(partial, int(n)-1, false, false)
813-
rule := partial.GetMetaAsString(kevent.RuleExpressionKey)
813+
rule := partial.GetMetaAsString(kevent.RuleSequenceID)
814814
// transition the state machine
815815
if matches {
816816
err := f.ss.matchTransition(rule, partial)
817817
if err != nil {
818818
matchTransitionErrors.Add(1)
819819
log.Warnf("out of order match transition failure: %v", err)
820820
}
821-
partial.RemoveMeta(kevent.RuleSequenceOutOfOrderKey)
821+
partial.RemoveMeta(kevent.RuleSequenceOOOKey)
822822
}
823823
}
824824
}

pkg/filter/rules_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ func TestSequenceOutOfOrder(t *testing.T) {
793793

794794
require.False(t, wrapProcessEvent(e2, rules.ProcessEvent))
795795
assert.Len(t, ss.partials[2], 1)
796-
assert.True(t, ss.partials[2][0].ContainsMeta(kevent.RuleSequenceOutOfOrderKey))
796+
assert.True(t, ss.partials[2][0].ContainsMeta(kevent.RuleSequenceOOOKey))
797797

798798
require.True(t, wrapProcessEvent(e1, rules.ProcessEvent))
799799
}

pkg/kevent/kevent.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,13 @@ const (
4444
YaraMatchesKey MetadataKey = "yara.matches"
4545
// RuleNameKey identifies the rule that was triggered by the event
4646
RuleNameKey MetadataKey = "rule.name"
47-
// RuleGroupKey identifies the group to which the triggered rule pertains
48-
RuleGroupKey MetadataKey = "rule.group"
49-
// RuleSequenceByKey represents the join field value in sequence rules
50-
RuleSequenceByKey MetadataKey = "rule.seq.by"
51-
// RuleExpressionKey represents the rule filter expression
52-
RuleExpressionKey MetadataKey = "rule.expr"
53-
// RuleSequenceOutOfOrderKey the presence of this metadata key indicates the
47+
// RuleSequenceLink represents the join link value in sequence rules
48+
RuleSequenceLink MetadataKey = "rule.seq.link"
49+
// RuleSequenceID represents the sequence id tied to the expression
50+
RuleSequenceID MetadataKey = "rule.seq.id"
51+
// RuleSequenceOOOKey the presence of this metadata key indicates the
5452
// event in the partials list arrived out of order and requires reevaluation
55-
RuleSequenceOutOfOrderKey MetadataKey = "rule.seq.outoforder"
53+
RuleSequenceOOOKey MetadataKey = "rule.seq.ooo"
5654
)
5755

5856
func (key MetadataKey) String() string { return string(key) }
@@ -267,6 +265,18 @@ func (e *Kevent) GetMetaAsString(k MetadataKey) string {
267265
return ""
268266
}
269267

268+
// GetMetaAsInt returns the metadata as integer value.
269+
func (e *Kevent) GetMetaAsInt(k MetadataKey) int {
270+
e.mmux.RLock()
271+
defer e.mmux.RUnlock()
272+
if v, ok := e.Metadata[k]; ok {
273+
if n, ok := v.(int); ok {
274+
return n
275+
}
276+
}
277+
return 0
278+
}
279+
270280
// ContainsMeta returns true if the metadata contains the specified key.
271281
func (e *Kevent) ContainsMeta(k MetadataKey) bool {
272282
e.mmux.RLock()
@@ -308,9 +318,9 @@ func (e *Kevent) GetFlagsAsSlice(name string) []string {
308318
return strings.Split(e.GetParamAsString(name), "|")
309319
}
310320

311-
// SequenceBy returns the BY statement join field from event metadata.
312-
func (e *Kevent) SequenceBy() any {
321+
// SequenceLink returns the sequence link value from event metadata.
322+
func (e *Kevent) SequenceLink() any {
313323
e.mmux.RLock()
314324
defer e.mmux.RUnlock()
315-
return e.Metadata[RuleSequenceByKey]
325+
return e.Metadata[RuleSequenceLink]
316326
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)