Skip to content

Commit

Permalink
chore(refactor): refactor pkg/ebpf/ksymbols and associated logic
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaeldtinoco committed Jan 16, 2024
1 parent e628195 commit 91477c7
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 109 deletions.
95 changes: 44 additions & 51 deletions pkg/ebpf/ksymbols.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,75 +3,68 @@ package ebpf
import (
"unsafe"

"github.com/aquasecurity/libbpfgo"
"github.com/aquasecurity/libbpfgo/helpers"

"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/logger"
)

// TODO: Just like recent change in `KernelSymbolTable`, in kernel_symbols.go,
// this needs to be changed somehow. Symbols might be duplicated, so might be
// the addresses (https://github.com/aquasecurity/tracee/issues/3798).

var maxKsymNameLen = 64 // Most match the constant in the bpf code
var globalSymbolOwner = "system"

func LoadKallsymsValues(ksymsTable *helpers.KernelSymbolTable, ksymbols []string) map[string]helpers.KernelSymbol {
kallsymsMap := make(map[string]helpers.KernelSymbol)
for _, name := range ksymbols {
symbol, err := ksymsTable.GetSymbolByOwnerAndName(globalSymbolOwner, name)
if err == nil {
kallsymsMap[name] = symbol[0]
}
func (t *Tracee) UpdateKallsyms() error {
// NOTE: Make sure to refresh the kernel symbols table before updating the eBPF map.

// Find the eBPF map.
bpfKsymsMap, err := t.bpfModule.GetMap("ksymbols_map")
if err != nil {
return errfmt.WrapError(err)
}
return kallsymsMap
}

func SendKsymbolsToMap(bpfKsymsMap *libbpfgo.BPFMap, ksymbols map[string]helpers.KernelSymbol) error {
for ksymName, value := range ksymbols {
key := make([]byte, maxKsymNameLen)
copy(key, ksymName)
address := value.Address
err := bpfKsymsMap.Update(unsafe.Pointer(&key[0]), unsafe.Pointer(&address))
if err != nil {
return errfmt.WrapError(err)
}
// Wrap long method names.
evtDefSymDeps := func(id events.ID) []events.KSymbol {
return events.Core.GetDefinitionByID(id).GetDependencies().GetKSymbols()
}
return nil
}

func (t *Tracee) UpdateKernelSymbols() error {
return t.kernelSymbols.Refresh()
}
// Get the symbols all events being traced require (t.eventsState already
// includes dependent events, no need to recurse again).

func (t *Tracee) UpdateBPFKsymbolsMap() error {
var err error
var bpfKsymsMap *libbpfgo.BPFMap
var allReqSymbols []string

bpfKsymsMap, err = t.bpfModule.GetMap("ksymbols_map")
if err != nil {
return errfmt.WrapError(err)
for evtID := range t.eventsState {
for _, symDep := range evtDefSymDeps(evtID) {
allReqSymbols = append(allReqSymbols, symDep.GetSymbolName())
}
}

// get required symbols by chosen events
var reqKsyms []string

for id := range t.eventsState {
if !events.Core.IsDefined(id) {
return errfmt.Errorf("wrong event id: %d", id)
}
eventDependencies := events.Core.GetDefinitionByID(id).GetDependencies()
for _, symDependency := range eventDependencies.GetKSymbols() {
reqKsyms = append(reqKsyms, symDependency.GetSymbol())
// For every ksymbol required by tracee ...
for _, required := range allReqSymbols {
// ... get the symbol address from the kallsyms file ...
symbol, err := t.kernelSymbols.GetSymbolByOwnerAndName(globalSymbolOwner, required)
if err != nil {
logger.Debugw("failed to get symbol", "symbol", required, "error", err)
continue
}
}
kallsymsValues := LoadKallsymsValues(t.kernelSymbols, reqKsyms)

return SendKsymbolsToMap(bpfKsymsMap, kallsymsValues)
}
// ... and update the eBPF map with the symbol address.
for _, sym := range symbol {
key := make([]byte, maxKsymNameLen)
copy(key, sym.Name)
addr := sym.Address

func (t *Tracee) UpdateKallsyms() error {
err := t.UpdateKernelSymbols()
if err != nil {
return errfmt.WrapError(err)
// Update the eBPF map with the symbol address.
err := bpfKsymsMap.Update(
unsafe.Pointer(&key[0]),
unsafe.Pointer(&addr),
)
if err != nil {
return errfmt.WrapError(err)
}
} // will overwrite the previous value (check TODO)
}

return t.UpdateBPFKsymbolsMap()
return nil
}
51 changes: 28 additions & 23 deletions pkg/ebpf/processor_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,35 +213,40 @@ func (t *Tracee) processSchedProcessExec(event *trace.Event) error {

// processDoFinitModule handles a do_finit_module event and triggers other hooking detection logic.
func (t *Tracee) processDoInitModule(event *trace.Event) error {
// Check if related events are being traced.
_, okSyscalls := t.eventsState[events.HookedSyscall]
_, okSeqOps := t.eventsState[events.HookedSeqOps]
_, okProcFops := t.eventsState[events.HookedProcFops]
_, okMemDump := t.eventsState[events.PrintMemDump]

if okSyscalls || okSeqOps || okProcFops || okMemDump {
err := capabilities.GetInstance().EBPF(
func() error {
return t.UpdateKallsyms()
},
)
if err != nil {
return errfmt.WrapError(err)
}
if err != nil {
return errfmt.WrapError(err)
}
if okSyscalls && expectedSyscallTableInit {
t.triggerSyscallTableIntegrityCheckCall()
}
if okSeqOps {
// Trigger seq_ops hooking detection
t.triggerSeqOpsIntegrityCheck(*event)
}
if okMemDump {
errs := t.triggerMemDump(*event)
for _, err := range errs {
logger.Warnw("Memory dump", "error", err)
if !okSyscalls && !okSeqOps && !okProcFops && !okMemDump {
return nil
}

err := capabilities.GetInstance().EBPF(
func() error {
err := t.kernelSymbols.Refresh()
if err != nil {
return errfmt.WrapError(err)
}
return t.UpdateKallsyms()
},
)
if err != nil {
return errfmt.WrapError(err)
}
if okSyscalls && expectedSyscallTableInit {
// Trigger syscall table hooking detection.
t.triggerSyscallTableIntegrityCheckCall()
}
if okSeqOps {
// Trigger seq_ops hooking detection
t.triggerSeqOpsIntegrityCheck(*event)
}
if okMemDump {
errs := t.triggerMemDump(*event)
for _, err := range errs {
logger.Warnw("Memory dump", "error", err)
}
}

Expand Down
60 changes: 26 additions & 34 deletions pkg/ebpf/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -964,41 +964,33 @@ func (t *Tracee) computeConfigValues(newPolicies *policy.Policies) []byte {
return configVal
}

// TODO: move this to Event Definition type, so can be reused by other components
// checkUnavailableKSymbols checks if all kernel symbols required by events are available.
func (t *Tracee) checkUnavailableKSymbols() map[events.ID][]string {
reqKSyms := []string{}
// getUnavKsymsPerEvtID returns event IDs and symbols that are unavailable to them.
func (t *Tracee) getUnavKsymsPerEvtID() map[events.ID][]string {
unavSymsPerEvtID := map[events.ID][]string{}

kSymbolsToEvents := make(map[string][]events.ID)
evtDefSymDeps := func(id events.ID) []events.KSymbol {
return events.Core.GetDefinitionByID(id).GetDependencies().GetKSymbols()
}

// Build a map of kernel symbols to events that require them
for id := range t.eventsState {
evtDefinition := events.Core.GetDefinitionByID(id)
for _, symDep := range evtDefinition.GetDependencies().GetKSymbols() {
if !symDep.IsRequired() {
for evtID := range t.eventsState {
for _, symDep := range evtDefSymDeps(evtID) {
sym, err := t.kernelSymbols.GetSymbolByName(symDep.GetSymbolName())
symName := symDep.GetSymbolName()
if err != nil {
// If the symbol is not found, it means it's unavailable.
unavSymsPerEvtID[evtID] = append(unavSymsPerEvtID[evtID], symName)
continue
}
symbol := symDep.GetSymbol()
reqKSyms = append(reqKSyms, symbol)
kSymbolsToEvents[symbol] = append(kSymbolsToEvents[symbol], id)
}
}

kallsymsValues := LoadKallsymsValues(t.kernelSymbols, reqKSyms)
unavailableKSymsForEventID := make(map[events.ID][]string)

// Build a map of events that require unavailable kernel symbols
for symName, evtsIDs := range kSymbolsToEvents {
ksym, ok := kallsymsValues[symName]
if ok && ksym.Address != 0 {
continue
}
for _, evtID := range evtsIDs {
unavailableKSymsForEventID[evtID] = append(unavailableKSymsForEventID[evtID], symName)
for _, s := range sym {
if s.Address == 0 {
// Same if the symbol is found but its address is 0.
unavSymsPerEvtID[evtID] = append(unavSymsPerEvtID[evtID], symName)
}
}
}
}

return unavailableKSymsForEventID
return unavSymsPerEvtID
}

// validateKallsymsDependencies load all symbols required by events dependencies
Expand All @@ -1008,7 +1000,7 @@ func (t *Tracee) validateKallsymsDependencies() {
depsToCancel := make(map[events.ID]string)

// Cancel events with unavailable symbols dependencies
for eventToCancel, missingDepSyms := range t.checkUnavailableKSymbols() {
for eventToCancel, missingDepSyms := range t.getUnavKsymsPerEvtID() {
eventNameToCancel := events.Core.GetDefinitionByID(eventToCancel).GetName()
logger.Debugw(
"Event canceled because of missing kernel symbol dependency",
Expand Down Expand Up @@ -1053,11 +1045,10 @@ func (t *Tracee) populateBPFMaps() error {
}
}

if t.kernelSymbols != nil {
err = t.UpdateBPFKsymbolsMap()
if err != nil {
return errfmt.WrapError(err)
}
// Update the kallsyms eBPF map with all symbols from the kallsyms file.
err = t.UpdateKallsyms()
if err != nil {
return errfmt.WrapError(err)
}

// Initialize kconfig variables (map used instead of relying in libbpf's .kconfig automated maps)
Expand Down Expand Up @@ -1301,6 +1292,7 @@ func (t *Tracee) initBPF() error {
}

// Initialize Control Plane

t.controlPlane, err = controlplane.NewController(
t.bpfModule,
t.containers,
Expand Down
12 changes: 11 additions & 1 deletion pkg/events/definition_dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ func (d Dependencies) GetKSymbols() []KSymbol {
return d.kSymbols
}

func (d Dependencies) GetRequiredKSymbols() []KSymbol {
var requiredKSymbols []KSymbol
for _, kSymbol := range d.kSymbols {
if kSymbol.required {
requiredKSymbols = append(requiredKSymbols, kSymbol)
}
}
return requiredKSymbols
}

func (d Dependencies) GetProbes() []Probe {
if d.probes == nil {
return []Probe{}
Expand Down Expand Up @@ -85,7 +95,7 @@ type KSymbol struct {
required bool // tracee fails if symbol is not found
}

func (ks KSymbol) GetSymbol() string {
func (ks KSymbol) GetSymbolName() string {
return ks.symbol
}

Expand Down

0 comments on commit 91477c7

Please sign in to comment.