1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ 3 #include <test_progs.h> 4 #include <bpf/btf.h> 5 6 #include "test_log_fixup.skel.h" 7 8 enum trunc_type { 9 TRUNC_NONE, 10 TRUNC_PARTIAL, 11 TRUNC_FULL, 12 }; 13 14 static void bad_core_relo(size_t log_buf_size, enum trunc_type trunc_type) 15 { 16 char log_buf[8 * 1024]; 17 struct test_log_fixup* skel; 18 int err; 19 20 skel = test_log_fixup__open(); 21 if (!ASSERT_OK_PTR(skel, "skel_open")) 22 return; 23 24 bpf_program__set_autoload(skel->progs.bad_relo, true); 25 memset(log_buf, 0, sizeof(log_buf)); 26 bpf_program__set_log_buf(skel->progs.bad_relo, log_buf, log_buf_size ?: sizeof(log_buf)); 27 28 err = test_log_fixup__load(skel); 29 if (!ASSERT_ERR(err, "load_fail")) 30 goto cleanup; 31 32 ASSERT_HAS_SUBSTR(log_buf, 33 "0: <invalid CO-RE relocation>\n" 34 "failed to resolve CO-RE relocation <byte_sz> ", 35 "log_buf_part1"); 36 37 switch (trunc_type) { 38 case TRUNC_NONE: 39 ASSERT_HAS_SUBSTR(log_buf, 40 "struct task_struct___bad.fake_field (0:1 @ offset 4)\n", 41 "log_buf_part2"); 42 ASSERT_HAS_SUBSTR(log_buf, 43 "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n", 44 "log_buf_end"); 45 break; 46 case TRUNC_PARTIAL: 47 /* we should get full libbpf message patch */ 48 ASSERT_HAS_SUBSTR(log_buf, 49 "struct task_struct___bad.fake_field (0:1 @ offset 4)\n", 50 "log_buf_part2"); 51 /* we shouldn't get full end of BPF verifier log */ 52 ASSERT_NULL(strstr(log_buf, "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n"), 53 "log_buf_end"); 54 break; 55 case TRUNC_FULL: 56 /* we shouldn't get second part of libbpf message patch */ 57 ASSERT_NULL(strstr(log_buf, "struct task_struct___bad.fake_field (0:1 @ offset 4)\n"), 58 "log_buf_part2"); 59 /* we shouldn't get full end of BPF verifier log */ 60 ASSERT_NULL(strstr(log_buf, "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n"), 61 "log_buf_end"); 62 break; 63 } 64 65 if (env.verbosity > VERBOSE_NONE) 66 printf("LOG: \n=================\n%s=================\n", log_buf); 67 cleanup: 68 test_log_fixup__destroy(skel); 69 } 70 71 static void bad_core_relo_subprog(void) 72 { 73 char log_buf[8 * 1024]; 74 struct test_log_fixup* skel; 75 int err; 76 77 skel = test_log_fixup__open(); 78 if (!ASSERT_OK_PTR(skel, "skel_open")) 79 return; 80 81 bpf_program__set_autoload(skel->progs.bad_relo_subprog, true); 82 bpf_program__set_log_buf(skel->progs.bad_relo_subprog, log_buf, sizeof(log_buf)); 83 84 err = test_log_fixup__load(skel); 85 if (!ASSERT_ERR(err, "load_fail")) 86 goto cleanup; 87 88 ASSERT_HAS_SUBSTR(log_buf, 89 ": <invalid CO-RE relocation>\n" 90 "failed to resolve CO-RE relocation <byte_off> ", 91 "log_buf"); 92 ASSERT_HAS_SUBSTR(log_buf, 93 "struct task_struct___bad.fake_field_subprog (0:2 @ offset 8)\n", 94 "log_buf"); 95 96 if (env.verbosity > VERBOSE_NONE) 97 printf("LOG: \n=================\n%s=================\n", log_buf); 98 99 cleanup: 100 test_log_fixup__destroy(skel); 101 } 102 103 static void missing_map(void) 104 { 105 char log_buf[8 * 1024]; 106 struct test_log_fixup* skel; 107 int err; 108 109 skel = test_log_fixup__open(); 110 if (!ASSERT_OK_PTR(skel, "skel_open")) 111 return; 112 113 bpf_map__set_autocreate(skel->maps.missing_map, false); 114 115 bpf_program__set_autoload(skel->progs.use_missing_map, true); 116 bpf_program__set_log_buf(skel->progs.use_missing_map, log_buf, sizeof(log_buf)); 117 118 err = test_log_fixup__load(skel); 119 if (!ASSERT_ERR(err, "load_fail")) 120 goto cleanup; 121 122 ASSERT_TRUE(bpf_map__autocreate(skel->maps.existing_map), "existing_map_autocreate"); 123 ASSERT_FALSE(bpf_map__autocreate(skel->maps.missing_map), "missing_map_autocreate"); 124 125 ASSERT_HAS_SUBSTR(log_buf, 126 "8: <invalid BPF map reference>\n" 127 "BPF map 'missing_map' is referenced but wasn't created\n", 128 "log_buf"); 129 130 if (env.verbosity > VERBOSE_NONE) 131 printf("LOG: \n=================\n%s=================\n", log_buf); 132 133 cleanup: 134 test_log_fixup__destroy(skel); 135 } 136 137 void test_log_fixup(void) 138 { 139 if (test__start_subtest("bad_core_relo_trunc_none")) 140 bad_core_relo(0, TRUNC_NONE /* full buf */); 141 if (test__start_subtest("bad_core_relo_trunc_partial")) 142 bad_core_relo(300, TRUNC_PARTIAL /* truncate original log a bit */); 143 if (test__start_subtest("bad_core_relo_trunc_full")) 144 bad_core_relo(250, TRUNC_FULL /* truncate also libbpf's message patch */); 145 if (test__start_subtest("bad_core_relo_subprog")) 146 bad_core_relo_subprog(); 147 if (test__start_subtest("missing_map")) 148 missing_map(); 149 } 150