Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2022 Facebook */
0003 
0004 #include <test_progs.h>
0005 #include "test_custom_sec_handlers.skel.h"
0006 
0007 #define COOKIE_ABC1 1
0008 #define COOKIE_ABC2 2
0009 #define COOKIE_CUSTOM 3
0010 #define COOKIE_FALLBACK 4
0011 #define COOKIE_KPROBE 5
0012 
0013 static int custom_setup_prog(struct bpf_program *prog, long cookie)
0014 {
0015     if (cookie == COOKIE_ABC1)
0016         bpf_program__set_autoload(prog, false);
0017 
0018     return 0;
0019 }
0020 
0021 static int custom_prepare_load_prog(struct bpf_program *prog,
0022                     struct bpf_prog_load_opts *opts, long cookie)
0023 {
0024     if (cookie == COOKIE_FALLBACK)
0025         opts->prog_flags |= BPF_F_SLEEPABLE;
0026     else if (cookie == COOKIE_ABC1)
0027         ASSERT_FALSE(true, "unexpected preload for abc");
0028 
0029     return 0;
0030 }
0031 
0032 static int custom_attach_prog(const struct bpf_program *prog, long cookie,
0033                   struct bpf_link **link)
0034 {
0035     switch (cookie) {
0036     case COOKIE_ABC2:
0037         *link = bpf_program__attach_raw_tracepoint(prog, "sys_enter");
0038         return libbpf_get_error(*link);
0039     case COOKIE_CUSTOM:
0040         *link = bpf_program__attach_tracepoint(prog, "syscalls", "sys_enter_nanosleep");
0041         return libbpf_get_error(*link);
0042     case COOKIE_KPROBE:
0043     case COOKIE_FALLBACK:
0044         /* no auto-attach for SEC("xyz") and SEC("kprobe") */
0045         *link = NULL;
0046         return 0;
0047     default:
0048         ASSERT_FALSE(true, "unexpected cookie");
0049         return -EINVAL;
0050     }
0051 }
0052 
0053 static int abc1_id;
0054 static int abc2_id;
0055 static int custom_id;
0056 static int fallback_id;
0057 static int kprobe_id;
0058 
0059 __attribute__((constructor))
0060 static void register_sec_handlers(void)
0061 {
0062     LIBBPF_OPTS(libbpf_prog_handler_opts, abc1_opts,
0063         .cookie = COOKIE_ABC1,
0064         .prog_setup_fn = custom_setup_prog,
0065         .prog_prepare_load_fn = custom_prepare_load_prog,
0066         .prog_attach_fn = NULL,
0067     );
0068     LIBBPF_OPTS(libbpf_prog_handler_opts, abc2_opts,
0069         .cookie = COOKIE_ABC2,
0070         .prog_setup_fn = custom_setup_prog,
0071         .prog_prepare_load_fn = custom_prepare_load_prog,
0072         .prog_attach_fn = custom_attach_prog,
0073     );
0074     LIBBPF_OPTS(libbpf_prog_handler_opts, custom_opts,
0075         .cookie = COOKIE_CUSTOM,
0076         .prog_setup_fn = NULL,
0077         .prog_prepare_load_fn = NULL,
0078         .prog_attach_fn = custom_attach_prog,
0079     );
0080 
0081     abc1_id = libbpf_register_prog_handler("abc", BPF_PROG_TYPE_RAW_TRACEPOINT, 0, &abc1_opts);
0082     abc2_id = libbpf_register_prog_handler("abc/", BPF_PROG_TYPE_RAW_TRACEPOINT, 0, &abc2_opts);
0083     custom_id = libbpf_register_prog_handler("custom+", BPF_PROG_TYPE_TRACEPOINT, 0, &custom_opts);
0084 }
0085 
0086 __attribute__((destructor))
0087 static void unregister_sec_handlers(void)
0088 {
0089     libbpf_unregister_prog_handler(abc1_id);
0090     libbpf_unregister_prog_handler(abc2_id);
0091     libbpf_unregister_prog_handler(custom_id);
0092 }
0093 
0094 void test_custom_sec_handlers(void)
0095 {
0096     LIBBPF_OPTS(libbpf_prog_handler_opts, opts,
0097         .prog_setup_fn = custom_setup_prog,
0098         .prog_prepare_load_fn = custom_prepare_load_prog,
0099         .prog_attach_fn = custom_attach_prog,
0100     );
0101     struct test_custom_sec_handlers* skel;
0102     int err;
0103 
0104     ASSERT_GT(abc1_id, 0, "abc1_id");
0105     ASSERT_GT(abc2_id, 0, "abc2_id");
0106     ASSERT_GT(custom_id, 0, "custom_id");
0107 
0108     /* override libbpf's handle of SEC("kprobe/...") but also allow pure
0109      * SEC("kprobe") due to "kprobe+" specifier. Register it as
0110      * TRACEPOINT, just for fun.
0111      */
0112     opts.cookie = COOKIE_KPROBE;
0113     kprobe_id = libbpf_register_prog_handler("kprobe+", BPF_PROG_TYPE_TRACEPOINT, 0, &opts);
0114     /* fallback treats everything as BPF_PROG_TYPE_SYSCALL program to test
0115      * setting custom BPF_F_SLEEPABLE bit in preload handler
0116      */
0117     opts.cookie = COOKIE_FALLBACK;
0118     fallback_id = libbpf_register_prog_handler(NULL, BPF_PROG_TYPE_SYSCALL, 0, &opts);
0119 
0120     if (!ASSERT_GT(fallback_id, 0, "fallback_id") /* || !ASSERT_GT(kprobe_id, 0, "kprobe_id")*/) {
0121         if (fallback_id > 0)
0122             libbpf_unregister_prog_handler(fallback_id);
0123         if (kprobe_id > 0)
0124             libbpf_unregister_prog_handler(kprobe_id);
0125         return;
0126     }
0127 
0128     /* open skeleton and validate assumptions */
0129     skel = test_custom_sec_handlers__open();
0130     if (!ASSERT_OK_PTR(skel, "skel_open"))
0131         goto cleanup;
0132 
0133     ASSERT_EQ(bpf_program__type(skel->progs.abc1), BPF_PROG_TYPE_RAW_TRACEPOINT, "abc1_type");
0134     ASSERT_FALSE(bpf_program__autoload(skel->progs.abc1), "abc1_autoload");
0135 
0136     ASSERT_EQ(bpf_program__type(skel->progs.abc2), BPF_PROG_TYPE_RAW_TRACEPOINT, "abc2_type");
0137     ASSERT_EQ(bpf_program__type(skel->progs.custom1), BPF_PROG_TYPE_TRACEPOINT, "custom1_type");
0138     ASSERT_EQ(bpf_program__type(skel->progs.custom2), BPF_PROG_TYPE_TRACEPOINT, "custom2_type");
0139     ASSERT_EQ(bpf_program__type(skel->progs.kprobe1), BPF_PROG_TYPE_TRACEPOINT, "kprobe1_type");
0140     ASSERT_EQ(bpf_program__type(skel->progs.xyz), BPF_PROG_TYPE_SYSCALL, "xyz_type");
0141 
0142     skel->rodata->my_pid = getpid();
0143 
0144     /* now attempt to load everything */
0145     err = test_custom_sec_handlers__load(skel);
0146     if (!ASSERT_OK(err, "skel_load"))
0147         goto cleanup;
0148 
0149     /* now try to auto-attach everything */
0150     err = test_custom_sec_handlers__attach(skel);
0151     if (!ASSERT_OK(err, "skel_attach"))
0152         goto cleanup;
0153 
0154     skel->links.xyz = bpf_program__attach(skel->progs.kprobe1);
0155     ASSERT_EQ(errno, EOPNOTSUPP, "xyz_attach_err");
0156     ASSERT_ERR_PTR(skel->links.xyz, "xyz_attach");
0157 
0158     /* trigger programs */
0159     usleep(1);
0160 
0161     /* SEC("abc") is set to not auto-loaded */
0162     ASSERT_FALSE(skel->bss->abc1_called, "abc1_called");
0163     ASSERT_TRUE(skel->bss->abc2_called, "abc2_called");
0164     ASSERT_TRUE(skel->bss->custom1_called, "custom1_called");
0165     ASSERT_TRUE(skel->bss->custom2_called, "custom2_called");
0166     /* SEC("kprobe") shouldn't be auto-attached */
0167     ASSERT_FALSE(skel->bss->kprobe1_called, "kprobe1_called");
0168     /* SEC("xyz") shouldn't be auto-attached */
0169     ASSERT_FALSE(skel->bss->xyz_called, "xyz_called");
0170 
0171 cleanup:
0172     test_custom_sec_handlers__destroy(skel);
0173 
0174     ASSERT_OK(libbpf_unregister_prog_handler(fallback_id), "unregister_fallback");
0175     ASSERT_OK(libbpf_unregister_prog_handler(kprobe_id), "unregister_kprobe");
0176 }