182 lines · c
1// SPDX-License-Identifier: GPL-2.02/* 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 8enum trunc_type {9 TRUNC_NONE,10 TRUNC_PARTIAL,11 TRUNC_FULL,12};13 14static 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 bpf_program__set_log_level(skel->progs.bad_relo, 1 | 8); /* BPF_LOG_FIXED to force truncation */28 29 err = test_log_fixup__load(skel);30 if (!ASSERT_ERR(err, "load_fail"))31 goto cleanup;32 33 ASSERT_HAS_SUBSTR(log_buf,34 "0: <invalid CO-RE relocation>\n"35 "failed to resolve CO-RE relocation <byte_sz> ",36 "log_buf_part1");37 38 switch (trunc_type) {39 case TRUNC_NONE:40 ASSERT_HAS_SUBSTR(log_buf,41 "struct task_struct___bad.fake_field (0:1 @ offset 4)\n",42 "log_buf_part2");43 ASSERT_HAS_SUBSTR(log_buf,44 "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n",45 "log_buf_end");46 break;47 case TRUNC_PARTIAL:48 /* we should get full libbpf message patch */49 ASSERT_HAS_SUBSTR(log_buf,50 "struct task_struct___bad.fake_field (0:1 @ offset 4)\n",51 "log_buf_part2");52 /* we shouldn't get full end of BPF verifier log */53 ASSERT_NULL(strstr(log_buf, "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n"),54 "log_buf_end");55 break;56 case TRUNC_FULL:57 /* we shouldn't get second part of libbpf message patch */58 ASSERT_NULL(strstr(log_buf, "struct task_struct___bad.fake_field (0:1 @ offset 4)\n"),59 "log_buf_part2");60 /* we shouldn't get full end of BPF verifier log */61 ASSERT_NULL(strstr(log_buf, "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n"),62 "log_buf_end");63 break;64 }65 66 if (env.verbosity > VERBOSE_NONE)67 printf("LOG: \n=================\n%s=================\n", log_buf);68cleanup:69 test_log_fixup__destroy(skel);70}71 72static void bad_core_relo_subprog(void)73{74 char log_buf[8 * 1024];75 struct test_log_fixup* skel;76 int err;77 78 skel = test_log_fixup__open();79 if (!ASSERT_OK_PTR(skel, "skel_open"))80 return;81 82 bpf_program__set_autoload(skel->progs.bad_relo_subprog, true);83 bpf_program__set_log_buf(skel->progs.bad_relo_subprog, log_buf, sizeof(log_buf));84 85 err = test_log_fixup__load(skel);86 if (!ASSERT_ERR(err, "load_fail"))87 goto cleanup;88 89 ASSERT_HAS_SUBSTR(log_buf,90 ": <invalid CO-RE relocation>\n"91 "failed to resolve CO-RE relocation <byte_off> ",92 "log_buf");93 ASSERT_HAS_SUBSTR(log_buf,94 "struct task_struct___bad.fake_field_subprog (0:2 @ offset 8)\n",95 "log_buf");96 97 if (env.verbosity > VERBOSE_NONE)98 printf("LOG: \n=================\n%s=================\n", log_buf);99 100cleanup:101 test_log_fixup__destroy(skel);102}103 104static void missing_map(void)105{106 char log_buf[8 * 1024];107 struct test_log_fixup* skel;108 int err;109 110 skel = test_log_fixup__open();111 if (!ASSERT_OK_PTR(skel, "skel_open"))112 return;113 114 bpf_map__set_autocreate(skel->maps.missing_map, false);115 116 bpf_program__set_autoload(skel->progs.use_missing_map, true);117 bpf_program__set_log_buf(skel->progs.use_missing_map, log_buf, sizeof(log_buf));118 119 err = test_log_fixup__load(skel);120 if (!ASSERT_ERR(err, "load_fail"))121 goto cleanup;122 123 ASSERT_TRUE(bpf_map__autocreate(skel->maps.existing_map), "existing_map_autocreate");124 ASSERT_FALSE(bpf_map__autocreate(skel->maps.missing_map), "missing_map_autocreate");125 126 ASSERT_HAS_SUBSTR(log_buf,127 ": <invalid BPF map reference>\n"128 "BPF map 'missing_map' is referenced but wasn't created\n",129 "log_buf");130 131 if (env.verbosity > VERBOSE_NONE)132 printf("LOG: \n=================\n%s=================\n", log_buf);133 134cleanup:135 test_log_fixup__destroy(skel);136}137 138static void missing_kfunc(void)139{140 char log_buf[8 * 1024];141 struct test_log_fixup* skel;142 int err;143 144 skel = test_log_fixup__open();145 if (!ASSERT_OK_PTR(skel, "skel_open"))146 return;147 148 bpf_program__set_autoload(skel->progs.use_missing_kfunc, true);149 bpf_program__set_log_buf(skel->progs.use_missing_kfunc, log_buf, sizeof(log_buf));150 151 err = test_log_fixup__load(skel);152 if (!ASSERT_ERR(err, "load_fail"))153 goto cleanup;154 155 ASSERT_HAS_SUBSTR(log_buf,156 "0: <invalid kfunc call>\n"157 "kfunc 'bpf_nonexistent_kfunc' is referenced but wasn't resolved\n",158 "log_buf");159 160 if (env.verbosity > VERBOSE_NONE)161 printf("LOG: \n=================\n%s=================\n", log_buf);162 163cleanup:164 test_log_fixup__destroy(skel);165}166 167void test_log_fixup(void)168{169 if (test__start_subtest("bad_core_relo_trunc_none"))170 bad_core_relo(0, TRUNC_NONE /* full buf */);171 if (test__start_subtest("bad_core_relo_trunc_partial"))172 bad_core_relo(300, TRUNC_PARTIAL /* truncate original log a bit */);173 if (test__start_subtest("bad_core_relo_trunc_full"))174 bad_core_relo(240, TRUNC_FULL /* truncate also libbpf's message patch */);175 if (test__start_subtest("bad_core_relo_subprog"))176 bad_core_relo_subprog();177 if (test__start_subtest("missing_map"))178 missing_map();179 if (test__start_subtest("missing_kfunc"))180 missing_kfunc();181}182