Skip to content

Commit 8151e89

Browse files
syogarajanakryiko
authored andcommitted
examples/c: add ksyscall example
Add an example to trace `kill` and `tgkill` syscalls using libbpf's `SEC(ksyscall)` program type. Signed-off-by: syogaraj <[email protected]>
1 parent 6d3bdec commit 8151e89

File tree

4 files changed

+114
-1
lines changed

4 files changed

+114
-1
lines changed

examples/c/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
/usdt
1010
/sockfilter
1111
/tc
12+
/ksyscall

examples/c/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ INCLUDES := -I$(OUTPUT) -I../../libbpf/include/uapi -I$(dir $(VMLINUX))
2424
CFLAGS := -g -Wall
2525
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)
2626

27-
APPS = minimal minimal_legacy bootstrap uprobe kprobe fentry usdt sockfilter tc
27+
APPS = minimal minimal_legacy bootstrap uprobe kprobe fentry usdt sockfilter tc ksyscall
2828

2929
CARGO ?= $(shell which cargo)
3030
ifeq ($(strip $(CARGO)),)

examples/c/ksyscall.bpf.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "vmlinux.h"
2+
#include <bpf/bpf_helpers.h>
3+
#include <bpf/bpf_tracing.h>
4+
#include <bpf/bpf_core_read.h>
5+
6+
#define TASK_COMM_LEN 16
7+
8+
SEC("ksyscall/tgkill")
9+
int BPF_KSYSCALL(tgkill_entry, pid_t tgid, pid_t tid, int sig)
10+
{
11+
char comm[TASK_COMM_LEN];
12+
__u32 caller_pid = bpf_get_current_pid_tgid() >> 32;
13+
14+
if (sig == 0) {
15+
/*
16+
If sig is 0, then no signal is sent, but existence and permission
17+
checks are still performed; this can be used to check for the
18+
existence of a process ID or process group ID that the caller is
19+
permitted to signal.
20+
*/
21+
return 0;
22+
}
23+
24+
bpf_get_current_comm(&comm, sizeof(comm));
25+
bpf_printk("tgkill syscall called by PID %d (%s) for thread id %d with pid %d and signal %d.",
26+
caller_pid, comm, tid, tgid, sig);
27+
return 0;
28+
}
29+
30+
SEC("ksyscall/kill")
31+
int BPF_KSYSCALL(entry_probe, pid_t pid, int sig)
32+
{
33+
char comm[TASK_COMM_LEN];
34+
__u32 caller_pid = bpf_get_current_pid_tgid() >> 32;
35+
36+
if (sig == 0) {
37+
/*
38+
If sig is 0, then no signal is sent, but existence and permission
39+
checks are still performed; this can be used to check for the
40+
existence of a process ID or process group ID that the caller is
41+
permitted to signal.
42+
*/
43+
return 0;
44+
}
45+
46+
bpf_get_current_comm(&comm, sizeof(comm));
47+
bpf_printk("KILL syscall called by PID %d (%s) for PID %d with signal %d.",
48+
caller_pid, comm, pid, sig);
49+
return 0;
50+
}
51+
52+
char _license[] SEC("license") = "GPL";

examples/c/ksyscall.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <stdio.h>
2+
#include <unistd.h>
3+
#include <signal.h>
4+
#include <string.h>
5+
#include <errno.h>
6+
#include <sys/resource.h>
7+
#include <bpf/libbpf.h>
8+
#include "ksyscall.skel.h"
9+
10+
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
11+
{
12+
return vfprintf(stderr, format, args);
13+
}
14+
15+
static volatile sig_atomic_t stop;
16+
17+
static void sig_int(int signo)
18+
{
19+
stop = 1;
20+
}
21+
22+
int main(int argc, char **argv)
23+
{
24+
struct ksyscall_bpf *skel;
25+
int err;
26+
27+
/* Set up libbpf errors and debug info callback */
28+
libbpf_set_print(libbpf_print_fn);
29+
30+
/* Open load and verify BPF application */
31+
skel = ksyscall_bpf__open_and_load();
32+
if (!skel) {
33+
fprintf(stderr, "Failed to open BPF skeleton\n");
34+
return 1;
35+
}
36+
37+
/* Attach tracepoint handler */
38+
err = ksyscall_bpf__attach(skel);
39+
if (err) {
40+
fprintf(stderr, "Failed to attach BPF skeleton\n");
41+
goto cleanup;
42+
}
43+
44+
if (signal(SIGINT, sig_int) == SIG_ERR) {
45+
fprintf(stderr, "can't set signal handler: %s\n", strerror(errno));
46+
goto cleanup;
47+
}
48+
49+
printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` "
50+
"to see output of the BPF programs.\n");
51+
52+
while (!stop) {
53+
fprintf(stderr, ".");
54+
sleep(1);
55+
}
56+
57+
cleanup:
58+
ksyscall_bpf__destroy(skel);
59+
return -err;
60+
}

0 commit comments

Comments
 (0)