Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an LSM BPF sample program #245

Merged
merged 1 commit into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add an entry to .gitignore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done @chenhengqi Thanks


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;
}
Loading