forked from libbpf/libbpf-bootstrap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpatmatch.bpf.c
131 lines (113 loc) · 4.19 KB
/
patmatch.bpf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright (c) 2021 Sartura */
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
/*
* Limitations of the code:
* 1. Can only be used for the file path matching
* 2. Limit on first pass:12chars second pass:64chars third pass:12chars
*
*/
char LICENSE[] SEC("license") = "Dual BSD/GPL";
// const char wc[] = "*/bin/*";
const char wc[] = "/home/*/*/????/*p";
#if 0
SEC("kprobe/do_execve")
int BPF_KPROBE(do_execve, const char *name,
const char *const *__argv,
const char *const *__envp)
{
pid_t pid;
char comm[64];
char filename[256];
pid = bpf_get_current_pid_tgid() >> 32;
bpf_get_current_comm(&comm, sizeof(comm));
bpf_probe_read_kernel_str(filename, sizeof(filename), (void *)name);
//bpf_probe_read_user_str(filename, sizeof(filename), (const char*)ctx->args[0]);
bpf_printk("=------KPROBE ENTRY pid=%d, comm=%s\n", pid, filename);
return 0;
}
#endif
#define CHK_2 \
if (!wild[w] || !str[i]) \
goto CHK_2_OUT; \
two++;\
\
if (wild[w] == '*') { \
if (!wild[++w]) return 1; \
mp = w; \
cp = i+1; \
} else if ((wild[w] == str[i]) || (wild[w] == '?')) { \
w++; \
i++; \
} else { \
w = mp; \
i = cp++; \
}
/*
* This function has to be eBPF compliant which means no unbound loops. Infact,
* no loops!
*/
static int wildcardMatch(const char* str, const char* wild)
{
int i = 0, w = 0, mp = 0, cp = 0, one = 0, two = 0, three = 0;
#define CHK_1 \
if (!str[i] || wild[i] == '*') goto CHK_1_OUT;\
if ((wild[i] != str[i]) && (wild[i] != '?')) return 0;\
one++;\
i++;
CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1
CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1
CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1
CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1 CHK_1
CHK_1_OUT:
w = i;
CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2
CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2
CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2
CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2
CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2
CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2
CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2
CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2 CHK_2
CHK_2_OUT:
#define CHK_3 \
if (wild[w] != '*') goto CHK_3_OUT;\
three++;\
w++;
CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3
CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3
CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3
CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3 CHK_3
CHK_3_OUT:
if (!wild[w]) {
bpf_printk("one:%d two:%d three:%d\n", one, two, three);
}
return !wild[w];
}
#if 0
SEC("kretprobe/do_execve")
int BPF_KRETPROBE(do_execve_exit)
{
pid_t pid;
char comm[64];
pid = bpf_get_current_pid_tgid() >> 32;
bpf_get_current_comm(&comm, sizeof(comm));
if (wildcardMatch(comm, wc)) {
bpf_printk("KRETPROBE ENTRY pid = %d, filename = %s\n", pid, comm);
}
return 0;
}
#endif
SEC("tracepoint/syscalls/sys_enter_execve")
int tracepoint__syscalls__sys_enter_execve(struct trace_event_raw_sys_enter* ctx)
{
char filename[128];
bpf_probe_read_user_str(filename, sizeof(filename), (const char*)ctx->args[0]);
if (wildcardMatch(filename, wc)) {
bpf_printk("TRACEPOINT ENTRY filename=%s\n", filename);
}
return 0;
}