Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ebpf): add stdin_info to sched_process_exec #4218

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
39 changes: 39 additions & 0 deletions pkg/bufferdecoder/eventsreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const (
uint64ArrT
u8T
timespecT
stdinInfoT
)

// These types don't match the ones defined in the ebpf code since they are not being used by syscalls arguments.
Expand Down Expand Up @@ -186,6 +187,8 @@ func readArgFromBuff(id events.ID, ebpfMsgDecoder *EbpfDecoder, params []trace.A
err = ebpfMsgDecoder.DecodeInt64(&nsec)
res = float64(sec) + (float64(nsec) / float64(1000000000))

case stdinInfoT:
res, err = readStdinInfoFromBuff(ebpfMsgDecoder)
default:
// if we don't recognize the arg type, we can't parse the rest of the buffer
return uint(argIdx), arg, errfmt.Errorf("error unknown arg type %v", argType)
Expand Down Expand Up @@ -241,19 +244,55 @@ func GetParamType(paramType string) ArgType {
return uint64ArrT
case "struct timespec*", "const struct timespec*":
return timespecT
case "struct stdin_info":
return stdinInfoT
default:
// Default to pointer (printed as hex) for unsupported types
return pointerT
}
}

func readStdinInfoFromBuff(ebpfMsgDecoder *EbpfDecoder) (map[string]string, error) {
res := make(map[string]string, 5)
var header int16
err := ebpfMsgDecoder.DecodeInt16(&header)
if err != nil {
return nil, errfmt.WrapError(err)
}

if uint64(header) == parsers.S_IFIFO.Value() {
return readStdinFifoFromBuffer(ebpfMsgDecoder)
}

if header == 0 {
return nil, nil
}

socketFamily, err := parsers.ParseSocketDomainArgument(uint64(header))
if err == nil {
return fillSocketInfo(ebpfMsgDecoder, res, int16(socketFamily))
}

return nil, nil
}

// TOOD: implement
func readStdinFifoFromBuffer(ebpfMsgDecoder *EbpfDecoder) (map[string]string, error) {
res := make(map[string]string, 5)
return res, nil
}

func readSockaddrFromBuff(ebpfMsgDecoder *EbpfDecoder) (map[string]string, error) {
res := make(map[string]string, 5)
var family int16
err := ebpfMsgDecoder.DecodeInt16(&family)
if err != nil {
return nil, errfmt.WrapError(err)
}
return fillSocketInfo(ebpfMsgDecoder, res, family)
}

func fillSocketInfo(ebpfMsgDecoder *EbpfDecoder, res map[string]string, family int16) (map[string]string, error) {
socketDomainArg, err := parsers.ParseSocketDomainArgument(uint64(family))
if err != nil {
socketDomainArg = parsers.AF_UNSPEC
Expand Down
40 changes: 39 additions & 1 deletion pkg/ebpf/c/tracee.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,43 @@ int tracepoint__sched__sched_process_exec(struct bpf_raw_tracepoint_args *ctx)

// clang-format on

statfunc void handle_stdin_sock(args_buffer_t *args_buf, struct file *stdin_file, u8 index)
{
struct socket *socket_from_file = (struct socket *) BPF_CORE_READ(stdin_file, private_data);
if (socket_from_file == NULL)
return;

save_sockaddr_to_buf(args_buf, socket_from_file, index);
}

struct stdin_fifo {
unsigned short file_type;
};

statfunc void handle_stdin_fifo(args_buffer_t *args_buf, struct file *stdin_file, u8 index)
{
struct stdin_fifo stdin_fifo = {.file_type = S_IFIFO};

save_to_submit_buf(args_buf, (void *) &stdin_fifo, sizeof(stdin_fifo), index);
}

statfunc void save_stdin_details(args_buffer_t *args_buf,
unsigned short stdin_type,
struct file *stdin_file,
u8 index)
{
switch (stdin_type) {
case S_IFSOCK:
handle_stdin_sock(args_buf, stdin_file, index);
break;
case S_IFIFO:
handle_stdin_fifo(args_buf, stdin_file, index);
break;
default:
return;
}
}

SEC("raw_tracepoint/sched_process_exec_event_submit_tail")
int sched_process_exec_event_submit_tail(struct bpf_raw_tracepoint_args *ctx)
{
Expand Down Expand Up @@ -1406,14 +1443,15 @@ int sched_process_exec_event_submit_tail(struct bpf_raw_tracepoint_args *ctx)
save_str_to_buf(&p.event->args_buf, stdin_path, 13);
save_to_submit_buf(&p.event->args_buf, &invoked_from_kernel, sizeof(int), 14);
save_str_to_buf(&p.event->args_buf, (void *) p.task_info->context.comm, 15);
save_stdin_details(&p.event->args_buf, stdin_type, stdin_file, 16);
if (p.config->options & OPT_EXEC_ENV) {
unsigned long env_start, env_end;
env_start = get_env_start_from_mm(mm);
env_end = get_env_end_from_mm(mm);
int envc = get_envc_from_bprm(bprm);

save_args_str_arr_to_buf(
&p.event->args_buf, (void *) env_start, (void *) env_end, envc, 16);
&p.event->args_buf, (void *) env_start, (void *) env_end, envc, 17);
}

events_perf_submit(&p, 0);
Expand Down
10 changes: 10 additions & 0 deletions pkg/ebpf/c/vmlinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,17 @@ struct alloc_context {
enum zone_type high_zoneidx;
};

typedef enum
{
SS_FREE = 0, /* not allocated */
SS_UNCONNECTED, /* unconnected to any socket */
SS_CONNECTING, /* in process of connecting */
SS_CONNECTED, /* connected to socket */
SS_DISCONNECTING /* in process of disconnecting */
} socket_state;

struct socket {
socket_state state;
short type;
struct file *file;
struct sock *sk;
Expand Down
1 change: 1 addition & 0 deletions pkg/events/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -11230,6 +11230,7 @@ var CoreEvents = map[ID]Definition{
{Type: "char*", Name: "stdin_path"},
{Type: "int", Name: "invoked_from_kernel"},
{Type: "const char*", Name: "prev_comm"},
{Type: "struct stdin_info", Name: "stdin_info"},
{Type: "const char**", Name: "env"},
},
},
Expand Down
Loading