Skip to content

Commit

Permalink
Bugfix: 32-bit compat program false positive
Browse files Browse the repository at this point in the history
32-bit programs on x86-64 may use a fast syscall method, whose code resides in the VDSO VMA.
This VMA is not  file backed, so it was incorrectly detected as anonymous memory.
  • Loading branch information
oshaked1 committed Jun 5, 2024
1 parent 2c2c067 commit 03d7be9
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 12 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/IBM/fluent-forward-go v0.2.1
github.com/Masterminds/sprig/v3 v3.2.3
github.com/aquasecurity/libbpfgo v0.7.0-libbpf-1.4
github.com/aquasecurity/libbpfgo/helpers v0.4.5
github.com/aquasecurity/tracee/api v0.0.0-20240531131043-a237ddf7b190
github.com/aquasecurity/tracee/signatures/helpers v0.0.0-20240404084547-37dc481cd60c
github.com/aquasecurity/tracee/types v0.0.0-20240122122429-7f84f526758d
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRB
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
github.com/aquasecurity/libbpfgo v0.7.0-libbpf-1.4 h1:rQ94U12Xlz2tncE8Rxnw3vpp/9hgUIEu3/Lv0/XQM0Q=
github.com/aquasecurity/libbpfgo v0.7.0-libbpf-1.4/go.mod h1:iI7QCIZ3kXG0MR+FHsDZck6cYs1y1HyZP3sMObBg0sk=
github.com/aquasecurity/libbpfgo/helpers v0.4.5 h1:eCoLclL3yqv4N9jqGL3T/ckrLPms2r13C4V2xtU75yc=
github.com/aquasecurity/libbpfgo/helpers v0.4.5/go.mod h1:j/TQLmsZpOIdF3CnJODzYngG4yu1YoDCoRMELxkQSSA=
github.com/aquasecurity/tracee/api v0.0.0-20240531131043-a237ddf7b190 h1:NJ69oeaA2kcRxrt7YFHVrUHujXCtiee8Re69npcbmHk=
github.com/aquasecurity/tracee/api v0.0.0-20240531131043-a237ddf7b190/go.mod h1:jXLAr/iFkfaNTuNcdbx2blngdMD/qaAfxQe9rCL9jwk=
github.com/aquasecurity/tracee/signatures/helpers v0.0.0-20240122160245-67dec940088c h1:Gms5lUHPIq+OpI5HjcZ+l0NZHhSwBd/47nyUZY89c+M=
github.com/aquasecurity/tracee/signatures/helpers v0.0.0-20240122160245-67dec940088c/go.mod h1:SSh6X96P8pT/9B6eBl6ptBo8QnaSCNCZHMOZ1iXyPUw=
github.com/aquasecurity/tracee/signatures/helpers v0.0.0-20240404084547-37dc481cd60c h1:bmv9GWkpNlqVMDR8z6GuntbQvr5U7o76bWKZ+RNXK+I=
github.com/aquasecurity/tracee/signatures/helpers v0.0.0-20240404084547-37dc481cd60c/go.mod h1:SSh6X96P8pT/9B6eBl6ptBo8QnaSCNCZHMOZ1iXyPUw=
github.com/aquasecurity/tracee/types v0.0.0-20240122122429-7f84f526758d h1:6CQjy5G6Cj/VKm8RP1uZnBZxDgfyGo15HfWFnYrkGro=
Expand Down
4 changes: 2 additions & 2 deletions pkg/ebpf/c/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ statfunc const char *get_device_name(struct device *dev)
#define has_prefix(p, s, n) \
({ \
int rc = 0; \
char *pre = p, *str = s; \
const char *pre = p, *str = s; \
_Pragma("unroll") for (int z = 0; z < n; pre++, str++, z++) \
{ \
if (!*pre) { \
Expand All @@ -49,7 +49,7 @@ statfunc const char *get_device_name(struct device *dev)

#else

static __inline int has_prefix(char *prefix, char *str, int n)
static __inline int has_prefix(const char *prefix, const char *str, int n)
{
int i;
#pragma unroll
Expand Down
12 changes: 12 additions & 0 deletions pkg/ebpf/c/common/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ statfunc unsigned long get_vma_start(struct vm_area_struct *);
statfunc struct vm_area_struct *find_vma(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);
statfunc bool vma_is_vdso(struct vm_area_struct *vma);

// FUNCTIONS

Expand Down Expand Up @@ -156,4 +158,14 @@ statfunc bool vma_is_anon(struct vm_area_struct *vma)
return BPF_CORE_READ(vma, vm_file) == NULL;
}

statfunc bool vma_is_vdso(struct vm_area_struct *vma)
{
struct vm_special_mapping *special_mapping =
(struct vm_special_mapping *) BPF_CORE_READ(vma, vm_private_data);
if (special_mapping == NULL)
return false;

return has_prefix("[vdso]", BPF_CORE_READ(special_mapping, name), 6) == 0;
}

#endif
3 changes: 2 additions & 1 deletion pkg/ebpf/c/tracee.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5117,8 +5117,9 @@ statfunc enum vma_type get_vma_type(struct vm_area_struct *vma)
if (vma_is_heap(vma))
return VMA_HEAP;

if (vma_is_anon(vma))
if (vma_is_anon(vma) && !vma_is_vdso(vma)) {
return VMA_ANON;
}

return VMA_OTHER;
}
Expand Down
12 changes: 12 additions & 0 deletions pkg/ebpf/c/vmlinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,16 @@ struct rb_node {
struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));

struct vm_area_struct;

struct vm_operations_struct {
const char *(*name)(struct vm_area_struct *vma);
};

struct vm_special_mapping {
const char *name;
};

struct vm_area_struct {
union {
struct {
Expand All @@ -299,7 +309,9 @@ struct vm_area_struct {
struct rb_node vm_rb;
struct mm_struct *vm_mm;
long unsigned int vm_flags;
const struct vm_operations_struct *vm_ops;
struct file *vm_file;
void *vm_private_data;
};

typedef unsigned int __kernel_gid32_t;
Expand Down
2 changes: 1 addition & 1 deletion pkg/ebpf/event_filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (t *Tracee) populateEventFilterMaps() error {
eventFilters := map[string]filters.Filter[*filters.StringFilter]{}
for it := t.config.Policies.CreateAllIterator(); it.HasNext(); {
p := it.Next()
f := p.ArgFilter.GetEventFilters(eventID)
f := p.DataFilter.GetEventFilters(eventID)
if len(f) == 0 {
continue
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/ebpf/initialization/kconfig.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package initialization

import (
"github.com/aquasecurity/libbpfgo/helpers"
"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/pkg/utils/environment"
Expand All @@ -11,7 +10,7 @@ import (
// Add here all kconfig variables used within tracee.bpf.c
const (
CONFIG_ARCH_HAS_SYSCALL_WRAPPER environment.KernelConfigOption = iota + environment.CUSTOM_OPTION_START
CONFIG_MMU helpers.KernelConfigOption = iota + helpers.CUSTOM_OPTION_START
CONFIG_MMU environment.KernelConfigOption = iota + environment.CUSTOM_OPTION_START
)

var kconfigUsed = map[environment.KernelConfigOption]string{
Expand All @@ -36,7 +35,7 @@ func LoadKconfigValues(kc *environment.KernelConfig) (map[environment.KernelConf
values[key] = environment.UNDEFINED
}
values[CONFIG_ARCH_HAS_SYSCALL_WRAPPER] = environment.BUILTIN // assume CONFIG_ARCH_HAS_SYSCALL_WRAPPER is a BUILTIN option
values[CONFIG_MMU] = helpers.BUILTIN // assume CONFIG_MMU is a BUILTIN option
values[CONFIG_MMU] = environment.BUILTIN // assume CONFIG_MMU is a BUILTIN option
} else {
for key := range kconfigUsed {
values[key] = kc.GetValue(key) // undefined, builtin OR module
Expand Down
6 changes: 3 additions & 3 deletions tests/e2e-inst-signatures/e2e-check_syscall_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package main
import (
"fmt"

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

"github.com/aquasecurity/tracee/signatures/helpers"
"github.com/aquasecurity/tracee/types/detect"
Expand All @@ -24,11 +24,11 @@ func (sig *e2eCheckSyscallSource) Init(ctx detect.SignatureContext) error {

// 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 := libbfgo.NewKernelSymbolTable()
ksyms, err := libbpfgo.NewKernelSymbolsMap()
if err != nil {
return err
}
_, err = ksyms.GetSymbolByName("mt_find")
_, err = ksyms.GetSymbolByName("system", "mt_find")
if err != nil {
sig.hasMapleTree = false
} else {
Expand Down

0 comments on commit 03d7be9

Please sign in to comment.