1// SPDX-License-Identifier: GPL-2.0
2#include <vmlinux.h>
3#include <limits.h>
4#include <bpf/bpf_tracing.h>
5#include <bpf/bpf_helpers.h>
6#include <bpf/bpf_core_read.h>
7#include <bpf/bpf_endian.h>
8#include "bpf_misc.h"
9#include "bpf_experimental.h"
10
11#define check_assert(type, op, name, value)				\
12	SEC("?tc")							\
13	__log_level(2) __failure					\
14	int check_assert_##name(void *ctx)				\
15	{								\
16		type num = bpf_ktime_get_ns();				\
17		bpf_assert(bpf_cmp_unlikely(num, op, value));		\
18		return *(u64 *)num;					\
19	}
20
21__msg(": R0_w=0xffffffff80000000")
22check_assert(s64, ==, eq_int_min, INT_MIN);
23__msg(": R0_w=0x7fffffff")
24check_assert(s64, ==, eq_int_max, INT_MAX);
25__msg(": R0_w=0")
26check_assert(s64, ==, eq_zero, 0);
27__msg(": R0_w=0x8000000000000000 R1_w=0x8000000000000000")
28check_assert(s64, ==, eq_llong_min, LLONG_MIN);
29__msg(": R0_w=0x7fffffffffffffff R1_w=0x7fffffffffffffff")
30check_assert(s64, ==, eq_llong_max, LLONG_MAX);
31
32__msg(": R0_w=scalar(id=1,smax=0x7ffffffe)")
33check_assert(s64, <, lt_pos, INT_MAX);
34__msg(": R0_w=scalar(id=1,smax=-1,umin=0x8000000000000000,var_off=(0x8000000000000000; 0x7fffffffffffffff))")
35check_assert(s64, <, lt_zero, 0);
36__msg(": R0_w=scalar(id=1,smax=0xffffffff7fffffff")
37check_assert(s64, <, lt_neg, INT_MIN);
38
39__msg(": R0_w=scalar(id=1,smax=0x7fffffff)")
40check_assert(s64, <=, le_pos, INT_MAX);
41__msg(": R0_w=scalar(id=1,smax=0)")
42check_assert(s64, <=, le_zero, 0);
43__msg(": R0_w=scalar(id=1,smax=0xffffffff80000000")
44check_assert(s64, <=, le_neg, INT_MIN);
45
46__msg(": R0_w=scalar(id=1,smin=umin=0x80000000,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))")
47check_assert(s64, >, gt_pos, INT_MAX);
48__msg(": R0_w=scalar(id=1,smin=umin=1,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))")
49check_assert(s64, >, gt_zero, 0);
50__msg(": R0_w=scalar(id=1,smin=0xffffffff80000001")
51check_assert(s64, >, gt_neg, INT_MIN);
52
53__msg(": R0_w=scalar(id=1,smin=umin=0x7fffffff,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))")
54check_assert(s64, >=, ge_pos, INT_MAX);
55__msg(": R0_w=scalar(id=1,smin=0,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))")
56check_assert(s64, >=, ge_zero, 0);
57__msg(": R0_w=scalar(id=1,smin=0xffffffff80000000")
58check_assert(s64, >=, ge_neg, INT_MIN);
59
60SEC("?tc")
61__log_level(2) __failure
62__msg(": R0=0 R1=ctx() R2=scalar(smin=0xffffffff80000002,smax=smax32=0x7ffffffd,smin32=0x80000002) R10=fp0")
63int check_assert_range_s64(struct __sk_buff *ctx)
64{
65	struct bpf_sock *sk = ctx->sk;
66	s64 num;
67
68	_Static_assert(_Generic((sk->rx_queue_mapping), s32: 1, default: 0), "type match");
69	if (!sk)
70		return 0;
71	num = sk->rx_queue_mapping;
72	bpf_assert_range(num, INT_MIN + 2, INT_MAX - 2);
73	return *((u8 *)ctx + num);
74}
75
76SEC("?tc")
77__log_level(2) __failure
78__msg(": R1=ctx() R2=scalar(smin=umin=smin32=umin32=4096,smax=umax=smax32=umax32=8192,var_off=(0x0; 0x3fff))")
79int check_assert_range_u64(struct __sk_buff *ctx)
80{
81	u64 num = ctx->len;
82
83	bpf_assert_range(num, 4096, 8192);
84	return *((u8 *)ctx + num);
85}
86
87SEC("?tc")
88__log_level(2) __failure
89__msg(": R0=0 R1=ctx() R2=4096 R10=fp0")
90int check_assert_single_range_s64(struct __sk_buff *ctx)
91{
92	struct bpf_sock *sk = ctx->sk;
93	s64 num;
94
95	_Static_assert(_Generic((sk->rx_queue_mapping), s32: 1, default: 0), "type match");
96	if (!sk)
97		return 0;
98	num = sk->rx_queue_mapping;
99
100	bpf_assert_range(num, 4096, 4096);
101	return *((u8 *)ctx + num);
102}
103
104SEC("?tc")
105__log_level(2) __failure
106__msg(": R1=ctx() R2=4096 R10=fp0")
107int check_assert_single_range_u64(struct __sk_buff *ctx)
108{
109	u64 num = ctx->len;
110
111	bpf_assert_range(num, 4096, 4096);
112	return *((u8 *)ctx + num);
113}
114
115SEC("?tc")
116__log_level(2) __failure
117__msg(": R1=pkt(off=64,r=64) R2=pkt_end() R6=pkt(r=64) R10=fp0")
118int check_assert_generic(struct __sk_buff *ctx)
119{
120	u8 *data_end = (void *)(long)ctx->data_end;
121	u8 *data = (void *)(long)ctx->data;
122
123	bpf_assert(data + 64 <= data_end);
124	return data[128];
125}
126
127SEC("?fentry/bpf_check")
128__failure __msg("At program exit the register R1 has smin=64 smax=64")
129int check_assert_with_return(void *ctx)
130{
131	bpf_assert_with(!ctx, 64);
132	return 0;
133}
134
135char _license[] SEC("license") = "GPL";
136