| #!/usr/bin/env python3 |
| # Copyright (c) PLUMgrid, Inc. |
| # Licensed under the Apache License, Version 2.0 (the "License") |
| |
| import bcc |
| import os |
| import unittest |
| from utils import mayFail, kernel_version_ge |
| import subprocess |
| |
| |
| @unittest.skipUnless(kernel_version_ge(4,6), "requires kernel >= 4.6") |
| class TestStackid(unittest.TestCase): |
| @mayFail("This fails on github actions environment, and needs to be fixed") |
| def test_simple(self): |
| b = bcc.BPF(text=""" |
| #include <uapi/linux/ptrace.h> |
| struct bpf_map; |
| BPF_STACK_TRACE(stack_traces, 10240); |
| BPF_HASH(stack_entries, int, int); |
| BPF_HASH(stub); |
| int kprobe__htab_map_lookup_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *k) { |
| int id = stack_traces.get_stackid(ctx, BPF_F_REUSE_STACKID); |
| if (id < 0) |
| return 0; |
| int key = 1; |
| stack_entries.update(&key, &id); |
| return 0; |
| } |
| """) |
| stub = b["stub"] |
| stack_traces = b["stack_traces"] |
| stack_entries = b["stack_entries"] |
| try: x = stub[stub.Key(1)] |
| except: pass |
| k = stack_entries.Key(1) |
| self.assertIn(k, stack_entries) |
| stackid = stack_entries[k] |
| self.assertIsNotNone(stackid) |
| stack = stack_traces[stackid].ip |
| self.assertEqual(b.ksym(stack[0]), b"htab_map_lookup_elem") |
| |
| def Get_libc_path(): |
| cmd = 'cat /proc/self/maps | grep libc | awk \'{print $6}\' | uniq' |
| output = subprocess.check_output(cmd, shell=True) |
| if not isinstance(output, str): |
| output = output.decode() |
| return output.split('\n')[0] |
| |
| @unittest.skipUnless(kernel_version_ge(4,17), "requires kernel >= 4.17") |
| class TestStackBuildid(unittest.TestCase): |
| def test_simple(self): |
| b = bcc.BPF(text=""" |
| #include <uapi/linux/ptrace.h> |
| struct bpf_map; |
| BPF_STACK_TRACE_BUILDID(stack_traces, 10240); |
| BPF_HASH(stack_entries, int, int); |
| BPF_HASH(stub); |
| int kprobe__sys_getuid(struct pt_regs *ctx, struct bpf_map *map, u64 *k) { |
| int id = stack_traces.get_stackid(ctx, BPF_F_USER_STACK); |
| if (id < 0) |
| return 0; |
| int key = 1; |
| stack_entries.update(&key, &id); |
| return 0; |
| } |
| """) |
| os.getuid() |
| stub = b["stub"] |
| stack_traces = b["stack_traces"] |
| stack_entries = b["stack_entries"] |
| b.add_module(Get_libc_path()) |
| try: x = stub[stub.Key(1)] |
| except: pass |
| k = stack_entries.Key(1) |
| self.assertIn(k, stack_entries) |
| stackid = stack_entries[k] |
| self.assertIsNotNone(stackid) |
| stack = stack_traces[stackid] |
| self.assertTrue(b.sym(stack.trace[0], -1).find(b"getuid")!=-1) |
| |
| if __name__ == "__main__": |
| unittest.main() |