Skip to content

Commit

Permalink
policies: replace "userspace" with "userland"
Browse files Browse the repository at this point in the history
  • Loading branch information
geyslan committed Jun 14, 2023
1 parent 5bc17ab commit d79107c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 66 deletions.
4 changes: 2 additions & 2 deletions pkg/ebpf/events_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,12 @@ func (t *Tracee) matchPolicies(event *trace.Event) uint64 {
bitmap := event.MatchedPoliciesKernel

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

for p := range t.config.Policies.FilterableInUserSpaceMap() { // range through each userland filterable policy
for p := range t.config.Policies.FilterableInUserlandMap() { // range through each userland filterable policy
// Policy ID is the bit offset in the bitmap.
bitOffset := uint(p.ID)

Expand Down
127 changes: 63 additions & 64 deletions pkg/policy/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,34 @@ import (

// TODO: add locking mechanism as policies will change at runtime
type Policies struct {
policiesArray [MaxPolicies]*Policy // underlying filter policies array
filterEnabledPoliciesMap map[*Policy]int // stores only enabled policies
filterUserSpacePoliciesMap map[*Policy]int // stores a reduced map with only user space filtered policies

uidFilterMin uint64
uidFilterMax uint64
pidFilterMin uint64
pidFilterMax uint64
uidFilterableInUserSpace bool
pidFilterableInUserSpace bool

filterableInUserSpace uint64 // bitmap of policies that must be filtered in user space
policiesArray [MaxPolicies]*Policy // underlying filter policies array
filterEnabledPoliciesMap map[*Policy]int // stores only enabled policies
filterUserlandPoliciesMap map[*Policy]int // stores a reduced map with only userland filterable policies

uidFilterMin uint64
uidFilterMax uint64
pidFilterMin uint64
pidFilterMax uint64
uidFilterableInUserland bool
pidFilterableInUserland bool

filterableInUserland uint64 // bitmap of policies that must be filtered in userland
containerFiltersEnabled uint64 // bitmap of policies that have at least one container filter type enabled
}

func NewPolicies() *Policies {
return &Policies{
policiesArray: [MaxPolicies]*Policy{},
filterEnabledPoliciesMap: map[*Policy]int{},
filterUserSpacePoliciesMap: map[*Policy]int{},
uidFilterMin: filters.MinNotSetUInt,
uidFilterMax: filters.MaxNotSetUInt,
pidFilterMin: filters.MinNotSetUInt,
pidFilterMax: filters.MaxNotSetUInt,
uidFilterableInUserSpace: false,
pidFilterableInUserSpace: false,
filterableInUserSpace: 0,
containerFiltersEnabled: 0,
policiesArray: [MaxPolicies]*Policy{},
filterEnabledPoliciesMap: map[*Policy]int{},
filterUserlandPoliciesMap: map[*Policy]int{},
uidFilterMin: filters.MinNotSetUInt,
uidFilterMax: filters.MaxNotSetUInt,
pidFilterMin: filters.MinNotSetUInt,
pidFilterMax: filters.MaxNotSetUInt,
uidFilterableInUserland: false,
pidFilterableInUserland: false,
filterableInUserland: 0,
containerFiltersEnabled: 0,
}
}

Expand All @@ -60,12 +60,12 @@ func (ps *Policies) PIDFilterMax() uint64 {
return ps.pidFilterMax
}

func (ps *Policies) UIDFilterableInUserSpace() bool {
return ps.uidFilterableInUserSpace
func (ps *Policies) UIDFilterableInUserland() bool {
return ps.uidFilterableInUserland
}

func (ps *Policies) PIDFilterableInUserSpace() bool {
return ps.pidFilterableInUserSpace
func (ps *Policies) PIDFilterableInUserland() bool {
return ps.pidFilterableInUserland
}

// ContainerFilterEnabled returns a bitmap of policies that have at least
Expand All @@ -77,16 +77,16 @@ func (ps *Policies) ContainerFilterEnabled() uint64 {
return atomic.LoadUint64(&ps.containerFiltersEnabled)
}

// FilterableInUserSpace returns a bitmap of policies that must be filtered in user space
// FilterableInUserland returns a bitmap of policies that must be filtered in userland
// (ArgFilter, RetFilter, ContextFilter, UIDFilter and PIDFilter).
//
// TODO: make sure the stores are also atomic (an atomic load is only protecting
// the read from context switches, not from CPU cache coherency issues).
func (ps *Policies) FilterableInUserSpace() uint64 {
return atomic.LoadUint64(&ps.filterableInUserSpace)
func (ps *Policies) FilterableInUserland() uint64 {
return atomic.LoadUint64(&ps.filterableInUserland)
}

// Compute recalculates values, updates flags, fills the reduced user space map,
// Compute recalculates values, updates flags, fills the reduced userland map,
// and sets the related bitmap that is used to prevent the iteration of the entire map.
//
// It must be called at initialization and at every runtime policies changes.
Expand All @@ -97,21 +97,21 @@ func (ps *Policies) Compute() {
// update enabled container filter flag
ps.updateContainerFilterEnabled()

userSpaceMap := make(map[*Policy]int)
ps.filterableInUserSpace = 0
userlandMap := make(map[*Policy]int)
ps.filterableInUserland = 0
for p := range ps.filterEnabledPoliciesMap {
if p.ArgFilter.Enabled() ||
p.RetFilter.Enabled() ||
p.ContextFilter.Enabled() ||
(p.UIDFilter.Enabled() && ps.UIDFilterableInUserSpace()) ||
(p.PIDFilter.Enabled() && ps.PIDFilterableInUserSpace()) {
(p.UIDFilter.Enabled() && ps.UIDFilterableInUserland()) ||
(p.PIDFilter.Enabled() && ps.PIDFilterableInUserland()) {
// add policy and set the related bit
userSpaceMap[p] = p.ID
utils.SetBit(&ps.filterableInUserSpace, uint(p.ID))
userlandMap[p] = p.ID
utils.SetBit(&ps.filterableInUserland, uint(p.ID))
}
}

ps.filterUserSpacePoliciesMap = userSpaceMap
ps.filterUserlandPoliciesMap = userlandMap
}

// set, if not err, always reassign values
Expand Down Expand Up @@ -168,7 +168,7 @@ func (ps *Policies) Delete(id int) error {
}

delete(ps.filterEnabledPoliciesMap, ps.policiesArray[id])
delete(ps.filterUserSpacePoliciesMap, ps.policiesArray[id])
delete(ps.filterUserlandPoliciesMap, ps.policiesArray[id])
ps.policiesArray[id] = nil

ps.Compute()
Expand Down Expand Up @@ -207,10 +207,10 @@ func (ps *Policies) Map() map[*Policy]int {
return ps.filterEnabledPoliciesMap
}

// FilterableInUserSpaceMap returns a reduced policies map which must be filtered in
// user space (ArgFilter, RetFilter, ContextFilter, UIDFilter and PIDFilter).
func (ps *Policies) FilterableInUserSpaceMap() map[*Policy]int {
return ps.filterUserSpacePoliciesMap
// FilterableInUserlandMap returns a reduced policies map which must be filtered in
// userland (ArgFilter, RetFilter, ContextFilter, UIDFilter and PIDFilter).
func (ps *Policies) FilterableInUserlandMap() map[*Policy]int {
return ps.filterUserlandPoliciesMap
}

func (ps *Policies) updateContainerFilterEnabled() {
Expand All @@ -223,13 +223,12 @@ func (ps *Policies) updateContainerFilterEnabled() {
}
}

// calculateGlobalMinMax sets the global min and max, to be checked in kernel
// space, of the Minimum and Maximum enabled filters only if context filter
// types (e.g. BPFUIDFilter) from all policies have both Minimum and Maximum
// values set.
// calculateGlobalMinMax sets the global min and max, to be checked in kernel,
// of the Minimum and Maximum enabled filters only if context filter types
// (e.g. BPFUIDFilter) from all policies have both Minimum and Maximum values set.
//
// Policies user space filter flags are also set (e.g.
// uidFilterableInUserSpace).
// Policies userland filter flags are also set (e.g.
// uidFilterableInUserland).
//
// The context filter types relevant for this function are just UIDFilter and
// PIDFilter.
Expand All @@ -243,10 +242,10 @@ func (ps *Policies) calculateGlobalMinMax() {
pidFilterCount int
policyCount int

uidMinFilterableInUserSpace bool
uidMaxFilterableInUserSpace bool
pidMinFilterableInUserSpace bool
pidMaxFilterableInUserSpace bool
uidMinFilterableInUserland bool
uidMaxFilterableInUserland bool
pidMinFilterableInUserland bool
pidMaxFilterableInUserland bool
)

for p := range ps.Map() {
Expand Down Expand Up @@ -274,21 +273,21 @@ func (ps *Policies) calculateGlobalMinMax() {
}
}

uidMinFilterableInUserSpace = policyCount > 1 && (uidMinFilterCount != uidFilterCount)
uidMaxFilterableInUserSpace = policyCount > 1 && (uidMaxFilterCount != uidFilterCount)
pidMinFilterableInUserSpace = policyCount > 1 && (pidMinFilterCount != pidFilterCount)
pidMaxFilterableInUserSpace = policyCount > 1 && (pidMaxFilterCount != pidFilterCount)
uidMinFilterableInUserland = policyCount > 1 && (uidMinFilterCount != uidFilterCount)
uidMaxFilterableInUserland = policyCount > 1 && (uidMaxFilterCount != uidFilterCount)
pidMinFilterableInUserland = policyCount > 1 && (pidMinFilterCount != pidFilterCount)
pidMaxFilterableInUserland = policyCount > 1 && (pidMaxFilterCount != pidFilterCount)

// reset global min max
ps.uidFilterMax = filters.MaxNotSetUInt
ps.uidFilterMin = filters.MinNotSetUInt
ps.pidFilterMax = filters.MaxNotSetUInt
ps.pidFilterMin = filters.MinNotSetUInt

ps.uidFilterableInUserSpace = uidMinFilterableInUserSpace || uidMaxFilterableInUserSpace
ps.pidFilterableInUserSpace = pidMinFilterableInUserSpace || pidMaxFilterableInUserSpace
ps.uidFilterableInUserland = uidMinFilterableInUserland || uidMaxFilterableInUserland
ps.pidFilterableInUserland = pidMinFilterableInUserland || pidMaxFilterableInUserland

if ps.UIDFilterableInUserSpace() && ps.PIDFilterableInUserSpace() {
if ps.UIDFilterableInUserland() && ps.PIDFilterableInUserland() {
// there's no need to iterate filter policies again since
// all uint events will be submitted from ebpf with no regards

Expand All @@ -298,18 +297,18 @@ func (ps *Policies) calculateGlobalMinMax() {
// set a reduced range of uint values to be filtered in ebpf
for p := range ps.filterEnabledPoliciesMap {
if p.UIDFilter.Enabled() {
if !uidMinFilterableInUserSpace {
if !uidMinFilterableInUserland {
ps.uidFilterMin = utils.Min(ps.uidFilterMin, p.UIDFilter.Minimum())
}
if !uidMaxFilterableInUserSpace {
if !uidMaxFilterableInUserland {
ps.uidFilterMax = utils.Max(ps.uidFilterMax, p.UIDFilter.Maximum())
}
}
if p.PIDFilter.Enabled() {
if !pidMinFilterableInUserSpace {
if !pidMinFilterableInUserland {
ps.pidFilterMin = utils.Min(ps.pidFilterMin, p.PIDFilter.Minimum())
}
if !pidMaxFilterableInUserSpace {
if !pidMaxFilterableInUserland {
ps.pidFilterMax = utils.Max(ps.pidFilterMax, p.PIDFilter.Maximum())
}
}
Expand Down

0 comments on commit d79107c

Please sign in to comment.