root/tools/testing/selftests/bpf/prog_tests/attach_probe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_base_addr
  2. test_attach_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <test_progs.h>
   3 
   4 ssize_t get_base_addr() {
   5         size_t start, offset;
   6         char buf[256];
   7         FILE *f;
   8 
   9         f = fopen("/proc/self/maps", "r");
  10         if (!f)
  11                 return -errno;
  12 
  13         while (fscanf(f, "%zx-%*x %s %zx %*[^\n]\n",
  14                       &start, buf, &offset) == 3) {
  15                 if (strcmp(buf, "r-xp") == 0) {
  16                         fclose(f);
  17                         return start - offset;
  18                 }
  19         }
  20 
  21         fclose(f);
  22         return -EINVAL;
  23 }
  24 
  25 void test_attach_probe(void)
  26 {
  27         const char *kprobe_name = "kprobe/sys_nanosleep";
  28         const char *kretprobe_name = "kretprobe/sys_nanosleep";
  29         const char *uprobe_name = "uprobe/trigger_func";
  30         const char *uretprobe_name = "uretprobe/trigger_func";
  31         const int kprobe_idx = 0, kretprobe_idx = 1;
  32         const int uprobe_idx = 2, uretprobe_idx = 3;
  33         const char *file = "./test_attach_probe.o";
  34         struct bpf_program *kprobe_prog, *kretprobe_prog;
  35         struct bpf_program *uprobe_prog, *uretprobe_prog;
  36         struct bpf_object *obj;
  37         int err, prog_fd, duration = 0, res;
  38         struct bpf_link *kprobe_link = NULL;
  39         struct bpf_link *kretprobe_link = NULL;
  40         struct bpf_link *uprobe_link = NULL;
  41         struct bpf_link *uretprobe_link = NULL;
  42         int results_map_fd;
  43         size_t uprobe_offset;
  44         ssize_t base_addr;
  45 
  46         base_addr = get_base_addr();
  47         if (CHECK(base_addr < 0, "get_base_addr",
  48                   "failed to find base addr: %zd", base_addr))
  49                 return;
  50         uprobe_offset = (size_t)&get_base_addr - base_addr;
  51 
  52         /* load programs */
  53         err = bpf_prog_load(file, BPF_PROG_TYPE_KPROBE, &obj, &prog_fd);
  54         if (CHECK(err, "obj_load", "err %d errno %d\n", err, errno))
  55                 return;
  56 
  57         kprobe_prog = bpf_object__find_program_by_title(obj, kprobe_name);
  58         if (CHECK(!kprobe_prog, "find_probe",
  59                   "prog '%s' not found\n", kprobe_name))
  60                 goto cleanup;
  61         kretprobe_prog = bpf_object__find_program_by_title(obj, kretprobe_name);
  62         if (CHECK(!kretprobe_prog, "find_probe",
  63                   "prog '%s' not found\n", kretprobe_name))
  64                 goto cleanup;
  65         uprobe_prog = bpf_object__find_program_by_title(obj, uprobe_name);
  66         if (CHECK(!uprobe_prog, "find_probe",
  67                   "prog '%s' not found\n", uprobe_name))
  68                 goto cleanup;
  69         uretprobe_prog = bpf_object__find_program_by_title(obj, uretprobe_name);
  70         if (CHECK(!uretprobe_prog, "find_probe",
  71                   "prog '%s' not found\n", uretprobe_name))
  72                 goto cleanup;
  73 
  74         /* load maps */
  75         results_map_fd = bpf_find_map(__func__, obj, "results_map");
  76         if (CHECK(results_map_fd < 0, "find_results_map",
  77                   "err %d\n", results_map_fd))
  78                 goto cleanup;
  79 
  80         kprobe_link = bpf_program__attach_kprobe(kprobe_prog,
  81                                                  false /* retprobe */,
  82                                                  SYS_NANOSLEEP_KPROBE_NAME);
  83         if (CHECK(IS_ERR(kprobe_link), "attach_kprobe",
  84                   "err %ld\n", PTR_ERR(kprobe_link))) {
  85                 kprobe_link = NULL;
  86                 goto cleanup;
  87         }
  88         kretprobe_link = bpf_program__attach_kprobe(kretprobe_prog,
  89                                                     true /* retprobe */,
  90                                                     SYS_NANOSLEEP_KPROBE_NAME);
  91         if (CHECK(IS_ERR(kretprobe_link), "attach_kretprobe",
  92                   "err %ld\n", PTR_ERR(kretprobe_link))) {
  93                 kretprobe_link = NULL;
  94                 goto cleanup;
  95         }
  96         uprobe_link = bpf_program__attach_uprobe(uprobe_prog,
  97                                                  false /* retprobe */,
  98                                                  0 /* self pid */,
  99                                                  "/proc/self/exe",
 100                                                  uprobe_offset);
 101         if (CHECK(IS_ERR(uprobe_link), "attach_uprobe",
 102                   "err %ld\n", PTR_ERR(uprobe_link))) {
 103                 uprobe_link = NULL;
 104                 goto cleanup;
 105         }
 106         uretprobe_link = bpf_program__attach_uprobe(uretprobe_prog,
 107                                                     true /* retprobe */,
 108                                                     -1 /* any pid */,
 109                                                     "/proc/self/exe",
 110                                                     uprobe_offset);
 111         if (CHECK(IS_ERR(uretprobe_link), "attach_uretprobe",
 112                   "err %ld\n", PTR_ERR(uretprobe_link))) {
 113                 uretprobe_link = NULL;
 114                 goto cleanup;
 115         }
 116 
 117         /* trigger & validate kprobe && kretprobe */
 118         usleep(1);
 119 
 120         err = bpf_map_lookup_elem(results_map_fd, &kprobe_idx, &res);
 121         if (CHECK(err, "get_kprobe_res",
 122                   "failed to get kprobe res: %d\n", err))
 123                 goto cleanup;
 124         if (CHECK(res != kprobe_idx + 1, "check_kprobe_res",
 125                   "wrong kprobe res: %d\n", res))
 126                 goto cleanup;
 127 
 128         err = bpf_map_lookup_elem(results_map_fd, &kretprobe_idx, &res);
 129         if (CHECK(err, "get_kretprobe_res",
 130                   "failed to get kretprobe res: %d\n", err))
 131                 goto cleanup;
 132         if (CHECK(res != kretprobe_idx + 1, "check_kretprobe_res",
 133                   "wrong kretprobe res: %d\n", res))
 134                 goto cleanup;
 135 
 136         /* trigger & validate uprobe & uretprobe */
 137         get_base_addr();
 138 
 139         err = bpf_map_lookup_elem(results_map_fd, &uprobe_idx, &res);
 140         if (CHECK(err, "get_uprobe_res",
 141                   "failed to get uprobe res: %d\n", err))
 142                 goto cleanup;
 143         if (CHECK(res != uprobe_idx + 1, "check_uprobe_res",
 144                   "wrong uprobe res: %d\n", res))
 145                 goto cleanup;
 146 
 147         err = bpf_map_lookup_elem(results_map_fd, &uretprobe_idx, &res);
 148         if (CHECK(err, "get_uretprobe_res",
 149                   "failed to get uretprobe res: %d\n", err))
 150                 goto cleanup;
 151         if (CHECK(res != uretprobe_idx + 1, "check_uretprobe_res",
 152                   "wrong uretprobe res: %d\n", res))
 153                 goto cleanup;
 154 
 155 cleanup:
 156         bpf_link__destroy(kprobe_link);
 157         bpf_link__destroy(kretprobe_link);
 158         bpf_link__destroy(uprobe_link);
 159         bpf_link__destroy(uretprobe_link);
 160         bpf_object__close(obj);
 161 }

/* [<][>][^][v][top][bottom][index][help] */