Skip to content

Commit

Permalink
chore: tidy up policy manager and related code
Browse files Browse the repository at this point in the history
- Remove Snapshot() use. In the future it could be managed by the policy
  manager itself.
- After PolicyManager initialization (first stages), Policies are not
  accessed directly anymore, but through the PolicyManager.
- t.config.Policies is now only transient and used for PolicyManager
  initialization.
- Policy version is deprecated and to be removed soon.
  • Loading branch information
geyslan committed Jul 2, 2024
1 parent 77d6758 commit dba1a42
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 86 deletions.
1 change: 0 additions & 1 deletion pkg/cmd/cobra/cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ func GetTraceeRunner(c *cobra.Command, version string) (cmd.Runner, error) {
}

cfg.Policies = policies
policy.Snapshots().Store(cfg.Policies)

// Output command line flags

Expand Down
2 changes: 0 additions & 2 deletions pkg/cmd/urfave/urfave.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/aquasecurity/tracee/pkg/config"
"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/pkg/policy"
"github.com/aquasecurity/tracee/pkg/utils/environment"
)

Expand Down Expand Up @@ -126,7 +125,6 @@ func GetTraceeRunner(c *cli.Context, version string) (cmd.Runner, error) {
return runner, err
}
cfg.Policies = policies
policy.Snapshots().Store(cfg.Policies)

broadcast, err := printer.NewBroadcast(
output.PrinterConfigs,
Expand Down
26 changes: 4 additions & 22 deletions pkg/ebpf/events_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/pkg/policy"
"github.com/aquasecurity/tracee/pkg/utils"
"github.com/aquasecurity/tracee/types/trace"
)
Expand Down Expand Up @@ -296,20 +295,14 @@ func (t *Tracee) matchPolicies(event *trace.Event) uint64 {
eventID := events.ID(event.EventID)
bitmap := event.MatchedPoliciesKernel

policies, err := policy.Snapshots().Get(event.PoliciesVersion)
if err != nil {
t.handleError(err)
return 0
}

// Short circuit if there are no policies in userland that need filtering.
if bitmap&policies.FilterableInUserland() == 0 {
if !t.policyManager.FilterableInUserland(bitmap) {
event.MatchedPoliciesUser = bitmap // store untouched bitmap to be used in sink stage
return bitmap
}

// range through each userland filterable policy
for it := policies.CreateUserlandIterator(); it.HasNext(); {
for it := t.policyManager.CreateUserlandIterator(); it.HasNext(); {
p := it.Next()
// Policy ID is the bit offset in the bitmap.
bitOffset := uint(p.ID)
Expand Down Expand Up @@ -465,14 +458,8 @@ func (t *Tracee) processEvents(ctx context.Context, in <-chan *trace.Event) (
continue
}

policies, err := policy.Snapshots().Get(event.PoliciesVersion)
if err != nil {
t.handleError(err)
continue
}

// Get a bitmap with all policies containing container filters
policiesWithContainerFilter := policies.WithContainerFilterEnabled()
policiesWithContainerFilter := t.policyManager.WithContainerFilterEnabled()

// Filter out events that don't have a container ID from all the policies that
// have container filters. This will guarantee that any of those policies
Expand Down Expand Up @@ -616,13 +603,8 @@ func (t *Tracee) sinkEvents(ctx context.Context, in <-chan *trace.Event) <-chan
continue
}

policies, err := policy.Snapshots().Get(event.PoliciesVersion)
if err != nil {
t.handleError(err)
continue
}
// Populate the event with the names of the matched policies.
event.MatchedPolicies = policies.MatchedNames(event.MatchedPoliciesUser)
event.MatchedPolicies = t.policyManager.MatchedNames(event.MatchedPoliciesUser)

// Parse args here if the rule engine is not enabled (parsed there if it is).
if !t.config.EngineConfig.Enabled {
Expand Down
64 changes: 28 additions & 36 deletions pkg/ebpf/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,6 @@ func New(cfg config.Config) (*Tracee, error) {
return nil, errfmt.Errorf("validation error: %v", err)
}

policyManager := policy.NewPolicyManager()

// Create Tracee

t := &Tracee{
Expand All @@ -236,10 +234,15 @@ func New(cfg config.Config) (*Tracee, error) {
eventsState: make(map[events.ID]events.EventState),
eventSignatures: make(map[events.ID]bool),
streamsManager: streams.NewStreamsManager(),
policyManager: policyManager,
policyManager: policy.NewPolicyManager(cfg.Policies),
requiredKsyms: []string{},
}

// In the future Tracee Config will be changed in runtime, and will demand a proper
// object to manage it. config.Config is currently a transient object that should be
// used only to create the Tracee instance.
t.config.Policies = nil // policies must be managed by the policy manager

eventsDependencies := dependencies.NewDependenciesManager(
func(id events.ID) events.Dependencies {
return events.Core.GetDefinitionByID(id).GetDependencies()
Expand Down Expand Up @@ -328,7 +331,7 @@ func New(cfg config.Config) (*Tracee, error) {

// TODO: extract this to a function to be called from here and from
// policies changes.
for it := t.config.Policies.CreateAllIterator(); it.HasNext(); {
for it := t.policyManager.CreateAllIterator(); it.HasNext(); {
p := it.Next()
for e := range p.EventsToTrace {
var submit, emit uint64
Expand All @@ -340,7 +343,7 @@ func New(cfg config.Config) (*Tracee, error) {
utils.SetBit(&emit, uint(p.ID))
t.selectEvent(e, events.EventState{Submit: submit, Emit: emit})

policyManager.EnableRule(p.ID, e)
t.policyManager.EnableRule(p.ID, e)
}
}

Expand Down Expand Up @@ -675,7 +678,7 @@ func (t *Tracee) initDerivationTable() error {
shouldSubmit := func(id events.ID) func() bool {
return func() bool { return t.eventsState[id].Submit > 0 }
}
symbolsCollisions := derive.SymbolsCollision(t.contSymbolsLoader, t.config.Policies)
symbolsCollisions := derive.SymbolsCollision(t.contSymbolsLoader, t.policyManager)

executeFailedGen, err := derive.InitProcessExecuteFailedGenerator()
if err != nil {
Expand Down Expand Up @@ -719,7 +722,7 @@ func (t *Tracee) initDerivationTable() error {
Enabled: shouldSubmit(events.SymbolsLoaded),
DeriveFunction: derive.SymbolsLoaded(
t.contSymbolsLoader,
t.config.Policies,
t.policyManager,
),
},
events.SymbolsCollision: {
Expand Down Expand Up @@ -895,12 +898,12 @@ func (t *Tracee) getOptionsConfig() uint32 {

// newConfig returns a new Config instance based on the current Tracee state and
// the given policies config and version.
func (t *Tracee) newConfig(cfg *policy.PoliciesConfig, version uint16) *Config {
func (t *Tracee) newConfig(cfg *policy.PoliciesConfig) *Config {
return &Config{
TraceePid: uint32(os.Getpid()),
Options: t.getOptionsConfig(),
CgroupV1Hid: uint32(t.cgroups.GetDefaultCgroupHierarchyID()),
PoliciesVersion: version,
PoliciesVersion: 1, // version will be removed soon
PoliciesConfig: *cfg,
}
}
Expand Down Expand Up @@ -963,7 +966,7 @@ func (t *Tracee) initKsymTableRequiredSyms() error {
}
}
if _, ok := t.eventsState[events.PrintMemDump]; ok {
for it := t.config.Policies.CreateAllIterator(); it.HasNext(); {
for it := t.policyManager.CreateAllIterator(); it.HasNext(); {
p := it.Next()
// This might break in the future if PrintMemDump will become a dependency of another event.
_, isChosen := p.EventsToTrace[events.PrintMemDump]
Expand Down Expand Up @@ -1145,7 +1148,7 @@ func (t *Tracee) populateBPFMaps() error {
}

// Initialize config and filter maps
err = t.populateFilterMaps(t.config.Policies, false)
err = t.populateFilterMaps(false)
if err != nil {
return errfmt.WrapError(err)
}
Expand Down Expand Up @@ -1217,8 +1220,8 @@ func (t *Tracee) populateBPFMaps() error {
}

// populateFilterMaps populates the eBPF maps with the given policies
func (t *Tracee) populateFilterMaps(newPolicies *policy.Policies, updateProcTree bool) error {
polCfg, err := newPolicies.UpdateBPF(
func (t *Tracee) populateFilterMaps(updateProcTree bool) error {
polCfg, err := t.policyManager.UpdateBPF(
t.bpfModule,
t.containers,
t.eventsState,
Expand All @@ -1232,7 +1235,7 @@ func (t *Tracee) populateFilterMaps(newPolicies *policy.Policies, updateProcTree

// Create new config with updated policies and update eBPF map

cfg := t.newConfig(polCfg, newPolicies.Version())
cfg := t.newConfig(polCfg)
if err := cfg.UpdateBPF(t.bpfModule); err != nil {
return errfmt.WrapError(err)
}
Expand Down Expand Up @@ -1382,7 +1385,7 @@ func (t *Tracee) initBPF() error {
}

// returned PoliciesConfig is not used here, therefore it's discarded
_, err = t.config.Policies.UpdateBPF(t.bpfModule, t.containers, t.eventsState, t.eventsParamTypes, false, true)
_, err = t.policyManager.UpdateBPF(t.bpfModule, t.containers, t.eventsState, t.eventsParamTypes, false, true)
if err != nil {
return errfmt.WrapError(err)
}
Expand Down Expand Up @@ -1715,11 +1718,11 @@ func (t *Tracee) getSelfLoadedPrograms(kprobesOnly bool) map[string]int {
func (t *Tracee) invokeInitEvents(out chan *trace.Event) {
var matchedPolicies uint64

setMatchedPolicies := func(event *trace.Event, matchedPolicies uint64, pols *policy.Policies) {
event.PoliciesVersion = pols.Version()
setMatchedPolicies := func(event *trace.Event, matchedPolicies uint64, pManager *policy.PolicyManager) {
event.PoliciesVersion = 1 // version will be removed soon
event.MatchedPoliciesKernel = matchedPolicies
event.MatchedPoliciesUser = matchedPolicies
event.MatchedPolicies = pols.MatchedNames(matchedPolicies)
event.MatchedPolicies = pManager.MatchedNames(matchedPolicies)
}

policiesMatch := func(state events.EventState) uint64 {
Expand All @@ -1731,7 +1734,7 @@ func (t *Tracee) invokeInitEvents(out chan *trace.Event) {
matchedPolicies = policiesMatch(t.eventsState[events.InitNamespaces])
if matchedPolicies > 0 {
systemInfoEvent := events.InitNamespacesEvent()
setMatchedPolicies(&systemInfoEvent, matchedPolicies, t.config.Policies)
setMatchedPolicies(&systemInfoEvent, matchedPolicies, t.policyManager)
out <- &systemInfoEvent
_ = t.stats.EventCount.Increment()
}
Expand All @@ -1743,7 +1746,7 @@ func (t *Tracee) invokeInitEvents(out chan *trace.Event) {
existingContainerEvents := events.ExistingContainersEvents(t.containers, t.config.NoContainersEnrich)
for i := range existingContainerEvents {
event := &(existingContainerEvents[i])
setMatchedPolicies(event, matchedPolicies, t.config.Policies)
setMatchedPolicies(event, matchedPolicies, t.policyManager)
out <- event
_ = t.stats.EventCount.Increment()
}
Expand All @@ -1754,7 +1757,7 @@ func (t *Tracee) invokeInitEvents(out chan *trace.Event) {
matchedPolicies = policiesMatch(t.eventsState[events.FtraceHook])
if matchedPolicies > 0 {
ftraceBaseEvent := events.GetFtraceBaseEvent()
setMatchedPolicies(ftraceBaseEvent, matchedPolicies, t.config.Policies)
setMatchedPolicies(ftraceBaseEvent, matchedPolicies, t.policyManager)
logger.Debugw("started ftraceHook goroutine")

// TODO: Ideally, this should be inside the goroutine and be computed before each run,
Expand Down Expand Up @@ -1823,18 +1826,7 @@ func (t *Tracee) triggerMemDump(event trace.Event) []error {

var errs []error

// We want to use the policies of relevant to the triggering event
policies, err := policy.Snapshots().Get(event.PoliciesVersion)
if err != nil {
logger.Debugw("Error getting policies for print_mem_dump event", "error", err)
// For fallback, try to use latest policies
policies, err = policy.Snapshots().GetLast()
if err != nil {
return []error{err}
}
}

for it := policies.CreateAllIterator(); it.HasNext(); {
for it := t.policyManager.CreateAllIterator(); it.HasNext(); {
p := it.Next()
// This might break in the future if PrintMemDump will become a dependency of another event.
_, isChosen := p.EventsToTrace[events.PrintMemDump]
Expand Down Expand Up @@ -1972,7 +1964,7 @@ func (t *Tracee) Subscribe(policyNames []string) (*streams.Stream, error) {
var policyMask uint64

for _, policyName := range policyNames {
p, err := t.config.Policies.LookupByName(policyName)
p, err := t.policyManager.LookupByName(policyName)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -2023,7 +2015,7 @@ func (t *Tracee) EnableRule(policyNames []string, ruleId string) error {
}

for _, policyName := range policyNames {
p, err := t.config.Policies.LookupByName(policyName)
p, err := t.policyManager.LookupByName(policyName)
if err != nil {
return err
}
Expand All @@ -2042,7 +2034,7 @@ func (t *Tracee) DisableRule(policyNames []string, ruleId string) error {
}

for _, policyName := range policyNames {
p, err := t.config.Policies.LookupByName(policyName)
p, err := t.policyManager.LookupByName(policyName)
if err != nil {
return err
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/events/derive/symbols_collision.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ import (
// `sched_process_exec` event for handling.
//

func SymbolsCollision(soLoader sharedobjs.DynamicSymbolsLoader, policies *policy.Policies,
func SymbolsCollision(
soLoader sharedobjs.DynamicSymbolsLoader,
pManager *policy.PolicyManager,
) DeriveFunction {
symbolsCollisionFilters := map[string]filters.Filter[*filters.StringFilter]{}

// pick white and black lists from the filters (TODO: change this)
for it := policies.CreateAllIterator(); it.HasNext(); {
for it := pManager.CreateAllIterator(); it.HasNext(); {
p := it.Next()
f := p.DataFilter.GetEventFilters(events.SymbolsCollision)
maps.Copy(symbolsCollisionFilters, f)
Expand Down
4 changes: 2 additions & 2 deletions pkg/events/derive/symbols_collision_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,12 +493,12 @@ func TestSymbolsCollision(t *testing.T) {
}

ps := policy.NewPolicies()
policy.Snapshots().Store(ps)
err := ps.Set(p)
require.NoError(t, err)
pManager := policy.NewPolicyManager(ps)

// Pick derive function from mocked tests
deriveFunc := SymbolsCollision(mockLoader, ps)
deriveFunc := SymbolsCollision(mockLoader, pManager)

mockLoader.addSOSymbols(
testSOInstance{
Expand Down
4 changes: 2 additions & 2 deletions pkg/events/derive/symbols_loaded.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import (

func SymbolsLoaded(
soLoader sharedobjs.DynamicSymbolsLoader,
policies *policy.Policies,
pManager *policy.PolicyManager,
) DeriveFunction {
symbolsLoadedFilters := map[string]filters.Filter[*filters.StringFilter]{}

for it := policies.CreateAllIterator(); it.HasNext(); {
for it := pManager.CreateAllIterator(); it.HasNext(); {
p := it.Next()
f := p.DataFilter.GetEventFilters(events.SymbolsLoaded)
maps.Copy(symbolsLoadedFilters, f)
Expand Down
4 changes: 3 additions & 1 deletion pkg/policy/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ func (ps *Policies) Count() int {
return ps.count()
}

// Deprecated: Version returns the version of the Policies.
// Will be removed soon.
func (ps *Policies) Version() uint16 {
return ps.version
return 1 // version will be removed soon
}

// WithContainerFilterEnabled returns a bitmap of policies that have at least one container filter type enabled.
Expand Down
Loading

0 comments on commit dba1a42

Please sign in to comment.