Skip to content

Commit

Permalink
Emit a warning if find_vma is not supported
Browse files Browse the repository at this point in the history
Avoid running the test altogether on unsupported kernels so that the warning doesn't fail the test.
  • Loading branch information
oshaked1 committed Oct 21, 2024
1 parent 85cdfcc commit 095ae59
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 34 deletions.
9 changes: 9 additions & 0 deletions pkg/ebpf/bpf_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ const (

// hidden kernel module functions
BPFLogIDHidKerMod

// find vma not supported
BPFLogIDFindVMAUnsupported // BPF_LOG_FIND_VMA_UNSUPPORTED
)

var stringMap = map[BPFLogType]string{
Expand All @@ -49,6 +52,9 @@ var stringMap = map[BPFLogType]string{

// hidden kernel module functions
BPFLogIDHidKerMod: "BPF_LOG_ID_HID_KER_MOD",

// find vma not supported
BPFLogIDFindVMAUnsupported: "BPF_LOG_FIND_VMA_UNSUPPORTED",
}

var errorMap = map[BPFLogType]string{
Expand All @@ -67,6 +73,9 @@ var errorMap = map[BPFLogType]string{

// hidden kernel module functions
BPFLogIDHidKerMod: "Failure in hidden kernel module seeker logic",

// find vma not supported
BPFLogIDFindVMAUnsupported: "Finding VMAs is not supported in this kernel",
}

func (b BPFLogType) String() string {
Expand Down
13 changes: 10 additions & 3 deletions pkg/ebpf/c/common/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ statfunc unsigned long get_env_start_from_mm(struct mm_struct *);
statfunc unsigned long get_env_end_from_mm(struct mm_struct *);
statfunc unsigned long get_vma_flags(struct vm_area_struct *);
statfunc unsigned long get_vma_start(struct vm_area_struct *);
statfunc struct vm_area_struct *find_vma(struct task_struct *task, u64 addr);
statfunc struct vm_area_struct *find_vma(void *ctx, struct task_struct *task, u64 addr);
statfunc bool vma_is_stack(struct vm_area_struct *vma);
statfunc bool vma_is_heap(struct vm_area_struct *vma);
statfunc bool vma_is_anon(struct vm_area_struct *vma);
Expand Down Expand Up @@ -74,17 +74,24 @@ statfunc unsigned long get_vma_start(struct vm_area_struct *vma)
*/
#define MAX_VMA_RB_TREE_DEPTH 25

static bool alerted_no_mm_rb = false;

// Given a task, find the first VMA which contains the given address.
statfunc struct vm_area_struct *find_vma(struct task_struct *task, u64 addr)
statfunc struct vm_area_struct *find_vma(void *ctx, struct task_struct *task, u64 addr)
{
/**
* TODO: from kernel version 6.1, the data structure with which VMAs
* are managed changed from an RB tree to a maple tree.
* We currently don't support finding VMAs on such systems.
*/
struct mm_struct *mm = BPF_CORE_READ(task, mm);
if (!bpf_core_field_exists(mm->mm_rb))
if (!bpf_core_field_exists(mm->mm_rb)) {
if (!alerted_no_mm_rb) {
tracee_log(ctx, BPF_LOG_LVL_WARN, BPF_LOG_FIND_VMA_UNSUPPORTED, 0);
alerted_no_mm_rb = true;
}
return NULL;
}

// TODO: we don't support NOMMU systems yet (looking up VMAs on them requires walking the VMA
// linked list)
Expand Down
2 changes: 1 addition & 1 deletion pkg/ebpf/c/tracee.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5228,7 +5228,7 @@ int BPF_KPROBE(check_syscall_source)
struct task_struct *task = (struct task_struct *) bpf_get_current_task();
if (unlikely(task == NULL))
return 0;
struct vm_area_struct *vma = find_vma(task, ip);
struct vm_area_struct *vma = find_vma(ctx, task, ip);
if (unlikely(vma == NULL))
return 0;

Expand Down
3 changes: 3 additions & 0 deletions pkg/ebpf/c/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ enum bpf_log_id

// hidden kernel module functions
BPF_LOG_ID_HID_KER_MOD,

// find vma not supported
BPF_LOG_FIND_VMA_UNSUPPORTED,
};

typedef struct bpf_log {
Expand Down
30 changes: 0 additions & 30 deletions tests/e2e-inst-signatures/e2e-check_syscall_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package main
import (
"fmt"

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

"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/signatures/helpers"
"github.com/aquasecurity/tracee/types/detect"
Expand All @@ -14,7 +12,6 @@ import (

type e2eCheckSyscallSource struct {
cb detect.SignatureHandler
hasMapleTree bool
foundStack bool
foundHeap bool
foundAnonVma bool
Expand All @@ -23,19 +20,6 @@ type e2eCheckSyscallSource struct {
func (sig *e2eCheckSyscallSource) Init(ctx detect.SignatureContext) error {
sig.cb = ctx.Callback

// Find if this system uses maple trees to manage VMAs.
// If so we don't expect any check_syscall_source event to be submitted.
ksyms, err := libbpfgo.NewKernelSymbolsMap()
if err != nil {
return err
}
_, err = ksyms.GetSymbolByName("system", "mt_find")
if err != nil {
sig.hasMapleTree = false
} else {
sig.hasMapleTree = true
}

return nil
}

Expand All @@ -53,7 +37,6 @@ func (sig *e2eCheckSyscallSource) GetMetadata() (detect.SignatureMetadata, error
func (sig *e2eCheckSyscallSource) GetSelectedEvents() ([]detect.SignatureEventSelector, error) {
return []detect.SignatureEventSelector{
{Source: "tracee", Name: "check_syscall_source"},
{Source: "tracee", Name: "init_namespaces"}, // This event always happens so we can pass the test on unsupported kernels
}, nil
}

Expand All @@ -64,19 +47,6 @@ func (sig *e2eCheckSyscallSource) OnEvent(event protocol.Event) error {
}

switch eventObj.EventName {
case "init_namespaces":
// If the system uses maple trees we won't get any check_syscall_source events, pass the test
if sig.hasMapleTree {
m, _ := sig.GetMetadata()

sig.cb(&detect.Finding{
SigMetadata: m,
Event: event,
Data: map[string]interface{}{},
})

return nil
}
case "check_syscall_source":
syscall, err := helpers.GetTraceeIntArgumentByName(eventObj, "syscall")
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions tests/e2e-inst-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ for TEST in $TESTS; do
fi
"${TESTS_DIR}"/ftrace_hook.sh
;;
CHECK_SYSCALL_SOURCE)
if cat /proc/kallsyms | grep -qP "trace.*vma_store"; then
info "skip check_syscall_source test on kernel $(uname -r) (VMAs stored in maple tree)"
continue
fi
;;
esac

# Run tracee
Expand Down

0 comments on commit 095ae59

Please sign in to comment.