12cbc469aSKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0 22cbc469aSKumar Kartikeya Dwivedi #include <test_progs.h> 3*0ef6740eSKumar Kartikeya Dwivedi #include <network_helpers.h> 42cbc469aSKumar Kartikeya Dwivedi 52cbc469aSKumar Kartikeya Dwivedi #include "map_kptr.skel.h" 604accf79SKumar Kartikeya Dwivedi #include "map_kptr_fail.skel.h" 72cbc469aSKumar Kartikeya Dwivedi 804accf79SKumar Kartikeya Dwivedi static char log_buf[1024 * 1024]; 904accf79SKumar Kartikeya Dwivedi 1004accf79SKumar Kartikeya Dwivedi struct { 1104accf79SKumar Kartikeya Dwivedi const char *prog_name; 1204accf79SKumar Kartikeya Dwivedi const char *err_msg; 1304accf79SKumar Kartikeya Dwivedi } map_kptr_fail_tests[] = { 1404accf79SKumar Kartikeya Dwivedi { "size_not_bpf_dw", "kptr access size must be BPF_DW" }, 1504accf79SKumar Kartikeya Dwivedi { "non_const_var_off", "kptr access cannot have variable offset" }, 1604accf79SKumar Kartikeya Dwivedi { "non_const_var_off_kptr_xchg", "R1 doesn't have constant offset. kptr has to be" }, 1704accf79SKumar Kartikeya Dwivedi { "misaligned_access_write", "kptr access misaligned expected=8 off=7" }, 1804accf79SKumar Kartikeya Dwivedi { "misaligned_access_read", "kptr access misaligned expected=8 off=1" }, 1904accf79SKumar Kartikeya Dwivedi { "reject_var_off_store", "variable untrusted_ptr_ access var_off=(0x0; 0x1e0)" }, 2004accf79SKumar Kartikeya Dwivedi { "reject_bad_type_match", "invalid kptr access, R1 type=untrusted_ptr_prog_test_ref_kfunc" }, 2104accf79SKumar Kartikeya Dwivedi { "marked_as_untrusted_or_null", "R1 type=untrusted_ptr_or_null_ expected=percpu_ptr_" }, 2204accf79SKumar Kartikeya Dwivedi { "correct_btf_id_check_size", "access beyond struct prog_test_ref_kfunc at off 32 size 4" }, 2304accf79SKumar Kartikeya Dwivedi { "inherit_untrusted_on_walk", "R1 type=untrusted_ptr_ expected=percpu_ptr_" }, 2404accf79SKumar Kartikeya Dwivedi { "reject_kptr_xchg_on_unref", "off=8 kptr isn't referenced kptr" }, 2504accf79SKumar Kartikeya Dwivedi { "reject_kptr_get_no_map_val", "arg#0 expected pointer to map value" }, 2604accf79SKumar Kartikeya Dwivedi { "reject_kptr_get_no_null_map_val", "arg#0 expected pointer to map value" }, 2704accf79SKumar Kartikeya Dwivedi { "reject_kptr_get_no_kptr", "arg#0 no referenced kptr at map value offset=0" }, 2804accf79SKumar Kartikeya Dwivedi { "reject_kptr_get_on_unref", "arg#0 no referenced kptr at map value offset=8" }, 2904accf79SKumar Kartikeya Dwivedi { "reject_kptr_get_bad_type_match", "kernel function bpf_kfunc_call_test_kptr_get args#0" }, 3004accf79SKumar Kartikeya Dwivedi { "mark_ref_as_untrusted_or_null", "R1 type=untrusted_ptr_or_null_ expected=percpu_ptr_" }, 3104accf79SKumar Kartikeya Dwivedi { "reject_untrusted_store_to_ref", "store to referenced kptr disallowed" }, 3204accf79SKumar Kartikeya Dwivedi { "reject_bad_type_xchg", "invalid kptr access, R2 type=ptr_prog_test_ref_kfunc expected=ptr_prog_test_member" }, 3304accf79SKumar Kartikeya Dwivedi { "reject_untrusted_xchg", "R2 type=untrusted_ptr_ expected=ptr_" }, 3404accf79SKumar Kartikeya Dwivedi { "reject_member_of_ref_xchg", "invalid kptr access, R2 type=ptr_prog_test_ref_kfunc" }, 3504accf79SKumar Kartikeya Dwivedi { "reject_indirect_helper_access", "kptr cannot be accessed indirectly by helper" }, 3604accf79SKumar Kartikeya Dwivedi { "reject_indirect_global_func_access", "kptr cannot be accessed indirectly by helper" }, 3704accf79SKumar Kartikeya Dwivedi { "kptr_xchg_ref_state", "Unreleased reference id=5 alloc_insn=" }, 3804accf79SKumar Kartikeya Dwivedi { "kptr_get_ref_state", "Unreleased reference id=3 alloc_insn=" }, 3904accf79SKumar Kartikeya Dwivedi }; 4004accf79SKumar Kartikeya Dwivedi 4104accf79SKumar Kartikeya Dwivedi static void test_map_kptr_fail_prog(const char *prog_name, const char *err_msg) 4204accf79SKumar Kartikeya Dwivedi { 4304accf79SKumar Kartikeya Dwivedi LIBBPF_OPTS(bpf_object_open_opts, opts, .kernel_log_buf = log_buf, 4404accf79SKumar Kartikeya Dwivedi .kernel_log_size = sizeof(log_buf), 4504accf79SKumar Kartikeya Dwivedi .kernel_log_level = 1); 4604accf79SKumar Kartikeya Dwivedi struct map_kptr_fail *skel; 4704accf79SKumar Kartikeya Dwivedi struct bpf_program *prog; 4804accf79SKumar Kartikeya Dwivedi int ret; 4904accf79SKumar Kartikeya Dwivedi 5004accf79SKumar Kartikeya Dwivedi skel = map_kptr_fail__open_opts(&opts); 5104accf79SKumar Kartikeya Dwivedi if (!ASSERT_OK_PTR(skel, "map_kptr_fail__open_opts")) 5204accf79SKumar Kartikeya Dwivedi return; 5304accf79SKumar Kartikeya Dwivedi 5404accf79SKumar Kartikeya Dwivedi prog = bpf_object__find_program_by_name(skel->obj, prog_name); 5504accf79SKumar Kartikeya Dwivedi if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) 5604accf79SKumar Kartikeya Dwivedi goto end; 5704accf79SKumar Kartikeya Dwivedi 5804accf79SKumar Kartikeya Dwivedi bpf_program__set_autoload(prog, true); 5904accf79SKumar Kartikeya Dwivedi 6004accf79SKumar Kartikeya Dwivedi ret = map_kptr_fail__load(skel); 6104accf79SKumar Kartikeya Dwivedi if (!ASSERT_ERR(ret, "map_kptr__load must fail")) 6204accf79SKumar Kartikeya Dwivedi goto end; 6304accf79SKumar Kartikeya Dwivedi 6404accf79SKumar Kartikeya Dwivedi if (!ASSERT_OK_PTR(strstr(log_buf, err_msg), "expected error message")) { 6504accf79SKumar Kartikeya Dwivedi fprintf(stderr, "Expected: %s\n", err_msg); 6604accf79SKumar Kartikeya Dwivedi fprintf(stderr, "Verifier: %s\n", log_buf); 6704accf79SKumar Kartikeya Dwivedi } 6804accf79SKumar Kartikeya Dwivedi 6904accf79SKumar Kartikeya Dwivedi end: 7004accf79SKumar Kartikeya Dwivedi map_kptr_fail__destroy(skel); 7104accf79SKumar Kartikeya Dwivedi } 7204accf79SKumar Kartikeya Dwivedi 7304accf79SKumar Kartikeya Dwivedi static void test_map_kptr_fail(void) 7404accf79SKumar Kartikeya Dwivedi { 7504accf79SKumar Kartikeya Dwivedi int i; 7604accf79SKumar Kartikeya Dwivedi 7704accf79SKumar Kartikeya Dwivedi for (i = 0; i < ARRAY_SIZE(map_kptr_fail_tests); i++) { 7804accf79SKumar Kartikeya Dwivedi if (!test__start_subtest(map_kptr_fail_tests[i].prog_name)) 7904accf79SKumar Kartikeya Dwivedi continue; 8004accf79SKumar Kartikeya Dwivedi test_map_kptr_fail_prog(map_kptr_fail_tests[i].prog_name, 8104accf79SKumar Kartikeya Dwivedi map_kptr_fail_tests[i].err_msg); 8204accf79SKumar Kartikeya Dwivedi } 8304accf79SKumar Kartikeya Dwivedi } 8404accf79SKumar Kartikeya Dwivedi 85*0ef6740eSKumar Kartikeya Dwivedi static void test_map_kptr_success(bool test_run) 862cbc469aSKumar Kartikeya Dwivedi { 87*0ef6740eSKumar Kartikeya Dwivedi LIBBPF_OPTS(bpf_test_run_opts, opts, 88*0ef6740eSKumar Kartikeya Dwivedi .data_in = &pkt_v4, 89*0ef6740eSKumar Kartikeya Dwivedi .data_size_in = sizeof(pkt_v4), 90*0ef6740eSKumar Kartikeya Dwivedi .repeat = 1, 91*0ef6740eSKumar Kartikeya Dwivedi ); 922cbc469aSKumar Kartikeya Dwivedi struct map_kptr *skel; 932cbc469aSKumar Kartikeya Dwivedi int key = 0, ret; 942cbc469aSKumar Kartikeya Dwivedi char buf[24]; 952cbc469aSKumar Kartikeya Dwivedi 962cbc469aSKumar Kartikeya Dwivedi skel = map_kptr__open_and_load(); 972cbc469aSKumar Kartikeya Dwivedi if (!ASSERT_OK_PTR(skel, "map_kptr__open_and_load")) 982cbc469aSKumar Kartikeya Dwivedi return; 992cbc469aSKumar Kartikeya Dwivedi 100*0ef6740eSKumar Kartikeya Dwivedi ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref), &opts); 101*0ef6740eSKumar Kartikeya Dwivedi ASSERT_OK(ret, "test_map_kptr_ref refcount"); 102*0ef6740eSKumar Kartikeya Dwivedi ASSERT_OK(opts.retval, "test_map_kptr_ref retval"); 103*0ef6740eSKumar Kartikeya Dwivedi ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_map_kptr_ref2), &opts); 104*0ef6740eSKumar Kartikeya Dwivedi ASSERT_OK(ret, "test_map_kptr_ref2 refcount"); 105*0ef6740eSKumar Kartikeya Dwivedi ASSERT_OK(opts.retval, "test_map_kptr_ref2 retval"); 106*0ef6740eSKumar Kartikeya Dwivedi 107*0ef6740eSKumar Kartikeya Dwivedi if (test_run) 108*0ef6740eSKumar Kartikeya Dwivedi return; 109*0ef6740eSKumar Kartikeya Dwivedi 1102cbc469aSKumar Kartikeya Dwivedi ret = bpf_map_update_elem(bpf_map__fd(skel->maps.array_map), &key, buf, 0); 1112cbc469aSKumar Kartikeya Dwivedi ASSERT_OK(ret, "array_map update"); 1122cbc469aSKumar Kartikeya Dwivedi ret = bpf_map_update_elem(bpf_map__fd(skel->maps.array_map), &key, buf, 0); 1132cbc469aSKumar Kartikeya Dwivedi ASSERT_OK(ret, "array_map update2"); 1142cbc469aSKumar Kartikeya Dwivedi 1152cbc469aSKumar Kartikeya Dwivedi ret = bpf_map_update_elem(bpf_map__fd(skel->maps.hash_map), &key, buf, 0); 1162cbc469aSKumar Kartikeya Dwivedi ASSERT_OK(ret, "hash_map update"); 1172cbc469aSKumar Kartikeya Dwivedi ret = bpf_map_delete_elem(bpf_map__fd(skel->maps.hash_map), &key); 1182cbc469aSKumar Kartikeya Dwivedi ASSERT_OK(ret, "hash_map delete"); 1192cbc469aSKumar Kartikeya Dwivedi 1202cbc469aSKumar Kartikeya Dwivedi ret = bpf_map_update_elem(bpf_map__fd(skel->maps.hash_malloc_map), &key, buf, 0); 1212cbc469aSKumar Kartikeya Dwivedi ASSERT_OK(ret, "hash_malloc_map update"); 1222cbc469aSKumar Kartikeya Dwivedi ret = bpf_map_delete_elem(bpf_map__fd(skel->maps.hash_malloc_map), &key); 1232cbc469aSKumar Kartikeya Dwivedi ASSERT_OK(ret, "hash_malloc_map delete"); 1242cbc469aSKumar Kartikeya Dwivedi 1252cbc469aSKumar Kartikeya Dwivedi ret = bpf_map_update_elem(bpf_map__fd(skel->maps.lru_hash_map), &key, buf, 0); 1262cbc469aSKumar Kartikeya Dwivedi ASSERT_OK(ret, "lru_hash_map update"); 1272cbc469aSKumar Kartikeya Dwivedi ret = bpf_map_delete_elem(bpf_map__fd(skel->maps.lru_hash_map), &key); 1282cbc469aSKumar Kartikeya Dwivedi ASSERT_OK(ret, "lru_hash_map delete"); 1292cbc469aSKumar Kartikeya Dwivedi 1302cbc469aSKumar Kartikeya Dwivedi map_kptr__destroy(skel); 1312cbc469aSKumar Kartikeya Dwivedi } 13204accf79SKumar Kartikeya Dwivedi 13304accf79SKumar Kartikeya Dwivedi void test_map_kptr(void) 13404accf79SKumar Kartikeya Dwivedi { 135*0ef6740eSKumar Kartikeya Dwivedi if (test__start_subtest("success")) { 136*0ef6740eSKumar Kartikeya Dwivedi test_map_kptr_success(false); 137*0ef6740eSKumar Kartikeya Dwivedi /* Do test_run twice, so that we see refcount going back to 1 138*0ef6740eSKumar Kartikeya Dwivedi * after we leave it in map from first iteration. 139*0ef6740eSKumar Kartikeya Dwivedi */ 140*0ef6740eSKumar Kartikeya Dwivedi test_map_kptr_success(true); 141*0ef6740eSKumar Kartikeya Dwivedi } 14204accf79SKumar Kartikeya Dwivedi test_map_kptr_fail(); 14304accf79SKumar Kartikeya Dwivedi } 144