diff --git a/pkg/ebpf/hooked_syscall_table.go b/pkg/ebpf/hooked_syscall_table.go index 95f4bd4d880e..2321f6ac2c99 100644 --- a/pkg/ebpf/hooked_syscall_table.go +++ b/pkg/ebpf/hooked_syscall_table.go @@ -159,17 +159,17 @@ func (t *Tracee) getSyscallNameByKerVer(restrictions []events.KernelRestrictions // populateExpectedSyscallTableArray fills the expected values of the syscall table func (t *Tracee) populateExpectedSyscallTableArray(tableMap *bpf.BPFMap) error { // Get address to the function that defines the not implemented sys call - niSyscallSymbol, err := t.kernelSymbols.GetSymbolByName("system", events.SyscallPrefix+"ni_syscall") + niSyscallSymbol, err := t.kernelSymbols.GetSymbolByOwnerAndName("system", events.SyscallPrefix+"ni_syscall") if err != nil { e := err // RHEL 8.x uses sys_ni_syscall instead of __arch_ni_syscall - niSyscallSymbol, err = t.kernelSymbols.GetSymbolByName("system", "sys_ni_syscall") + niSyscallSymbol, err = t.kernelSymbols.GetSymbolByOwnerAndName("system", "sys_ni_syscall") if err != nil { logger.Debugw("hooked_syscall: syscall symbol not found", "name", "sys_ni_syscall") return e } } - niSyscallAddress := niSyscallSymbol.Address + niSyscallAddress := niSyscallSymbol[0].Address for i, kernelRestrictionArr := range events.SyscallSymbolNames { syscallName := t.getSyscallNameByKerVer(kernelRestrictionArr) @@ -187,13 +187,13 @@ func (t *Tracee) populateExpectedSyscallTableArray(tableMap *bpf.BPFMap) error { continue } - kernelSymbol, err := t.kernelSymbols.GetSymbolByName("system", events.SyscallPrefix+syscallName) + kernelSymbol, err := t.kernelSymbols.GetSymbolByOwnerAndName("system", events.SyscallPrefix+syscallName) if err != nil { logger.Errorw("hooked_syscall: syscall symbol not found", "id", index) return err } - var expectedAddress = kernelSymbol.Address + var expectedAddress = kernelSymbol[0].Address err = tableMap.Update(unsafe.Pointer(&index), unsafe.Pointer(&expectedAddress)) if err != nil { return err diff --git a/pkg/ebpf/ksymbols.go b/pkg/ebpf/ksymbols.go index 00797a0b0943..cfc316ec3a1b 100644 --- a/pkg/ebpf/ksymbols.go +++ b/pkg/ebpf/ksymbols.go @@ -8,24 +8,23 @@ import ( "github.com/aquasecurity/tracee/pkg/errfmt" "github.com/aquasecurity/tracee/pkg/events" - "github.com/aquasecurity/tracee/pkg/utils/ksyms" ) 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) +func LoadKallsymsValues(ksymsTable *helpers.KernelSymbolTable, ksymbols []string) map[string]helpers.KernelSymbol { + kallsymsMap := make(map[string]helpers.KernelSymbol) for _, name := range ksymbols { - symbol, err := ksymsTable.GetSymbolByName(globalSymbolOwner, name) + symbol, err := ksymsTable.GetSymbolByOwnerAndName(globalSymbolOwner, name) if err == nil { - kallsymsMap[name] = symbol + kallsymsMap[name] = symbol[0] } } return kallsymsMap } -func SendKsymbolsToMap(bpfKsymsMap *libbpfgo.BPFMap, ksymbols map[string]*helpers.KernelSymbol) error { +func SendKsymbolsToMap(bpfKsymsMap *libbpfgo.BPFMap, ksymbols map[string]helpers.KernelSymbol) error { for ksymName, value := range ksymbols { key := make([]byte, maxKsymNameLen) copy(key, ksymName) @@ -38,18 +37,6 @@ func SendKsymbolsToMap(bpfKsymsMap *libbpfgo.BPFMap, ksymbols map[string]*helper return nil } -func (t *Tracee) NewKernelSymbols() error { - // reading kallsyms needs CAP_SYSLOG - kernelSymbols, err := ksyms.NewSafeKsymbolTable() - if err != nil { - return errfmt.WrapError(err) - } - - t.kernelSymbols = kernelSymbols - - return nil -} - func (t *Tracee) UpdateKernelSymbols() error { return t.kernelSymbols.Refresh() } diff --git a/pkg/ebpf/tracee.go b/pkg/ebpf/tracee.go index b7a45cf1a8f5..f3768ad396c2 100644 --- a/pkg/ebpf/tracee.go +++ b/pkg/ebpf/tracee.go @@ -78,7 +78,7 @@ type Tracee struct { // Internal Data readFiles map[string]string pidsInMntns bucketscache.BucketsCache // first n PIDs in each mountns - kernelSymbols helpers.KernelSymbolTable + kernelSymbols *helpers.KernelSymbolTable // eBPF bpfModule *bpf.Module probes *probes.ProbeGroup @@ -342,28 +342,22 @@ func New(cfg config.Config) (*Tracee, error) { // initialization logic, especially one that causes side effects, should go // here and not New(). func (t *Tracee) Init(ctx gocontext.Context) error { - // Initialize needed values - - initReq, err := t.generateInitValues() - if err != nil { - return errfmt.Errorf("failed to generate required init values: %s", err) - } + var err error // Init kernel symbols map - if initReq.Kallsyms { - err = capabilities.GetInstance().Specific( - func() error { - return t.NewKernelSymbols() - }, - cap.SYSLOG, - ) - if err != nil { - return errfmt.WrapError(err) - } + err = capabilities.GetInstance().Specific( + func() error { + t.kernelSymbols, err = helpers.NewKernelSymbolTable() + return err + }, + cap.SYSLOG, + ) + if err != nil { + return errfmt.WrapError(err) } - t.validateKallsymsDependencies() // Canceling events missing kernel symbols + t.validateKallsymsDependencies() // disable events w/ missing ksyms dependencies // Initialize buckets cache @@ -537,7 +531,6 @@ func (t *Tracee) Init(ctx gocontext.Context) error { return nil } -// InitValues determines if to initialize values that might be needed by eBPF programs type InitValues struct { Kallsyms bool } @@ -1691,11 +1684,11 @@ func (t *Tracee) triggerSeqOpsIntegrityCheck(event trace.Event) { } var seqOpsPointers [len(derive.NetSeqOps)]uint64 for i, seqName := range derive.NetSeqOps { - seqOpsStruct, err := t.kernelSymbols.GetSymbolByName("system", seqName) + seqOpsStruct, err := t.kernelSymbols.GetSymbolByOwnerAndName("system", seqName) if err != nil { continue } - seqOpsPointers[i] = seqOpsStruct.Address + seqOpsPointers[i] = seqOpsStruct[0].Address } eventHandle := t.triggerContexts.Store(event) _ = t.triggerSeqOpsIntegrityCheckCall( @@ -1780,7 +1773,7 @@ func (t *Tracee) triggerMemDump(event trace.Event) []error { continue } - symbol, err := t.kernelSymbols.GetSymbolByName(owner, name) + symbol, err := t.kernelSymbols.GetSymbolByOwnerAndName(owner, name) if err != nil { if owner != "system" { errs = append(errs, errfmt.Errorf("policy %d: invalid symbols provided to print_mem_dump event: %s - %v", p.ID, field, err)) @@ -1792,7 +1785,7 @@ func (t *Tracee) triggerMemDump(event trace.Event) []error { prefixes := []string{"sys_", "__x64_sys_", "__arm64_sys_"} var errSyscall error for _, prefix := range prefixes { - symbol, errSyscall = t.kernelSymbols.GetSymbolByName(owner, prefix+name) + symbol, errSyscall = t.kernelSymbols.GetSymbolByOwnerAndName(owner, prefix+name) if errSyscall == nil { err = nil break @@ -1816,7 +1809,7 @@ func (t *Tracee) triggerMemDump(event trace.Event) []error { } } eventHandle := t.triggerContexts.Store(event) - _ = t.triggerMemDumpCall(symbol.Address, length, uint64(eventHandle)) + _ = t.triggerMemDumpCall(symbol[0].Address, length, uint64(eventHandle)) } } } diff --git a/pkg/events/derive/hooked_seq_ops.go b/pkg/events/derive/hooked_seq_ops.go index a1a35b033422..585cd9f315ef 100644 --- a/pkg/events/derive/hooked_seq_ops.go +++ b/pkg/events/derive/hooked_seq_ops.go @@ -28,11 +28,11 @@ var NetSeqOpsFuncs = [4]string{ "stop", } -func HookedSeqOps(kernelSymbols helpers.KernelSymbolTable) DeriveFunction { +func HookedSeqOps(kernelSymbols *helpers.KernelSymbolTable) DeriveFunction { return deriveSingleEvent(events.HookedSeqOps, deriveHookedSeqOpsArgs(kernelSymbols)) } -func deriveHookedSeqOpsArgs(kernelSymbols helpers.KernelSymbolTable) deriveArgsFunction { +func deriveHookedSeqOpsArgs(kernelSymbols *helpers.KernelSymbolTable) deriveArgsFunction { return func(event trace.Event) ([]interface{}, error) { seqOpsArr, err := parse.ArgVal[[]uint64](event.Args, "net_seq_ops") if err != nil || len(seqOpsArr) < 1 { diff --git a/pkg/events/derive/hooked_syscall.go b/pkg/events/derive/hooked_syscall.go index f36c82e3a36b..c1aacb8c7838 100644 --- a/pkg/events/derive/hooked_syscall.go +++ b/pkg/events/derive/hooked_syscall.go @@ -28,11 +28,11 @@ func InitHookedSyscall() error { return err } -func DetectHookedSyscall(kernelSymbols helpers.KernelSymbolTable) DeriveFunction { +func DetectHookedSyscall(kernelSymbols *helpers.KernelSymbolTable) DeriveFunction { return deriveSingleEvent(events.HookedSyscall, deriveDetectHookedSyscallArgs(kernelSymbols)) } -func deriveDetectHookedSyscallArgs(kernelSymbols helpers.KernelSymbolTable) deriveArgsFunction { +func deriveDetectHookedSyscallArgs(kernelSymbols *helpers.KernelSymbolTable) deriveArgsFunction { return func(event trace.Event) ([]interface{}, error) { syscallId, err := parse.ArgVal[int32](event.Args, "syscall_id") if err != nil { @@ -55,8 +55,8 @@ func deriveDetectHookedSyscallArgs(kernelSymbols helpers.KernelSymbolTable) deri hookedOwner := "" hookedFuncSymbol, err := kernelSymbols.GetSymbolByAddr(address) if err == nil { - hookedFuncName = hookedFuncSymbol.Name - hookedOwner = hookedFuncSymbol.Owner + hookedFuncName = hookedFuncSymbol[0].Name + hookedOwner = hookedFuncSymbol[0].Owner } syscallName := convertToSyscallName(syscallId) diff --git a/pkg/utils/ksyms/safe_ksym_table.go b/pkg/utils/ksyms/safe_ksym_table.go deleted file mode 100644 index b36a1d9cc3a4..000000000000 --- a/pkg/utils/ksyms/safe_ksym_table.go +++ /dev/null @@ -1,49 +0,0 @@ -package ksyms - -import ( - "sync" - - "github.com/aquasecurity/libbpfgo/helpers" -) - -type safeKsymbolTable struct { - helpers.KernelSymbolTable - l *sync.Mutex -} - -// NewSafeKsymbolTable returns a safe wrapper for implementations of the KernelSymbolTable interface. -// The wrapper is needed because provided implementations do not guarentee thread-safety. -func NewSafeKsymbolTable() (*safeKsymbolTable, error) { - table, err := helpers.NewLazyKernelSymbolsMap() - if err != nil { - return nil, err - } - - return &safeKsymbolTable{ - table, new(sync.Mutex), - }, nil -} - -func (t *safeKsymbolTable) TextSegmentContains(addr uint64) (bool, error) { - t.l.Lock() - defer t.l.Unlock() - return t.KernelSymbolTable.TextSegmentContains(addr) -} - -func (t *safeKsymbolTable) GetSymbolByName(owner string, name string) (*helpers.KernelSymbol, error) { - t.l.Lock() - defer t.l.Unlock() - return t.KernelSymbolTable.GetSymbolByName(owner, name) -} - -func (t *safeKsymbolTable) GetSymbolByAddr(addr uint64) (*helpers.KernelSymbol, error) { - t.l.Lock() - defer t.l.Unlock() - return t.KernelSymbolTable.GetSymbolByAddr(addr) -} - -func (t *safeKsymbolTable) Refresh() error { - t.l.Lock() - defer t.l.Unlock() - return t.KernelSymbolTable.Refresh() -} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 3d9ceb8aae23..319153fe3878 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -13,14 +13,20 @@ type Cloner interface { Clone() Cloner } -func ParseSymbol(address uint64, table helpers.KernelSymbolTable) *helpers.KernelSymbol { - hookingFunction, err := table.GetSymbolByAddr(address) +func ParseSymbol(address uint64, table *helpers.KernelSymbolTable) helpers.KernelSymbol { + var hookingFunction helpers.KernelSymbol + + symbols, err := table.GetSymbolByAddr(address) if err != nil { - hookingFunction = &helpers.KernelSymbol{} + hookingFunction = helpers.KernelSymbol{} hookingFunction.Owner = "hidden" + } else { + hookingFunction = symbols[0] } + hookingFunction.Owner = strings.TrimPrefix(hookingFunction.Owner, "[") hookingFunction.Owner = strings.TrimSuffix(hookingFunction.Owner, "]") + return hookingFunction }