Skip to content

Commit

Permalink
fix(events): derive multiple hooked_syscall events if needed
Browse files Browse the repository at this point in the history
After running the init function of a kernel module, the kernel frees the memory that was allocated for it but doesn't remove its symbol from kallsyms.
This resulsts in a scenario where a subsequent loaded module can be allocated to the same area as the free'd init function of the prevous module.
This could result in 2 symbols at the same address, one is the free'd init function and another from the newly loaded module.
This caused an undeterminism in which symbol is used by the hooked_syscall event, which only used the first symbol that was found, resulting in random test failures.
This commit changes the hooked_syscall event to emit one event for each found symbol.
  • Loading branch information
oshaked1 committed Jan 1, 2025
1 parent 321a1df commit eaa12ab
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions pkg/events/derive/hooked_syscall.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ func InitHookedSyscall() error {
}

func DetectHookedSyscall(kernelSymbols *environment.KernelSymbolTable) DeriveFunction {
return deriveSingleEvent(events.HookedSyscall, deriveDetectHookedSyscallArgs(kernelSymbols))
return deriveMultipleEvents(events.HookedSyscall, deriveDetectHookedSyscallArgs(kernelSymbols))
}

func deriveDetectHookedSyscallArgs(kernelSymbols *environment.KernelSymbolTable) deriveArgsFunction {
return func(event trace.Event) ([]interface{}, error) {
func deriveDetectHookedSyscallArgs(kernelSymbols *environment.KernelSymbolTable) multiDeriveArgsFunction {
return func(event trace.Event) ([][]interface{}, []error) {
syscallId, err := parse.ArgVal[int32](event.Args, "syscall_id")
if err != nil {
return nil, errfmt.Errorf("error parsing syscall_id arg: %v", err)
return nil, []error{errfmt.Errorf("error parsing syscall_id arg: %v", err)}
}

address, err := parse.ArgVal[uint64](event.Args, "syscall_address")
if err != nil {
return nil, errfmt.Errorf("error parsing syscall_address arg: %v", err)
return nil, []error{errfmt.Errorf("error parsing syscall_address arg: %v", err)}
}

alreadyReportedAddress, found := reportedHookedSyscalls.Get(syscallId)
Expand All @@ -50,18 +50,20 @@ func deriveDetectHookedSyscallArgs(kernelSymbols *environment.KernelSymbolTable)

reportedHookedSyscalls.Add(syscallId, address) // Upsert

hookedFuncName := ""
hookedOwner := ""
hookedFuncSymbol, err := kernelSymbols.GetSymbolByAddr(address)
if err == nil {
hookedFuncName = hookedFuncSymbol[0].Name
hookedOwner = hookedFuncSymbol[0].Owner
}

syscallName := convertToSyscallName(syscallId)
hexAddress := fmt.Sprintf("%x", address)

return []interface{}{syscallName, hexAddress, hookedFuncName, hookedOwner}, nil
hookedFuncSymbols, err := kernelSymbols.GetSymbolByAddr(address)
if err != nil {
return [][]interface{}{{syscallName, hexAddress, "", ""}}, nil
}

events := make([][]interface{}, 0)
for _, symbol := range hookedFuncSymbols {
events = append(events, []interface{}{syscallName, hexAddress, symbol.Name, symbol.Owner})
}

return events, nil
}
}

Expand Down

0 comments on commit eaa12ab

Please sign in to comment.