• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright (c) PLUMgrid, Inc.
3# Licensed under the Apache License, Version 2.0 (the "License")
4
5import bcc
6import os
7import unittest
8from utils import mayFail, kernel_version_ge
9import subprocess
10
11
12@unittest.skipUnless(kernel_version_ge(4,6), "requires kernel >= 4.6")
13class TestStackid(unittest.TestCase):
14    @mayFail("This fails on github actions environment, and needs to be fixed")
15    def test_simple(self):
16        b = bcc.BPF(text="""
17#include <uapi/linux/ptrace.h>
18struct bpf_map;
19BPF_STACK_TRACE(stack_traces, 10240);
20BPF_HASH(stack_entries, int, int);
21BPF_HASH(stub);
22int kprobe__htab_map_lookup_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *k) {
23    int id = stack_traces.get_stackid(ctx, BPF_F_REUSE_STACKID);
24    if (id < 0)
25        return 0;
26    int key = 1;
27    stack_entries.update(&key, &id);
28    return 0;
29}
30""")
31        stub = b["stub"]
32        stack_traces = b["stack_traces"]
33        stack_entries = b["stack_entries"]
34        try: x = stub[stub.Key(1)]
35        except: pass
36        k = stack_entries.Key(1)
37        self.assertIn(k, stack_entries)
38        stackid = stack_entries[k]
39        self.assertIsNotNone(stackid)
40        stack = stack_traces[stackid].ip
41        self.assertEqual(b.ksym(stack[0]), b"htab_map_lookup_elem")
42
43def Get_libc_path():
44  cmd = 'cat /proc/self/maps | grep libc | awk \'{print $6}\' | uniq'
45  output = subprocess.check_output(cmd, shell=True)
46  if not isinstance(output, str):
47    output = output.decode()
48  return output.split('\n')[0]
49
50@unittest.skipUnless(kernel_version_ge(4,17), "requires kernel >= 4.17")
51class TestStackBuildid(unittest.TestCase):
52    def test_simple(self):
53        b = bcc.BPF(text="""
54#include <uapi/linux/ptrace.h>
55struct bpf_map;
56BPF_STACK_TRACE_BUILDID(stack_traces, 10240);
57BPF_HASH(stack_entries, int, int);
58BPF_HASH(stub);
59int kprobe__sys_getuid(struct pt_regs *ctx, struct bpf_map *map, u64 *k) {
60    int id = stack_traces.get_stackid(ctx, BPF_F_USER_STACK);
61    if (id < 0)
62        return 0;
63    int key = 1;
64    stack_entries.update(&key, &id);
65    return 0;
66}
67""")
68        os.getuid()
69        stub = b["stub"]
70        stack_traces = b["stack_traces"]
71        stack_entries = b["stack_entries"]
72        b.add_module(Get_libc_path())
73        try: x = stub[stub.Key(1)]
74        except: pass
75        k = stack_entries.Key(1)
76        self.assertIn(k, stack_entries)
77        stackid = stack_entries[k]
78        self.assertIsNotNone(stackid)
79        stack = stack_traces[stackid]
80        self.assertTrue(b.sym(stack.trace[0], -1).find(b"getuid")!=-1)
81
82if __name__ == "__main__":
83    unittest.main()
84