Skip to content

Commit

Permalink
fix(events): add kernel-granularity support for hooked_syscall event
Browse files Browse the repository at this point in the history
  • Loading branch information
OriGlassman authored and randomname21 committed Oct 26, 2023
1 parent 1f946be commit da2a309
Show file tree
Hide file tree
Showing 3 changed files with 1,024 additions and 909 deletions.
102 changes: 100 additions & 2 deletions pkg/ebpf/hooked_syscall_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (
"unsafe"

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

"github.com/aquasecurity/tracee/pkg/capabilities"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/events/derive"
"github.com/aquasecurity/tracee/pkg/logger"
Expand Down Expand Up @@ -44,7 +46,12 @@ func (t *Tracee) hookedSyscallTableRoutine(ctx gocontext.Context) {
return
}

if err := t.populateExpectedSyscallTableArray(expectedSyscallTableMap); err != nil {
err = capabilities.GetInstance().EBPF(
func() error {
return t.populateExpectedSyscallTableArray(expectedSyscallTableMap)
},
)
if err != nil {
logger.Errorw("Error populating expected syscall table array: " + err.Error())
return
}
Expand All @@ -64,6 +71,91 @@ func (t *Tracee) hookedSyscallTableRoutine(ctx gocontext.Context) {
}
}

// isAboveSatisfied is 'above' requirement satisfied
func (t *Tracee) isAboveSatisfied(aboveRequirement string) (bool, error) {
kerVerCmpAbove, err := t.config.OSInfo.CompareOSBaseKernelRelease(aboveRequirement)
if err != nil {
return false, err
}

if kerVerCmpAbove == helpers.KernelVersionOlder || kerVerCmpAbove == helpers.KernelVersionEqual { // above requirement is older/equal running kernel (aka satisfies requirement)
return true, nil
}

return false, nil
}

// isBelowSatisfied is 'below' requirement satisfied
func (t *Tracee) isBelowSatisfied(belowRequirement string) (bool, error) {
kerVerCmpBelow, err := t.config.OSInfo.CompareOSBaseKernelRelease(belowRequirement)
if err != nil {
return false, err
}

if kerVerCmpBelow == helpers.KernelVersionNewer { // below requirement is newer than running kernel (aka satisfies requirement)
return true, nil
}

return false, nil
}

// getSyscallNameByKerVer searches for a syscall name that satisfies 'above' and 'below' kernel version requirements
// in comparison with the current running kernel.
// 'below' requirement is exclusive, 'above' is inclusive.
// For example, for running kernel 6.2, 'below'==6.2 is NOT a match, whereas 'above'==6.2 is a match.
func (t *Tracee) getSyscallNameByKerVer(restrictions []events.KernelRestrictions) string {
for _, restriction := range restrictions {
below := restriction.Below
above := restriction.Above

if above == "" && below == "" {
// no requirements - found a match
return restriction.Name
}

if below != "" {
// There's a 'below' requirement - check it
isMatch, err := t.isBelowSatisfied(below)
if err != nil {
return ""
}

if !isMatch {
continue
}

// 'below' match - is there an 'above' requirement?

if above == "" { // no above - we found a match
return restriction.Name
}

// Check match with 'above'

isMatch, err = t.isAboveSatisfied(above)
if err != nil {
return ""
}

if isMatch {
// Both requirements pass - found a match
return restriction.Name
}
} else if above != "" {
// If we're here then we only have 'above' requirement
isMatch, err := t.isAboveSatisfied(above)
if err != nil {
return ""
}

if isMatch {
return restriction.Name
}
}
}
return "" // no match found - kernel does not support this syscall
}

// 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
Expand All @@ -73,7 +165,12 @@ func (t *Tracee) populateExpectedSyscallTableArray(tableMap *bpf.BPFMap) error {
}
niSyscallAddress := niSyscallSymbol.Address

for i, syscallName := range events.SyscallSymbolNames {
for i, kernelRestrictionArr := range events.SyscallSymbolNames {
syscallName := t.getSyscallNameByKerVer(kernelRestrictionArr)
if syscallName == "" {
logger.Debugw("hooked_syscall: skipping syscall", "index", i)
continue
}
var index = uint32(i)

if strings.HasPrefix(syscallName, events.SyscallNotImplemented) {
Expand All @@ -86,6 +183,7 @@ func (t *Tracee) populateExpectedSyscallTableArray(tableMap *bpf.BPFMap) error {

kernelSymbol, err := t.kernelSymbols.GetSymbolByName("system", events.SyscallPrefix+syscallName)
if err != nil {
logger.Errorw("hooked_syscall: syscall symbol not found", "id", index)
return err
}

Expand Down
Loading

0 comments on commit da2a309

Please sign in to comment.