Skip to content

Commit

Permalink
feat(ksymbols): reimplement ksymbols
Browse files Browse the repository at this point in the history
This implementation stores all symbols, or if a `requiredDataSymbolsOnly`
flag is used when creating the symbol table, only non-data symbols are saved
(and required data symbols must be registered before updating).
This new implementation uses a generic symbol table implementation that is
responsible for managing symbol lookups, and can be used by future code for
managing exeutable file symbols.
  • Loading branch information
oshaked1 committed Dec 26, 2024
1 parent a481d11 commit 421eb9b
Show file tree
Hide file tree
Showing 13 changed files with 865 additions and 407 deletions.
4 changes: 2 additions & 2 deletions pkg/ebpf/hooked_syscall_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func (t *Tracee) populateExpectedSyscallTableArray(tableMap *bpf.BPFMap) error {
return e
}
}
niSyscallAddress := niSyscallSymbol[0].Address
niSyscallAddress := niSyscallSymbol[0].Address()

for i, kernelRestrictionArr := range events.SyscallSymbolNames {
syscallName := t.getSyscallNameByKerVer(kernelRestrictionArr)
Expand Down Expand Up @@ -199,7 +199,7 @@ func (t *Tracee) populateExpectedSyscallTableArray(tableMap *bpf.BPFMap) error {
continue
}

var expectedAddress = kernelSymbol[0].Address
var expectedAddress = kernelSymbol[0].Address()
err = tableMap.Update(unsafe.Pointer(&index), unsafe.Pointer(&expectedAddress))
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions pkg/ebpf/ksymbols.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func (t *Tracee) UpdateKallsyms() error {
// ... and update the eBPF map with the symbol address.
for _, sym := range symbol {
key := make([]byte, maxKsymNameLen)
copy(key, sym.Name)
addr := sym.Address
copy(key, sym.Name())
addr := sym.Address()

// Update the eBPF map with the symbol address.
err := bpfKsymsMap.Update(
Expand Down
20 changes: 10 additions & 10 deletions pkg/ebpf/probes/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (p *TraceProbe) attach(module *bpf.Module, args ...interface{}) error {
var err error
var link *bpf.BPFLink
var attachFunc func(uint64) (*bpf.BPFLink, error)
var syms []environment.KernelSymbol
var syms []*environment.KernelSymbol
// https://github.com/aquasecurity/tracee/issues/3653#issuecomment-1832642225
//
// After commit b022f0c7e404 ('tracing/kprobes: Return EADDRNOTAVAIL
Expand Down Expand Up @@ -141,10 +141,10 @@ func (p *TraceProbe) attach(module *bpf.Module, args ...interface{}) error {
goto rollback
}
if p.probeType == SyscallEnter {
link, err = prog.AttachKprobe(syms[0].Name)
link, err = prog.AttachKprobe(syms[0].Name())
}
if p.probeType == SyscallExit {
link, err = prog.AttachKretprobe(syms[0].Name)
link, err = prog.AttachKretprobe(syms[0].Name())
}
if err != nil {
goto rollback
Expand All @@ -155,21 +155,21 @@ func (p *TraceProbe) attach(module *bpf.Module, args ...interface{}) error {
symsCompat, _ := ksyms.GetSymbolByName(SyscallPrefixCompat + p.eventName)
if len(symsCompat) > 0 {
if p.probeType == SyscallEnter {
link, _ = prog.AttachKprobe(symsCompat[0].Name)
link, _ = prog.AttachKprobe(symsCompat[0].Name())
}
if p.probeType == SyscallExit {
link, _ = prog.AttachKretprobe(symsCompat[0].Name)
link, _ = prog.AttachKretprobe(symsCompat[0].Name())
}
p.bpfLink = append(p.bpfLink, link)
}
// In x86, there are 2 possible compat prefixes - we handle it here
symsCompat, _ = ksyms.GetSymbolByName(SyscallPrefixCompat2 + p.eventName)
if len(symsCompat) > 0 {
if p.probeType == SyscallEnter {
link, _ = prog.AttachKprobe(symsCompat[0].Name)
link, _ = prog.AttachKprobe(symsCompat[0].Name())
}
if p.probeType == SyscallExit {
link, _ = prog.AttachKretprobe(symsCompat[0].Name)
link, _ = prog.AttachKretprobe(symsCompat[0].Name())
}
p.bpfLink = append(p.bpfLink, link)
}
Expand All @@ -188,9 +188,9 @@ func (p *TraceProbe) attach(module *bpf.Module, args ...interface{}) error {
case 1: // single address, attach kprobe using symbol name
switch p.probeType {
case KProbe:
link, err = prog.AttachKprobe(syms[0].Name)
link, err = prog.AttachKprobe(syms[0].Name())
case KretProbe:
link, err = prog.AttachKretprobe(syms[0].Name)
link, err = prog.AttachKretprobe(syms[0].Name())
}
if err != nil {
goto rollback
Expand All @@ -204,7 +204,7 @@ func (p *TraceProbe) attach(module *bpf.Module, args ...interface{}) error {
attachFunc = prog.AttachKretprobeOnOffset
}
for _, sym := range syms {
link, err := attachFunc(sym.Address)
link, err := attachFunc(sym.Address())
if err != nil {
goto rollback
}
Expand Down
14 changes: 7 additions & 7 deletions pkg/ebpf/processor_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func (t *Tracee) processDoInitModule(event *trace.Event) error {

err := capabilities.GetInstance().EBPF(
func() error {
err := t.kernelSymbols.Refresh()
err := t.kernelSymbols.Update()
if err != nil {
return errfmt.WrapError(err)
}
Expand Down Expand Up @@ -281,8 +281,8 @@ func (t *Tracee) processHookedProcFops(event *trace.Event) error {
if addr == 0 { // address is in text segment, marked as 0
continue
}
hookingFunction := utils.ParseSymbol(addr, t.kernelSymbols)
if hookingFunction.Owner == "system" {
hookingFunction := t.kernelSymbols.GetPotentiallyHiddenSymbolByAddr(addr)[0]
if hookingFunction.Owner() == "system" {
continue
}
functionName := "unknown"
Expand All @@ -292,7 +292,7 @@ func (t *Tracee) processHookedProcFops(event *trace.Event) error {
case Iterate:
functionName = "iterate"
}
hookedFops = append(hookedFops, trace.HookedSymbolData{SymbolName: functionName, ModuleOwner: hookingFunction.Owner})
hookedFops = append(hookedFops, trace.HookedSymbolData{SymbolName: functionName, ModuleOwner: hookingFunction.Owner()})
}
err = events.SetArgValue(event, hookedFopsPointersArgName, hookedFops)
if err != nil {
Expand Down Expand Up @@ -326,7 +326,7 @@ func (t *Tracee) processPrintMemDump(event *trace.Event) error {
}

addressUint64 := uint64(address)
symbol := utils.ParseSymbol(addressUint64, t.kernelSymbols)
symbol := t.kernelSymbols.GetPotentiallyHiddenSymbolByAddr(addressUint64)[0]
var utsName unix.Utsname
arch := ""
if err := unix.Uname(&utsName); err != nil {
Expand All @@ -337,11 +337,11 @@ func (t *Tracee) processPrintMemDump(event *trace.Event) error {
if err != nil {
return err
}
err = events.SetArgValue(event, "symbol_name", symbol.Name)
err = events.SetArgValue(event, "symbol_name", symbol.Name())
if err != nil {
return err
}
err = events.SetArgValue(event, "symbol_owner", symbol.Owner)
err = events.SetArgValue(event, "symbol_owner", symbol.Owner())
if err != nil {
return err
}
Expand Down
18 changes: 11 additions & 7 deletions pkg/ebpf/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,16 @@ func (t *Tracee) Init(ctx gocontext.Context) error {

err = capabilities.GetInstance().Specific(
func() error {
t.kernelSymbols, err = environment.NewKernelSymbolTable(
environment.WithRequiredSymbols(t.requiredKsyms),
)
t.kernelSymbols = environment.NewKernelSymbolTable(true, true)
// t.requiredKsyms may contain non-data symbols, but it doesn't affect the validity of this call
t.kernelSymbols.AddRequiredDataSymbols(t.requiredKsyms)
err := t.kernelSymbols.Update()
if err != nil {
return err
}
// Cleanup memory in list
t.requiredKsyms = []string{}
return err
return nil
},
cap.SYSLOG,
)
Expand Down Expand Up @@ -920,7 +924,7 @@ func getUnavailbaleKsymbols(ksymbols []events.KSymbol, kernelSymbols *environmen
continue
}
for _, s := range sym {
if s.Address == 0 {
if s.Address() == 0 {
// Same if the symbol is found but its address is 0.
unavailableSymbols = append(unavailableSymbols, ksymbol)
}
Expand Down Expand Up @@ -1726,7 +1730,7 @@ func (t *Tracee) triggerSeqOpsIntegrityCheck(event trace.Event) {
if err != nil {
continue
}
seqOpsPointers[i] = seqOpsStruct[0].Address
seqOpsPointers[i] = seqOpsStruct[0].Address()
}
eventHandle := t.triggerContexts.Store(event)
_ = t.triggerSeqOpsIntegrityCheckCall(
Expand Down Expand Up @@ -1852,7 +1856,7 @@ func (t *Tracee) triggerMemDump(event trace.Event) []error {
}
}
eventHandle := t.triggerContexts.Store(event)
_ = t.triggerMemDumpCall(symbol[0].Address, length, uint64(eventHandle))
_ = t.triggerMemDumpCall(symbol[0].Address(), length, uint64(eventHandle))
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/events/derive/hooked_seq_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/events/parse"
"github.com/aquasecurity/tracee/pkg/utils"
"github.com/aquasecurity/tracee/pkg/utils/environment"
"github.com/aquasecurity/tracee/types/trace"
)
Expand Down Expand Up @@ -43,11 +42,11 @@ func deriveHookedSeqOpsArgs(kernelSymbols *environment.KernelSymbolTable) derive
if addr == 0 {
continue
}
hookingFunction := utils.ParseSymbol(addr, kernelSymbols)
hookingFunction := kernelSymbols.GetPotentiallyHiddenSymbolByAddr(addr)[0]
seqOpsStruct := NetSeqOps[i/4]
seqOpsFunc := NetSeqOpsFuncs[i%4]
hookedSeqOps[seqOpsStruct+"_"+seqOpsFunc] =
trace.HookedSymbolData{SymbolName: hookingFunction.Name, ModuleOwner: hookingFunction.Owner}
trace.HookedSymbolData{SymbolName: hookingFunction.Name(), ModuleOwner: hookingFunction.Owner()}
}
return []interface{}{hookedSeqOps}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/events/derive/hooked_syscall.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func deriveDetectHookedSyscallArgs(kernelSymbols *environment.KernelSymbolTable)
hookedOwner := ""
hookedFuncSymbol, err := kernelSymbols.GetSymbolByAddr(address)
if err == nil {
hookedFuncName = hookedFuncSymbol[0].Name
hookedOwner = hookedFuncSymbol[0].Owner
hookedFuncName = hookedFuncSymbol[0].Name()
hookedOwner = hookedFuncSymbol[0].Owner()
}

syscallName := convertToSyscallName(syscallId)
Expand Down
Loading

0 comments on commit 421eb9b

Please sign in to comment.