Skip to content

Commit 694117d

Browse files
DavadDianakryiko
authored andcommitted
Add the LSM BPF sample code, and enhance the README.md documentation.
Signed-off-by: DavadDi <[email protected]>
1 parent 6aa0c77 commit 694117d

File tree

5 files changed

+100
-1
lines changed

5 files changed

+100
-1
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,33 @@ Task Info. Pid: 1600497. Process Name: tmux: server. Kernel Stack Len: 0. State:
322322
Task Info. Pid: 1600498. Process Name: bash. Kernel Stack Len: 5. State: INTERRUPTIBLE
323323
```
324324

325+
## lsm
326+
`lsm` serves as an illustrative example of utilizing [LSM BPF](https://docs.kernel.org/bpf/prog_lsm.html). In this example, the `bpf()` system call is effectively blocked. Once the `lsm` program is operational, its successful execution can be confirmed by using the `bpftool prog list` command.
327+
328+
```shell
329+
$ sudo ./lsm
330+
libbpf: loading object 'lsm_bpf' from buffer
331+
...
332+
Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` to see output of the BPF programs.
333+
..........
334+
```
335+
336+
The output from `lsm` in `/sys/kernel/debug/tracing/trace_pipe` is expected to resemble the following:
337+
338+
````shell
339+
$ sudo cat /sys/kernel/debug/tracing/trace_pipe
340+
bpftool-70646 [002] ...11 279318.416393: bpf_trace_printk: LSM: block bpf() worked
341+
bpftool-70646 [002] ...11 279318.416532: bpf_trace_printk: LSM: block bpf() worked
342+
bpftool-70646 [002] ...11 279318.416533: bpf_trace_printk: LSM: block bpf() worked
343+
````
344+
345+
When the `bpf()` system call gets blocked, the `bpftool prog list` command yields the following output:
346+
347+
```shell
348+
$ sudo bpftool prog list
349+
Error: can't get next program: Operation not permitted
350+
```
351+
325352
# Building
326353
327354
libbpf-bootstrap supports multiple build systems that do the same thing.

examples/c/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
/tc
1212
/ksyscall
1313
/task_iter
14+
/lsm
1415
/cmake-build-debug/
1516
/cmake-build-release/

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)) -I$(LIBB
2424
CFLAGS := -g -Wall
2525
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)
2626

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

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

examples/c/lsm.bpf.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "vmlinux.h"
2+
#include <bpf/bpf_helpers.h>
3+
#include <bpf/bpf_tracing.h>
4+
5+
char LICENSE[] SEC("license") = "GPL";
6+
7+
#define EPERM 1
8+
9+
SEC("lsm/bpf")
10+
int BPF_PROG(lsm_bpf, int cmd, union bpf_attr *attr, unsigned int size, int ret)
11+
{
12+
/* ret is the return value from the previous BPF program
13+
* or 0 if it's the first hook.
14+
*/
15+
if (ret != 0)
16+
return ret;
17+
18+
bpf_printk("LSM: block bpf() worked");
19+
return -EPERM;
20+
}

examples/c/lsm.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2+
/* Copyright (c) 2024 David Di */
3+
#include <stdio.h>
4+
#include <unistd.h>
5+
#include <sys/resource.h>
6+
#include <bpf/libbpf.h>
7+
#include "lsm.skel.h"
8+
9+
/* Notice: Ensure your kernel version is 5.7 or higher, BTF (BPF Type Format) is enabled,
10+
* and the file '/sys/kernel/security/lsm' includes 'bpf'.
11+
*/
12+
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
13+
{
14+
return vfprintf(stderr, format, args);
15+
}
16+
17+
int main(int argc, char **argv)
18+
{
19+
struct lsm_bpf *skel;
20+
int err;
21+
22+
/* Set up libbpf errors and debug info callback */
23+
libbpf_set_print(libbpf_print_fn);
24+
25+
/* Open, load, and verify BPF application */
26+
skel = lsm_bpf__open_and_load();
27+
if (!skel) {
28+
fprintf(stderr, "Failed to open and load BPF skeleton\n");
29+
goto cleanup;
30+
}
31+
32+
/* Attach lsm handler */
33+
err = lsm_bpf__attach(skel);
34+
if (err) {
35+
fprintf(stderr, "Failed to attach BPF skeleton\n");
36+
goto cleanup;
37+
}
38+
39+
printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` "
40+
"to see output of the BPF programs.\n");
41+
42+
for (;;) {
43+
/* trigger our BPF program */
44+
fprintf(stderr, ".");
45+
sleep(1);
46+
}
47+
48+
cleanup:
49+
lsm_bpf__destroy(skel);
50+
return -err;
51+
}

0 commit comments

Comments
 (0)