Skip to content

Commit

Permalink
tetragon: Harden loader sensor
Browse files Browse the repository at this point in the history
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
  • Loading branch information
olsajiri committed Jan 26, 2024
1 parent 0430d5b commit 3f78506
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
10 changes: 2 additions & 8 deletions bpf/process/bpf_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ loader_kprobe(struct pt_regs *ctx)
struct perf_mmap_event *mmap_event;
struct execve_map_value *curr;
struct task_struct *current;
struct vm_area_struct *vma;
struct msg_loader *msg;
unsigned long vm_flags;
struct perf_event *pe;
__u64 *id_map, id_pe;
const char *path;
Expand Down Expand Up @@ -110,16 +108,12 @@ loader_kprobe(struct pt_regs *ctx)

mmap_event = (struct perf_mmap_event *)PT_REGS_PARM2_CORE(ctx);

vma = BPF_CORE_READ(mmap_event, vma);
vm_flags = BPF_CORE_READ(vma, vm_flags);

/* We are interested only in exec maps. */
if (!(vm_flags & VM_EXEC))
msg->buildid_size = BPF_CORE_READ(mmap_event, build_id_size);
if (!msg->buildid_size)
return 0;

probe_read(&msg->buildid[0], sizeof(msg->buildid),
_(&mmap_event->build_id[0]));
msg->buildid_size = BPF_CORE_READ(mmap_event, build_id_size);

path = BPF_CORE_READ(mmap_event, file_name);
len = probe_read_str(&msg->path, sizeof(msg->path), path);
Expand Down
43 changes: 42 additions & 1 deletion pkg/sensors/tracing/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"bytes"
"encoding/binary"
"fmt"
"log"
"syscall"
"unsafe"

Expand All @@ -44,9 +45,19 @@ import (
"github.com/cilium/tetragon/pkg/sensors/program"
"github.com/cilium/tetragon/pkg/strutils"
"github.com/cilium/tetragon/pkg/tracingpolicy"
lru "github.com/hashicorp/golang-lru/v2"
"golang.org/x/sys/unix"
)

type cacheKey struct {
Pid uint32
Path string
}

const (
cacheSize = 100
)

var (
loader = program.Builder(
"bpf_loader.o",
Expand All @@ -59,6 +70,8 @@ var (
idsMap = program.MapBuilder("ids_map", loader)

loaderEnabled bool

cache *lru.Cache[cacheKey, bool]
)

type loaderSensor struct {
Expand All @@ -73,6 +86,18 @@ func init() {
sensors.RegisterPolicyHandlerAtInit(loader.name, loader)

observer.RegisterEventHandlerAtInit(ops.MSG_OP_LOADER, handleLoader)

var err error
cache, err = lru.NewWithEvict(
cacheSize,
func(_ cacheKey, _ bool) {
// not used at the moment, let's see if we want to add metric for this
},
)
if err != nil {
log.Fatalf("loader init failed with %v", err)
}

}

func GetLoaderSensor() *sensors.Sensor {
Expand Down Expand Up @@ -110,7 +135,7 @@ func createLoaderEvents() error {
Type: unix.PERF_TYPE_SOFTWARE,
Config: unix.PERF_COUNT_SW_BPF_OUTPUT,
Sample_type: unix.PERF_SAMPLE_RAW,
Bits: unix.PerfBitMmap | unix.PerfBitMmap2 | bpf.PerfBitBuildId,
Bits: unix.PerfBitMmap | unix.PerfBitMmap2 | bpf.PerfBitBuildId | unix.PerfBitMmapData,
}

nCpus := bpf.GetNumPossibleCPUs()
Expand Down Expand Up @@ -156,6 +181,16 @@ func (k *loaderSensor) LoadProbe(args sensors.LoadProbeArgs) error {
return nil
}

func inCache(pid uint32, path string) bool {
key := cacheKey{pid, path}
_, ok := cache.Get(key)
if ok {
return true
}
cache.Add(key, true)
return false
}

func handleLoader(r *bytes.Reader) ([]observer.Event, error) {
m := tracingapi.MsgLoader{}
err := binary.Read(r, binary.LittleEndian, &m)
Expand All @@ -166,6 +201,12 @@ func handleLoader(r *bytes.Reader) ([]observer.Event, error) {

path := m.Path[:m.PathSize-1]

// We can get multiple entries for given pid/path,
// check if we already processed it
if inCache(m.Pid, string(path[:])) {
return nil, nil
}

msg := &tracing.MsgProcessLoaderUnix{
Msg: &m,
Path: strutils.UTF8FromBPFBytes(path),
Expand Down

0 comments on commit 3f78506

Please sign in to comment.