Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ cleanbuild: clean sync bin
full: clean sync generate bin

debug:
dlv debug "./userspace/cmd/" -- dump --policy ./test_files/test.policy.yaml security_file_open
dlv debug "./userspace/cmd/" -- dump --policy ./test_files/test.policy.yaml
130 changes: 29 additions & 101 deletions manager/ebpf_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package manager
import (
"context"
"errors"
"fmt"
"os"
"regexp"
"sync"
Expand All @@ -23,8 +22,8 @@ import (
"github.com/Velocidex/tracee_velociraptor/userspace/events"
"github.com/Velocidex/tracee_velociraptor/userspace/events/data"
"github.com/Velocidex/tracee_velociraptor/userspace/events/dependencies"
k8s "github.com/Velocidex/tracee_velociraptor/userspace/k8s/apis/tracee.aquasec.com/v1beta1"
"github.com/Velocidex/tracee_velociraptor/userspace/policy"
"github.com/Velocidex/tracee_velociraptor/userspace/policy/v1beta1"
time_util "github.com/Velocidex/tracee_velociraptor/userspace/time"
"github.com/cilium/ebpf"
"github.com/cilium/ebpf/perf"
Expand Down Expand Up @@ -53,8 +52,6 @@ type EBPFManager struct {
collection *ebpf.Collection
currently_loading bool

policy_id uint16

probes *probes.ProbeGroup

bpfModule *bpf.Module
Expand Down Expand Up @@ -82,14 +79,7 @@ type EBPFManager struct {

dataTypeDecoder bufferdecoder.TypeDecoder

policies []string
}

func (self *EBPFManager) AddPolicies(policies []string) {
self.mu.Lock()
defer self.mu.Unlock()

self.policies = append(self.policies, policies...)
eventDecodeTypes map[events.ID][]data.DecodeAs
}

func (self *EBPFManager) EidMonitored() []events.ID {
Expand Down Expand Up @@ -291,7 +281,7 @@ func (self *EBPFManager) setTailCalls() error {
}
}

return self.setEventIDPolicy()
return nil
}

func (self *EBPFManager) setTailCall(eid events.ID, remove bool) error {
Expand Down Expand Up @@ -325,58 +315,6 @@ func (self *EBPFManager) setTailCall(eid events.ID, remove bool) error {
return nil
}

func (self *EBPFManager) setEventIDPolicy() error {
return nil

var event_inner_map *ebpf.Map

// The events_map_version is an inner map - we always renew it
// with a new map so we can easily account for events added and
// removed.
map_spec, pres := self.spec.Maps["events_map_version"]
if !pres {
return mapNotValid
}

event_inner_map, err := ebpf.NewMap(map_spec.InnerMap)
if err != nil {
return err
}

for _, key := range self._EidMonitored() {
eid := key

event_config := &ebpfEventConfigT{
SubmitForPolicies: uint64(self.policy_id),
}

/*
params, pres := self.eventsFieldTypes[eid]
if pres {
for n, paramType := range params {
event_config.FieldTypes |= (uint64(paramType) << (8 * n))
}
}
*/

err = event_inner_map.Put(unsafe.Pointer(&eid),
unsafe.Pointer(event_config))
if err != nil {
return err
}
}

event_inner_map_fd := uint32(event_inner_map.FD())
events_map_version, pres := self.collection.Maps["events_map_version"]
if !pres {
return mapNotValid
}

return events_map_version.Put(
unsafe.Pointer(&self.policy_id),
unsafe.Pointer(&event_inner_map_fd))
}

func (self *EBPFManager) Close() {}

func (self *EBPFManager) applyConfig() (err error) {
Expand Down Expand Up @@ -518,12 +456,11 @@ func (self *EBPFManager) updateEbpfState() (err error) {
}

func (self *EBPFManager) compilePolicies() error {
policies, err := v1beta1.PoliciesFromPaths(self.policies)
if err != nil {
return err
}
var policies []k8s.PolicyInterface

fmt.Printf("Policies %#v\n", policies)
for _, p := range self.listeners {
policies = append(policies, p.Policy())
}

scope_map, event_map, err := flags.PrepareFilterMapsFromPolicies(policies)
if err != nil {
Expand All @@ -534,8 +471,6 @@ func (self *EBPFManager) compilePolicies() error {
return err
}

fmt.Printf("Policies %#v\n", ps)

depsManager := dependencies.NewDependenciesManager(
func(id events.ID) events.DependencyStrategy {
return events.Core.GetDefinitionByID(id).GetDependencies()
Expand All @@ -547,18 +482,9 @@ func (self *EBPFManager) compilePolicies() error {
return err
}

eventDecodeTypes := make(map[events.ID][]data.DecodeAs)
for _, eventDefinition := range events.Core.GetDefinitions() {
id := eventDefinition.GetID()
fields := eventDefinition.GetFields()
for _, field := range fields {
eventDecodeTypes[id] = append(eventDecodeTypes[id], field.DecodeAs)
}
}

containerManager := &container.Manager{}
_, err = policyManager.UpdateBPF(self.bpfModule, containerManager,
eventDecodeTypes,
self.eventDecodeTypes,
true, // createNewMaps
false, // updateProcTree
)
Expand All @@ -573,13 +499,19 @@ func (self *EBPFManager) Watch(
self.mu.Lock()
defer self.mu.Unlock()

if opts.Policy != "" {
self.policies = append(self.policies, opts.Policy)
p, err := PolicyFromString(opts.Policy)
if err != nil {
return nil, nil, err
}

events, err := EventIDsForPolicy(p)
if err != nil {
return nil, nil, err
}

// Add a new listener to the event loop.
new_listener := NewListner(self.logger, self.dnscache, ctx,
self.ctx, opts.SelectedEvents)
new_listener := NewListner(
self.logger, self.dnscache, ctx, self.ctx, events, p)
new_listener.SetPrefilter(opts.Prefilter)
self.listeners = append(self.listeners, new_listener)

Expand All @@ -592,7 +524,7 @@ func (self *EBPFManager) Watch(
}
}

err := self.compilePolicies()
err = self.compilePolicies()
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -657,32 +589,28 @@ func NewEBPFManager(
}

self := &EBPFManager{
policy_id: 1,
logger: logger,
ebpf_config_obj: config_obj,
idle_unload_time: config.IdleUnloadTimeout,
ctx: ctx,
KernelConfig: kernelConfig,
//eventsFieldTypes: make(map[events.ID][]bufferdecoder.ArgType),
cgroups: cgroups_obj,
dataTypeDecoder: bufferdecoder.NewTypeDecoder(),
cgroups: cgroups_obj,
dataTypeDecoder: bufferdecoder.NewTypeDecoder(),
eventDecodeTypes: make(map[events.ID][]data.DecodeAs),
}

if self.idle_unload_time == 0 {
self.idle_unload_time = time.Duration(5 * time.Minute)
}

/*
// Initialize the event parameter types
for _, eventDefinition := range events.Core.GetDefinitions() {
id := eventDefinition.GetID()
params := eventDefinition.GetParams()
for _, param := range params {
self.eventsFieldTypes[id] = append(self.eventsFieldTypes[id],
bufferdecoder.GetParamType(param.Type))
}
for _, eventDefinition := range events.Core.GetDefinitions() {
id := eventDefinition.GetID()
fields := eventDefinition.GetFields()
for _, field := range fields {
self.eventDecodeTypes[id] = append(self.eventDecodeTypes[id],
field.DecodeAs)
}
*/
}

// Set the clocks and initialize.
time_util.Init(unix.CLOCK_BOOTTIME)
Expand Down
12 changes: 11 additions & 1 deletion manager/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
dnscache "github.com/Velocidex/tracee_velociraptor/userspace/datastores/dns"
"github.com/Velocidex/tracee_velociraptor/userspace/events"
"github.com/Velocidex/tracee_velociraptor/userspace/events/derive"
k8s "github.com/Velocidex/tracee_velociraptor/userspace/k8s/apis/tracee.aquasec.com/v1beta1"
)

type Action bool
Expand Down Expand Up @@ -50,6 +51,12 @@ type listener struct {
logger Logger

prefilter func(buf []byte) bool

policy k8s.PolicyInterface
}

func (self *listener) Policy() k8s.PolicyInterface {
return self.policy
}

func (self *listener) SetPrefilter(filter func(in []byte) bool) {
Expand Down Expand Up @@ -297,12 +304,15 @@ func (self *listener) close() {
func NewListner(
logger Logger, dnscache *dnscache.DNSCache,
caller_ctx, global_ctx context.Context,
selected_events []events.ID) *listener {
selected_events []events.ID,
policy k8s.PolicyInterface) *listener {

res := &listener{
output_chan: make(chan *ordereddict.Dict),
global_ctx: global_ctx,
caller_ctx: caller_ctx,
eid_monitored: make(map[events.ID]Action),
policy: policy,
}

for _, eid := range selected_events {
Expand Down
26 changes: 26 additions & 0 deletions manager/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,35 @@ package manager
import "github.com/Velocidex/tracee_velociraptor/userspace/events"

type EBPFWatchOptions struct {
// Forward all these events to the watcher.
SelectedEvents []events.ID
Prefilter func(in []byte) bool

// Alternatively callers can supply a policy.
//
// The policy can provide filters and a set of events. Filters are
// applied in the kernel so they are essential for reducing CPU
// use.
//
// NOTE: Currently all watchers that watch the same event id will
// receive all events - regardless if their specific policy
// applies or if another listener selected the same event with
// another policy. Therefore events should be post-filtered again.
//
// Therefore, Policy filters should be considered as a performance
// optimization only.
//
// For example:
//
// metadata:
// name: file-open-home
// spec:
// scope:
// - global
// rules:
// - event: security_file_open
// filters:
// - args.pathname=/home/*
Policy string
}

Expand Down
65 changes: 65 additions & 0 deletions manager/policies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package manager

import (
"encoding/json"
"errors"
"strings"

"github.com/Velocidex/tracee_velociraptor/userspace/cmd/flags"
"github.com/Velocidex/tracee_velociraptor/userspace/events"
k8s "github.com/Velocidex/tracee_velociraptor/userspace/k8s/apis/tracee.aquasec.com/v1beta1"
"github.com/Velocidex/tracee_velociraptor/userspace/policy/v1beta1"
"gopkg.in/yaml.v2"
)

func PolicyFromString(in string) (res k8s.PolicyInterface, err error) {
in = strings.TrimSpace(in)
if len(in) == 0 {
return nil, errors.New("Invalid policy")
}

var p v1beta1.PolicyFile

// JSON type
if in[0] == '{' {
err = json.Unmarshal([]byte(in), &p)
} else {
err = yaml.Unmarshal([]byte(in), &p)
}
if err != nil {
return nil, err
}

// We dont care about some fields to make the policy definitions a
// bit simpler.
p.APIVersion = "tracee.aquasec.com/v1beta1"
p.Kind = "Policy"

err = p.Validate()
if err != nil {
return p, err
}

return p, nil
}

func EventIDsForPolicy(p k8s.PolicyInterface) ([]events.ID, error) {
scope_map, event_map, err := flags.PrepareFilterMapsFromPolicies(
[]k8s.PolicyInterface{p})
if err != nil {
return nil, err
}

ps, err := flags.CreatePolicies(scope_map, event_map)
if err != nil {
return nil, err
}

var events []events.ID
for _, p := range ps {
for e := range p.Rules {
events = append(events, e)
}
}
return events, nil
}
Loading
Loading