Skip to content

Commit

Permalink
API improvements for BPF LSM programs (iovisor#2979)
Browse files Browse the repository at this point in the history
* Enhanced support for LSM programs
- added explicit libbcc support for LSM programs
- added bcc helpers to attach LSM programs
- added bcc helper to indicate kernel support for LSM programs
- added LSM programs to __trace_autoload hook
- removed (now) unnecessary load_func from LSM unit test
- Remove detach_kfunc

Signed-off-by: William Findlay <[email protected]>
  • Loading branch information
willfindlay committed Jun 19, 2020
1 parent f438bff commit 9b82af3
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 13 deletions.
15 changes: 9 additions & 6 deletions src/cc/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1186,20 +1186,23 @@ bool bpf_has_kernel_btf(void)
return libbpf_find_vmlinux_btf_id("bpf_prog_put", 0) > 0;
}

int bpf_detach_kfunc(int prog_fd, char *func)
int bpf_attach_kfunc(int prog_fd)
{
UNUSED(prog_fd);
UNUSED(func);
return 0;
int ret;

ret = bpf_raw_tracepoint_open(NULL, prog_fd);
if (ret < 0)
fprintf(stderr, "bpf_attach_raw_tracepoint (kfunc): %s\n", strerror(errno));
return ret;
}

int bpf_attach_kfunc(int prog_fd)
int bpf_attach_lsm(int prog_fd)
{
int ret;

ret = bpf_raw_tracepoint_open(NULL, prog_fd);
if (ret < 0)
fprintf(stderr, "bpf_attach_raw_tracepoint (kfunc): %s\n", strerror(errno));
fprintf(stderr, "bpf_attach_raw_tracepoint (lsm): %s\n", strerror(errno));
return ret;
}

Expand Down
4 changes: 2 additions & 2 deletions src/cc/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ int bpf_detach_tracepoint(const char *tp_category, const char *tp_name);

int bpf_attach_raw_tracepoint(int progfd, const char *tp_name);

int bpf_detach_kfunc(int prog_fd, char *func);

int bpf_attach_kfunc(int prog_fd);

int bpf_attach_lsm(int prog_fd);

bool bpf_has_kernel_btf(void);

void * bpf_open_perf_buffer(perf_reader_raw_cb raw_cb,
Expand Down
35 changes: 35 additions & 0 deletions src/python/bcc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ def __init__(self, src_file=b"", hdr_file=b"", text=None, debug=0,
self.raw_tracepoint_fds = {}
self.kfunc_entry_fds = {}
self.kfunc_exit_fds = {}
self.lsm_fds = {}
self.perf_buffers = {}
self.open_perf_events = {}
self.tracefile = None
Expand Down Expand Up @@ -899,6 +900,15 @@ def support_kfunc():
return True
return False

@staticmethod
def support_lsm():
if not lib.bpf_has_kernel_btf():
return False
# kernel symbol "bpf_lsm_bpf" indicates BPF LSM support
if BPF.ksymname(b"bpf_lsm_bpf") != -1:
return True
return False

def detach_kfunc(self, fn_name=b""):
fn_name = _assert_is_bytes(fn_name)
fn_name = BPF.add_prefix(b"kfunc__", fn_name)
Expand Down Expand Up @@ -945,6 +955,29 @@ def attach_kretfunc(self, fn_name=b""):
self.kfunc_exit_fds[fn_name] = fd;
return self

def detach_lsm(self, fn_name=b""):
fn_name = _assert_is_bytes(fn_name)
fn_name = BPF.add_prefix(b"lsm__", fn_name)

if fn_name not in self.lsm_fds:
raise Exception("LSM %s is not attached" % fn_name)
os.close(self.lsm_fds[fn_name])
del self.lsm_fds[fn_name]

def attach_lsm(self, fn_name=b""):
fn_name = _assert_is_bytes(fn_name)
fn_name = BPF.add_prefix(b"lsm__", fn_name)

if fn_name in self.lsm_fds:
raise Exception("LSM %s has been attached" % fn_name)

fn = self.load_func(fn_name, BPF.LSM)
fd = lib.bpf_attach_lsm(fn.fd)
if fd < 0:
raise Exception("Failed to attach LSM")
self.lsm_fds[fn_name] = fd;
return self

@staticmethod
def support_raw_tracepoint():
# kernel symbol "bpf_find_raw_tracepoint" indicates raw_tracepoint support
Expand Down Expand Up @@ -1204,6 +1237,8 @@ def _trace_autoload(self):
self.attach_kfunc(fn_name=func_name)
elif func_name.startswith(b"kretfunc__"):
self.attach_kretfunc(fn_name=func_name)
elif func_name.startswith(b"lsm__"):
self.attach_lsm(fn_name=func_name)

def trace_open(self, nonblocking=False):
"""trace_open(nonblocking=False)
Expand Down
2 changes: 2 additions & 0 deletions src/python/bcc/libbcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@
lib.bpf_attach_raw_tracepoint.argtypes = [ct.c_int, ct.c_char_p]
lib.bpf_attach_kfunc.restype = ct.c_int
lib.bpf_attach_kfunc.argtypes = [ct.c_int]
lib.bpf_attach_lsm.restype = ct.c_int
lib.bpf_attach_lsm.argtypes = [ct.c_int]
lib.bpf_has_kernel_btf.restype = ct.c_bool
lib.bpf_has_kernel_btf.argtypes = None
lib.bpf_open_perf_buffer.restype = ct.c_void_p
Expand Down
8 changes: 3 additions & 5 deletions tests/python/test_clang.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,15 +321,13 @@ def test_char_array_probe(self):

@skipUnless(kernel_version_ge(5,7), "requires kernel >= 5.7")
def test_lsm_probe(self):
# Skip if the kernel is not compiled with CONFIG_BPF_LSM
if not BPF.support_lsm():
return
b = BPF(text="""
LSM_PROBE(bpf, int cmd, union bpf_attr *uattr, unsigned int size) {
return 0;
}""")
# depending on CONFIG_BPF_LSM being compiled in
try:
b.load_func("lsm__bpf", BPF.LSM)
except:
pass

def test_probe_read_helper(self):
b = BPF(text="""
Expand Down

0 comments on commit 9b82af3

Please sign in to comment.