Skip to content

Commit

Permalink
examples/c: add ksyscall example
Browse files Browse the repository at this point in the history
Add an example to trace `kill` and `tgkill` syscalls using libbpf's
`SEC(ksyscall)` program type.

Signed-off-by: syogaraj <[email protected]>
  • Loading branch information
syogaraj authored and anakryiko committed Apr 11, 2023
1 parent 6d3bdec commit 8151e89
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 1 deletion.
1 change: 1 addition & 0 deletions examples/c/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
/usdt
/sockfilter
/tc
/ksyscall
2 changes: 1 addition & 1 deletion examples/c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ INCLUDES := -I$(OUTPUT) -I../../libbpf/include/uapi -I$(dir $(VMLINUX))
CFLAGS := -g -Wall
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)

APPS = minimal minimal_legacy bootstrap uprobe kprobe fentry usdt sockfilter tc
APPS = minimal minimal_legacy bootstrap uprobe kprobe fentry usdt sockfilter tc ksyscall

CARGO ?= $(shell which cargo)
ifeq ($(strip $(CARGO)),)
Expand Down
52 changes: 52 additions & 0 deletions examples/c/ksyscall.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>

#define TASK_COMM_LEN 16

SEC("ksyscall/tgkill")
int BPF_KSYSCALL(tgkill_entry, pid_t tgid, pid_t tid, int sig)
{
char comm[TASK_COMM_LEN];
__u32 caller_pid = bpf_get_current_pid_tgid() >> 32;

if (sig == 0) {
/*
If sig is 0, then no signal is sent, but existence and permission
checks are still performed; this can be used to check for the
existence of a process ID or process group ID that the caller is
permitted to signal.
*/
return 0;
}

bpf_get_current_comm(&comm, sizeof(comm));
bpf_printk("tgkill syscall called by PID %d (%s) for thread id %d with pid %d and signal %d.",
caller_pid, comm, tid, tgid, sig);
return 0;
}

SEC("ksyscall/kill")
int BPF_KSYSCALL(entry_probe, pid_t pid, int sig)
{
char comm[TASK_COMM_LEN];
__u32 caller_pid = bpf_get_current_pid_tgid() >> 32;

if (sig == 0) {
/*
If sig is 0, then no signal is sent, but existence and permission
checks are still performed; this can be used to check for the
existence of a process ID or process group ID that the caller is
permitted to signal.
*/
return 0;
}

bpf_get_current_comm(&comm, sizeof(comm));
bpf_printk("KILL syscall called by PID %d (%s) for PID %d with signal %d.",
caller_pid, comm, pid, sig);
return 0;
}

char _license[] SEC("license") = "GPL";
60 changes: 60 additions & 0 deletions examples/c/ksyscall.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include "ksyscall.skel.h"

static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
return vfprintf(stderr, format, args);
}

static volatile sig_atomic_t stop;

static void sig_int(int signo)
{
stop = 1;
}

int main(int argc, char **argv)
{
struct ksyscall_bpf *skel;
int err;

/* Set up libbpf errors and debug info callback */
libbpf_set_print(libbpf_print_fn);

/* Open load and verify BPF application */
skel = ksyscall_bpf__open_and_load();
if (!skel) {
fprintf(stderr, "Failed to open BPF skeleton\n");
return 1;
}

/* Attach tracepoint handler */
err = ksyscall_bpf__attach(skel);
if (err) {
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto cleanup;
}

if (signal(SIGINT, sig_int) == SIG_ERR) {
fprintf(stderr, "can't set signal handler: %s\n", strerror(errno));
goto cleanup;
}

printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` "
"to see output of the BPF programs.\n");

while (!stop) {
fprintf(stderr, ".");
sleep(1);
}

cleanup:
ksyscall_bpf__destroy(skel);
return -err;
}

0 comments on commit 8151e89

Please sign in to comment.