Skip to content

Commit

Permalink
feat(ebpf): use watchers for ksymbols validation
Browse files Browse the repository at this point in the history
  • Loading branch information
AlonZivony committed Apr 14, 2024
1 parent 2edd39e commit e0e589f
Showing 1 changed file with 49 additions and 31 deletions.
80 changes: 49 additions & 31 deletions pkg/ebpf/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,50 +854,68 @@ func (t *Tracee) newConfig(cfg *policy.PoliciesConfig, version uint16) *Config {
}
}

// getUnavKsymsPerEvtID returns event IDs and symbols that are unavailable to them.
func (t *Tracee) getUnavKsymsPerEvtID() map[events.ID][]string {
unavSymsPerEvtID := map[events.ID][]string{}
// getUnavailbaleKsymbols return all kernel symbols missing from given symbols
func getUnavailbaleKsymbols(ksymbols []events.KSymbol, kernelSymbols *helpers.KernelSymbolTable) []events.KSymbol {
var unavailableSymbols []events.KSymbol

for _, ksymbol := range ksymbols {
sym, err := kernelSymbols.GetSymbolByName(ksymbol.GetSymbolName())
if err != nil {
// If the symbol is not found, it means it's unavailable.
unavailableSymbols = append(unavailableSymbols, ksymbol)
continue
}
for _, s := range sym {
if s.Address == 0 {
// Same if the symbol is found but its address is 0.
unavailableSymbols = append(unavailableSymbols, ksymbol)
}
}
}
return unavailableSymbols
}

// validateKallsymsDependencies load all symbols required by events dependencies
// from the kallsyms file to check for missing symbols. If some symbols are
// missing, it will cancel their event with informative error message.
func (t *Tracee) validateKallsymsDependencies() {
evtDefSymDeps := func(id events.ID) []events.KSymbol {
depsNode, _ := t.eventsDependencies.GetEvent(id)
deps := depsNode.GetDependencies()
return deps.GetKSymbols()
}

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
validateEvent := func(eventId events.ID) {
missingDepSyms := getUnavailbaleKsymbols(evtDefSymDeps(eventId), t.kernelSymbols)
shouldFailEvent := false
for _, symDep := range missingDepSyms {
if symDep.IsRequired() {
shouldFailEvent = true
break
}
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)
}
}
if shouldFailEvent {
eventNameToCancel := events.Core.GetDefinitionByID(eventId).GetName()
var missingSymsNames []string
for _, symDep := range missingDepSyms {
missingSymsNames = append(missingSymsNames, symDep.GetSymbolName())
}
logger.Warnw(
"Event canceled because of missing kernel symbol dependency",
"missing symbols", missingSymsNames, "event", eventNameToCancel,
)
// Cancel the event, it dependencies and its dependant events
t.eventsDependencies.RemoveEvent(eventId)
}
}

return unavSymsPerEvtID
}
t.eventsDependencies.SubscribeAdd(
func(node *dependencies.EventNode) {
validateEvent(node.GetID())
})

// validateKallsymsDependencies load all symbols required by events dependencies
// from the kallsyms file to check for missing symbols. If some symbols are
// missing, it will cancel their event with informative error message.
func (t *Tracee) validateKallsymsDependencies() {
// Cancel events with unavailable symbols dependencies
for eventToCancel, missingDepSyms := range t.getUnavKsymsPerEvtID() {
eventNameToCancel := events.Core.GetDefinitionByID(eventToCancel).GetName()
logger.Debugw(
"Event canceled because of missing kernel symbol dependency",
"missing symbols", missingDepSyms, "event", eventNameToCancel,
)
// Cancel the event, it depencies and its dependant events
t.eventsDependencies.RemoveEvent(eventToCancel)
for eventId := range t.eventsState {
validateEvent(eventId)
}
}

Expand Down

0 comments on commit e0e589f

Please sign in to comment.