Skip to content

Commit 0869e50

Browse files
Alexei Starovoitovanakryiko
authored andcommitted
selftests/bpf: Add a testcase for 64-bit bounds propagation issue.
./test_progs-no_alu32 -vv -t twfw Before the 64-bit_into_32-bit fix: 19: (25) if r1 > 0x3f goto pc+6 R1_w=inv(id=0,umax_value=63,var_off=(0x0; 0xff),s32_max_value=255,u32_max_value=255) and eventually: invalid access to map value, value_size=8 off=7 size=8 R6 max value is outside of the allowed memory range libbpf: failed to load object 'no_alu32/twfw.o' After the fix: 19: (25) if r1 > 0x3f goto pc+6 R1_w=inv(id=0,umax_value=63,var_off=(0x0; 0x3f)) verif_twfw:OK Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: Yonghong Song <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 388e2c0 commit 0869e50

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,8 @@ void test_verif_scale_seg6_loop()
202202
{
203203
scale_test("test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL, false);
204204
}
205+
206+
void test_verif_twfw()
207+
{
208+
scale_test("twfw.o", BPF_PROG_TYPE_CGROUP_SKB, false);
209+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2021 Facebook */
3+
#include <linux/types.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include <linux/bpf.h>
6+
#include <stdint.h>
7+
8+
#define TWFW_MAX_TIERS (64)
9+
/*
10+
* load is successful
11+
* #define TWFW_MAX_TIERS (64u)$
12+
*/
13+
14+
struct twfw_tier_value {
15+
unsigned long mask[1];
16+
};
17+
18+
struct rule {
19+
uint8_t seqnum;
20+
};
21+
22+
struct rules_map {
23+
__uint(type, BPF_MAP_TYPE_ARRAY);
24+
__type(key, __u32);
25+
__type(value, struct rule);
26+
__uint(max_entries, 1);
27+
};
28+
29+
struct tiers_map {
30+
__uint(type, BPF_MAP_TYPE_ARRAY);
31+
__type(key, __u32);
32+
__type(value, struct twfw_tier_value);
33+
__uint(max_entries, 1);
34+
};
35+
36+
struct rules_map rules SEC(".maps");
37+
struct tiers_map tiers SEC(".maps");
38+
39+
SEC("cgroup_skb/ingress")
40+
int twfw_verifier(struct __sk_buff* skb)
41+
{
42+
const uint32_t key = 0;
43+
const struct twfw_tier_value* tier = bpf_map_lookup_elem(&tiers, &key);
44+
if (!tier)
45+
return 1;
46+
47+
struct rule* rule = bpf_map_lookup_elem(&rules, &key);
48+
if (!rule)
49+
return 1;
50+
51+
if (rule && rule->seqnum < TWFW_MAX_TIERS) {
52+
/* rule->seqnum / 64 should always be 0 */
53+
unsigned long mask = tier->mask[rule->seqnum / 64];
54+
if (mask)
55+
return 0;
56+
}
57+
return 1;
58+
}

0 commit comments

Comments
 (0)