1 // SPDX-License-Identifier: GPL-2.0 2 3 /* 4 * Copyright (c) 2022 Facebook 5 * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH 6 * 7 * Author: Roberto Sassu <roberto.sassu@huawei.com> 8 */ 9 10 #include <test_progs.h> 11 #include "test_kfunc_dynptr_param.skel.h" 12 13 static size_t log_buf_sz = 1048576; /* 1 MB */ 14 static char obj_log_buf[1048576]; 15 16 static struct { 17 const char *prog_name; 18 const char *expected_verifier_err_msg; 19 int expected_runtime_err; 20 } kfunc_dynptr_tests[] = { 21 {"not_valid_dynptr", "Expected an initialized dynptr as arg #1", 0}, 22 {"not_ptr_to_stack", "arg#0 expected pointer to stack or dynptr_ptr", 0}, 23 {"dynptr_data_null", NULL, -EBADMSG}, 24 }; 25 26 static bool kfunc_not_supported; 27 28 static int libbpf_print_cb(enum libbpf_print_level level, const char *fmt, 29 va_list args) 30 { 31 if (strcmp(fmt, "libbpf: extern (func ksym) '%s': not found in kernel or module BTFs\n")) 32 return 0; 33 34 if (strcmp(va_arg(args, char *), "bpf_verify_pkcs7_signature")) 35 return 0; 36 37 kfunc_not_supported = true; 38 return 0; 39 } 40 41 static void verify_fail(const char *prog_name, const char *expected_err_msg) 42 { 43 struct test_kfunc_dynptr_param *skel; 44 LIBBPF_OPTS(bpf_object_open_opts, opts); 45 libbpf_print_fn_t old_print_cb; 46 struct bpf_program *prog; 47 int err; 48 49 opts.kernel_log_buf = obj_log_buf; 50 opts.kernel_log_size = log_buf_sz; 51 opts.kernel_log_level = 1; 52 53 skel = test_kfunc_dynptr_param__open_opts(&opts); 54 if (!ASSERT_OK_PTR(skel, "test_kfunc_dynptr_param__open_opts")) 55 goto cleanup; 56 57 prog = bpf_object__find_program_by_name(skel->obj, prog_name); 58 if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) 59 goto cleanup; 60 61 bpf_program__set_autoload(prog, true); 62 63 bpf_map__set_max_entries(skel->maps.ringbuf, getpagesize()); 64 65 kfunc_not_supported = false; 66 67 old_print_cb = libbpf_set_print(libbpf_print_cb); 68 err = test_kfunc_dynptr_param__load(skel); 69 libbpf_set_print(old_print_cb); 70 71 if (err < 0 && kfunc_not_supported) { 72 fprintf(stderr, 73 "%s:SKIP:bpf_verify_pkcs7_signature() kfunc not supported\n", 74 __func__); 75 test__skip(); 76 goto cleanup; 77 } 78 79 if (!ASSERT_ERR(err, "unexpected load success")) 80 goto cleanup; 81 82 if (!ASSERT_OK_PTR(strstr(obj_log_buf, expected_err_msg), "expected_err_msg")) { 83 fprintf(stderr, "Expected err_msg: %s\n", expected_err_msg); 84 fprintf(stderr, "Verifier output: %s\n", obj_log_buf); 85 } 86 87 cleanup: 88 test_kfunc_dynptr_param__destroy(skel); 89 } 90 91 static void verify_success(const char *prog_name, int expected_runtime_err) 92 { 93 struct test_kfunc_dynptr_param *skel; 94 libbpf_print_fn_t old_print_cb; 95 struct bpf_program *prog; 96 struct bpf_link *link; 97 __u32 next_id; 98 int err; 99 100 skel = test_kfunc_dynptr_param__open(); 101 if (!ASSERT_OK_PTR(skel, "test_kfunc_dynptr_param__open")) 102 return; 103 104 skel->bss->pid = getpid(); 105 106 bpf_map__set_max_entries(skel->maps.ringbuf, getpagesize()); 107 108 kfunc_not_supported = false; 109 110 old_print_cb = libbpf_set_print(libbpf_print_cb); 111 err = test_kfunc_dynptr_param__load(skel); 112 libbpf_set_print(old_print_cb); 113 114 if (err < 0 && kfunc_not_supported) { 115 fprintf(stderr, 116 "%s:SKIP:bpf_verify_pkcs7_signature() kfunc not supported\n", 117 __func__); 118 test__skip(); 119 goto cleanup; 120 } 121 122 if (!ASSERT_OK(err, "test_kfunc_dynptr_param__load")) 123 goto cleanup; 124 125 prog = bpf_object__find_program_by_name(skel->obj, prog_name); 126 if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) 127 goto cleanup; 128 129 link = bpf_program__attach(prog); 130 if (!ASSERT_OK_PTR(link, "bpf_program__attach")) 131 goto cleanup; 132 133 err = bpf_prog_get_next_id(0, &next_id); 134 135 bpf_link__destroy(link); 136 137 if (!ASSERT_OK(err, "bpf_prog_get_next_id")) 138 goto cleanup; 139 140 ASSERT_EQ(skel->bss->err, expected_runtime_err, "err"); 141 142 cleanup: 143 test_kfunc_dynptr_param__destroy(skel); 144 } 145 146 void test_kfunc_dynptr_param(void) 147 { 148 int i; 149 150 for (i = 0; i < ARRAY_SIZE(kfunc_dynptr_tests); i++) { 151 if (!test__start_subtest(kfunc_dynptr_tests[i].prog_name)) 152 continue; 153 154 if (kfunc_dynptr_tests[i].expected_verifier_err_msg) 155 verify_fail(kfunc_dynptr_tests[i].prog_name, 156 kfunc_dynptr_tests[i].expected_verifier_err_msg); 157 else 158 verify_success(kfunc_dynptr_tests[i].prog_name, 159 kfunc_dynptr_tests[i].expected_runtime_err); 160 } 161 } 162