Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ DOCKERFILE_PATH=./build/Dockerfile
BINARY_NAME=node-agent

IMAGE?=quay.io/kubescape/$(BINARY_NAME)
GADGETS=advise_seccomp trace_capabilities trace_dns trace_exec trace_open
GADGETS=advise_seccomp trace_capabilities trace_dns trace_exec
VERSION=v0.48.1
KUBESCAPE_GADGETS=bpf exit fork hardlink http iouring_new iouring_old kmod network ptrace randomx ssh symlink unshare
KUBESCAPE_GADGETS=bpf exit fork hardlink http iouring_new iouring_old kmod network ptrace randomx ssh symlink trace_open unshare
TAG?=test
# TAG?=v0.0.1

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,5 @@ require (
)

replace github.com/inspektor-gadget/inspektor-gadget => github.com/matthyx/inspektor-gadget v0.0.0-20260203101533-6ef87216d3dd

replace github.com/kubescape/storage => github.com/k8sstormcenter/storage v0.0.240-0.20260212190935-ef26bee09329
3,011 changes: 3,011 additions & 0 deletions go.sum

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions pkg/containerwatcher/v2/tracers/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package tracers

import (
"context"
"strconv"

"github.com/inspektor-gadget/inspektor-gadget/pkg/datasource"
gadgetcontext "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-context"
Expand All @@ -19,7 +18,7 @@ import (
)

const (
openImageName = "ghcr.io/inspektor-gadget/gadget/trace_open:v0.48.1"
openImageName = "trace_open:latest"
openTraceName = "trace_open"
)

Expand Down Expand Up @@ -70,7 +69,7 @@ func (ot *OpenTracer) Start(ctx context.Context) error {
)
go func() {
params := map[string]string{
"operator.oci.ebpf.paths": strconv.FormatBool(ot.cfg.EnableFullPathTracing),
"operator.oci.ebpf.paths": "true", //strconv.FormatBool(ot.cfg.EnableFullPathTracing),
"operator.LocalManager.host": "true", // don't error if container-collection is nil when using local manager
}
err := ot.runtime.RunGadget(ot.gadgetCtx, nil, params)
Expand Down
10 changes: 10 additions & 0 deletions pkg/ebpf/gadgets/trace_open/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
IMAGE?=trace_open
TAG?=latest

build:
sudo TMPDIR=$$TMPDIR ig image build -t $(IMAGE):$(TAG) .

run:
sudo ig run $(IMAGE):$(TAG) --verify-image=false -o jsonpretty

build-and-run: build run
50 changes: 50 additions & 0 deletions pkg/ebpf/gadgets/trace_open/gadget.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: trace open
description: trace open files
homepageURL: https://inspektor-gadget.io/
documentationURL: https://www.inspektor-gadget.io/docs/latest/gadgets/trace_open
sourceURL: https://github.com/inspektor-gadget/inspektor-gadget/tree/main/gadgets/trace_open
datasources:
open:
fields:
flags_raw:
annotations:
columns.hidden: true
flags:
annotations:
columns.hidden: true
columns.width: 10
mode_raw:
annotations:
columns.hidden: true
mode:
annotations:
description: File access mode
error_raw:
annotations:
columns.hidden: true
fd:
annotations:
description: File descriptor. 0 in case of error
columns.minwidth: 2
columns.maxwidth: 3
columns.alignment: right
fname:
annotations:
description: File name as given in the open syscall
columns.width: 32
columns.minwidth: 24
fpath:
annotations:
description: Full file path after symlink resolution (require --paths flag)
columns.width: 32
columns.minwidth: 24
params:
ebpf:
targ_failed:
key: failed
defaultValue: "false"
description: Show only failed events
paths:
key: paths
defaultValue: "false"
description: Show file path after symlink resolution
160 changes: 160 additions & 0 deletions pkg/ebpf/gadgets/trace_open/program.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019 Facebook
// Copyright (c) 2020 Netflix

#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>

#include <gadget/buffer.h>
#include <gadget/common.h>
#include <gadget/filter.h>
#include <gadget/macros.h>
#include <gadget/types.h>
#include <gadget/user_stack_map.h>
#include <gadget/filesystem.h>

#define TASK_RUNNING 0
#define NAME_MAX 255

struct args_t {
const char *fname;
int flags;
__u16 mode;
};

struct event {
gadget_timestamp timestamp_raw;
struct gadget_process proc;

gadget_errno error_raw;
__u32 fd;
gadget_file_flags flags_raw;
gadget_file_mode mode_raw;
struct gadget_user_stack ustack;
char fname[NAME_MAX];
char fpath[GADGET_PATH_MAX];
};

const volatile bool targ_failed = false;
const volatile bool paths = false;

GADGET_PARAM(targ_failed);
GADGET_PARAM(paths);

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 10240);
__type(key, u32);
__type(value, struct args_t);
} start SEC(".maps");

GADGET_TRACER_MAP(events, 1024 * 256);

GADGET_TRACER(open, events, event);

static __always_inline int trace_enter(const char *filename, int flags,
__u16 mode)
{
__u64 pid = bpf_get_current_pid_tgid();

if (gadget_should_discard_data_current())
return 0;

struct args_t args = {};
args.fname = filename;
args.flags = flags;
args.mode = mode;
bpf_map_update_elem(&start, &pid, &args, 0);

return 0;
}

#ifndef __TARGET_ARCH_arm64
SEC("tracepoint/syscalls/sys_enter_open")
int ig_open_e(struct syscall_trace_enter *ctx)
{
return trace_enter((const char *)ctx->args[0], (int)ctx->args[1],
(__u16)ctx->args[2]);
}
#endif /* !__TARGET_ARCH_arm64 */

SEC("tracepoint/syscalls/sys_enter_openat")
int ig_openat_e(struct syscall_trace_enter *ctx)
{
return trace_enter((const char *)ctx->args[1], (int)ctx->args[2],
(__u16)ctx->args[3]);
}

static __always_inline int trace_exit(struct syscall_trace_exit *ctx)
{
struct event *event;
struct args_t *ap;
long int ret;
__u32 fd;
__s32 errval;
__u64 pid_tgid = bpf_get_current_pid_tgid();

// pid from kernel po
u32 pid = (u32)pid_tgid;

ap = bpf_map_lookup_elem(&start, &pid);
if (!ap)
return 0; /* missed entry */
ret = ctx->ret;
if (targ_failed && ret >= 0)
goto cleanup; /* want failed only */

event = gadget_reserve_buf(&events, sizeof(*event));
if (!event)
goto cleanup;

fd = 0;
errval = 0;
if (ret >= 0) {
fd = ret;

if (paths) {
long r = read_full_path_of_open_file_fd(
fd, (char *)event->fpath, sizeof(event->fpath));
if (r <= 0)
event->fpath[0] = '\0';
}
} else {
errval = -ret;
}

/* event data */
gadget_process_populate(&event->proc);
gadget_get_user_stack(ctx, &event->ustack);

bpf_probe_read_user_str(&event->fname, sizeof(event->fname), ap->fname);
event->flags_raw = ap->flags;
event->mode_raw = ap->mode;
event->error_raw = errval;
event->fd = fd;
event->timestamp_raw = bpf_ktime_get_boot_ns();

/* emit event */
gadget_submit_buf(ctx, &events, event, sizeof(*event));

cleanup:
bpf_map_delete_elem(&start, &pid);
return 0;
}

#ifndef __TARGET_ARCH_arm64
SEC("tracepoint/syscalls/sys_exit_open")
int ig_open_x(struct syscall_trace_exit *ctx)
{
return trace_exit(ctx);
}
#endif /* !__TARGET_ARCH_arm64 */

SEC("tracepoint/syscalls/sys_exit_openat")
int ig_openat_x(struct syscall_trace_exit *ctx)
{
return trace_exit(ctx);
}

char LICENSE[] SEC("license") = "GPL";
22 changes: 22 additions & 0 deletions pkg/ebpf/gadgets/trace_open/program.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-2.0

#pragma once

#include <gadget/types.h>
#include <gadget/user_stack_map.h>
#include <gadget/filesystem.h>

#define NAME_MAX 255

struct event {
gadget_timestamp timestamp_raw;
struct gadget_process proc;

gadget_errno error_raw;
__u32 fd;
gadget_file_flags flags_raw;
gadget_file_mode mode_raw;
struct gadget_user_stack ustack;
char fname[NAME_MAX];
char fpath[GADGET_PATH_MAX];
};
6 changes: 5 additions & 1 deletion pkg/utils/datasource_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ func (e *DatasourceEvent) GetFlagsRaw() uint32 {
}
}

// @constanze: something is going wrong between here and GetPath
func (e *DatasourceEvent) GetFullPath() string {
switch e.EventType {
case OpenEventType:
Expand Down Expand Up @@ -552,13 +553,16 @@ func (e *DatasourceEvent) GetOtherIp() string {
}
}

// @constanze : this issue is that apparently FullPath is not really FullPath anymore
func (e *DatasourceEvent) GetPath() string {
if e.FullPathTracing {
return e.GetFullPath()
}
switch e.EventType {
case OpenEventType:
path, _ := e.getFieldAccessor("fname").String(e.Data)
//path, _ := e.getFieldAccessor("fname").String(e.Data)
//hack this should be same as GetFullPath == remove after triage
path, _ := e.getFieldAccessor("fpath").String(e.Data)
return path
default:
logger.L().Warning("GetPath not implemented for event type", helpers.String("eventType", string(e.EventType)))
Expand Down
Loading
Loading