Skip to content

Commit

Permalink
Add the LSM BPF sample code, and enhance the README.md documentation.
Browse files Browse the repository at this point in the history
Signed-off-by: DavadDi <[email protected]>
  • Loading branch information
DavadDi committed Jan 25, 2024
1 parent 6aa0c77 commit cbdebca
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 1 deletion.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,33 @@ Task Info. Pid: 1600497. Process Name: tmux: server. Kernel Stack Len: 0. State:
Task Info. Pid: 1600498. Process Name: bash. Kernel Stack Len: 5. State: INTERRUPTIBLE
```

## lsm
`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.

```shell
$ sudo ./lsm
libbpf: loading object 'lsm_bpf' from buffer
...
Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` to see output of the BPF programs.
..........
```

The output from `lsm` in `/sys/kernel/debug/tracing/trace_pipe` is expected to resemble the following:

````shell
$ sudo cat /sys/kernel/debug/tracing/trace_pipe
bpftool-70646 [002] ...11 279318.416393: bpf_trace_printk: LSM: block bpf() worked
bpftool-70646 [002] ...11 279318.416532: bpf_trace_printk: LSM: block bpf() worked
bpftool-70646 [002] ...11 279318.416533: bpf_trace_printk: LSM: block bpf() worked
````

When the `bpf()` system call gets blocked, the `bpftool prog list` command yields the following output:

```shell
$ sudo bpftool prog list
Error: can't get next program: Operation not permitted
```
# Building
libbpf-bootstrap supports multiple build systems that do the same thing.
Expand Down
1 change: 1 addition & 0 deletions examples/c/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
/tc
/ksyscall
/task_iter
/lsm
/cmake-build-debug/
/cmake-build-release/
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)) -I$(LIBB
CFLAGS := -g -Wall
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)

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

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

char LICENSE[] SEC("license") = "GPL";

#define EPERM 1

SEC("lsm/bpf")
int BPF_PROG(lsm_bpf, int cmd, union bpf_attr *attr, unsigned int size, int ret)
{
/* ret is the return value from the previous BPF program
* or 0 if it's the first hook.
*/
if (ret != 0)
return ret;

bpf_printk("LSM: block bpf() worked");
return -EPERM;
}
51 changes: 51 additions & 0 deletions examples/c/lsm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
/* Copyright (c) 2024 David Di */
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include "lsm.skel.h"

/* Notice: Ensure your kernel version is 5.7 or higher, BTF (BPF Type Format) is enabled,
* and the file '/sys/kernel/security/lsm' includes 'bpf'.
*/
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
return vfprintf(stderr, format, args);
}

int main(int argc, char **argv)
{
struct lsm_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 = lsm_bpf__open_and_load();
if (!skel) {
fprintf(stderr, "Failed to open and load BPF skeleton\n");
goto cleanup;
}

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

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

for (;;) {
/* trigger our BPF program */
fprintf(stderr, ".");
sleep(1);
}

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

0 comments on commit cbdebca

Please sign in to comment.