• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Alan-Jowett / ebpf-verifier / 22235569093

20 Feb 2026 02:12AM UTC coverage: 88.002% (-0.2%) from 88.157%
22235569093

push

github

web-flow
Handle Call builtins: fix handling of Falco tests  (#1025)

* falco: fix raw_tracepoint privilege and group expected failures

Mark raw_tracepoint/raw_tracepoint_writable as privileged program types so Falco raw-tracepoint sections are not treated as unprivileged argument checks.

Update Falco sample matrix to move now-passing sections out of TEST_SECTION_FAIL and group the remaining expected failures by root-cause class (offset lower-bound loss vs size lower-bound loss at correlated joins).

Signed-off-by: Elazar Gershuni <elazarg@gmail.com>

* elf/unmarshal: gate builtin relocations via platform call model

Add platform hooks to resolve builtin symbols and provide builtin call contracts, thread relocation-gated builtin call offsets through ProgramInfo, and only treat static helper IDs as builtins at gated call sites.

Also extend platform-table, marshal, and YAML-platform tests to cover builtin resolver wiring and call unmarshal behavior.
* crab: canonicalize unsigned intervals in bitwise_and
When uvalue intervals temporarily carry signed lower bounds (e.g. after joins), Interval::bitwise_and asserted in debug builds. Canonicalize both operands via zero_extend(64) before unsigned bitwise reasoning, preserving soundness and avoiding debug aborts.

Validated by reproducing SIGABRT on reverted code in [falco][verify] and confirming the patched build completes with expected 73 pass / 20 failed-as-expected.

* Fix unsound bitwise_and case for non-singleton all-ones rhs

Signed-off-by: Elazar Gershuni <elazarg@gmail.com>

239 of 252 new or added lines in 9 files covered. (94.84%)

602 existing lines in 16 files now uncovered.

11743 of 13344 relevant lines covered (88.0%)

3262592.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.88
/src/test/test_verify.cpp
1
// Copyright (c) Prevail Verifier contributors.
2
// SPDX-License-Identifier: MIT
3
#include <catch2/catch_all.hpp>
4
#include <ranges>
5
#include <thread>
6

7
#include "ebpf_verifier.hpp"
8
#include "linux/gpl/spec_type_descriptors.hpp"
9

10
using namespace prevail;
11

12
#define FAIL_LOAD_ELF(dirname, filename, sectionname)                                                    \
13
    TEST_CASE("Try loading nonexisting program: " dirname "/" filename, "[elf]") {                       \
14
        try {                                                                                            \
15
            thread_local_options = {};                                                                   \
16
            read_elf("ebpf-samples/" dirname "/" filename, sectionname, "", {}, &g_ebpf_platform_linux); \
17
            REQUIRE(false);                                                                              \
18
        } catch (const std::runtime_error&) {                                                            \
19
        }                                                                                                \
20
    }
21

22
// Some intentional failures
23
FAIL_LOAD_ELF("cilium", "not-found.o", "2/1")
11✔
24
FAIL_LOAD_ELF("cilium", "bpf_lxc.o", "not-found")
11✔
25
FAIL_LOAD_ELF("build", "badrelo.o", ".text")
11✔
26
FAIL_LOAD_ELF("invalid", "badsymsize.o", "xdp_redirect_map")
11✔
27

28
#define FAIL_UNMARSHAL(dirname, filename, sectionname)                                                                \
29
    TEST_CASE("Try unmarshalling bad program: " dirname "/" filename " " sectionname, "[unmarshal]") {                \
30
        thread_local_options = {};                                                                                    \
31
        auto raw_progs = read_elf("ebpf-samples/" dirname "/" filename, sectionname, "", {}, &g_ebpf_platform_linux); \
32
        REQUIRE(raw_progs.size() == 1);                                                                               \
33
        const RawProgram& raw_prog = raw_progs.back();                                                                \
34
        std::variant<InstructionSeq, std::string> prog_or_error = unmarshal(raw_prog, thread_local_options);          \
35
        REQUIRE(std::holds_alternative<std::string>(prog_or_error));                                                  \
36
    }
37

38
// Some intentional unmarshal failures
39
FAIL_UNMARSHAL("invalid", "invalid-lddw.o", ".text")
13✔
40

41
TEST_CASE("instruction feature handling after unmarshal", "[unmarshal]") {
52✔
42
    constexpr EbpfInst exit{.opcode = INST_OP_EXIT};
52✔
43
    ebpf_platform_t platform = g_ebpf_platform_linux;
52✔
44
    ProgramInfo info{.platform = &platform, .type = platform.get_program_type("unspec", "unspec")};
130✔
45

46
    SECTION("unknown kfunc btf id") {
52✔
47
        RawProgram raw_prog{
2✔
48
            "", "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1}, exit}, info};
5✔
49
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
50
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
51
        REQUIRE_THROWS_WITH(
9✔
52
            Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {}),
53
            Catch::Matchers::ContainsSubstring("not implemented: kfunc prototype lookup failed for BTF id 1") &&
54
                Catch::Matchers::ContainsSubstring("(at 0)"));
55
    }
54✔
56

57
    SECTION("kfunc call by BTF id is accepted when prototype is known") {
52✔
58
        RawProgram raw_prog{
2✔
59
            "", "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1000}, exit}, info};
5✔
60
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
61
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
62
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
63
        REQUIRE(verify(prog));
2✔
64
    }
54✔
65

66
    SECTION("kfunc call in local subprogram does not use helper prototype lookup") {
52✔
67
        RawProgram raw_prog{"",
2✔
68
                            "",
1✔
69
                            0,
70
                            "",
1✔
71
                            {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_LOCAL, .imm = 1}, exit,
72
                             EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1000}, exit},
73
                            info};
5✔
74
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
75
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
76
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
77
        REQUIRE(verify(prog));
2✔
78
    }
54✔
79

80
    SECTION("kfunc in subprogram is not misclassified when BTF id overlaps helper id") {
52✔
81
        RawProgram raw_prog{"",
2✔
82
                            "",
1✔
83
                            0,
84
                            "",
1✔
85
                            {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_LOCAL, .imm = 1}, exit,
86
                             EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 12}, exit},
87
                            info};
5✔
88
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
89
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
90
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
91
        REQUIRE(verify(prog));
2✔
92
    }
54✔
93

94
    SECTION("kfunc map-value return is lowered to map-lookup call contract") {
52✔
95
        constexpr uint8_t mov64_imm = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_IMM;
2✔
96
        RawProgram raw_prog{"",
2✔
97
                            "",
1✔
98
                            0,
99
                            "",
1✔
100
                            {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1005},
101
                             EbpfInst{.opcode = mov64_imm, .dst = 0, .imm = 0}, exit},
102
                            info};
5✔
103
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
104
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
105
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
106
        const auto* call = std::get_if<Call>(&prog.instruction_at(Label{0}));
4✔
107
        REQUIRE(call != nullptr);
2✔
108
        REQUIRE(call->is_map_lookup);
2✔
109
        REQUIRE(verify(prog));
2✔
110
    }
54✔
111

112
    SECTION("kfunc with unsupported flags is rejected") {
52✔
113
        RawProgram raw_prog{
2✔
114
            "", "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1002}, exit}, info};
5✔
115
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
116
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
117
        REQUIRE_THROWS_WITH(
9✔
118
            Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {}),
119
            Catch::Matchers::ContainsSubstring("not implemented: kfunc flags are unsupported on this platform") &&
120
                Catch::Matchers::ContainsSubstring("(at 0)"));
121
    }
54✔
122

123
    SECTION("kfunc program type gating is enforced") {
52✔
124
        RawProgram raw_prog{
2✔
125
            "", "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1003}, exit}, info};
5✔
126
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
127
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
128
        REQUIRE_THROWS_WITH(
8✔
129
            Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {}),
130
            Catch::Matchers::ContainsSubstring("not implemented: kfunc is unavailable for program type") &&
131
                Catch::Matchers::ContainsSubstring("(at 0)"));
132

133
        ProgramInfo xdp_info{.platform = &platform, .type = platform.get_program_type("xdp", "xdp")};
5✔
134
        RawProgram xdp_raw_prog{
2✔
135
            "",      "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1003}, exit},
1✔
136
            xdp_info};
5✔
137
        auto xdp_prog_or_error = unmarshal(xdp_raw_prog, {});
2✔
138
        REQUIRE(std::holds_alternative<InstructionSeq>(xdp_prog_or_error));
2✔
139
        const Program xdp_prog = Program::from_sequence(std::get<InstructionSeq>(xdp_prog_or_error), xdp_info, {});
2✔
140
        REQUIRE(verify(xdp_prog));
2✔
141
    }
54✔
142

143
    SECTION("kfunc privileged gating is enforced") {
52✔
144
        RawProgram raw_prog{
2✔
145
            "", "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1004}, exit}, info};
5✔
146
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
147
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
148
        REQUIRE_THROWS_WITH(
8✔
149
            Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {}),
150
            Catch::Matchers::ContainsSubstring("not implemented: kfunc requires privileged program type") &&
151
                Catch::Matchers::ContainsSubstring("(at 0)"));
152

153
        ProgramInfo kprobe_info{
1✔
154
            .platform = &platform,
155
            .type = platform.get_program_type("kprobe/test_prog", ""),
3✔
156
        };
5✔
157
        RawProgram kprobe_raw_prog{
2✔
158
            "",         "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1004}, exit},
1✔
159
            kprobe_info};
5✔
160
        auto kprobe_prog_or_error = unmarshal(kprobe_raw_prog, {});
2✔
161
        REQUIRE(std::holds_alternative<InstructionSeq>(kprobe_prog_or_error));
2✔
162
        const Program kprobe_prog =
1✔
163
            Program::from_sequence(std::get<InstructionSeq>(kprobe_prog_or_error), kprobe_info, {});
2✔
164
        REQUIRE(verify(kprobe_prog));
2✔
165
    }
54✔
166

167
    SECTION("kfunc argument typing is enforced from prototype table") {
52✔
168
        constexpr uint8_t mov64_imm = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_IMM;
2✔
169

170
        RawProgram good_raw_prog{
2✔
171
            "", "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1001}, exit}, info};
5✔
172
        auto good_prog_or_error = unmarshal(good_raw_prog, {});
2✔
173
        REQUIRE(std::holds_alternative<InstructionSeq>(good_prog_or_error));
2✔
174
        const Program good_prog = Program::from_sequence(std::get<InstructionSeq>(good_prog_or_error), info, {});
2✔
175
        REQUIRE(verify(good_prog));
2✔
176

177
        RawProgram bad_raw_prog{"",
2✔
178
                                "",
1✔
179
                                0,
180
                                "",
1✔
181
                                {EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 0},
182
                                 EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1001}, exit},
183
                                info};
5✔
184
        auto bad_prog_or_error = unmarshal(bad_raw_prog, {});
2✔
185
        REQUIRE(std::holds_alternative<InstructionSeq>(bad_prog_or_error));
2✔
186
        const Program bad_prog = Program::from_sequence(std::get<InstructionSeq>(bad_prog_or_error), info, {});
2✔
187
        REQUIRE_FALSE(verify(bad_prog));
2✔
188
    }
54✔
189

190
    SECTION("kfunc pointer-size argument pairs enforce null and size constraints") {
52✔
191
        constexpr uint8_t mov64_imm = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_IMM;
2✔
192

193
        RawProgram good_raw_prog{"",
2✔
194
                                 "",
1✔
195
                                 0,
196
                                 "",
1✔
197
                                 {EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 0},
198
                                  EbpfInst{.opcode = mov64_imm, .dst = 2, .imm = 0},
199
                                  EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1006}, exit},
200
                                 info};
5✔
201
        auto good_prog_or_error = unmarshal(good_raw_prog, {});
2✔
202
        REQUIRE(std::holds_alternative<InstructionSeq>(good_prog_or_error));
2✔
203
        const Program good_prog = Program::from_sequence(std::get<InstructionSeq>(good_prog_or_error), info, {});
2✔
204
        REQUIRE(verify(good_prog));
2✔
205

206
        RawProgram bad_size_raw_prog{"",
2✔
207
                                     "",
1✔
208
                                     0,
209
                                     "",
1✔
210
                                     {EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 0},
211
                                      EbpfInst{.opcode = mov64_imm, .dst = 2, .imm = -1},
212
                                      EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1006}, exit},
213
                                     info};
5✔
214
        auto bad_size_prog_or_error = unmarshal(bad_size_raw_prog, {});
2✔
215
        REQUIRE(std::holds_alternative<InstructionSeq>(bad_size_prog_or_error));
2✔
216
        const Program bad_size_prog =
1✔
217
            Program::from_sequence(std::get<InstructionSeq>(bad_size_prog_or_error), info, {});
2✔
218
        REQUIRE_FALSE(verify(bad_size_prog));
2✔
219

220
        RawProgram bad_nullability_raw_prog{
2✔
221
            "",
1✔
222
            "",
1✔
223
            0,
224
            "",
1✔
225
            {EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 1}, EbpfInst{.opcode = mov64_imm, .dst = 2, .imm = 0},
226
             EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1006}, exit},
227
            info};
5✔
228
        auto bad_nullability_prog_or_error = unmarshal(bad_nullability_raw_prog, {});
2✔
229
        REQUIRE(std::holds_alternative<InstructionSeq>(bad_nullability_prog_or_error));
2✔
230
        const Program bad_nullability_prog =
1✔
231
            Program::from_sequence(std::get<InstructionSeq>(bad_nullability_prog_or_error), info, {});
2✔
232
        REQUIRE_FALSE(verify(bad_nullability_prog));
2✔
233
    }
54✔
234

235
    SECTION("kfunc writable-memory argument pairs enforce writeability and strict size") {
52✔
236
        constexpr uint8_t mov64_imm = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_IMM;
2✔
237
        constexpr uint8_t mov64_reg = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_REG;
2✔
238
        constexpr uint8_t add64_imm = INST_CLS_ALU64 | INST_ALU_OP_ADD | INST_SRC_IMM;
2✔
239

240
        RawProgram good_raw_prog{"",
2✔
241
                                 "",
1✔
242
                                 0,
243
                                 "",
1✔
244
                                 {EbpfInst{.opcode = mov64_reg, .dst = 1, .src = R10_STACK_POINTER},
245
                                  EbpfInst{.opcode = add64_imm, .dst = 1, .imm = -8},
246
                                  EbpfInst{.opcode = mov64_imm, .dst = 2, .imm = 4},
247
                                  EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1007}, exit},
248
                                 info};
5✔
249
        auto good_prog_or_error = unmarshal(good_raw_prog, {});
2✔
250
        REQUIRE(std::holds_alternative<InstructionSeq>(good_prog_or_error));
2✔
251
        const Program good_prog = Program::from_sequence(std::get<InstructionSeq>(good_prog_or_error), info, {});
2✔
252
        REQUIRE(verify(good_prog));
2✔
253

254
        RawProgram bad_nullability_raw_prog{
2✔
255
            "",
1✔
256
            "",
1✔
257
            0,
258
            "",
1✔
259
            {EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 0}, EbpfInst{.opcode = mov64_imm, .dst = 2, .imm = 4},
260
             EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1007}, exit},
261
            info};
5✔
262
        auto bad_nullability_prog_or_error = unmarshal(bad_nullability_raw_prog, {});
2✔
263
        REQUIRE(std::holds_alternative<InstructionSeq>(bad_nullability_prog_or_error));
2✔
264
        const Program bad_nullability_prog =
1✔
265
            Program::from_sequence(std::get<InstructionSeq>(bad_nullability_prog_or_error), info, {});
2✔
266
        REQUIRE_FALSE(verify(bad_nullability_prog));
2✔
267

268
        RawProgram bad_size_raw_prog{"",
2✔
269
                                     "",
1✔
270
                                     0,
271
                                     "",
1✔
272
                                     {EbpfInst{.opcode = mov64_reg, .dst = 1, .src = R10_STACK_POINTER},
273
                                      EbpfInst{.opcode = add64_imm, .dst = 1, .imm = -8},
274
                                      EbpfInst{.opcode = mov64_imm, .dst = 2, .imm = 0},
275
                                      EbpfInst{.opcode = INST_OP_CALL, .src = INST_CALL_BTF_HELPER, .imm = 1007}, exit},
276
                                     info};
5✔
277
        auto bad_size_prog_or_error = unmarshal(bad_size_raw_prog, {});
2✔
278
        REQUIRE(std::holds_alternative<InstructionSeq>(bad_size_prog_or_error));
2✔
279
        const Program bad_size_prog =
1✔
280
            Program::from_sequence(std::get<InstructionSeq>(bad_size_prog_or_error), info, {});
2✔
281
        REQUIRE_FALSE(verify(bad_size_prog));
2✔
282
    }
54✔
283

284
    SECTION("lddw variable_addr pseudo") {
52✔
285
        RawProgram raw_prog{
2✔
286
            "",  "", 0, "", {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 1, .src = 3, .imm = 7}, EbpfInst{}, exit},
1✔
287
            info};
5✔
288
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
289
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
290
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
291
        const auto* bin = std::get_if<Bin>(&prog.instruction_at(Label{0}));
4✔
292
        REQUIRE(bin != nullptr);
2✔
293
        REQUIRE(bin->op == Bin::Op::MOV);
2✔
294
        REQUIRE(bin->is64);
2✔
295
        REQUIRE(bin->lddw);
2✔
296
        REQUIRE(bin->dst == Reg{1});
2✔
297
        const auto* imm = std::get_if<Imm>(&bin->v);
2✔
298
        REQUIRE(imm != nullptr);
2✔
299
        REQUIRE(imm->v == 7ULL);
2✔
300
    }
54✔
301

302
    SECTION("lddw code_addr pseudo") {
52✔
303
        RawProgram raw_prog{
2✔
304
            "",  "", 0, "", {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 2, .src = 4, .imm = 11}, EbpfInst{}, exit},
1✔
305
            info};
5✔
306
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
307
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
308
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
309
        const auto* pseudo = std::get_if<LoadPseudo>(&prog.instruction_at(Label{0}));
4✔
310
        REQUIRE(pseudo != nullptr);
2✔
311
        REQUIRE(pseudo->dst == Reg{2});
2✔
312
        REQUIRE(pseudo->addr.kind == PseudoAddress::Kind::CODE_ADDR);
2✔
313
        REQUIRE(pseudo->addr.imm == 11);
2✔
314
    }
54✔
315

316
    SECTION("lddw immediate merges high and low words") {
52✔
317
        RawProgram raw_prog{
2✔
318
            "",
1✔
319
            "",
1✔
320
            0,
321
            "",
1✔
322
            {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 3, .src = 0, .imm = 1}, EbpfInst{.imm = 2}, exit},
323
            info};
5✔
324
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
325
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
326
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
327
        const auto* bin = std::get_if<Bin>(&prog.instruction_at(Label{0}));
4✔
328
        REQUIRE(bin != nullptr);
2✔
329
        REQUIRE(bin->op == Bin::Op::MOV);
2✔
330
        REQUIRE(bin->is64);
2✔
331
        REQUIRE(bin->lddw);
2✔
332
        REQUIRE(bin->dst == Reg{3});
2✔
333
        const auto* imm = std::get_if<Imm>(&bin->v);
2✔
334
        REQUIRE(imm != nullptr);
2✔
335
        REQUIRE(imm->v == ((2ULL << 32) | 1ULL));
2✔
336
    }
54✔
337

338
    SECTION("lddw immediate does not sign-extend low word") {
52✔
339
        RawProgram raw_prog{
2✔
340
            "",
1✔
341
            "",
1✔
342
            0,
343
            "",
1✔
344
            {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 3, .src = 0, .imm = -1}, EbpfInst{.imm = 0}, exit},
345
            info};
5✔
346
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
347
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
348
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
349
        const auto* bin = std::get_if<Bin>(&prog.instruction_at(Label{0}));
4✔
350
        REQUIRE(bin != nullptr);
2✔
351
        REQUIRE(bin->op == Bin::Op::MOV);
2✔
352
        REQUIRE(bin->is64);
2✔
353
        REQUIRE(bin->lddw);
2✔
354
        REQUIRE(bin->dst == Reg{3});
2✔
355
        const auto* imm = std::get_if<Imm>(&bin->v);
2✔
356
        REQUIRE(imm != nullptr);
2✔
357
        REQUIRE(imm->v == 0x00000000FFFFFFFFULL);
2✔
358
    }
54✔
359

360
    SECTION("lddw code_addr pseudo") {
52✔
361
        RawProgram raw_prog{
2✔
362
            "",
1✔
363
            "",
1✔
364
            0,
365
            "",
1✔
366
            {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 2, .src = INST_LD_MODE_CODE_ADDR, .imm = 7}, EbpfInst{}, exit},
367
            info};
5✔
368
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
369
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
370
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
371
        const auto* pseudo = std::get_if<LoadPseudo>(&prog.instruction_at(Label{0}));
4✔
372
        REQUIRE(pseudo != nullptr);
2✔
373
        REQUIRE(pseudo->addr.kind == PseudoAddress::Kind::CODE_ADDR);
2✔
374
    }
54✔
375

376
    SECTION("helper ptr_to_func argument type is accepted for bpf_loop") {
52✔
377
        constexpr uint8_t mov64_imm = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_IMM;
2✔
378
        RawProgram raw_prog{
2✔
379
            "",
1✔
380
            "",
1✔
381
            0,
382
            "",
1✔
383
            {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 2, .src = INST_LD_MODE_CODE_ADDR, .imm = 1}, EbpfInst{},
384
             EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 1}, EbpfInst{.opcode = mov64_imm, .dst = 3, .imm = 0},
385
             EbpfInst{.opcode = mov64_imm, .dst = 4, .imm = 0}, EbpfInst{.opcode = INST_OP_CALL, .imm = 181}, exit},
386
            info};
5✔
387
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
388
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
389
        const Program prog = Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {});
2✔
390
        const auto* call = std::get_if<Call>(&prog.instruction_at(Label{5}));
4✔
391
        REQUIRE(call != nullptr);
2✔
392
        REQUIRE(call->is_supported);
2✔
393
        REQUIRE(std::ranges::any_of(call->singles, [](const ArgSingle& arg) {
6✔
394
            return arg.kind == ArgSingle::Kind::PTR_TO_FUNC && arg.reg == Reg{2};
395
        }));
396
    }
54✔
397

398
    SECTION("ptr_to_func argument enforces function type") {
52✔
399
        constexpr uint8_t mov64_imm = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_IMM;
2✔
400
        RawProgram good_raw_prog{
2✔
401
            "",
1✔
402
            "",
1✔
403
            0,
404
            "",
1✔
405
            {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 2, .src = INST_LD_MODE_CODE_ADDR, .imm = 7}, EbpfInst{},
406
             EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 1}, EbpfInst{.opcode = mov64_imm, .dst = 3, .imm = 0},
407
             EbpfInst{.opcode = mov64_imm, .dst = 4, .imm = 0}, EbpfInst{.opcode = INST_OP_CALL, .imm = 181}, exit,
408
             EbpfInst{.opcode = mov64_imm, .dst = 0, .imm = 0}, exit},
409
            info};
5✔
410
        auto good_prog_or_error = unmarshal(good_raw_prog, {});
2✔
411
        REQUIRE(std::holds_alternative<InstructionSeq>(good_prog_or_error));
2✔
412
        const Program good_prog = Program::from_sequence(std::get<InstructionSeq>(good_prog_or_error), info, {});
2✔
413
        REQUIRE(verify(good_prog));
2✔
414

415
        RawProgram bad_raw_prog{
2✔
416
            "",
1✔
417
            "",
1✔
418
            0,
419
            "",
1✔
420
            {EbpfInst{.opcode = mov64_imm, .dst = 2, .imm = 7}, EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 1},
421
             EbpfInst{.opcode = mov64_imm, .dst = 3, .imm = 0}, EbpfInst{.opcode = mov64_imm, .dst = 4, .imm = 0},
422
             EbpfInst{.opcode = INST_OP_CALL, .imm = 181}, exit},
423
            info};
5✔
424
        auto bad_prog_or_error = unmarshal(bad_raw_prog, {});
2✔
425
        REQUIRE(std::holds_alternative<InstructionSeq>(bad_prog_or_error));
2✔
426
        const Program bad_prog = Program::from_sequence(std::get<InstructionSeq>(bad_prog_or_error), info, {});
2✔
427
        REQUIRE_FALSE(verify(bad_prog));
2✔
428
    }
54✔
429

430
    SECTION("ptr_to_func callback target must be a valid instruction label") {
52✔
431
        constexpr uint8_t mov64_imm = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_IMM;
2✔
432
        RawProgram good_raw_prog{
2✔
433
            "",
1✔
434
            "",
1✔
435
            0,
436
            "",
1✔
437
            {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 2, .src = INST_LD_MODE_CODE_ADDR, .imm = 7}, EbpfInst{},
438
             EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 1}, EbpfInst{.opcode = mov64_imm, .dst = 3, .imm = 0},
439
             EbpfInst{.opcode = mov64_imm, .dst = 4, .imm = 0}, EbpfInst{.opcode = INST_OP_CALL, .imm = 181}, exit,
440
             EbpfInst{.opcode = mov64_imm, .dst = 0, .imm = 0}, exit},
441
            info};
5✔
442
        auto good_prog_or_error = unmarshal(good_raw_prog, {});
2✔
443
        REQUIRE(std::holds_alternative<InstructionSeq>(good_prog_or_error));
2✔
444
        const Program good_prog = Program::from_sequence(std::get<InstructionSeq>(good_prog_or_error), info, {});
2✔
445
        REQUIRE(verify(good_prog));
2✔
446

447
        RawProgram bad_raw_prog{
2✔
448
            "",
1✔
449
            "",
1✔
450
            0,
451
            "",
1✔
452
            {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 2, .src = INST_LD_MODE_CODE_ADDR, .imm = 1}, EbpfInst{},
453
             EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 1}, EbpfInst{.opcode = mov64_imm, .dst = 3, .imm = 0},
454
             EbpfInst{.opcode = mov64_imm, .dst = 4, .imm = 0}, EbpfInst{.opcode = INST_OP_CALL, .imm = 181}, exit,
455
             EbpfInst{.opcode = mov64_imm, .dst = 0, .imm = 0}, exit},
456
            info};
5✔
457
        auto bad_prog_or_error = unmarshal(bad_raw_prog, {});
2✔
458
        REQUIRE(std::holds_alternative<InstructionSeq>(bad_prog_or_error));
2✔
459
        const Program bad_prog = Program::from_sequence(std::get<InstructionSeq>(bad_prog_or_error), info, {});
2✔
460
        REQUIRE_FALSE(verify(bad_prog));
2✔
461
    }
54✔
462

463
    SECTION("ptr_to_func callback target must have reachable exit") {
52✔
464
        constexpr uint8_t mov64_imm = INST_CLS_ALU64 | INST_ALU_OP_MOV | INST_SRC_IMM;
2✔
465
        RawProgram bad_raw_prog{
2✔
466
            "",
1✔
467
            "",
1✔
468
            0,
469
            "",
1✔
470
            {EbpfInst{.opcode = INST_OP_LDDW_IMM, .dst = 2, .src = INST_LD_MODE_CODE_ADDR, .imm = 7}, EbpfInst{},
471
             EbpfInst{.opcode = mov64_imm, .dst = 1, .imm = 1}, EbpfInst{.opcode = mov64_imm, .dst = 3, .imm = 0},
472
             EbpfInst{.opcode = mov64_imm, .dst = 4, .imm = 0}, EbpfInst{.opcode = INST_OP_CALL, .imm = 181}, exit,
473
             EbpfInst{.opcode = INST_OP_JA16, .offset = -1}},
474
            info};
5✔
475
        auto bad_prog_or_error = unmarshal(bad_raw_prog, {});
2✔
476
        REQUIRE(std::holds_alternative<InstructionSeq>(bad_prog_or_error));
2✔
477
        const Program bad_prog = Program::from_sequence(std::get<InstructionSeq>(bad_prog_or_error), info, {});
2✔
478
        REQUIRE_FALSE(verify(bad_prog));
2✔
479
    }
54✔
480

481
    SECTION("helper id not usable on platform") {
52✔
482
        RawProgram raw_prog{"", "", 0, "", {EbpfInst{.opcode = INST_OP_CALL, .imm = 0x7fff}, exit}, info};
6✔
483
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
484
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
485
        REQUIRE_THROWS_WITH(
9✔
486
            Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {}),
487
            Catch::Matchers::ContainsSubstring("rejected: helper function is unavailable on this platform") &&
488
                Catch::Matchers::ContainsSubstring("(at 0)"));
489
    }
54✔
490

491
    SECTION("be64 requires base64 conformance group") {
52✔
492
        ebpf_platform_t p = g_ebpf_platform_linux;
2✔
493
        p.supported_conformance_groups &= ~bpf_conformance_groups_t::base64;
2✔
494
        ProgramInfo pinfo{.platform = &p, .type = p.get_program_type("unspec", "unspec")};
5✔
495
        RawProgram raw_prog{"",
2✔
496
                            "",
1✔
497
                            0,
498
                            "",
1✔
499
                            {EbpfInst{.opcode = static_cast<uint8_t>(INST_CLS_ALU | INST_ALU_OP_END | INST_END_BE),
500
                                      .dst = 1,
501
                                      .imm = 64},
502
                             exit},
503
                            pinfo};
5✔
504
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
505
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
506
        REQUIRE_THROWS_WITH(Program::from_sequence(std::get<InstructionSeq>(prog_or_error), pinfo, {}),
9✔
507
                            Catch::Matchers::ContainsSubstring("rejected: requires conformance group base64") &&
508
                                Catch::Matchers::ContainsSubstring("(at 0)"));
509
    }
54✔
510

511
    SECTION("call btf cannot use register-call opcode form") {
52✔
512
        RawProgram raw_prog{
2✔
513
            "",  "", 0, "", {EbpfInst{.opcode = INST_OP_CALLX, .dst = 0, .src = INST_CALL_BTF_HELPER, .imm = 1}, exit},
1✔
514
            info};
5✔
515
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
516
        REQUIRE(std::holds_alternative<std::string>(prog_or_error));
2✔
517
        REQUIRE_THAT(std::get<std::string>(prog_or_error), Catch::Matchers::ContainsSubstring("bad instruction"));
7✔
518
    }
54✔
519

520
    SECTION("tail call chain depth above 33 is rejected") {
52✔
521
        std::vector<EbpfInst> insts;
2✔
522
        for (size_t i = 0; i < 34; i++) {
70✔
523
            insts.push_back(EbpfInst{.opcode = INST_OP_CALL, .imm = 12});
68✔
524
        }
525
        insts.push_back(exit);
2✔
526
        RawProgram raw_prog{"", "", 0, "", std::move(insts), info};
5✔
527
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
528
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
529
        REQUIRE_THROWS_WITH(Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {}),
9✔
530
                            Catch::Matchers::ContainsSubstring("tail call chain depth exceeds 33") &&
531
                                Catch::Matchers::ContainsSubstring("(at"));
532
    }
54✔
533

534
    SECTION("tail call chain depth of exactly 33 is accepted") {
52✔
535
        std::vector<EbpfInst> insts;
2✔
536
        for (size_t i = 0; i < 33; i++) {
68✔
537
            insts.push_back(EbpfInst{.opcode = INST_OP_CALL, .imm = 12});
66✔
538
        }
539
        insts.push_back(exit);
2✔
540
        RawProgram raw_prog{"", "", 0, "", std::move(insts), info};
5✔
541
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
542
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
543
        REQUIRE_NOTHROW(Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {}));
3✔
544
    }
54✔
545

546
    SECTION("tail call cycle does not inflate chain depth") {
52✔
547
        // No exit instruction is intentional; this checks SCC-based depth accounting, not termination.
548
        RawProgram raw_prog{"",
2✔
549
                            "",
1✔
550
                            0,
551
                            "",
1✔
552
                            {
553
                                EbpfInst{.opcode = INST_OP_CALL, .imm = 12},
554
                                EbpfInst{.opcode = INST_OP_JA16, .offset = -2},
555
                            },
556
                            info};
5✔
557
        auto prog_or_error = unmarshal(raw_prog, {});
2✔
558
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));
2✔
559
        REQUIRE_NOTHROW(Program::from_sequence(std::get<InstructionSeq>(prog_or_error), info, {}));
3✔
560
    }
54✔
561
}
52✔
562

563
// Verify a program in a section that may have multiple programs in it.
564
#define VERIFY_PROGRAM(dirname, filename, section_name, program_name, _options, platform, should_pass, count) \
565
    do {                                                                                                      \
566
        thread_local_options = _options;                                                                      \
567
        const auto raw_progs =                                                                                \
568
            read_elf("ebpf-samples/" dirname "/" filename, section_name, "", thread_local_options, platform); \
569
        REQUIRE(raw_progs.size() == count);                                                                   \
570
        for (const auto& raw_prog : raw_progs) {                                                              \
571
            if (count == 1 || raw_prog.function_name == program_name) {                                       \
572
                const auto prog_or_error = unmarshal(raw_prog, thread_local_options);                         \
573
                const auto inst_seq = std::get_if<InstructionSeq>(&prog_or_error);                            \
574
                REQUIRE(inst_seq);                                                                            \
575
                const Program prog = Program::from_sequence(*inst_seq, raw_prog.info, thread_local_options);  \
576
                REQUIRE(verify(prog) == should_pass);                                                         \
577
            }                                                                                                 \
578
        }                                                                                                     \
579
    } while (0)
580

581
// Verify a section with only one program in it.
582
#define VERIFY_SECTION(dirname, filename, section_name, _options, platform, should_pass) \
583
    VERIFY_PROGRAM(dirname, filename, section_name, "", _options, platform, should_pass, 1)
584

585
#define TEST_SECTION(project, filename, section)                                      \
586
    TEST_CASE(project "/" filename " " section, "[verify][samples][" project "]") {   \
587
        VERIFY_SECTION(project, filename, section, {}, &g_ebpf_platform_linux, true); \
588
    }
589

590
#define TEST_SECTION_SLOW(project, filename, section)                                     \
591
    TEST_CASE(project "/" filename " " section, "[verify][samples][slow][" project "]") { \
592
        VERIFY_SECTION(project, filename, section, {}, &g_ebpf_platform_linux, true);     \
593
    }
594

595
#define TEST_PROGRAM(project, filename, section_name, program_name, count)                                      \
596
    TEST_CASE(project "/" filename " " program_name, "[verify][samples][" project "]") {                        \
597
        VERIFY_PROGRAM(project, filename, section_name, program_name, {}, &g_ebpf_platform_linux, true, count); \
598
    }
599

600
#define TEST_PROGRAM_FAIL(project, filename, section_name, program_name, count)                                 \
601
    TEST_CASE(project "/" filename " " program_name, "[!shouldfail][verify][samples][" project "]") {           \
602
        VERIFY_PROGRAM(project, filename, section_name, program_name, {}, &g_ebpf_platform_linux, true, count); \
603
    }
604

605
#define TEST_PROGRAM_REJECT(project, filename, section_name, program_name, count)                                \
606
    TEST_CASE(project "/" filename " " program_name, "[verify][samples][" project "]") {                         \
607
        VERIFY_PROGRAM(project, filename, section_name, program_name, {}, &g_ebpf_platform_linux, false, count); \
608
    }
609

610
#define TEST_PROGRAM_REJECT_FAIL(project, filename, section_name, program_name, count)                           \
611
    TEST_CASE(project "/" filename " " program_name, "[!shouldfail][verify][samples][" project "]") {            \
612
        VERIFY_PROGRAM(project, filename, section_name, program_name, {}, &g_ebpf_platform_linux, false, count); \
613
    }
614

615
#define TEST_SECTION_REJECT(project, filename, section)                                \
616
    TEST_CASE(project "/" filename " " section, "[verify][samples][" project "]") {    \
617
        VERIFY_SECTION(project, filename, section, {}, &g_ebpf_platform_linux, false); \
618
    }
619

620
#define TEST_SECTION_REJECT_IF_STRICT(project, filename, section)                           \
621
    TEST_CASE(project "/" filename " " section, "[verify][samples][" project "]") {         \
622
        ebpf_verifier_options_t options{};                                                  \
623
        VERIFY_SECTION(project, filename, section, options, &g_ebpf_platform_linux, true);  \
624
        options.strict = true;                                                              \
625
        VERIFY_SECTION(project, filename, section, options, &g_ebpf_platform_linux, false); \
626
    }
627

628
#define TEST_SECTION_FAIL(project, filename, section)                                                              \
629
    TEST_CASE("expect failure " project "/" filename " " section, "[!shouldfail][verify][samples][" project "]") { \
630
        VERIFY_SECTION(project, filename, section, {}, &g_ebpf_platform_linux, true);                              \
631
    }
632

633
#define TEST_SECTION_FAIL_SLOW(project, filename, section)                            \
634
    TEST_CASE("expect failure " project "/" filename " " section,                     \
635
              "[!shouldfail][verify][samples][slow][" project "]") {                  \
636
        VERIFY_SECTION(project, filename, section, {}, &g_ebpf_platform_linux, true); \
637
    }
638

639
#define TEST_SECTION_REJECT_FAIL(project, filename, section)                                                       \
640
    TEST_CASE("expect failure " project "/" filename " " section, "[!shouldfail][verify][samples][" project "]") { \
641
        VERIFY_SECTION(project, filename, section, {}, &g_ebpf_platform_linux, false);                             \
642
    }
643

644
#define TEST_LEGACY(dirname, filename, sectionname)                                                             \
645
    TEST_CASE("Unsupported instructions: " dirname "/" filename " " sectionname, "[unmarshal]") {               \
646
        ebpf_platform_t platform = g_ebpf_platform_linux;                                                       \
647
        platform.supported_conformance_groups &= ~bpf_conformance_groups_t::packet;                             \
648
        auto raw_progs = read_elf("ebpf-samples/" dirname "/" filename, sectionname, "", {}, &platform);        \
649
        REQUIRE(raw_progs.size() == 1);                                                                         \
650
        RawProgram raw_prog = raw_progs.back();                                                                 \
651
        std::variant<InstructionSeq, std::string> prog_or_error = unmarshal(raw_prog, {});                      \
652
        REQUIRE(std::holds_alternative<InstructionSeq>(prog_or_error));                                         \
653
        REQUIRE_THROWS_WITH(Program::from_sequence(std::get<InstructionSeq>(prog_or_error), raw_prog.info, {}), \
654
                            Catch::Matchers::ContainsSubstring("rejected: requires conformance group packet")); \
655
    }
656

657
#define TEST_SECTION_LEGACY(dirname, filename, sectionname) \
658
    TEST_SECTION(dirname, filename, sectionname)            \
659
    TEST_LEGACY(dirname, filename, sectionname)
660

661
#define TEST_SECTION_LEGACY_SLOW(dirname, filename, sectionname) \
662
    TEST_SECTION_SLOW(dirname, filename, sectionname)            \
663
    TEST_LEGACY(dirname, filename, sectionname)
664

665
#define TEST_SECTION_LEGACY_FAIL(dirname, filename, sectionname) \
666
    TEST_SECTION_FAIL(dirname, filename, sectionname)            \
667
    TEST_LEGACY(dirname, filename, sectionname)
668

669
TEST_SECTION_SLOW("bpf_cilium_test", "bpf_lxc_jit.o", "1/0xdc06")
16✔
670
TEST_SECTION("bpf_cilium_test", "bpf_lxc_jit.o", "2/1")
16✔
671
TEST_SECTION("bpf_cilium_test", "bpf_lxc_jit.o", "2/3")
16✔
672
TEST_SECTION("bpf_cilium_test", "bpf_lxc_jit.o", "2/4")
16✔
673
TEST_SECTION("bpf_cilium_test", "bpf_lxc_jit.o", "2/5")
16✔
674
TEST_SECTION("bpf_cilium_test", "bpf_lxc_jit.o", "2/6")
16✔
675
TEST_SECTION_SLOW("bpf_cilium_test", "bpf_lxc_jit.o", "2/7")
16✔
676
TEST_SECTION_LEGACY_SLOW("bpf_cilium_test", "bpf_lxc_jit.o", "2/10")
33✔
677
TEST_SECTION("bpf_cilium_test", "bpf_lxc_jit.o", "from-container")
16✔
678

679
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "1/0x1010")
16✔
680
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "2/1")
16✔
681
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "2/2")
16✔
682
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "2/3")
16✔
683
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "2/4")
16✔
684
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "2/5")
16✔
685
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "2/6")
16✔
686
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "2/7")
16✔
687
TEST_SECTION_LEGACY("bpf_cilium_test", "bpf_lxc-DUNKNOWN.o", "from-container")
33✔
688

689
TEST_SECTION_SLOW("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "1/0x1010")
16✔
690
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "2/1")
16✔
691
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "2/2")
16✔
692
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "2/3")
16✔
693
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "2/4")
16✔
694
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "2/5")
16✔
695
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "2/6")
16✔
696
TEST_SECTION_SLOW("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "2/7")
16✔
697
TEST_SECTION("bpf_cilium_test", "bpf_lxc-DDROP_ALL.o", "from-container")
16✔
698

699
TEST_SECTION("bpf_cilium_test", "bpf_netdev.o", "2/1")
16✔
700
TEST_SECTION("bpf_cilium_test", "bpf_netdev.o", "2/2")
16✔
701
TEST_SECTION("bpf_cilium_test", "bpf_netdev.o", "2/3")
16✔
702
TEST_SECTION("bpf_cilium_test", "bpf_netdev.o", "2/4")
16✔
703
TEST_SECTION("bpf_cilium_test", "bpf_netdev.o", "2/5")
16✔
704
TEST_SECTION("bpf_cilium_test", "bpf_netdev.o", "2/7")
16✔
705

706
TEST_SECTION("bpf_cilium_test", "bpf_overlay.o", "2/1")
16✔
707
TEST_SECTION("bpf_cilium_test", "bpf_overlay.o", "2/2")
16✔
708
TEST_SECTION("bpf_cilium_test", "bpf_overlay.o", "2/3")
16✔
709
TEST_SECTION("bpf_cilium_test", "bpf_overlay.o", "2/4")
16✔
710
TEST_SECTION("bpf_cilium_test", "bpf_overlay.o", "2/5")
16✔
711
TEST_SECTION("bpf_cilium_test", "bpf_overlay.o", "2/7")
16✔
712
TEST_SECTION("bpf_cilium_test", "bpf_overlay.o", "3/2")
16✔
713
TEST_SECTION_LEGACY_SLOW("bpf_cilium_test", "bpf_overlay.o", "from-overlay")
33✔
714

715
TEST_SECTION("bpf_cilium_test", "bpf_lb-DLB_L3.o", "2/1")
16✔
716
TEST_SECTION("bpf_cilium_test", "bpf_lb-DLB_L3.o", "2/2")
16✔
717
TEST_SECTION("bpf_cilium_test", "bpf_lb-DLB_L3.o", "from-netdev")
16✔
718

719
TEST_SECTION("bpf_cilium_test", "bpf_lb-DLB_L4.o", "2/1")
16✔
720
TEST_SECTION("bpf_cilium_test", "bpf_lb-DLB_L4.o", "2/2")
16✔
721
TEST_SECTION("bpf_cilium_test", "bpf_lb-DLB_L4.o", "from-netdev")
16✔
722

723
TEST_SECTION("bpf_cilium_test", "bpf_lb-DUNKNOWN.o", "2/1")
16✔
724
TEST_SECTION("bpf_cilium_test", "bpf_lb-DUNKNOWN.o", "2/2")
16✔
725
TEST_SECTION("bpf_cilium_test", "bpf_lb-DUNKNOWN.o", "from-netdev")
16✔
726

727
TEST_SECTION("cilium", "bpf_lb.o", "2/1")
16✔
728
TEST_SECTION("cilium", "bpf_lb.o", "from-netdev")
16✔
729

730
TEST_SECTION("cilium", "bpf_lxc.o", "1/0x1010")
16✔
731
TEST_SECTION("cilium", "bpf_lxc.o", "2/1")
16✔
732
TEST_SECTION("cilium", "bpf_lxc.o", "2/3")
16✔
733
TEST_SECTION("cilium", "bpf_lxc.o", "2/4")
16✔
734
TEST_SECTION("cilium", "bpf_lxc.o", "2/5")
16✔
735
TEST_SECTION("cilium", "bpf_lxc.o", "2/6")
16✔
736
TEST_SECTION("cilium", "bpf_lxc.o", "2/8")
16✔
737
TEST_SECTION("cilium", "bpf_lxc.o", "2/9")
16✔
738
TEST_SECTION("cilium", "bpf_lxc.o", "from-container")
16✔
739

740
TEST_SECTION("cilium", "bpf_netdev.o", "2/1")
16✔
741
TEST_SECTION("cilium", "bpf_netdev.o", "2/3")
16✔
742
TEST_SECTION("cilium", "bpf_netdev.o", "2/4")
16✔
743
TEST_SECTION("cilium", "bpf_netdev.o", "2/5")
16✔
744
TEST_SECTION("cilium", "bpf_netdev.o", "2/7")
16✔
745

746
TEST_SECTION("cilium", "bpf_overlay.o", "2/1")
16✔
747
TEST_SECTION("cilium", "bpf_overlay.o", "2/3")
16✔
748
TEST_SECTION("cilium", "bpf_overlay.o", "2/4")
16✔
749
TEST_SECTION("cilium", "bpf_overlay.o", "2/5")
16✔
750
TEST_SECTION("cilium", "bpf_overlay.o", "2/7")
16✔
751
TEST_SECTION_LEGACY("cilium", "bpf_overlay.o", "from-overlay")
33✔
752

753
TEST_SECTION("cilium", "bpf_xdp.o", "from-netdev")
16✔
754

755
TEST_SECTION("cilium", "bpf_xdp_dsr_linux_v1_1.o", "from-netdev")
16✔
756
TEST_SECTION("cilium", "bpf_xdp_dsr_linux.o", "2/1")
16✔
757
TEST_SECTION("cilium", "bpf_xdp_dsr_linux.o", "from-netdev")
16✔
758

759
TEST_SECTION("cilium", "bpf_xdp_snat_linux.o", "2/1")
16✔
760
TEST_SECTION("cilium", "bpf_xdp_snat_linux.o", "from-netdev")
16✔
761

762
TEST_SECTION("linux", "cpustat_kern.o", "tracepoint/power/cpu_frequency")
16✔
763
TEST_SECTION("linux", "cpustat_kern.o", "tracepoint/power/cpu_idle")
16✔
764
TEST_SECTION("linux", "lathist_kern.o", "kprobe/trace_preempt_off")
16✔
765
TEST_SECTION("linux", "lathist_kern.o", "kprobe/trace_preempt_on")
16✔
766
TEST_SECTION("linux", "lwt_len_hist_kern.o", "len_hist")
16✔
767
TEST_SECTION("linux", "map_perf_test_kern.o", "kprobe/sys_getegid")
16✔
768
TEST_SECTION("linux", "map_perf_test_kern.o", "kprobe/sys_geteuid")
16✔
769
TEST_SECTION("linux", "map_perf_test_kern.o", "kprobe/sys_getgid")
16✔
770
TEST_SECTION("linux", "map_perf_test_kern.o", "kprobe/sys_getpgid")
16✔
771
TEST_SECTION("linux", "map_perf_test_kern.o", "kprobe/sys_getppid")
16✔
772
TEST_SECTION("linux", "map_perf_test_kern.o", "kprobe/sys_gettid")
16✔
773
TEST_SECTION("linux", "map_perf_test_kern.o", "kprobe/sys_getuid")
16✔
774
TEST_SECTION("linux", "offwaketime_kern.o", "kprobe/try_to_wake_up")
16✔
775
TEST_SECTION("linux", "offwaketime_kern.o", "tracepoint/sched/sched_switch")
16✔
776
TEST_SECTION("linux", "sampleip_kern.o", "perf_event")
16✔
777
TEST_SECTION("linux", "sock_flags_kern.o", "cgroup/sock1")
16✔
778
TEST_SECTION("linux", "sock_flags_kern.o", "cgroup/sock2")
16✔
779
TEST_SECTION_LEGACY("linux", "sockex1_kern.o", "socket1")
33✔
780
TEST_SECTION_LEGACY("linux", "sockex2_kern.o", "socket2")
33✔
781
TEST_SECTION_LEGACY("linux", "sockex3_kern.o", "socket/3")
33✔
782
TEST_SECTION_LEGACY("linux", "sockex3_kern.o", "socket/4")
33✔
783
TEST_SECTION_LEGACY("linux", "sockex3_kern.o", "socket/1")
33✔
784
TEST_SECTION_LEGACY("linux", "sockex3_kern.o", "socket/2")
33✔
785
TEST_SECTION_LEGACY("linux", "sockex3_kern.o", "socket/0")
33✔
786
TEST_SECTION("linux", "spintest_kern.o", "kprobe/__htab_percpu_map_update_elem")
16✔
787
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_lock")
16✔
788
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_lock_bh")
16✔
789
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_lock_irq")
16✔
790
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_lock_irqsave")
16✔
791
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_trylock_bh")
16✔
792
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_trylock")
16✔
793
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_unlock")
16✔
794
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_unlock_bh")
16✔
795
TEST_SECTION("linux", "spintest_kern.o", "kprobe/_raw_spin_unlock_irqrestore")
16✔
796
TEST_SECTION("linux", "spintest_kern.o", "kprobe/htab_map_alloc")
16✔
797
TEST_SECTION("linux", "spintest_kern.o", "kprobe/htab_map_update_elem")
16✔
798
TEST_SECTION("linux", "spintest_kern.o", "kprobe/mutex_spin_on_owner")
16✔
799
TEST_SECTION("linux", "spintest_kern.o", "kprobe/rwsem_spin_on_owner")
16✔
800
TEST_SECTION("linux", "spintest_kern.o", "kprobe/spin_lock")
16✔
801
TEST_SECTION("linux", "spintest_kern.o", "kprobe/spin_unlock")
16✔
802
TEST_SECTION("linux", "spintest_kern.o", "kprobe/spin_unlock_irqrestore")
16✔
803
TEST_SECTION("linux", "syscall_tp_kern.o", "tracepoint/syscalls/sys_enter_open")
17✔
804
TEST_SECTION("linux", "syscall_tp_kern.o", "tracepoint/syscalls/sys_exit_open")
16✔
805
TEST_SECTION("linux", "task_fd_query_kern.o", "kprobe/blk_start_request")
16✔
806
TEST_SECTION("linux", "task_fd_query_kern.o", "kretprobe/blk_account_io_completion")
16✔
807
TEST_SECTION("linux", "tc_l2_redirect_kern.o", "drop_non_tun_vip")
16✔
808
TEST_SECTION("linux", "tc_l2_redirect_kern.o", "l2_to_ip6tun_ingress_redirect")
16✔
809
TEST_SECTION("linux", "tc_l2_redirect_kern.o", "l2_to_iptun_ingress_forward")
16✔
810
TEST_SECTION("linux", "tc_l2_redirect_kern.o", "l2_to_iptun_ingress_redirect")
16✔
811
TEST_SECTION("linux", "tcp_basertt_kern.o", "sockops")
16✔
812
TEST_SECTION("linux", "tcp_bufs_kern.o", "sockops")
16✔
813
TEST_SECTION("linux", "tcp_cong_kern.o", "sockops")
16✔
814
TEST_SECTION("linux", "tcp_iw_kern.o", "sockops")
16✔
815
TEST_SECTION_LEGACY("linux", "tcbpf1_kern.o", "classifier")
33✔
816
TEST_SECTION("linux", "tcbpf1_kern.o", "clone_redirect_recv")
16✔
817
TEST_SECTION("linux", "tcbpf1_kern.o", "clone_redirect_xmit")
16✔
818
TEST_SECTION("linux", "tcbpf1_kern.o", "redirect_recv")
16✔
819
TEST_SECTION("linux", "tcbpf1_kern.o", "redirect_xmit")
16✔
820
TEST_SECTION("linux", "tcp_clamp_kern.o", "sockops")
16✔
821
TEST_SECTION("linux", "tcp_rwnd_kern.o", "sockops")
16✔
822
TEST_SECTION("linux", "tcp_synrto_kern.o", "sockops")
16✔
823
TEST_SECTION("linux", "test_cgrp2_tc_kern.o", "filter")
16✔
824
TEST_SECTION("linux", "test_current_task_under_cgroup_kern.o", "kprobe/sys_sync")
16✔
825
TEST_SECTION("linux", "test_overhead_kprobe_kern.o", "kprobe/__set_task_comm")
16✔
826
TEST_SECTION("linux", "test_overhead_kprobe_kern.o", "kprobe/urandom_read")
16✔
827
TEST_SECTION("linux", "test_overhead_raw_tp_kern.o", "raw_tracepoint/task_rename")
16✔
828
TEST_SECTION("linux", "test_overhead_raw_tp_kern.o", "raw_tracepoint/urandom_read")
16✔
829
TEST_SECTION("linux", "test_overhead_tp_kern.o", "tracepoint/random/urandom_read")
16✔
830
TEST_SECTION("linux", "test_overhead_tp_kern.o", "tracepoint/task/task_rename")
16✔
831
TEST_SECTION("linux", "test_probe_write_user_kern.o", "kprobe/sys_connect")
16✔
832
TEST_SECTION("linux", "trace_event_kern.o", "perf_event")
16✔
833
TEST_SECTION("linux", "trace_output_kern.o", "kprobe/sys_write")
16✔
834
TEST_SECTION("linux", "tracex1_kern.o", "kprobe/__netif_receive_skb_core")
16✔
835
TEST_SECTION("linux", "tracex2_kern.o", "kprobe/kfree_skb")
16✔
836
TEST_SECTION("linux", "tracex2_kern.o", "kprobe/sys_write")
16✔
837
TEST_SECTION("linux", "tracex3_kern.o", "kprobe/blk_account_io_completion")
16✔
838
TEST_SECTION("linux", "tracex3_kern.o", "kprobe/blk_start_request")
16✔
839
TEST_SECTION("linux", "tracex4_kern.o", "kprobe/kmem_cache_free")
16✔
840
TEST_SECTION("linux", "tracex4_kern.o", "kretprobe/kmem_cache_alloc_node")
16✔
841
TEST_SECTION("linux", "tracex5_kern.o", "kprobe/__seccomp_filter")
16✔
842
TEST_SECTION("linux", "tracex5_kern.o", "kprobe/0")
16✔
843
TEST_SECTION("linux", "tracex5_kern.o", "kprobe/1")
16✔
844
TEST_SECTION("linux", "tracex5_kern.o", "kprobe/9")
16✔
845
TEST_SECTION("linux", "tracex6_kern.o", "kprobe/htab_map_get_next_key")
16✔
846
TEST_SECTION("linux", "tracex6_kern.o", "kprobe/htab_map_lookup_elem")
16✔
847
TEST_SECTION("linux", "tracex7_kern.o", "kprobe/open_ctree")
16✔
848
TEST_SECTION("linux", "xdp_adjust_tail_kern.o", "xdp_icmp")
16✔
849
TEST_SECTION("linux", "xdp_fwd_kern.o", "xdp_fwd")
16✔
850
TEST_SECTION("linux", "xdp_fwd_kern.o", "xdp_fwd_direct")
16✔
851
TEST_SECTION("linux", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_cpumap_enqueue")
16✔
852
TEST_SECTION("linux", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_cpumap_kthread")
16✔
853
TEST_SECTION("linux", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_devmap_xmit")
16✔
854
TEST_SECTION("linux", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_exception")
16✔
855
TEST_SECTION("linux", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_redirect")
16✔
856
TEST_SECTION("linux", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_redirect_err")
16✔
857
TEST_SECTION("linux", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_redirect_map")
16✔
858
TEST_SECTION("linux", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_redirect_map_err")
16✔
859
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "xdp_cpu_map0")
16✔
860
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "xdp_cpu_map1_touch_data")
16✔
861
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "xdp_cpu_map2_round_robin")
16✔
862
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "xdp_cpu_map3_proto_separate")
16✔
863
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "xdp_cpu_map4_ddos_filter_pktgen")
16✔
864
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "xdp_cpu_map5_lb_hash_ip_pairs")
16✔
865
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_cpumap_enqueue")
16✔
866
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_cpumap_kthread")
16✔
867
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_exception")
16✔
868
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_redirect_err")
16✔
869
TEST_SECTION("linux", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_redirect_map_err")
16✔
870
TEST_SECTION("linux", "xdp_redirect_kern.o", "xdp_redirect")
16✔
871
TEST_SECTION("linux", "xdp_redirect_kern.o", "xdp_redirect_dummy")
16✔
872
TEST_SECTION("linux", "xdp_redirect_map_kern.o", "xdp_redirect_dummy")
16✔
873
TEST_SECTION("linux", "xdp_redirect_map_kern.o", "xdp_redirect_map")
16✔
874
TEST_SECTION("linux", "xdp_router_ipv4_kern.o", "xdp_router_ipv4")
16✔
875
TEST_SECTION("linux", "xdp_rxq_info_kern.o", "xdp_prog0")
16✔
876
TEST_SECTION("linux", "xdp_sample_pkts_kern.o", "xdp_sample")
16✔
877
TEST_SECTION("linux", "xdp_tx_iptunnel_kern.o", "xdp_tx_iptunnel")
16✔
878
TEST_SECTION("linux", "xdp1_kern.o", "xdp1")
16✔
879
TEST_SECTION("linux", "xdp2_kern.o", "xdp1")
16✔
880
TEST_SECTION("linux", "xdp2skb_meta_kern.o", "tc_mark")
16✔
881
TEST_SECTION("linux", "xdp2skb_meta_kern.o", "xdp_mark")
16✔
882
TEST_SECTION("linux", "xdpsock_kern.o", "xdp_sock")
16✔
883
// Finally passes; still requires double-check
884
TEST_SECTION("linux", "map_perf_test_kern.o", "kprobe/sys_connect")
16✔
885

886
TEST_SECTION("prototype-kernel", "napi_monitor_kern.o", "tracepoint/irq/softirq_entry")
16✔
887
TEST_SECTION("prototype-kernel", "napi_monitor_kern.o", "tracepoint/irq/softirq_exit")
16✔
888
TEST_SECTION("prototype-kernel", "napi_monitor_kern.o", "tracepoint/irq/softirq_raise")
16✔
889
TEST_SECTION("prototype-kernel", "napi_monitor_kern.o", "tracepoint/napi/napi_poll")
16✔
890
TEST_SECTION("prototype-kernel", "tc_bench01_redirect_kern.o", "ingress_redirect")
16✔
891
TEST_SECTION("prototype-kernel", "xdp_bench01_mem_access_cost_kern.o", "xdp_bench01")
16✔
892
TEST_SECTION("prototype-kernel", "xdp_bench02_drop_pattern_kern.o", "xdp_bench02")
16✔
893
TEST_SECTION("prototype-kernel", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_redirect")
16✔
894
TEST_SECTION("prototype-kernel", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_redirect_err")
16✔
895
TEST_SECTION("prototype-kernel", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_redirect_map_err")
16✔
896
TEST_SECTION("prototype-kernel", "xdp_monitor_kern.o", "tracepoint/xdp/xdp_redirect_map")
16✔
897
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "xdp_cpu_map0")
16✔
898
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "xdp_cpu_map2_round_robin")
16✔
899
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_cpumap_enqueue")
16✔
900
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_cpumap_kthread")
16✔
901
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_exception")
16✔
902
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_redirect_err")
16✔
903
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "tracepoint/xdp/xdp_redirect_map_err")
16✔
904
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "xdp_cpu_map1_touch_data")
16✔
905
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "xdp_cpu_map3_proto_separate")
16✔
906
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "xdp_cpu_map4_ddos_filter_pktgen")
16✔
907
TEST_SECTION("prototype-kernel", "xdp_redirect_cpu_kern.o", "xdp_cpu_map5_ip_l3_flow_hash")
16✔
908
TEST_SECTION("prototype-kernel", "xdp_redirect_err_kern.o", "xdp_redirect_dummy")
16✔
909
TEST_SECTION("prototype-kernel", "xdp_redirect_err_kern.o", "xdp_redirect_map")
16✔
910
TEST_SECTION("prototype-kernel", "xdp_redirect_err_kern.o", "xdp_redirect_map_rr")
16✔
911
TEST_SECTION("prototype-kernel", "xdp_tcpdump_kern.o", "xdp_tcpdump_to_perf_ring")
16✔
912
TEST_SECTION("prototype-kernel", "xdp_ttl_kern.o", "xdp_ttl")
16✔
913
TEST_SECTION("prototype-kernel", "xdp_vlan01_kern.o", "tc_vlan_push")
16✔
914
TEST_SECTION("prototype-kernel", "xdp_vlan01_kern.o", "xdp_drop_vlan_4011")
16✔
915
TEST_SECTION("prototype-kernel", "xdp_vlan01_kern.o", "xdp_vlan_change")
16✔
916
TEST_SECTION("prototype-kernel", "xdp_vlan01_kern.o", "xdp_vlan_remove_outer")
16✔
917
TEST_SECTION("prototype-kernel", "xdp_vlan01_kern.o", "xdp_vlan_remove_outer2")
16✔
918

919
TEST_SECTION("ovs", "datapath.o", "tail-0")
16✔
920
TEST_SECTION("ovs", "datapath.o", "tail-1")
16✔
921
TEST_SECTION("ovs", "datapath.o", "tail-2")
16✔
922
TEST_SECTION_LEGACY("ovs", "datapath.o", "tail-3")
33✔
923
TEST_SECTION("ovs", "datapath.o", "tail-4")
16✔
924
TEST_SECTION("ovs", "datapath.o", "tail-5")
16✔
925
TEST_SECTION("ovs", "datapath.o", "tail-7")
16✔
926
TEST_SECTION("ovs", "datapath.o", "tail-8")
16✔
927
TEST_SECTION("ovs", "datapath.o", "tail-11")
16✔
928
TEST_SECTION("ovs", "datapath.o", "tail-12")
16✔
929
TEST_SECTION("ovs", "datapath.o", "tail-13")
16✔
930
TEST_SECTION_LEGACY("ovs", "datapath.o", "tail-32")
33✔
931
TEST_SECTION("ovs", "datapath.o", "tail-33")
16✔
932
TEST_SECTION("ovs", "datapath.o", "tail-35")
16✔
933
TEST_SECTION("ovs", "datapath.o", "af_xdp")
16✔
934
TEST_SECTION("ovs", "datapath.o", "downcall")
16✔
935
TEST_SECTION("ovs", "datapath.o", "egress")
16✔
936
TEST_SECTION("ovs", "datapath.o", "ingress")
16✔
937
TEST_SECTION("ovs", "datapath.o", "xdp")
16✔
938

939
TEST_SECTION_LEGACY("suricata", "bypass_filter.o", "filter")
33✔
940
TEST_SECTION_LEGACY("suricata", "lb.o", "loadbalancer")
33✔
941
TEST_SECTION("suricata", "filter.o", "filter")
16✔
942
TEST_SECTION("suricata", "vlan_filter.o", "filter")
16✔
943
TEST_SECTION("suricata", "xdp_filter.o", "xdp")
16✔
944

945
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_accept4_e")
16✔
946
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_empty")
16✔
947
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_pread64_e")
16✔
948
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_preadv64_e")
16✔
949
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_pwrite64_e")
16✔
950
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_single_x")
16✔
951
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_sysdigevent_e")
16✔
952
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/terminate_filler")
16✔
953
TEST_SECTION("falco", "probe.o", "raw_tracepoint/page_fault_kernel")
16✔
954
TEST_SECTION("falco", "probe.o", "raw_tracepoint/page_fault_user")
16✔
955
TEST_SECTION("falco", "probe.o", "raw_tracepoint/sched_switch")
16✔
956
TEST_SECTION("falco", "probe.o", "raw_tracepoint/signal_deliver")
16✔
957

958
// Test some programs that should pass verification except when the strict flag is set.
959
TEST_SECTION_REJECT_IF_STRICT("build", "mapoverflow.o", ".text")
30✔
960
TEST_SECTION_REJECT_IF_STRICT("build", "mapunderflow.o", ".text")
30✔
961

962
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_access_e")
16✔
963
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_bpf_x")
16✔
964
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_brk_munmap_mmap_x")
16✔
965
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_eventfd_e")
16✔
966
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_execve_e")
16✔
967
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_generic")
16✔
968
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_getrlimit_setrlimit_e")
16✔
969
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_getrlimit_setrlrimit_x")
16✔
970
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_mount_e")
16✔
971
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_pagefault_e")
16✔
972
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_procexit_e")
16✔
973
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_single")
16✔
974
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_unshare_e")
16✔
975
TEST_SECTION("falco", "probe.o", "raw_tracepoint/sched_process_exit")
16✔
976
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_chmod_x")
16✔
977
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_fchmod_x")
16✔
978
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_fcntl_e")
16✔
979
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_flock_e")
16✔
980
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_prlimit_e")
16✔
981
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_prlimit_x")
16✔
982
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_ptrace_e")
16✔
983
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_quotactl_e")
16✔
984
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_semop_x")
16✔
985
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_send_e")
16✔
986
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_sendfile_x")
16✔
987
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_setns_e")
16✔
988
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_shutdown_e")
16✔
989
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_fchmodat_x")
16✔
990
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_futex_e")
16✔
991
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_lseek_e")
16✔
992
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_mkdirat_x")
16✔
993
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_ptrace_x")
16✔
994
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_quotactl_x")
16✔
995
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_semget_e")
16✔
996
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_signaldeliver_e")
16✔
997
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_symlinkat_x")
16✔
998
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_unlinkat_x")
16✔
999
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_writev_e")
16✔
1000
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_llseek_e")
16✔
1001
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_pwritev_e")
16✔
1002
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_renameat_x")
16✔
1003
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_semctl_e")
16✔
1004
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sched_switch_e")
16✔
1005
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_linkat_x")
16✔
1006
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_renameat2_x")
16✔
1007
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_sendfile_e")
16✔
1008
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_setsockopt_x")
16✔
1009
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_getresuid_and_gid_x")
16✔
1010
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_mmap_e")
16✔
1011
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_socket_x")
16✔
1012
TEST_SECTION("falco", "probe.o", "raw_tracepoint/sys_enter")
16✔
1013
TEST_SECTION("falco", "probe.o", "raw_tracepoint/sys_exit")
16✔
1014
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_pipe_x")
16✔
1015
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_socketpair_x")
16✔
1016
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_creat_x")
16✔
1017
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_open_x")
16✔
1018
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_openat_x")
16✔
1019
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/sys_autofill")
16✔
1020
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/proc_startupdate_3")
16✔
1021
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/proc_startupdate")
16✔
1022
TEST_SECTION("falco", "probe.o", "raw_tracepoint/filler/proc_startupdate_2")
16✔
1023

1024
// Falco expected-fail group A (offset lower-bound loss):
1025
// In these sections, a shared-pointer base is incremented by a scalar offset that
1026
// is only upper-bounded by control-flow assumptions. At merge points, the scalar's
1027
// lower bound is lost, so valid_access(..., write) cannot prove offset >= 0.
1028
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_nanosleep_e")
19✔
1029
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_poll_x")
19✔
1030
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_poll_e")
19✔
1031
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_ppoll_e")
19✔
1032
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_getsockopt_x")
19✔
1033

1034
// Falco expected-fail group B (size lower-bound loss at correlated joins):
1035
// Common pattern:
1036
// 1) branch constrains size_candidate (e.g., assume const > r2)
1037
// 2) alternate branch writes a concrete fallback size
1038
// 3) join loses the branch/value correlation and retains only size <= const
1039
// Then ValidSize for probe_read* cannot prove r2 >= 0.
1040
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_socket_bind_x")
19✔
1041
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_recvmsg_x_2")
19✔
1042
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_sendmsg_e")
19✔
1043
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_connect_x")
19✔
1044
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_sendto_e")
19✔
1045
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_accept_x")
19✔
1046
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_read_x")
19✔
1047
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_recv_x")
19✔
1048
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_recvmsg_x")
19✔
1049
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_send_x")
19✔
1050
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_readv_preadv_x")
19✔
1051
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_write_x")
19✔
1052
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_writev_pwritev_x")
19✔
1053
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_sendmsg_x")
19✔
1054
TEST_SECTION_FAIL("falco", "probe.o", "raw_tracepoint/filler/sys_recvfrom_x")
19✔
1055

1056
TEST_PROGRAM("build", "bpf2bpf.o", ".text", "add1", 2);
19✔
1057
TEST_PROGRAM("build", "bpf2bpf.o", ".text", "add2", 2);
19✔
1058
TEST_PROGRAM("build", "bpf2bpf.o", "test", "func", 1);
16✔
1059

1060
TEST_SECTION("build", "byteswap.o", ".text")
16✔
1061
TEST_SECTION("build", "stackok.o", ".text")
16✔
1062
TEST_SECTION("build", "packet_start_ok.o", "xdp")
16✔
1063
TEST_SECTION("build", "packet_access.o", "xdp")
16✔
1064
TEST_SECTION("build", "tail_call.o", "xdp_prog")
16✔
1065
TEST_SECTION("build", "map_in_map.o", ".text")
16✔
1066
TEST_SECTION("build", "map_in_map_anonymous.o", ".text")
16✔
1067
TEST_SECTION("build", "map_in_map_legacy.o", ".text")
16✔
1068
TEST_SECTION("build", "store_map_value_in_map.o", ".text")
16✔
1069
TEST_SECTION("build", "twomaps.o", ".text");
16✔
1070
TEST_SECTION("build", "twostackvars.o", ".text");
16✔
1071
TEST_SECTION("build", "twotypes.o", ".text");
16✔
1072
TEST_SECTION("build", "global_variable.o", ".text")
16✔
1073
TEST_PROGRAM("build", "prog_array.o", ".text", "func", 5);
25✔
1074
TEST_PROGRAM("build", "prog_array.o", ".text", "func0", 5);
25✔
1075
TEST_PROGRAM("build", "prog_array.o", ".text", "func1", 5);
25✔
1076
TEST_PROGRAM("build", "prog_array.o", ".text", "func2", 5);
25✔
1077
TEST_PROGRAM("build", "prog_array.o", ".text", "func3", 5);
25✔
1078

1079
// Test some programs that ought to fail verification.
1080
TEST_SECTION_REJECT("build", "badmapptr.o", "test")
16✔
1081
TEST_SECTION_REJECT("build", "badhelpercall.o", ".text")
16✔
1082
TEST_SECTION_REJECT("build", "ctxoffset.o", "sockops")
16✔
1083
TEST_SECTION_FAIL("build", "dependent_read.o", "xdp")
19✔
1084
TEST_SECTION_REJECT("build", "exposeptr.o", ".text")
16✔
1085
TEST_SECTION_REJECT("build", "exposeptr2.o", ".text")
16✔
1086
TEST_SECTION_REJECT("build", "mapvalue-overrun.o", ".text")
16✔
1087
TEST_SECTION_REJECT("build", "nullmapref.o", "test")
16✔
1088
TEST_SECTION_REJECT("build", "packet_overflow.o", "xdp")
16✔
1089
TEST_SECTION_REJECT("build", "packet_reallocate.o", "socket_filter")
16✔
1090
TEST_SECTION_REJECT("build", "tail_call_bad.o", "xdp_prog")
16✔
1091
TEST_SECTION_REJECT("build", "ringbuf_uninit.o", ".text");
16✔
1092

1093
// The following eBPF programs currently fail verification.
1094
// If the verifier is later updated to accept them, these should
1095
// be changed to TEST_SECTION().
1096

1097
// This fails due to correlated branches not being handled precisely enough,
1098
// Unless the analysis tracks the correlation between shared_offset and the type of another register,
1099
// which is probably arbitrary and brittle.
1100
TEST_SECTION_FAIL("prototype-kernel", "xdp_ddos01_blacklist_kern.o", "xdp_prog")
19✔
1101

1102
// Unsupported: ebpf-function
1103
TEST_SECTION_FAIL("prototype-kernel", "xdp_ddos01_blacklist_kern.o", ".text")
19✔
1104

1105
// Unsupported: implications are lost in correlated branches
1106
TEST_SECTION_FAIL("cilium", "bpf_xdp_dsr_linux.o", "2/7")
19✔
1107

1108
// Failure: 166:168: Upper bound must be at most packet_size (valid_access(r4.offset, width=2) for read)
1109
// This is the result of merging two branches, one with value 0 and another with value -22,
1110
// then checking that the result is != 0. The minor issue is not handling the int32 comparison precisely enough.
1111
// The bigger issue is that the convexity of the numerical domain means that precise handling would still get
1112
// [-22, -1] which is not sufficient (at most -2 is needed)
1113
TEST_SECTION_FAIL("cilium", "bpf_xdp_dsr_linux.o", "2/10")
19✔
1114
TEST_SECTION_FAIL("cilium", "bpf_xdp_dsr_linux.o", "2/21")
19✔
1115
TEST_SECTION_FAIL_SLOW("cilium", "bpf_xdp_dsr_linux.o", "2/24")
19✔
1116

1117
TEST_SECTION_FAIL_SLOW("cilium", "bpf_xdp_dsr_linux.o", "2/15")
19✔
1118

1119
TEST_SECTION_FAIL("cilium", "bpf_xdp_dsr_linux.o", "2/17")
19✔
1120

1121
// Failure: trying to access r4 where r4.packet_offset=[0, 255] and packet_size=[54, 65534]
1122
// Root cause: r5.value=[0, 65535] 209: w5 >>= 8; clears r5 instead of yielding [0, 255]
1123
TEST_SECTION_FAIL("cilium", "bpf_xdp_dsr_linux.o", "2/18")
19✔
1124
TEST_SECTION_FAIL("cilium", "bpf_xdp_snat_linux.o", "2/10")
19✔
1125
TEST_SECTION_FAIL("cilium", "bpf_xdp_snat_linux.o", "2/18")
19✔
1126

1127
TEST_SECTION_FAIL_SLOW("cilium", "bpf_xdp_dsr_linux.o", "2/19")
19✔
1128

1129
// Failure: 230: Upper bound must be at most packet_size (valid_access(r3.offset+32, width=8) for write)
1130
// r3.packet_offset=[0, 82] and packet_size=[34, 65534]
1131
// looks like a combination of misunderstanding the value passed to xdp_adjust_tail()
1132
// which is "r7.value=[0, 82]; w7 -= r9;" where r9.value where "r7.value-r9.value<=48"
1133
TEST_SECTION_FAIL("cilium", "bpf_xdp_dsr_linux.o", "2/20")
19✔
1134

1135
TEST_SECTION_FAIL("cilium", "bpf_xdp_snat_linux.o", "2/7")
19✔
1136
TEST_SECTION_FAIL_SLOW("cilium", "bpf_xdp_snat_linux.o", "2/15")
19✔
1137
TEST_SECTION_FAIL("cilium", "bpf_xdp_snat_linux.o", "2/17")
19✔
1138
TEST_SECTION_FAIL_SLOW("cilium", "bpf_xdp_snat_linux.o", "2/19")
19✔
1139

1140
// Failure (&255): assert r5.type == number; w5 &= 255;
1141
// fails since in one branch (77) r5 is a number but in another (92:93) it is a packet
1142
TEST_SECTION_FAIL_SLOW("cilium", "bpf_xdp_snat_linux.o", "2/24")
19✔
1143
// Failure (&255): assert r3.type == number; w3 &= 255;
1144
TEST_SECTION_FAIL_SLOW("cilium", "bpf_xdp_dsr_linux.o", "2/16")
19✔
1145
TEST_SECTION_FAIL_SLOW("cilium", "bpf_xdp_snat_linux.o", "2/16")
19✔
1146

1147
// False positive, unknown cause
1148
TEST_SECTION_FAIL("linux", "test_map_in_map_kern.o", "kprobe/sys_connect")
19✔
1149

1150
TEST_SECTION_LEGACY("cilium", "bpf_netdev.o", "from-netdev")
33✔
1151
TEST_SECTION_LEGACY_SLOW("bpf_cilium_test", "bpf_netdev.o", "from-netdev")
33✔
1152
TEST_SECTION_SLOW("cilium", "bpf_lxc.o", "2/7")
16✔
1153
TEST_SECTION_LEGACY_SLOW("cilium", "bpf_lxc.o", "2/10")
33✔
1154
TEST_SECTION_SLOW("cilium", "bpf_lxc.o", "2/11")
16✔
1155
TEST_SECTION_SLOW("cilium", "bpf_lxc.o", "2/12")
16✔
1156

1157
// cilium-core/bpf_host.o
1158
TEST_PROGRAM_FAIL("cilium-core", "bpf_host.o", "tc/entry", "cil_from_netdev", 5)
20✔
1159
TEST_PROGRAM_FAIL("cilium-core", "bpf_host.o", "tc/entry", "cil_from_host", 5)
22✔
1160
TEST_PROGRAM_FAIL("cilium-core", "bpf_host.o", "tc/entry", "cil_to_netdev", 5)
24✔
1161
// - cil_to_host: unsupported function: skc_lookup_tcp
1162
TEST_PROGRAM_FAIL("cilium-core", "bpf_host.o", "tc/entry", "cil_host_policy", 5)
28✔
1163

1164
// cilium-core/bpf_lxc.o
1165
TEST_PROGRAM("cilium-core", "bpf_lxc.o", "tc/entry", "cil_from_container", 4)
23✔
1166
TEST_PROGRAM("cilium-core", "bpf_lxc.o", "tc/entry", "cil_lxc_policy", 4)
23✔
1167
TEST_PROGRAM("cilium-core", "bpf_lxc.o", "tc/entry", "cil_lxc_policy_egress", 4)
23✔
1168
TEST_PROGRAM("cilium-core", "bpf_lxc.o", "tc/entry", "cil_to_container", 4)
23✔
1169

1170
// cilium-core/bpf_network.o
1171
TEST_SECTION("cilium-core", "bpf_network.o", "tc/entry")
16✔
1172

1173
// cilium-core/bpf_overlay.o
1174
TEST_PROGRAM("cilium-core", "bpf_overlay.o", "tc/entry", "cil_from_overlay", 2)
19✔
1175
// - cil_to_overlay: CRAB_ERROR("Bound: inf / inf")
1176

1177
// cilium-core/bpf_sock.o
1178
TEST_SECTION("cilium-core", "bpf_sock.o", "cgroup/connect4")
16✔
1179
TEST_SECTION("cilium-core", "bpf_sock.o", "cgroup/connect6")
16✔
1180
TEST_SECTION("cilium-core", "bpf_sock.o", "cgroup/post_bind4")
16✔
1181
TEST_SECTION("cilium-core", "bpf_sock.o", "cgroup/post_bind6")
16✔
1182
TEST_SECTION("cilium-core", "bpf_sock.o", "cgroup/sendmsg4")
16✔
1183
TEST_SECTION("cilium-core", "bpf_sock.o", "cgroup/sendmsg6")
16✔
1184
TEST_SECTION("cilium-core", "bpf_sock.o", "cgroup/recvmsg4")
16✔
1185
TEST_SECTION_FAIL("cilium-core", "bpf_sock.o", "cgroup/recvmsg6")
19✔
1186
// - bpf_sock.o cgroup/sock_release: invalid helper function id 46
1187

1188
// cilium-core/bpf_wireguard.o
1189
TEST_PROGRAM("cilium-core", "bpf_wireguard.o", "tc/entry", "cil_from_wireguard", 2)
19✔
1190
TEST_PROGRAM("cilium-core", "bpf_wireguard.o", "tc/entry", "cil_to_wireguard", 2)
19✔
1191

1192
// cilium-core/bpf_xdp.o
1193
TEST_SECTION_FAIL("cilium-core", "bpf_xdp.o", "xdp/entry")
19✔
1194

1195
// cilium-examples tests
1196
TEST_SECTION("cilium-examples", "cgroup_skb_bpf_bpfel.o", "cgroup_skb/egress")
16✔
1197
TEST_SECTION("cilium-examples", "kprobe_bpf_bpfel.o", "kprobe/sys_execve")
16✔
1198
TEST_SECTION("cilium-examples", "kprobe_percpu_bpf_bpfel.o", "kprobe/sys_execve")
16✔
1199
TEST_SECTION("cilium-examples", "kprobepin_bpf_bpfel.o", "kprobe/sys_execve")
16✔
1200
TEST_SECTION("cilium-examples", "tracepoint_in_c_bpf_bpfel.o", "tracepoint/kmem/mm_page_alloc")
16✔
1201
TEST_SECTION("cilium-examples", "xdp_bpf_bpfel.o", "xdp")
16✔
1202
// This is TEST_SECTION_FAIL, but with a shorter filename to avoid CATCH2 test name limits.
1203
TEST_CASE("expect failure cilium-examples/uretprobe_x86 uretprobe/bash_readline",
2✔
1204
          "[!shouldfail][verify][samples][cilium-examples]") {
1205
    VERIFY_SECTION("cilium-examples", "uretprobe_bpf_x86_bpfel.o", "uretprobe/bash_readline", {},
19✔
1206
                   &g_ebpf_platform_linux, true);
UNCOV
1207
}
×
1208

1209
TEST_PROGRAM("cilium-examples", "tcx_bpf_bpfel.o", "tc", "ingress_prog_func", 2)
19✔
1210
TEST_PROGRAM("cilium-examples", "tcx_bpf_bpfel.o", "tc", "egress_prog_func", 2)
19✔
1211

1212
static void test_analyze_thread(const Program* prog, const ProgramInfo* info, bool* res) {
4✔
1213
    thread_local_program_info.set(*info);
6✔
1214
    *res = verify(*prog);
4✔
1215
}
4✔
1216

1217
// Test multithreading
1218
TEST_CASE("multithreading", "[verify][multithreading]") {
2✔
1219
    auto raw_progs1 = read_elf("ebpf-samples/bpf_cilium_test/bpf_netdev.o", "2/1", "", {}, &g_ebpf_platform_linux);
8✔
1220
    REQUIRE(raw_progs1.size() == 1);
2✔
1221
    RawProgram raw_prog1 = raw_progs1.back();
2✔
1222
    auto prog_or_error1 = unmarshal(raw_prog1, {});
2✔
1223
    auto inst_seq1 = std::get_if<InstructionSeq>(&prog_or_error1);
2✔
1224
    REQUIRE(inst_seq1);
2✔
1225
    const Program prog1 = Program::from_sequence(*inst_seq1, raw_prog1.info, {});
2✔
1226

1227
    auto raw_progs2 = read_elf("ebpf-samples/bpf_cilium_test/bpf_netdev.o", "2/2", "", {}, &g_ebpf_platform_linux);
8✔
1228
    REQUIRE(raw_progs2.size() == 1);
2✔
1229
    RawProgram raw_prog2 = raw_progs2.back();
2✔
1230
    auto prog_or_error2 = unmarshal(raw_prog2, {});
2✔
1231
    auto inst_seq2 = std::get_if<InstructionSeq>(&prog_or_error2);
2✔
1232
    REQUIRE(inst_seq2);
2✔
1233
    const Program prog2 = Program::from_sequence(*inst_seq2, raw_prog2.info, {});
2✔
1234

1235
    bool res1, res2;
1✔
1236
    std::thread a(test_analyze_thread, &prog1, &raw_prog1.info, &res1);
2✔
1237
    std::thread b(test_analyze_thread, &prog2, &raw_prog2.info, &res2);
2✔
1238
    a.join();
2✔
1239
    b.join();
2✔
1240

1241
    REQUIRE(res1);
2✔
1242
    REQUIRE(res2);
3✔
1243
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc